1b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
2b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
3b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
4b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Licensed under the Apache License, Version 2.0 (the "License");
5b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * you may not use this file except in compliance with the License.
6b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * You may obtain a copy of the License at
7b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
8b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *     http://www.apache.org/licenses/LICENSE-2.0
9b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
10b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Unless required by applicable law or agreed to in writing, software
11b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * distributed under the License is distributed on an "AS IS" BASIS,
12b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * See the License for the specific language governing permissions and
14b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * limitations under the License.
15b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
16b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**
17b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * @file picoos.c
18b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
19b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * Copyright (C) 2008-2009 SVOX AG, Baslerstr. 30, 8048 Zuerich, Switzerland
20b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * All rights reserved.
21b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
22b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * History:
23b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * - 2009-04-20 -- initial version
24b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
25b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
26b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
27b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include <stdarg.h>
28b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodefs.h"
29b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picopal.h"
30b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picoos.h"
31b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#include "picodbg.h"
32b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
33b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
34b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern "C" {
35b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
36b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#if 0
37b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
38b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
39b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
40b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
41b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_SVOXFileHeader (picoos_char *)" (C) SVOX AG "
42b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
43b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **********************************************
44b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * default error and warning messages
45b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * **********************************************/
46b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
47b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
48b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_NUMBER_FORMAT  (picoos_char *)  "wrong number format"
49b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_MAX_NUM_EXCEED (picoos_char *)  "number exceeded"
50b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_NAME_CONFLICT  (picoos_char *)  "name conflict"
51b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_NAME_UNDEFINED (picoos_char *)  "name undefined"
52b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_NAME_ILLEGAL   (picoos_char *)  "illegal name"
53b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
54b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* buffer interaction */
55b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_BUF_OVERFLOW   (picoos_char *)   "buffer overflow"
56b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_BUF_UNDERFLOW  (picoos_char *)   "buffer underflow"
57b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_BUF_IGNORE     (picoos_char *)   "buffer error"
58b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
59b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* memory allocation */
60b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_OUT_OF_MEM     (picoos_char *)   "out of memory"
61b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
62b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* files */
63b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_CANT_OPEN_FILE       (picoos_char *) "cannot open file"
64b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_UNEXPECTED_FILE_TYPE (picoos_char *) "unexpected file type"
65b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_FILE_CORRUPT         (picoos_char *) "corrupt file"
66b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_FILE_NOT_FOUND       (picoos_char *) "file not found"
67b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
68b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* resources */
69b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_RESOURCE_BUSY         (picoos_char *)  "resource is busy"
70b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_RESOURCE_MISSING      (picoos_char *)  "cannot find resource"
71b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
72b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* knowledge bases */
73b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_EXC_KB_MISSING     (picoos_char *)  "knowledge base missing"
74b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
75b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* runtime exceptions (programming problems, usually a bug. E.g. trying to access null pointer) */
76b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_ERR_NULLPTR_ACCESS     (picoos_char *)   "access violation"
77b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_ERR_INVALID_HANDLE     (picoos_char *)   "invalid handle value"
78b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_ERR_INVALID_ARGUMENT   (picoos_char *)   "invalid argument supplied"
79b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_ERR_INDEX_OUT_OF_RANGE (picoos_char *)   "index out of range"
80b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
81b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
82b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* errors ("external" errors, e.g. hardware failure. Usually cannot be dealt with from inside pico.) */
83b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_ERR_OTHER         (picoos_char *) "other error"
84b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
85b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_ERR_PU            (picoos_char *) "error in processing unit"
86b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
87b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* WARNINGS */
88b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
89b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* general */
90b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_INCOMPLETE    (picoos_char *)  "incomplete output"
91b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_FALLBACK      (picoos_char *)  "using fall-back"
92b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_OTHER         (picoos_char *)  "other warning"
93b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
94b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* resources */
95b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_KB_OVERWRITE          (picoos_char *)  "overwriting knowledge base"
96b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_RESOURCE_DOUBLE_LOAD  (picoos_char *)  "resource already loaded"
97b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
98b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* decision trees */
99b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_INVECTOR        (picoos_char *)  "input vector not constructed"
100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_CLASSIFICATION  (picoos_char *)  "output not classified"
101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_OUTVECTOR       (picoos_char *)  "output vector not decomposed"
102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* processing units */
104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_PU_IRREG_ITEM   (picoos_char *)  "irregular item in processing unit"
105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_MSG_WARN_PU_DISCARD_BUF  (picoos_char *)  "discarding processing unit buffer"
106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **********************************************
109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * wrappers for picopal functions
110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * **********************************************/
111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_int32 picoos_atoi(const picoos_char *s)
113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_int32)picopal_atoi((const picoos_char *)s);
115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_int8 picoos_strcmp(const picoos_char *a, const picoos_char *b)
119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int32 res = picopal_strcmp((const picopal_char *)a,
121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (const picopal_char *)b);
122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_int8) ((res < 0) ? -1 : (res > 0) ? 1 : 0);
123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_int8 picoos_strncmp(const picoos_char *a, const picoos_char *b, picoos_objsize_t siz)
125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int32 res = picopal_strncmp((const picopal_char *)a,
127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (const picopal_char *)b, siz);
128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_int8) ((res < 0) ? -1 : (res > 0) ? 1 : 0);
129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint32 picoos_strlen(const picoos_char *s)
132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_uint32)picopal_strlen((const picopal_char *)s);
134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_char *picoos_strchr(const picoos_char *s, picoos_char c)
137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_char *)picopal_strchr((const picopal_char *)s,
139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (picopal_char)c);
140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_char *picoos_strstr(const picoos_char *s, const picoos_char * substr)
143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_char *)picopal_strstr((const picopal_char *)s,
145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (const picopal_char *)substr);
146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_int16 picoos_slprintf(picoos_char * b, picoos_uint32 bsize, const picoos_char *f, ...)
149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_int16 i;
151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_list args;
152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_start(args, (char *)f);
154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = (picoos_int16)picopal_vslprintf((picoos_char *) b, bsize, (const picoos_char *)f, args);
155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_end(args);
156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return i;
157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_char *picoos_strcpy(picoos_char *d, const picoos_char *s)
160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_char *)picopal_strcpy((picopal_char *)d,
162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (const picopal_char *)s);
163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_char *picoos_strcat(picoos_char *d, const picoos_char *s)
166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_char *)picopal_strcat((picopal_char *)d,
168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (const picopal_char *)s);
169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_objsize_t picoos_strlcpy(picoos_char *dst, const picoos_char *src, picoos_objsize_t siz)
172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_objsize_t) picopal_strlcpy((picopal_char *) dst, (const picopal_char *) src, (picopal_objsize_t) siz);
174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* copies 'length' bytes from 'src' to 'dest'. (regions may be overlapping) no error checks! */
177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid * picoos_mem_copy(const void * src, void * dst,  picoos_objsize_t length)
178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picopal_mem_copy(src,dst,(picopal_objsize_t) length);
180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* sets 'length' bytes starting at dest[0] to 'byte_val' */
183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid * picoos_mem_set(void * dest, picoos_uint8 byte_val, picoos_objsize_t length) {
184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen          return picopal_mem_set(dest,(picopal_uint8)byte_val, (picopal_objsize_t)length);
185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_double picoos_cos (const picoos_double cos_arg)
189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_double) picopal_cos ((picopal_double) cos_arg);
191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_double picoos_sin (const picoos_double sin_arg)
195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_double) picopal_sin((picopal_double) sin_arg);
197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_double picoos_fabs (const picoos_double fabs_arg)
199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_double) picopal_fabs((picopal_double) fabs_arg);
201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_double picoos_quick_exp(const picoos_double y) {
204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_double) picopal_quick_exp ((picopal_double)y);
205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* "Common"                                                        */
210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* picoos_common is a collection of basic functionalities that must be globally
212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * accessible from every "big" function. It includes pointers to the MemoryManasger,
213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * ExceptionManager and a system-wide list of open files. */
214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_Common picoos_newCommon(picoos_MemoryManager mm)
216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_Common this = (picoos_Common) picoos_allocate(mm,sizeof(*this));
218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* initialize */
220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->em = NULL;
221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->mm = NULL;
222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->fileList = NULL;
223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_disposeCommon(picoos_MemoryManager mm, picoos_Common * this)
228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != (*this)) {
230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* terminate */
231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm,(void *)this);
232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Memory Management                                               */
238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct mem_block_hdr * MemBlockHdr;
241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct mem_block_hdr
242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemBlockHdr next;
244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    byte_ptr_t data;
245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t size;
246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} mem_block_hdr_t;
247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct mem_cell_hdr * MemCellHdr;
249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct mem_cell_hdr
250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* size may be <0 if used */
252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_ptrdiff_t size;
253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr leftCell;
254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr prevFree, nextFree;
255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} mem_cell_hdr_t;
256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct memory_manager
258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemBlockHdr firstBlock, lastBlock; /* memory blockList */
260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr freeCells, lastFree; /* free memory cells (first/last sentinel */
261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* "constants" */
262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t fullCellHdrSize; /* aligned size of full cell header, including free-links */
263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t usedCellHdrSize; /* aligned size of header part without free-links */
264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t minContSize; /* minimum requestable application content size for allocation;
265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     must hold free-list info; = fullCellHdrSize-usedCellHdrSize */
266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t minCellSize; /* minimum remaining cell size when a free cell is split */
267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool protMem;  /* true if memory protection is enabled */
268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_ptrdiff_t usedSize;
269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_ptrdiff_t prevUsedSize;
270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_ptrdiff_t maxUsedSize;
271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} memory_manager_t;
272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** allocates 'alloc_size' bytes at start of raw memory block ('raw_mem',raw_mem_size)
274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *  and returns pointer to allocated region. Returns remaining (correctly aligned) raw memory block
275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *  in ('rest_mem','rest_mem_size').
276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *  The allocated memory is not subject to memory management, so that it can never be freed again!
277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid * picoos_raw_malloc(byte_ptr_t raw_mem,
280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_objsize_t raw_mem_size, picoos_objsize_t alloc_size,
281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        byte_ptr_t * rest_mem, picoos_objsize_t * rest_mem_size)
282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_ptrdiff_t rest;
284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (raw_mem == NULL) {
285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (alloc_size < 1) {
288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            alloc_size = 1;
289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        alloc_size = ((alloc_size + PICOOS_ALIGN_SIZE - 1) / PICOOS_ALIGN_SIZE)
291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                * PICOOS_ALIGN_SIZE;
292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        rest = raw_mem_size - alloc_size;
294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (rest < 0) {
295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return NULL;
296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            *rest_mem_size = rest;
298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            *rest_mem = raw_mem + alloc_size;
299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            return (void *) raw_mem;
300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** initializes the last block of mm */
305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic int os_init_mem_block(picoos_MemoryManager this)
306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int isFirstBlock;
308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    void * newBlockAddr;
309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t size;
310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr cbeg, cmid, cend;
311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    isFirstBlock = (this->freeCells == NULL);
313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    newBlockAddr = (void *) this->lastBlock->data;
314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    size = this->lastBlock->size;
315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cbeg = (MemCellHdr) newBlockAddr;
316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cmid = (MemCellHdr)((picoos_objsize_t)newBlockAddr + this->fullCellHdrSize);
317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cend = (MemCellHdr)((picoos_objsize_t)newBlockAddr + size
318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            - this->fullCellHdrSize);
319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cbeg->size = 0;
320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cbeg->leftCell = NULL;
322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cmid->size = size - 2 * this->fullCellHdrSize;
323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cmid->leftCell = cbeg;
324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cend->size = 0;
325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cend->leftCell = cmid;
326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (isFirstBlock) {
327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cbeg->nextFree = cmid;
328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cbeg->prevFree = NULL;
329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cmid->nextFree = cend;
330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cmid->prevFree = cbeg;
331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cend->nextFree = NULL;
332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cend->prevFree = cmid;
333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->freeCells = cbeg;
334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->lastFree = cend;
335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* add cmid to free cell list */
337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cbeg->nextFree = NULL;
338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cbeg->prevFree = NULL;
339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cmid->nextFree = this->freeCells->nextFree;
340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cmid->prevFree = this->freeCells;
341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cmid->nextFree->prevFree = cmid;
342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cmid->prevFree->nextFree = cmid;
343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cend->nextFree = NULL;
344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cbeg->prevFree = NULL;
345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_MemoryManager picoos_newMemoryManager(
351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        void *raw_memory,
352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_objsize_t size,
353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_bool enableMemProt)
354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    byte_ptr_t rest_mem;
356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t rest_mem_size;
357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_MemoryManager this;
358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t size2;
359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    mem_cell_hdr_t test_cell;
360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this = picoos_raw_malloc(raw_memory, size, sizeof(memory_manager_t),
362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            &rest_mem, &rest_mem_size);
363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this == NULL) {
364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* test if memory protection functionality is available on the current
368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       platform (if not, picopal_mpr_alloc() always returns NULL) */
369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (enableMemProt) {
370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        void *addr = picopal_mpr_alloc(100);
371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (addr == NULL) {
372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            enableMemProt = FALSE;
373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picopal_mpr_free(&addr);
375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->firstBlock = NULL;
379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->lastBlock = NULL;
380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->freeCells = NULL;
381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->lastFree = NULL;
382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->protMem = enableMemProt;
384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->usedSize = 0;
385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->prevUsedSize = 0;
386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->maxUsedSize = 0;
387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* get aligned full header size */
389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->fullCellHdrSize = ((sizeof(mem_cell_hdr_t) + PICOOS_ALIGN_SIZE - 1)
390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            / PICOOS_ALIGN_SIZE) * PICOOS_ALIGN_SIZE;
391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* get aligned size of header without free-list fields; the result may be compiler-dependent;
392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     the size is therefore computed by inspecting the end addresses of the fields 'size' and 'leftCell';
393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     the higher of the ending addresses is used to get the (aligned) starting address
394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     of the application contents */
395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->usedCellHdrSize = (picoos_objsize_t) &test_cell.size
396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            - (picoos_objsize_t) &test_cell + sizeof(picoos_objsize_t);
397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    size2 = (picoos_objsize_t) &test_cell.leftCell - (picoos_objsize_t)
398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            &test_cell + sizeof(MemCellHdr);
399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (size2 > this->usedCellHdrSize) {
400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->usedCellHdrSize = size2;
401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* get minimum application-usable size; must be large enough to hold remainder of
403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     cell header (free-list links) when in free-list */
404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->minContSize = this->fullCellHdrSize - this->usedCellHdrSize;
405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* get minimum required size of a cell remaining after a cell split */
406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->minCellSize = this->fullCellHdrSize + PICOOS_ALIGN_SIZE;
407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* install remainder of raw memory block as first block */
409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    raw_memory = rest_mem;
410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    size = rest_mem_size;
411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->firstBlock = this->lastBlock = picoos_raw_malloc(raw_memory, size,
412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            sizeof(mem_block_hdr_t), &rest_mem, &rest_mem_size);
413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this->lastBlock == NULL) {
414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->lastBlock->next = NULL;
417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->lastBlock->data = rest_mem;
418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->lastBlock->size = rest_mem_size;
419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    os_init_mem_block(this);
421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_disposeMemoryManager(picoos_MemoryManager * mm)
426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *mm = NULL;
428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* the following memory manager routines are for testing and
432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   debugging purposes */
433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid *picoos_allocProtMem(picoos_MemoryManager mm, picoos_objsize_t byteSize)
436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (mm->protMem) {
438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picopal_mpr_alloc(byteSize);
439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_allocate(mm, byteSize);
441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_deallocProtMem(picoos_MemoryManager mm, void **addr)
446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (mm->protMem) {
448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picopal_mpr_free(addr);
449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, addr);
451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_protectMem(
456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_MemoryManager mm,
457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        void *addr,
458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_objsize_t len,
459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_bool enable)
460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (mm->protMem) {
462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        int prot = PICOPAL_PROT_READ;
463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (!enable) {
464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            prot |= PICOPAL_PROT_WRITE;
465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picopal_mpr_protect(addr, len, prot);
467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* memory protection disabled; nothing to do */
469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOPAL_PROT_NONE   0   /* the memory cannot be accessed at all */
473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOPAL_PROT_READ   1   /* the memory can be read */
474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOPAL_PROT_WRITE  2   /* the memory can be written to */
475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_getMemUsage(
477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_MemoryManager this,
478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_bool resetIncremental,
479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int32 *usedBytes,
480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int32 *incrUsedBytes,
481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int32 *maxUsedBytes)
482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *usedBytes = (picoos_int32) this->usedSize;
484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *incrUsedBytes = (picoos_int32) (this->usedSize - this->prevUsedSize);
485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *maxUsedBytes = (picoos_int32) this->maxUsedSize;
486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (resetIncremental) {
487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->prevUsedSize = this->usedSize;
488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_showMemUsage(picoos_MemoryManager this, picoos_bool incremental,
493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_bool resetIncremental)
494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 usedBytes, incrUsedBytes, maxUsedBytes;
496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
497b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_getMemUsage(this, resetIncremental, &usedBytes, &incrUsedBytes,
498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            &maxUsedBytes);
499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (incremental) {
500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("additional memory used: %d", incrUsedBytes));
501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG(("memory used: %d, maximally used: %d", usedBytes, maxUsedBytes));
503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid * picoos_allocate(picoos_MemoryManager this,
508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_objsize_t byteSize)
509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_objsize_t cellSize;
512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr c, c2, c2r;
513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    void * adr;
514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (byteSize < this->minContSize) {
516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        byteSize = this->minContSize;
517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    byteSize = ((byteSize + PICOOS_ALIGN_SIZE - 1) / PICOOS_ALIGN_SIZE)
519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            * PICOOS_ALIGN_SIZE;
520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    cellSize = byteSize + this->usedCellHdrSize;
522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*PICODBG_TRACE(("allocating %d", cellSize));*/
523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c = this->freeCells->nextFree;
524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (
525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (c != NULL) &&
526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (c->size != (picoos_ptrdiff_t) cellSize) &&
527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (c->size < (picoos_ptrdiff_t)(cellSize+ this->minCellSize))) {
528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c = c->nextFree;
529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (c == NULL) {
531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return NULL;
532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((c->size == (picoos_ptrdiff_t) cellSize)) {
534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c->prevFree->nextFree = c->nextFree;
535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c->nextFree->prevFree = c->prevFree;
536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2 = (MemCellHdr)((picoos_objsize_t)c + cellSize);
538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2->size = c->size - cellSize;
539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c->size = cellSize;
540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2->leftCell = c;
541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2r = (MemCellHdr)((picoos_objsize_t)c2 + c2->size);
542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2r->leftCell = c2;
543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2->nextFree = c->nextFree;
544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2->nextFree->prevFree = c2;
545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2->prevFree = c->prevFree;
546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c2->prevFree->nextFree = c2;
547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* statistics */
550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->usedSize += cellSize;
551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (this->usedSize > this->maxUsedSize) {
552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->maxUsedSize = this->usedSize;
553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    c->size = -(c->size);
556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    adr = (void *)((picoos_objsize_t)c + this->usedCellHdrSize);
557b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return adr;
558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_deallocate(picoos_MemoryManager this, void * * adr)
561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr c;
563b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr cr;
564b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr cl;
565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    MemCellHdr crr;
566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((*adr) != NULL) {
569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c = (MemCellHdr)((picoos_objsize_t)(*adr) - this->usedCellHdrSize);
570b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        c->size = -(c->size);
571b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /*PICODBG_TRACE(("deallocating %d", c->size));*/
573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* statistics */
574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->usedSize -= c->size;
575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cr = (MemCellHdr)((picoos_objsize_t)c + c->size);
577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        cl = c->leftCell;
578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (cl->size > 0) {
579b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (cr->size > 0) {
580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                crr = (MemCellHdr)((picoos_objsize_t)cr + cr->size);
581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                crr->leftCell = cl;
582b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cl->size = ((cl->size + c->size) + cr->size);
583b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cr->nextFree->prevFree = cr->prevFree;
584b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cr->prevFree->nextFree = cr->nextFree;
585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
586b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cl->size = (cl->size + c->size);
587b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                cr->leftCell = cl;
588b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
589b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
590b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((cr->size > 0)) {
591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                crr = (MemCellHdr)((picoos_objsize_t)cr + cr->size);
592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                crr->leftCell = c;
593b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->size = (c->size + cr->size);
594b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->nextFree = cr->nextFree;
595b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->prevFree = cr->prevFree;
596b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->nextFree->prevFree = c;
597b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->prevFree->nextFree = c;
598b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
599b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->nextFree = this->freeCells->nextFree;
600b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->prevFree = this->freeCells;
601b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->nextFree->prevFree = c;
602b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                c->prevFree->nextFree = c;
603b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
604b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
605b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
606b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *adr = NULL;
607b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
608b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
609b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
610b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Exception Management                                                */
611b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
612b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**  object   : exceptionManager
613b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   shortcut : em
614b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
615b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
616b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
617b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef picoos_char picoos_exc_msg[PICOOS_MAX_EXC_MSG_LEN];
618b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef picoos_char picoos_warn_msg[PICOOS_MAX_WARN_MSG_LEN];
619b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
620b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct picoos_exception_manager
621b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
622b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 curExceptionCode;
623b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_exc_msg curExceptionMessage;
624b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
625b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 curNumWarnings;
626b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 curWarningCode[PICOOS_MAX_NUM_WARNINGS];
627b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_warn_msg curWarningMessage[PICOOS_MAX_NUM_WARNINGS];
628b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
629b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picoos_exception_manager_t;
630b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
631b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_emReset(picoos_ExceptionManager this)
632b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
633b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->curExceptionCode = PICO_OK;
634b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->curExceptionMessage[0] = '\0';
635b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    this->curNumWarnings = 0;
636b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
637b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
638b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_ExceptionManager picoos_newExceptionManager(picoos_MemoryManager mm)
639b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
640b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_ExceptionManager this = (picoos_ExceptionManager) picoos_allocate(
641b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            mm, sizeof(*this));
642b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
643b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* initialize */
644b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emReset(this);
645b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
646b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
647b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
648b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
649b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_disposeExceptionManager(picoos_MemoryManager mm,
650b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_ExceptionManager * this)
651b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
652b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != (*this)) {
653b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* terminate */
654b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *)this);
655b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
656b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
657b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
658b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void picoos_vSetErrorMsg(picoos_char * dst, picoos_objsize_t siz,
659b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 code, picoos_char * base, const picoos_char *fmt, va_list args)
660b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
661b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 bsize;
662b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
663b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == base) {
664b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (code) {
665b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_NUMBER_FORMAT:
666b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_NUMBER_FORMAT;
667b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
668b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_MAX_NUM_EXCEED:
669b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_MAX_NUM_EXCEED;
670b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
671b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_NAME_CONFLICT:
672b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_NAME_CONFLICT;
673b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
674b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_NAME_UNDEFINED:
675b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_NAME_UNDEFINED;
676b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
677b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_NAME_ILLEGAL:
678b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_NAME_ILLEGAL;
679b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
680b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
681b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* buffer interaction */
682b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_BUF_OVERFLOW:
683b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_BUF_OVERFLOW;
684b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
685b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_BUF_UNDERFLOW:
686b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_BUF_UNDERFLOW;
687b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
688b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_BUF_IGNORE:
689b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_BUF_IGNORE;
690b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
691b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
692b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* memory allocation */
693b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_OUT_OF_MEM:
694b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_OUT_OF_MEM;
695b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
696b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
697b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* files */
698b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_CANT_OPEN_FILE:
699b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_CANT_OPEN_FILE;
700b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
701b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_UNEXPECTED_FILE_TYPE:
702b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_UNEXPECTED_FILE_TYPE;
703b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
704b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_FILE_CORRUPT:
705b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_FILE_CORRUPT;
706b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
707b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
708b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_FILE_NOT_FOUND:
709b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_FILE_NOT_FOUND;
710b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
711b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
712b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* resources */
713b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_RESOURCE_BUSY:
714b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_RESOURCE_BUSY;
715b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
716b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_RESOURCE_MISSING:
717b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_EXC_RESOURCE_MISSING;
718b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
719b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
720b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* knowledge bases */
721b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_EXC_KB_MISSING:
722b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                fmt = PICOOS_MSG_EXC_KB_MISSING;
723b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
724b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
725b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* runtime exceptions (programming problems, usually a bug. E.g. trying to access null pointer) */
726b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_ERR_NULLPTR_ACCESS:
727b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_ERR_NULLPTR_ACCESS;
728b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
729b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_ERR_INVALID_HANDLE:
730b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_ERR_INVALID_HANDLE;
731b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
732b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_ERR_INVALID_ARGUMENT:
733b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_ERR_INVALID_ARGUMENT;
734b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
735b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_ERR_INDEX_OUT_OF_RANGE:
736b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_ERR_INDEX_OUT_OF_RANGE;
737b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
738b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
739b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* errors ("external" errors, e.g. hardware failure. Usually cannot be dealt with from inside pico.) */
740b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_ERR_OTHER:
741b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_ERR_OTHER;
742b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
743b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
744b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* other error inside pu */
745b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_STEP_ERROR:
746b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_ERR_PU;
747b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
748b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
749b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* WARNINGS */
750b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
751b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* general */
752b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_INCOMPLETE:
753b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_INCOMPLETE;
754b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
755b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_FALLBACK:
756b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_FALLBACK;
757b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
758b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
759b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_OTHER:
760b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_OTHER;
761b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
762b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
763b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* resources */
764b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_KB_OVERWRITE:
765b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_KB_OVERWRITE;
766b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
767b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_RESOURCE_DOUBLE_LOAD:
768b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_RESOURCE_DOUBLE_LOAD;
769b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
770b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
771b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* decision trees */
772b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_INVECTOR:
773b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_INVECTOR;
774b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
775b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_CLASSIFICATION:
776b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_CLASSIFICATION;
777b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
778b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_OUTVECTOR:
779b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_OUTVECTOR;
780b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
781b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
782b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* processing units */
783b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_PU_IRREG_ITEM:
784b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_PU_IRREG_ITEM;
785b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
786b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICO_WARN_PU_DISCARD_BUF:
787b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = PICOOS_MSG_WARN_PU_DISCARD_BUF;
788b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
789b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
790b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            default:
791b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                base = (picoos_char *) "unknown error";
792b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
793b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
794b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
795b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    bsize = picoos_strlcpy(dst,base,siz);
796b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((NULL != fmt) && (bsize < siz)) { /* there is something to add and more space to add it */
797b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (bsize > 0) {
798b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            dst += bsize;
799b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            siz -= bsize;
800b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bsize = picoos_strlcpy(dst,(picoos_char *)": ",siz);
801b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
802b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (bsize < siz) {
803b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picopal_vslprintf((picopal_char *) dst + bsize, siz - bsize, (picopal_char *)fmt, args);
804b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
805b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
806b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
807b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
808b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_setErrorMsg(picoos_char * dst, picoos_objsize_t siz,
809b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 code, picoos_char * base, const picoos_char *fmt, ...)
810b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
811b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_list args;
812b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_start(args, (char *)fmt);
813b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_vSetErrorMsg(dst,siz, code, base, fmt,args);
814b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_end(args);
815b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
816b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
817b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* For convenience, this function returns the resulting current exception code. The return value therefore is NOT the status of raising
818b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * the error! */
819b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_emRaiseException(picoos_ExceptionManager this,
820b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        pico_status_t exceptionCode, picoos_char * baseMessage, picoos_char * fmt, ...)
821b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
822b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_list args;
823b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
824b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
825b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (PICO_OK == this->curExceptionCode && PICO_OK != exceptionCode) {
826b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->curExceptionCode = exceptionCode;
827b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        va_start(args, (char *)fmt);
828b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_vSetErrorMsg(this->curExceptionMessage,PICOOS_MAX_EXC_MSG_LEN, exceptionCode, baseMessage, fmt,args);
829b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_DEBUG((
830b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            "exit with exception code=%i, exception message='%s'",
831b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            this->curExceptionCode, this->curExceptionMessage));
832b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
833b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        va_end(args);
834b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
835b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
836b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this->curExceptionCode;
837b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
838b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
839b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_emGetExceptionCode(picoos_ExceptionManager this)
840b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
841b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this->curExceptionCode;
842b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
843b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
844b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_emGetExceptionMessage(picoos_ExceptionManager this, picoos_char * msg, picoos_uint16 maxsize)
845b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
846b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_strlcpy(msg,this->curExceptionMessage,maxsize);
847b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
848b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
849b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_emRaiseWarning(picoos_ExceptionManager this,
850b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        pico_status_t warningCode, picoos_char * baseMessage, picoos_char * fmt, ...)
851b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
852b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    va_list args;
853b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((this->curNumWarnings < PICOOS_MAX_NUM_WARNINGS) && (PICO_OK != warningCode)) {
854b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (PICOOS_MAX_NUM_WARNINGS-1 == this->curNumWarnings) {
855b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            this->curWarningCode[this->curNumWarnings] = PICO_EXC_MAX_NUM_EXCEED;
856b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_strlcpy(this->curWarningMessage[this->curNumWarnings],(picoos_char *) "too many warnings",PICOOS_MAX_WARN_MSG_LEN);
857b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
858b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            this->curWarningCode[this->curNumWarnings] = warningCode;
859b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            va_start(args, (char *)fmt);
860b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_vSetErrorMsg(this->curWarningMessage[this->curNumWarnings],PICOOS_MAX_WARN_MSG_LEN, warningCode, baseMessage, fmt,args);
861b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            va_end(args);
862b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
863b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->curNumWarnings++;
864b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
865b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG((
866b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        "exit with code=%i and message='%s', resulting in #warnings=%i",
867b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->curWarningCode[this->curNumWarnings-1],
868b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->curWarningMessage[this->curNumWarnings-1],
869b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        this->curNumWarnings));
870b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
871b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
872b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoos_emGetNumOfWarnings(picoos_ExceptionManager this)
873b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
874b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this->curNumWarnings;
875b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
876b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
877b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_emGetWarningCode(picoos_ExceptionManager this, picoos_uint8 index)
878b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
879b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (index < this->curNumWarnings) {
880b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen      return this->curWarningCode[index];
881b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
882b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
883b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
884b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
885b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
886b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_emGetWarningMessage(picoos_ExceptionManager this, picoos_uint8 index, picoos_char * msg, picoos_uint16 maxsize)
887b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
888b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (index < this->curNumWarnings) {
889b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_strlcpy(msg,this->curWarningMessage[index],maxsize);
890b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
891b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            msg[0] = NULLC;
892b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
893b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
894b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
895b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
896b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
897b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
898b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
899b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* File Access                                                     */
900b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
901b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
902b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_MagicNumber 192837465
903b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_MaxBufSize 1000000
904b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_MaxNrOfBuffers 1000000
905b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_MaxBufLen 8192
906b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_HashFuncId0 0
907b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_HashTableSize0 101
908b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_HashTableSize1 1731
909b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define picoos_MaxHashTableSize HashTableSize1
910b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
911b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define cardinal_ptr_t picoos_uint32 *
912b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
913b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct picoos_buffer
914b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
915b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_char * data;
916b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int start; /* denotes the file position of the buffer beginning */
917b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int len; /* denotes the length of the buffer; -1 means invalid buffer */
918b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int pos; /* denotes the position in the buffer */
919b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picoos_buffer_t;
920b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
921b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef picoos_buffer_t picoos_buffer_array_t[picoos_MaxNrOfBuffers];
922b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef picoos_int32 picoos_buffer_index_array_t[picoos_MaxNrOfBuffers];
923b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
924b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**  object   : File
925b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   shortcut : f
926b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
927b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
928b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct picoos_file
929b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
930b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_FileName name;
931b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 binary;
932b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 write;
933b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
934b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_File nf;
935b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
936b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 lFileLen;
937b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 lPos;
938b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
939b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_File next;
940b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_File prev;
941b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
942b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picoos_file_t;
943b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
944b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_File picoos_newFile(picoos_MemoryManager mm)
945b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
946b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_File this = (picoos_File) picoos_allocate(mm, sizeof(*this));
947b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != this) {
948b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* initialize */
949b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
950b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return this;
951b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
952b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
953b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_disposeFile(picoos_MemoryManager mm, picoos_File * this)
954b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
955b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != (*this)) {
956b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* terminate */
957b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(mm, (void *)this);
958b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
959b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
960b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
961b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
962b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ************************************************************
963b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * low-level file operations
964b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen **************************************************************/
965b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
966b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_int32 os_min(const picoos_int32 x, const picoos_int32 y)
967b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
968b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (x < y) ? x : y;
969b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
970b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
971b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/*
972b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen static picoos_uint8 LReadChar (picoos_File f, picoos_char * ch);
973b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
974b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
975b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen static picoos_uint8 LSetPos (picoos_File f, unsigned int pos);
976b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
977b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
978b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen static picoos_uint8 LGetPos (picoos_File f, picoos_uint32 * pos);
979b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
980b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
981b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen static picoos_uint8 LEof (picoos_File f);
982b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
983b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
984b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool LOpen(picoos_Common g, picoos_File * f,
985b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_char fileName[], picopal_access_mode mode)
986b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
987b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
988b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
989b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *f = picoos_newFile(g->mm);
990b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_strcpy((*f)->name, fileName);
991b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->write = ((mode == PICOPAL_TEXT_WRITE) || (mode
992b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            == PICOPAL_BINARY_WRITE));
993b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->binary = (mode
994b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            == PICOPAL_BINARY_WRITE);
995b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->next = NULL;
996b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->prev = NULL;
997b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->nf = picopal_get_fnil();
998b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->lFileLen = 0;
999b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*f)->lPos = 0;
1000b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (picopal_strlen((*f)->name)) {
1001b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen       (*f)->nf = picopal_fopen((*f)->name, mode);
1002b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = !(picopal_is_fnil((*f)->nf));
1003b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (done) {
1004b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*f)->lFileLen = picopal_flength((*f)->nf);
1005b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1006b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1007b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (done) {
1008b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*f)->next = g->fileList;
1009b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (g->fileList != NULL) {
1010b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            g->fileList->prev = (*f);
1011b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1012b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        g->fileList = (*f);
1013b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1014b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_disposeFile(g->mm, f);
1015b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*f) = NULL;
1016b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1017b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1018b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1019b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1020b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool LClose(picoos_Common g, picoos_File * f)
1021b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1022b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1023b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done;
1024b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1025b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (((*f) != NULL)) {
1026b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = (PICO_OK == picopal_fclose((*f)->nf));
1027b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (((*f)->next != NULL)) {
1028b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*f)->next->prev = (*f)->prev;
1029b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1030b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (((*f)->prev != NULL)) {
1031b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*f)->prev->next = (*f)->next;
1032b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1033b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            g->fileList = (*f)->next;
1034b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1035b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_disposeFile(g->mm, f);
1036b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1037b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = TRUE;
1038b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1039b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1040b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1041b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1042b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1043b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1044b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1045b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* caller must ensure that bytes[] has at least len allocated bytes */
1046b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool LReadBytes(picoos_File f, picoos_uint8 bytes[],
1047b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * len)
1048b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1049b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done;
1050b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 res;
1051b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1052b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_TRACE(("trying to read %i bytes",*len));
1053b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((f != NULL)) {
1054b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        res = picopal_fread_bytes(f->nf, (void *) &bytes[(0)], 1, (*len));
1055b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_TRACE(("res = %i",res));
1056b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (res < 0) { /* non-ansi */
1057b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*len) = 0;
1058b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1059b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if (((picoos_uint32)res != (*len))) {
1060b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*len) = res;
1061b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1062b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1063b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = TRUE;
1064b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1065b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        f->lPos = (f->lPos + (*len));
1066b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1067b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*len) = 0;
1068b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1069b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1070b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1071b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1072b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1073b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen static picoos_bool LWriteBytes(picoos_File f, const picoos_char bytes[], int * len) {
1074b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done;
1075b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int res;
1076b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /*int n;
1077b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    void * bptr; */
1078b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1079b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (f != NULL) {
1080b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        res = picopal_fwrite_bytes(f->nf, (void *) bytes, 1, *len);
1081b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((res < 0)) {
1082b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*len) = 0;
1083b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1084b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if ((res != (*len))) {
1085b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*len) = res;
1086b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1087b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1088b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = TRUE;
1089b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1090b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        f->lPos = (f->lPos + (unsigned int) (*len));
1091b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((f->lPos > f->lFileLen)) {
1092b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            f->lFileLen = f->lPos;
1093b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1094b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1095b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*len) = 0;
1096b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1097b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1098b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1099b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool LSetPos(picoos_File f, unsigned int pos)
1103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done;
1106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((f != NULL)) {
1108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((pos == f->lPos)) {
1109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = TRUE;
1110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = (PICO_OK == picopal_fseek(f->nf, pos, PICOPAL_SEEK_SET));
1112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (done) {
1113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                f->lPos = pos;
1114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool LGetPos(picoos_File f, picoos_uint32 * pos)
1123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((f != NULL)) {
1126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*pos) = f->lPos;
1127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*pos) = 0;
1130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool LEof(picoos_File f)
1136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool isEof;
1138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((f != NULL)) {
1140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        isEof = picopal_feof(f->nf);
1141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        isEof = TRUE;
1143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return isEof;
1145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **************************************************************************************/
1149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* read a given string 'str' from file. If no match was found, the read position is advanced until and including the first
1153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * non-matching character */
1154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool picoos_StrRead (picoos_File f, picoos_char str[])
1155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 i = 0;
1157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_char b;
1159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (done && (str[i] != NULLC)) {
1161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = done && picoos_ReadByte(f,(picoos_char *)&b);
1162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = done && (b == str[i]);
1163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
1164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* write 'str' to file */
1169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool picoos_WriteStr (picoos_File f, picoos_char str[])
1170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 i = 0;
1172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (done && (str[i] != NULLC)) {
1175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = done && picoos_WriteByte(f,str[i]);
1176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
1177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **** Sequential binary file access ******/
1184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Remark: 'ReadByte', 'ReadBytes' and 'ReadVar' may be mixed;
1186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 'WriteByte', 'WriteBytes' and 'WriteVar' may be mixed. */
1187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Open existing binary file for read access. Reading is buffered
1189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * with 'nrOfBufs' buffers of size 'bufSize'. If 'nrOfBufs' or
1190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 'bufSize' is 0 reading is not buffered.
1191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * If 'key' is not empty, the file is decrypted with 'key'.
1192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * If the opened file is in an encrypted archive file, it
1193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoos_OpenBinary(picoos_Common g, picoos_File * f,
1195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_char fileName[])
1196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return LOpen(g, f, fileName, PICOPAL_BINARY_READ);
1198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Read next byte from file 'f'. */
1202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_ReadByte(picoos_File f, picoos_uint8 * by)
1203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n = 1;
1205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picoos_ReadBytes(f, by, &n) && (n == 1);
1207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Read next 'len' bytes from 'f' into 'bytes'; 'len' returns the
1211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen number of bytes actually read (may be smaller than requested
1212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen length if at end of file). bytes[] must be big enough to hold at least len bytes.
1213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen*/
1214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_ReadBytes(picoos_File f, picoos_uint8 bytes[],
1215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * len)
1216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* unsigned int origPos; */
1219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((f != NULL)) {
1221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = LReadBytes(f, bytes, len);
1222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /*if ((f->keyLen > 0)) {
1223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         DecryptBytes(f->key,picoos_MaxKeyLen,f->keyLen,origPos,bytes,(*len));
1224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         }*/
1225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Create new binary file.
1232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen If 'key' is not empty, the file is encrypted with 'key'. */
1233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_CreateBinary(picoos_Common g, picoos_File * f,
1234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_char fileName[])
1235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return LOpen(g, f, fileName, PICOPAL_BINARY_WRITE);
1237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoos_WriteByte(picoos_File f, picoos_char by)
1242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int n = 1;
1244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picoos_WriteBytes(f, (picoos_char *) &by, &n);
1246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Writes 'len' bytes from 'bytes' onto file 'f'; 'len' returns
1250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen the number of bytes actually written. */
1251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_WriteBytes(picoos_File f, const picoos_char bytes[],        picoos_int32 * len) {
1252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = FALSE;
1253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (f != NULL) {
1255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = LWriteBytes(f, bytes, len);
1256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Close previously opened binary file. */
1264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoos_CloseBinary(picoos_Common g, picoos_File * f)
1265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return LClose(g, f);
1267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **************************************************************************************/
1271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *** general routines *****/
1272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Returns whether end of file was encountered in previous
1275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen read operation. */
1276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_Eof(picoos_File f)
1277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((NULL != f)) {
1279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return LEof(f);
1280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return TRUE;
1282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* sets the file pointer to
1287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen 'pos' bytes from beginning (first byte = byte 0). This
1288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen routine should only be used for binary files. */
1289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_SetPos(picoos_File f, picoos_int32 pos)
1290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((NULL != f)) {
1293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = LSetPos(f, pos);
1294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Get position from file 'f'. */
1302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_GetPos(picoos_File f, picoos_uint32 * pos)
1303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != f) {
1305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* if (f->bFile) {
1306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         (*pos) =  BGetPos(f);
1307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen         } else { */
1308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*pos) =  LGetPos(f, pos);
1309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* } */
1310b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return TRUE;
1311b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1312b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*pos) = 0;
1313b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return FALSE;
1314b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1315b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1316b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1317b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Returns the length of the file in bytes. */
1318b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_FileLength(picoos_File f, picoos_uint32 * len)
1319b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1320b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1321b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != f) {
1322b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *len = f->lFileLen;
1323b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return TRUE;
1324b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1325b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *len = 0;
1326b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return FALSE;
1327b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1328b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1329b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1330b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Return full name of file 'f'. maxsize is the size of 'name[]' in bytes */
1331b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_Name(picoos_File f, picoos_char name[], picoos_uint32 maxsize)
1332b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1333b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1334b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1335b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != f) {
1336b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = (picoos_strlcpy(name, f->name,maxsize) < maxsize);
1337b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1338b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        name[0] = (picoos_char)NULLC;
1339b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1340b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1341b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1342b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1343b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1344b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1345b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Returns whether file 'name' exists or not. */
1346b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_bool picoos_FileExists(picoos_Common g, picoos_char name[])
1347b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1348b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_File f;
1349b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1350b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (picoos_OpenBinary(g, & f,name)) {
1351b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_CloseBinary(g, & f);
1352b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return TRUE;
1353b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1354b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return FALSE;
1355b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1356b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1357b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1358b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1359b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* ******************************************************************/
1360b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Array conversion operations: all procedures convert 'nrElems' values from
1361b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   'src' starting with index 'srcStartInd' into corresponding (possibly
1362b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   rounded) values in 'dst' starting at 'dstStartInd'. */
1363b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1364b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* taking pi to be le, these are just the array versions of read_mem_pi_*int16 */
1365b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef picoos_uint8 two_byte_t[2];
1366b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1367b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void arr_conv_le_int16 (picoos_uint8 src[], picoos_uint32 srcShortStartInd, picoos_uint32 nrElems, picoos_int16 dst[], picoos_uint32 dstStartInd)
1368b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1369b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    two_byte_t * src_p = (two_byte_t *) (src + (srcShortStartInd * 2));
1370b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int16 * dst_p = dst + dstStartInd;
1371b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 i;
1372b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1373b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i=0; i<nrElems; i++) {
1374b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *(dst_p++) = (*src_p)[0] + (((*src_p)[1] & 0x7F) << 8) - (((*src_p)[1] & 0x80) ? 0x8000 : 0);
1375b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        src_p++;
1376b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1377b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1378b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1379b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1380b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1381b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* convert array of int16 into little-endian format */
1382b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void arr_conv_int16_le (picoos_int16 src[], picoos_uint32 srcStartInd, picoos_uint32 nrElems, picoos_uint8 dst[], picoos_uint32 dstShortStartInd)
1383b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1384b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    two_byte_t * dst_p = (two_byte_t *) (dst + (dstShortStartInd * 2));
1385b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int16 * src_p = src + srcStartInd;
1386b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 i;
1387b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 val;
1388b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1389b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i=0; i<nrElems; i++) {
1390b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        val = (picoos_uint16) *(src_p++);
1391b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*dst_p)[0] = (picoos_uint8)(val & 0x00FF);
1392b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*dst_p)[1] = (picoos_uint8)((val & 0xFF00)>>8);
1393b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        dst_p++;
1394b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1395b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1396b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1397b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
1398b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Sampled Data Files                                                    */
1399b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
1400b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1401b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_SDF_BUF_LEN 1024
1402b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1403b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_INT16_MIN   -32768
1404b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_INT16_MAX   32767
1405b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_UINT16_MAX  0xffff
1406b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_INT32_MIN   -2147483648
1407b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_INT32_MAX   2147483647
1408b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define PICOOS_UINT32_MAX  0xffffffff
1409b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1410b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/**  object   : SDFile
1411b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *   shortcut : sdf
1412b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen *
1413b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen */
1414b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* typedef struct picoos_sd_file * picoos_SDFile */
1415b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chentypedef struct picoos_sd_file
1416b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1417b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 sf;
1418b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wave_file_type_t fileType; /* (acoustic) wav, au, raw, other */
1419b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 hdrSize;
1420b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_encoding_t enc;
1421b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_File file;
1422b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 nrFileSamples;
1423b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int16 buf[PICOOS_SDF_BUF_LEN];
1424b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 bufPos;
1425b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 bBuf[2*PICOOS_SDF_BUF_LEN];
1426b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool aborted;
1427b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen} picoos_sd_file_t;
1428b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1429b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1430b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Tries to read wav header at beginning of file 'f';
1431b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   returns sampling rate 'sf', encoding type 'enc',
1432b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   nr of samples in file 'nrSamples', header size 'hdrSize',
1433b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   and byte order 'bOrder'; returns whether a supported
1434b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen   wav header and format was found. */
1435b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool picoos_readWavHeader(picoos_File f, picoos_uint32 * sf,
1436b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_encoding_t * enc, picoos_uint32 * nrSamples,
1437b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * hdrSize) {
1438b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 n16;
1439b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n32;
1440b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 formatTag;
1441b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 sampleRate;
1442b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 bytesPerSec;
1443b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 blockAlign;
1444b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 sampleSize;
1445b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 dataLength;
1446b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 fileLen;
1447b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 nrFileSamples;
1448b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done;
1449b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1450b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1451b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_SetPos(f, 0);
1452b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_FileLength(f, &fileLen);
1453b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = picoos_StrRead(f, (picoos_char *) "RIFF");
1454b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint32(f, &n32)); /* length of riff chunk, unused */
1455b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_StrRead(f, (picoos_char *) "WAVE");
1456b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_StrRead(f, (picoos_char *) "fmt ");
1457b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint32(f, &n32)); /* length of fmt chunk in bytes; must be 16 */
1458b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (n32 == 16);
1459b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint16(f, &formatTag));
1460b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint16(f, &n16)); /* number of channels; must be mono */
1461b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (n16 == 1);
1462b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint32(f, &sampleRate));
1463b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint32(f, &bytesPerSec));
1464b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint16(f, &blockAlign));
1465b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint16(f, &sampleSize));
1466b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_StrRead(f, (picoos_char *) "data");
1467b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && (PICO_OK == picoos_read_le_uint32(f, &dataLength)); /* length of data chunk in bytes */
1468b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*hdrSize) = 44;
1469b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (done) {
1470b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*sf) = sampleRate;
1471b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*nrSamples) = 0;
1472b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (formatTag) {
1473b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        case FORMAT_TAG_LIN:
1474b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*enc) = PICOOS_ENC_LIN;
1475b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = ((blockAlign == 2) && (sampleSize == 16));
1476b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*nrSamples) = (dataLength / 2);
1477b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            nrFileSamples = ((fileLen - (*hdrSize)) / 2);
1478b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1479b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        case FORMAT_TAG_ULAW:
1480b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*enc) = PICOOS_ENC_ULAW;
1481b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = ((blockAlign == 1) && (sampleSize == 8));
1482b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*nrSamples) = dataLength;
1483b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            nrFileSamples = (fileLen - (*hdrSize));
1484b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1485b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        case FORMAT_TAG_ALAW:
1486b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*enc) = PICOOS_ENC_ALAW;
1487b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = ((blockAlign == 1) && (sampleSize == 8));
1488b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*nrSamples) = dataLength;
1489b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            nrFileSamples = (fileLen - (*hdrSize));
1490b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1491b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        default:
1492b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1493b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1494b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1495b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (!done) {
1496b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* communicate "unsupported format" */
1497b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICODBG_WARN(("unsupported wav format"));
1498b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1499b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (nrFileSamples != (*nrSamples)) {
1500b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* warn "inconsistent number of samples" */
1501b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                PICODBG_WARN(("inconsistent number of samples in wav file: %d vs. %d",nrFileSamples,(*nrSamples)));
1502b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*nrSamples) = nrFileSamples;
1503b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1504b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1505b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1506b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1507b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1508b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1509b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1510b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1511b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfOpenIn(picoos_Common g, picoos_SDFile * sdFile,
1512b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_char fileName[], picoos_uint32 * sf, picoos_encoding_t * enc,
1513b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * numSamples)
1514b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1515b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = FALSE;
1516b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_sd_file_t * sdf = NULL;
1517b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    wave_file_type_t fileType = FILE_TYPE_OTHER;
1518b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1519b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*sf) = 0;
1520b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*numSamples) = 0;
1521b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*enc) = PICOOS_ENC_LIN;
1522b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*sdFile) = NULL;
1523b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1524b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    sdf = picoos_allocate(g->mm,sizeof(picoos_sd_file_t));
1525b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == sdf) {
1526b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(g->em,PICO_EXC_OUT_OF_MEM,NULL,NULL);
1527b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return FALSE;
1528b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1529b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1530b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* buffered access not supported, yet */
1531b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (picoos_OpenBinary(g,&(sdf->file),fileName)) {
1532b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (picoos_has_extension(fileName,(picoos_char *) ".wav")) {
1533b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            fileType = FILE_TYPE_WAV;
1534b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = picoos_readWavHeader(sdf->file,&(sdf->sf),&(sdf->enc),&(sdf->nrFileSamples),&(sdf->hdrSize));
1535b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1536b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* we prefer not to treat other formats, rather than treat it as raw */
1537b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* fileType = FILE_TYPE_RAW; */
1538b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            fileType = FILE_TYPE_OTHER;
1539b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1540b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1541b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1542b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (FILE_TYPE_OTHER == fileType) {
1543b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_emRaiseWarning(g->em,PICO_EXC_UNEXPECTED_FILE_TYPE,(picoos_char *)"unsupported filename suffix",NULL);
1544b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else if (!done) {
1545b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_emRaiseWarning(g->em,PICO_EXC_UNEXPECTED_FILE_TYPE,(picoos_char *)"non-conforming header",NULL);
1546b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1547b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*numSamples) = sdf->nrFileSamples;
1548b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*sf) = sdf->sf;
1549b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*enc) = sdf->enc;
1550b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            /* check whether sd file properties are supported */
1551b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (PICOOS_ENC_LIN != sdf->enc) {
1552b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = FALSE;
1553b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_emRaiseWarning(g->em,PICO_EXC_UNEXPECTED_FILE_TYPE,NULL,(picoos_char *)"encoding not supported");
1554b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1555b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (SAMPLE_FREQ_16KHZ != sdf->sf) {
1556b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = FALSE;
1557b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_emRaiseWarning(g->em,PICO_EXC_UNEXPECTED_FILE_TYPE,NULL,(picoos_char *)"sample frequency not supported");
1558b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1559b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*sdFile) = sdf;
1560b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1561b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (!done){
1562b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_CloseBinary(g,&(sdf->file));
1563b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1564b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1565b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseException(g->em,PICO_EXC_CANT_OPEN_FILE,NULL,NULL);
1566b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1567b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!done) {
1568b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(g->mm,(void *)&sdf);
1569b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*sdFile) = NULL;
1570b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1571b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1572b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1573b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1574b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1575b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic void picoos_sdfLoadSamples(picoos_SDFile sdFile,
1576b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * nrSamples) {
1577b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 len;
1578b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_sd_file_t * sdf = sdFile;
1579b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1580b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    switch (sdFile->enc) {
1581b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    case PICOOS_ENC_LIN:
1582b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((*nrSamples) > PICOOS_SDF_BUF_LEN) {
1583b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*nrSamples) = PICOOS_SDF_BUF_LEN;
1584b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1585b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        len = 2 * (*nrSamples);
1586b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_ReadBytes(sdf->file, sdf->bBuf, &len);
1587b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*nrSamples) = len / 2;
1588b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        arr_conv_le_int16(sdf->bBuf, 0, (*nrSamples), sdf->buf, 0);
1589b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        break;
1590b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* @todo : may be useful */
1591b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    case PICOOS_ENC_ULAW:
1592b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    case PICOOS_ENC_ALAW:
1593b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    default:
1594b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*nrSamples) = 0;
1595b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1596b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1597b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1598b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1599b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfGetSamples (
1600b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_SDFile sdFile,
1601b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 start,
1602b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * nrSamples,
1603b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int16 samples[])
1604b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1605b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 b;
1606b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 rem;
1607b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n;
1608b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 i;
1609b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 j;
1610b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = FALSE;
1611b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1612b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == sdFile) {
1613b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*nrSamples) = 0;
1614b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1615b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (start >= sdFile->nrFileSamples) {
1616b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (start > sdFile->nrFileSamples) {
1617b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICODBG_WARN(("start has to be <= sdFile->nrFileSamples"));
1618b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1619b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*nrSamples) = 0;
1620b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
1621b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if (((start + (*nrSamples)) > sdFile->nrFileSamples)) {
1622b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    (*nrSamples) = (sdFile->nrFileSamples - start);
1623b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1624b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                if ((sdFile->enc == PICOOS_ENC_LIN)) {
1625b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    b = 2;
1626b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                } else {
1627b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    b = 1;
1628b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1629b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_SetPos(sdFile->file,(sdFile->hdrSize + (b * start)));
1630b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                j = 0;
1631b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                rem = (*nrSamples);
1632b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                n = rem;
1633b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                while ((rem > 0) && (n > 0)) {
1634b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* set n=min(rem,buffer_length) and try loading next n samples */
1635b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    n = (rem < PICOOS_SDF_BUF_LEN) ? rem : PICOOS_SDF_BUF_LEN;
1636b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    picoos_sdfLoadSamples(sdFile, &n);
1637b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    /* n may be smaller now */
1638b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    for (i = 0; i < n; i++) {
1639b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        samples[j] = sdFile->buf[i];
1640b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        j++;
1641b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    }
1642b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    rem -= n;
1643b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    start += n;
1644b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                }
1645b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*nrSamples) = j;
1646b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = ((*nrSamples) > 0);
1647b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1648b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1649b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1650b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1651b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1652b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1653b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfCloseIn (picoos_Common g, picoos_SDFile * sdFile)
1654b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1655b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != (*sdFile)) {
1656b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_CloseBinary(g,&((*sdFile)->file));
1657b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(g->mm,(void *)sdFile);
1658b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1659b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
1660b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1661b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1662b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1663b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool picoos_writeWavHeader(picoos_File f, picoos_uint32 sf,
1664b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_encoding_t enc, picoos_uint32 nrSamples,
1665b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * hdrSize) {
1666b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 formatTag = FORMAT_TAG_LIN;
1667b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 sampleRate;
1668b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 bytesPerSec;
1669b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 bytesPerSample = 2;
1670b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 blockAlign;
1671b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint16 sampleSize = 16;
1672b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 dataLength;
1673b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1674b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1675b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_SetPos(f, 0);
1676b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1677b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    switch (enc) {
1678b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        case PICOOS_ENC_LIN:
1679b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            formatTag = FORMAT_TAG_LIN;
1680b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bytesPerSample = 2;
1681b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            sampleSize = 16;
1682b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1683b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        case PICOOS_ENC_ULAW:
1684b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            formatTag = FORMAT_TAG_ULAW;
1685b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bytesPerSample = 1;
1686b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            sampleSize = 8;
1687b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1688b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        case PICOOS_ENC_ALAW:
1689b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            formatTag = FORMAT_TAG_ALAW;
1690b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bytesPerSample = 1;
1691b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            sampleSize = 8;
1692b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1693b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        default:
1694b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = FALSE;
1695b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            break;
1696b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1697b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1698b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    bytesPerSec = (sf * bytesPerSample);
1699b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    blockAlign = bytesPerSample;
1700b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    sampleRate = sf;
1701b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    dataLength = (bytesPerSample * nrSamples);
1702b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_WriteStr(f,(picoos_char *)"RIFF");
1703b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint32(f,dataLength + 36);
1704b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_WriteStr(f,(picoos_char *)"WAVE");
1705b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_WriteStr(f,(picoos_char *)"fmt ");
1706b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint32(f,16);
1707b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint16(f,formatTag);
1708b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint16(f,1);
1709b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint32(f,sampleRate);
1710b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint32(f,bytesPerSec);
1711b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint16(f,blockAlign);
1712b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint16(f,sampleSize);
1713b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_WriteStr(f,(picoos_char *)"data");
1714b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = done && picoos_write_le_uint32(f,dataLength);
1715b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*hdrSize) = 44;
1716b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1717b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1718b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1719b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1720b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#define DummyLen 100000000
1721b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1722b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfOpenOut(picoos_Common g, picoos_SDFile * sdFile,
1723b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_char fileName[], int sf, picoos_encoding_t enc)
1724b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1725b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1726b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_sd_file_t * sdf = NULL;
1727b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1728b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*sdFile) = NULL;
1729b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    sdf = picoos_allocate(g->mm, sizeof(picoos_sd_file_t));
1730b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL == sdf) {
1731b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(g->em, PICO_EXC_OUT_OF_MEM, NULL, NULL);
1732b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return FALSE;
1733b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1734b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    sdf->sf = sf;
1735b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    sdf->enc = enc;
1736b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* check whether sd file properties are supported */
1737b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (PICOOS_ENC_LIN != sdf->enc) {
1738b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1739b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(g->em, PICO_EXC_UNEXPECTED_FILE_TYPE, NULL,
1740b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (picoos_char *) "encoding not supported");
1741b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1742b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (SAMPLE_FREQ_16KHZ != sdf->sf) {
1743b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1744b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_emRaiseWarning(g->em, PICO_EXC_UNEXPECTED_FILE_TYPE, NULL,
1745b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (picoos_char *) "sample frequency not supported");
1746b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1747b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (done) {
1748b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        sdf->nrFileSamples = 0;
1749b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        sdf->bufPos = 0;
1750b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        sdf->aborted = FALSE;
1751b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (picoos_CreateBinary(g, &(sdf->file), fileName)) {
1752b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (picoos_has_extension(fileName, (picoos_char *) ".wav")) {
1753b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                sdf->fileType = FILE_TYPE_WAV;
1754b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = picoos_writeWavHeader(sdf->file, sdf->sf, sdf->enc,
1755b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        DummyLen, &(sdf->hdrSize));
1756b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
1757b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* we prefer not to treat other formats, rather than treat it as raw */
1758b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* fileType = FILE_TYPE_RAW; */
1759b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                sdf->fileType = FILE_TYPE_OTHER;
1760b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = FALSE;
1761b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1762b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1763b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (FILE_TYPE_OTHER == sdf->fileType) {
1764b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_emRaiseWarning(g->em, PICO_EXC_UNEXPECTED_FILE_TYPE,
1765b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        (picoos_char *) "unsupported filename suffix", NULL);
1766b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else if (!done) {
1767b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_emRaiseWarning(g->em, PICO_EXC_UNEXPECTED_FILE_TYPE,
1768b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        (picoos_char *) "non-conforming header", NULL);
1769b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
1770b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*sdFile) = sdf;
1771b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1772b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (!done) {
1773b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                picoos_CloseBinary(g, &(sdf->file));
1774b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1775b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        } else {
1776b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            picoos_emRaiseException(g->em, PICO_EXC_CANT_OPEN_FILE, NULL, NULL);
1777b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1778b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1779b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!done) {
1780b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(g->mm, (void *) &sdf);
1781b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*sdFile) = NULL;
1782b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1783b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1784b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1785b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1786b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_bool picoos_sdfFlushOutBuf(picoos_SDFile sdFile)
1787b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1788b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = FALSE;
1789b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 len;
1790b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 nrSamples;
1791b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1792b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (!(sdFile->aborted)) {
1793b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        nrSamples = sdFile->bufPos;
1794b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        switch (sdFile->enc) {
1795b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOOS_ENC_LIN:
1796b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                arr_conv_int16_le(sdFile->buf, 0, nrSamples, sdFile->bBuf, 0);
1797b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                len = (nrSamples * 2);
1798b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = picoos_WriteBytes(sdFile->file, sdFile->bBuf, &len)
1799b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                        && ((nrSamples * 2) == len);
1800b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1801b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOOS_ENC_ULAW:
1802b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            case PICOOS_ENC_ALAW:
1803b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            default:
1804b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                nrSamples = 0;
1805b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                break;
1806b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1807b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        sdFile->nrFileSamples = (sdFile->nrFileSamples + nrSamples);
1808b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1809b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1810b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    sdFile->bufPos = 0;
1811b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1812b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1813b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1814b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfFlushOutput(picoos_SDFile sdFile)
1815b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1816b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((sdFile != NULL) &&  !(sdFile->aborted) && (sdFile->bufPos > 0)) {
1817b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return picoos_sdfFlushOutBuf(sdFile);
1818b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1819b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return TRUE;
1820b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1821b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1822b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1823b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1824b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfPutSamples (picoos_SDFile sdFile, picoos_uint32 nrSamples, picoos_int16 samples[])
1825b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1826b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 i;
1827b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 s;
1828b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = FALSE;
1829b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1830b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((sdFile != NULL) &&  !(sdFile->aborted)) {
1831b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = TRUE;
1832b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        for (i = 0; i < nrSamples; i++) {
1833b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            s = samples[i];
1834b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((s > PICOOS_INT16_MAX)) {
1835b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                s = PICOOS_INT16_MAX;
1836b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else if (s < PICOOS_INT16_MIN) {
1837b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                s = PICOOS_INT16_MIN;
1838b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1839b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            sdFile->buf[sdFile->bufPos++] = s;
1840b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if (sdFile->bufPos >= PICOOS_SDF_BUF_LEN) {
1841b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done = picoos_sdfFlushOutBuf(sdFile);
1842b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
1843b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1844b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1845b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = FALSE;
1846b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1847b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1848b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1849b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1850b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1851b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern picoos_bool picoos_sdfCloseOut (picoos_Common g, picoos_SDFile * sdFile)
1852b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1853b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1854b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_bool done = TRUE;
1855b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 hdrSize;
1856b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1857b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (NULL != (*sdFile)) {
1858b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (!((*sdFile)->aborted) && ((*sdFile)->bufPos > 0)) {
1859b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = picoos_sdfFlushOutBuf(*sdFile);
1860b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1861b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (FILE_TYPE_WAV == (*sdFile)->fileType) {
1862b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = picoos_writeWavHeader((*sdFile)->file, (*sdFile)->sf,
1863b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    (*sdFile)->enc, (*sdFile)->nrFileSamples, &hdrSize);
1864b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1865b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = picoos_CloseBinary(g, &((*sdFile)->file));
1866b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_deallocate(g->mm, (void *) sdFile);
1867b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1868b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return done;
1869b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1870b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1871b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1872b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
1873b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* FileHeader                                                      */
1874b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
1875b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1876b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1877b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1878b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_clearHeader(picoos_FileHeader header)
1879b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1880b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 i;
1881b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i=0; i < PICOOS_MAX_NUM_HEADER_FIELDS; i++) {
1882b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        header->field[i].key[0] = NULLC;
1883b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        header->field[i].value[0] = NULLC;
1884b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        header->field[i].op = PICOOS_FIELD_IGNORE;
1885b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1886b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    header->numFields = 0;
1887b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
1888b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1889b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1890b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_setHeaderField(picoos_FileHeader header,
1891b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 index, picoos_char * key, picoos_char * value,
1892b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_compare_op_t op)
1893b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1894b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (index >= header->numFields) {
1895b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_INDEX_OUT_OF_RANGE;
1896b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1897b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    header->field[index].op = op;
1898b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((picoos_strlcpy(header->field[index].key, key,
1899b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICOOS_MAX_FIELD_STRING_LEN) < PICOOS_MAX_FIELD_STRING_LEN)
1900b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            && (picoos_strlcpy(header->field[index].value, value,
1901b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOOS_MAX_FIELD_STRING_LEN)) < PICOOS_MAX_FIELD_STRING_LEN) {
1902b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
1903b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1904b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_INDEX_OUT_OF_RANGE;
1905b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1906b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1907b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1908b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1909b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* caller has to make sure allocated space at key and value are large enough to hold a picoos_field_string */
1910b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_getHeaderField(picoos_FileHeader header, picoos_uint8 index, picoos_field_string_t key, picoos_field_string_t value, picoos_compare_op_t * op)
1911b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1912b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (index >= header->numFields) {
1913b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_INDEX_OUT_OF_RANGE;
1914b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1915b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *op = header->field[index].op;
1916b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((picoos_strlcpy(key,header->field[index].key,
1917b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            PICOOS_MAX_FIELD_STRING_LEN) < PICOOS_MAX_FIELD_STRING_LEN)
1918b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            && (picoos_strlcpy(value,header->field[index].value,
1919b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                    PICOOS_MAX_FIELD_STRING_LEN)) < PICOOS_MAX_FIELD_STRING_LEN) {
1920b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
1921b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1922b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_INDEX_OUT_OF_RANGE;
1923b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1924b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
1925b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1926b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1927b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1928b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* check whether 'str' of length strlen matches contents in circular buffer buf, located in the first strlen bytes and ending
1929b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * position bufpos. */
1930b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenstatic picoos_uint8 os_matched( picoos_char * str,  picoos_uint32 strlen, picoos_char * buf,  picoos_int32 bufpos) {
1931b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 i = strlen-1;
1932b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while (i >= 0 && buf[bufpos] == str[i]) {
1933b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i--;
1934b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        bufpos--;
1935b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if (bufpos < 0) {
1936b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bufpos = strlen-1;
1937b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1938b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1939b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (i<0);
1940b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1941b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1942b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_getSVOXHeaderString(picoos_char * str, picoos_uint8 * len, picoos_uint32 maxlen)
1943b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1944b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_char * ch;
1945b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *len = picoos_strlcpy(str,picoos_SVOXFileHeader,maxlen);
1946b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (*len < maxlen) {
1947b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        ch = str;
1948b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* SVOX header is made less readable */
1949b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        while (*ch) {
1950b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            *ch -= ' ';
1951b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            ch++;
1952b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1953b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
1954b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1955b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_OTHER;
1956b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1957b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1958b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1959b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_readPicoHeader(picoos_File f, picoos_uint32 * headerlen)
1960b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1961b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_char str[32];
1962b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_char buf[32];
1963b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 strlen, bufpos;
1964b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n;
1965b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 done;
1966b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1967b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_getSVOXHeaderString(str,&strlen,32);
1968b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* search for svox header somewhere near the file start. This allows for initial
1969b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen     * non-svox-header bytes for a customer-specific header and/or filling bytes for alignment */
1970b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *headerlen = 0;
1971b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* read in initial chunk of length strlen */
1972b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    n = strlen;
1973b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    done = picoos_ReadBytes(f,(picoos_uint8 *)buf,&n) && (n == strlen);
1974b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (done) {
1975b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *headerlen = n;
1976b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        bufpos = strlen-1; /* last legal buf position */
1977b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done = os_matched(str,strlen,buf,bufpos);
1978b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        while (!done && *headerlen < PICO_MAX_FOREIGN_HEADER_LEN) {
1979b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            n = 1;
1980b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            bufpos = (bufpos + 1) % strlen;
1981b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = picoos_ReadBytes(f,(picoos_uint8 *)buf+bufpos,&n) && 1 == n;
1982b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            done = done && os_matched(str,strlen,buf,bufpos);
1983b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            headerlen++;
1984b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
1985b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1986b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (done) {
1987b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
1988b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
1989b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_EXC_UNEXPECTED_FILE_TYPE;
1990b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
1991b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
1992b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1993b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoos_get_str (picoos_char * fromStr, picoos_uint32 * pos, picoos_char * toStr, picoos_objsize_t maxsize)
1994b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
1995b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 i = 0;
1996b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* skip non-printables */
1997b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
1998b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((fromStr[*pos] != NULLC) && (fromStr[*pos] <= ' ')) {
1999b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*pos)++;
2000b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2001b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* copy printable portion */
2002b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((fromStr[*pos] != NULLC) && (fromStr[*pos] > ' ') && (i < maxsize-1)) {
2003b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        toStr[i++] = fromStr[(*pos)++];
2004b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2005b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    toStr[i] = NULLC;
2006b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (i > 0) && (fromStr[*pos] <= ' ');
2007b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2008b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2009b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_hdrParseHeader(picoos_FileHeader header, picoos_header_string_t str)
2010b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2011b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 curpos = 0;
2012b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 i, numFields;
2013b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2014b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2015b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* read number of fields */
2016b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    numFields = str[curpos++];
2017b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    numFields = os_min(numFields,PICOOS_MAX_NUM_HEADER_FIELDS);
2018b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* read in all field pairs */
2019b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    PICODBG_DEBUG(("number of fields = %i", numFields));
2020b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    for (i = 0; i < numFields; i++) {
2021b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_get_str(str,&curpos,header->field[i].key,PICOOS_MAX_FIELD_STRING_LEN);
2022b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_get_str(str,&curpos,header->field[i].value,PICOOS_MAX_FIELD_STRING_LEN);
2023b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2024b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
2025b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2026b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2027b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2028b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2029b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2030b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2031b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **************************************************************************/
2032b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Read  little-endian / platform-independent integers from file or memory  */
2033b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **************************************************************************/
2034b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2035b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* read little-endian */
2036b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_le_uint16 (picoos_File file, picoos_uint16 * val)
2037b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2038b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 by[2];
2039b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n = 2;
2040b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (picoos_ReadBytes(file, by, &n) && 2 == n) {
2041b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* little-endian */
2042b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *val = (picoos_uint16) by[1] << 8 | (picoos_uint16) by[0];
2043b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
2044b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
2045b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *val = 0;
2046b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_OTHER;
2047b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2048b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2049b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2050b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_le_int16 (picoos_File file, picoos_int16 * val)
2051b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2052b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picoos_read_le_uint16(file, (picoos_uint16 *)val);
2053b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2054b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2055b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_le_uint32 (picoos_File file, picoos_uint32 * val)
2056b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2057b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 by[4];
2058b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint32 n = 4;
2059b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (picoos_ReadBytes(file, by, &n) && (4 == n)) {
2060b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* little-endian */
2061b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_TRACE(("reading uint 32:  %i %i %i %i",
2062b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                       by[0], by[1], by[2], by[3]));
2063b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *val = (((picoos_uint32) by[3] << 8 | (picoos_uint32) by[2]) << 8 | (picoos_uint32) by[1]) << 8 | (picoos_uint32) by[0];
2064b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        PICODBG_TRACE(("uint 32:  %i %i %i %i corresponds %i",
2065b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                       by[0], by[1], by[2], by[3], *val));
2066b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
2067b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
2068b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *val = 0;
2069b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_ERR_OTHER;
2070b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2071b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2072b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2073b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* platform-independent */
2074b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* our convention is that pi is little-endian. */
2075b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2076b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/** @todo : direct implementation if too slow */
2077b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2078b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_pi_uint16 (picoos_File file, picoos_uint16 * val)
2079b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2080b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picoos_read_le_uint16(file,val);
2081b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2082b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2083b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_pi_uint32 (picoos_File file, picoos_uint32 * val)
2084b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2085b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picoos_read_le_uint32(file, val);
2086b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2087b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2088b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_pi_int32 (picoos_File file, picoos_int32 * val)
2089b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2090b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return picoos_read_le_uint32(file, (picoos_uint32 *)val);
2091b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2092b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2093b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* read pi from memory */
2094b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2095b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_mem_pi_uint16 (picoos_uint8 * data, picoos_uint32 * pos, picoos_uint16 * val)
2096b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2097b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * by = data + *pos;
2098b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2099b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* little-endian */
2100b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    *val = (picoos_uint16) by[1] << 8 | (picoos_uint16) by[0];
2101b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*pos) += 2;
2102b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
2103b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2104b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2105b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_read_mem_pi_uint32 (picoos_uint8 * data, picoos_uint32 * pos, picoos_uint32 * val)
2106b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2107b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint8 * by = data + *pos;
2108b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2109b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        /* little-endian */
2110b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        *val = (((picoos_uint32) by[3] << 8 | (picoos_uint32) by[2]) << 8 | (picoos_uint32) by[1]) << 8 | (picoos_uint32) by[0];
2111b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*pos) += 4;
2112b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
2113b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2114b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2115b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **************************************************************************/
2116b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* Write little-endian / platform-independent integers into file or memory  */
2117b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* **************************************************************************/
2118b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* write little-endian */
2119b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_write_le_uint16 (picoos_File file, picoos_uint16 val)
2120b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2121b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 len = 2;
2122b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 by[2];
2123b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2124b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[0]  = (picoos_uint8)((val) & 0x00FF);
2125b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[1]  = (picoos_uint8)(((val) & 0xFF00)>>8);
2126b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_WriteBytes(file,by,&len) && (2 == len));
2127b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2128b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_write_le_uint32 (picoos_File file, picoos_uint32 val)
2129b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2130b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 len = 4;
2131b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 by[4];
2132b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2133b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[0]  = (picoos_uint8)(val & 0x000000FF);
2134b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[1]  = (picoos_uint8)((val & 0x0000FF00)>>8);
2135b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[2]  = (picoos_uint8)((val & 0x00FF0000)>>16);
2136b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[3]  = (picoos_uint8)((val & 0xFF000000)>>24);
2137b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (picoos_WriteBytes(file,by,&len) && (4 == len));
2138b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2139b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2140b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* write pi to mem */
2141b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_write_mem_pi_uint16 (picoos_uint8 * data, picoos_uint32 * pos, picoos_uint16 val)
2142b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2143b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 * by = data + *pos;
2144b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* little-endian */
2145b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[0]  = (picoos_uint8)((val) & 0x00FF);
2146b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    by[1]  = (picoos_uint8)(((val) & 0xFF00)>>8);
2147b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    (*pos) += 2;
2148b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return PICO_OK;
2149b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2150b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2151b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
2152b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* String search and compare operations                            */
2153b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
2154b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2155b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* this function is case-sensitive */
2156b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpicoos_uint8 picoos_has_extension(const picoos_char *str, const picoos_char *suf)
2157b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2158b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 istr = picoos_strlen(str)-1;
2159b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 isuf = picoos_strlen(suf)-1;
2160b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((istr >= 0) && (isuf >=0) && (str[istr] == suf[isuf])) {
2161b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        istr--;
2162b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        isuf--;
2163b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2164b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    return (isuf < 0);
2165b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2166b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2167b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2168b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
2169b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* String/Number Conversions  (may be moved to picopal)            */
2170b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
2171b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2172b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_string_to_int32(picoos_char str[],
2173b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int32 * res)
2174b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2175b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* syntax: [+|-] dig {dig} */
2176b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2177b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int i;
2178b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int neg;
2179b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int val;
2180b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int err;
2181b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2182b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    err = 0;
2183b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 0;
2184b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((str[i] <= ' ') && (str[i] != '\0')) {
2185b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2186b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2187b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    neg = 0;
2188b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (str[i] == '-') {
2189b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        neg = 1;
2190b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2191b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else if (str[i] == '+') {
2192b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2193b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2194b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    val = 0;
2195b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((str[i] < '0') || (str[i]> '9')) {
2196b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        err = 1;
2197b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2198b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((str[i] >= '0') && (str[i] <= '9')) {
2199b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        val = val * 10 + (str[i] - '0');
2200b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2201b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2202b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((str[i] <= ' ') && (str[i] != '\0')) {
2203b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2204b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2205b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (neg == 1) {
2206b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        val = -val;
2207b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2208b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((err == 0) && (str[i] == '\0')) {
2209b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*res) = val;
2210b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
2211b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
2212b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*res) = 0;
2213b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_EXC_NUMBER_FORMAT;
2214b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2215b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2216b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2217b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenpico_status_t picoos_string_to_uint32(picoos_char str[],
2218b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_uint32 * res)
2219b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2220b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    /* syntax: [+] dig {dig} */
2221b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2222b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int i;
2223b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int val;
2224b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    int err;
2225b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2226b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    err = 0;
2227b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    i = 0;
2228b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((str[i] <= ' ') && (str[i] != '\0')) {
2229b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2230b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2231b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (str[i] == '+') {
2232b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2233b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2234b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    val = 0;
2235b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((str[i] < '0') || (str[i]> '9')) {
2236b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        err = 1;
2237b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2238b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((str[i] >= '0') && (str[i] <= '9')) {
2239b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        val = val * 10 + (str[i] - '0');
2240b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2241b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2242b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    while ((str[i] <= ' ') && (str[i] != '\0')) {
2243b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        i++;
2244b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2245b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if ((err == 0) && (str[i] == '\0')) {
2246b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*res) = val;
2247b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_OK;
2248b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
2249b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*res) = 0;
2250b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        return PICO_EXC_NUMBER_FORMAT;
2251b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2252b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2253b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2254b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* 'stringlen' is the part of input string to be considered,
2255b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * possibly not containing NULLC (e.g. result of strlen).
2256b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * 'maxsize' is the maximal size of 'part' including a byte
2257b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen * for the terminating NULLC! */
2258b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenvoid picoos_get_sep_part_str(picoos_char string[],
2259b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_int32 stringlen, picoos_int32 * ind, picoos_char sepCh,
2260b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        picoos_char part[], picoos_int32 maxsize, picoos_uint8 * done)
2261b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2262b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2263b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_int32 j;
2264b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picoos_uint8 done1;
2265b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2266b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    if (((*ind) >= stringlen)) {
2267b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*done) = 0;
2268b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        part[0] = (picoos_char) NULLC;
2269b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    } else {
2270b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        done1 = 1;
2271b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        j = 0;
2272b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        while ((((*ind) < stringlen) && (string[(*ind)] != sepCh)) && (string[((*ind))] != (picoos_char)NULLC)) {
2273b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((j < maxsize-1)) {
2274b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                part[(j)] = string[(*ind)];
2275b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                j++;
2276b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else {
2277b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                done1 = 0;
2278b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
2279b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            (*ind)++;
2280b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
2281b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        part[j] = (picoos_char)NULLC;
2282b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        if ((*ind) < stringlen) {
2283b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            if ((string[(*ind)] == sepCh)) {
2284b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*ind)++; /* skip separator character */
2285b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            } else if (string[(*ind)] == (picoos_char)NULLC) {
2286b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                /* reached end of input; set ind to stringlen so that no
2287b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                 more (empty) partial strings will be found */
2288b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen                (*ind) = stringlen;
2289b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen            }
2290b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        }
2291b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen        (*done) = done1;
2292b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    }
2293b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2294b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2295b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
2296b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* timer function                                                  */
2297b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* *****************************************************************/
2298b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2299b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chenextern void picoos_get_timer(picopal_uint32 * sec, picopal_uint32 * usec)
2300b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen{
2301b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen    picopal_get_timer(sec, usec);
2302b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2303b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2304b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#ifdef __cplusplus
2305b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen}
2306b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen#endif
2307b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2308b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen
2309b190149a69b110e6719ce0a41877a683f8db7ae7Charles Chen/* end */
2310