1 /*************************************************************************/
2 /*                                                                       */
3 /*                  Language Technologies Institute                      */
4 /*                     Carnegie Mellon University                        */
5 /*                        Copyright (c) 2001                             */
6 /*                        All Rights Reserved.                           */
7 /*                                                                       */
8 /*  Permission is hereby granted, free of charge, to use and distribute  */
9 /*  this software and its documentation without restriction, including   */
10 /*  without limitation the rights to use, copy, modify, merge, publish,  */
11 /*  distribute, sublicense, and/or sell copies of this work, and to      */
12 /*  permit persons to whom this work is furnished to do so, subject to   */
13 /*  the following conditions:                                            */
14 /*   1. The code must retain the above copyright notice, this list of    */
15 /*      conditions and the following disclaimer.                         */
16 /*   2. Any modifications must be clearly marked as such.                */
17 /*   3. Original authors' names are not deleted.                         */
18 /*   4. The authors' names are not used to endorse or promote products   */
19 /*      derived from this software without specific prior written        */
20 /*      permission.                                                      */
21 /*                                                                       */
22 /*  CARNEGIE MELLON UNIVERSITY AND THE CONTRIBUTORS TO THIS WORK         */
23 /*  DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING      */
24 /*  ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT   */
25 /*  SHALL CARNEGIE MELLON UNIVERSITY NOR THE CONTRIBUTORS BE LIABLE      */
26 /*  FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES    */
27 /*  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN   */
28 /*  AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,          */
29 /*  ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF       */
30 /*  THIS SOFTWARE.                                                       */
31 /*                                                                       */
32 /*************************************************************************/
33 /*             Author:  Alan W Black <awb@cs.cmu.edu>                    */
34 /*               Date:  July 2004                                        */
35 /*************************************************************************/
36 /*                                                                       */
37 /*  File I/O wrappers for PalmOS platforms.                              */
38 /*                                                                       */
39 /*  flop/armflite currently (Jan 05) only uses cst_sprintf               */
40 /*                                                                       */
41 /*************************************************************************/
42 
43 #include "cst_file.h"
44 #include "cst_error.h"
45 #include "cst_alloc.h"
46 
47 #define	 _STDIO_PALM_C_
48 #include <PalmOS.h>
49 #include <StdIOPalm.h>
50 #include <System/FileStream.h>
51 
52 #include <string.h>
53 #include <stdarg.h>
54 
cst_fopen(const char * path,int mode)55 cst_file cst_fopen(const char *path, int mode)
56 {
57     /* This is kind of hacky. */
58     if ((mode & CST_OPEN_WRITE) && (mode & CST_OPEN_READ))
59 	    return FileOpen(0, path, 0, 0, fileModeReadWrite, NULL);
60     else if ((mode & CST_OPEN_APPEND) && (mode & CST_OPEN_READ))
61 	    return FileOpen(0, path, 0, 0,
62 			    fileModeAppend | fileModeReadWrite, NULL);
63     else if (mode & CST_OPEN_WRITE)
64 	    return FileOpen(0, path, 0, 0, fileModeReadWrite, NULL);
65     else if (mode & CST_OPEN_APPEND)
66 	    return FileOpen(0, path, 0, 0, fileModeAppend, NULL);
67     else if (mode & CST_OPEN_READ)
68 	    return FileOpen(0, path, 0, 0, fileModeReadOnly, NULL);
69     else
70 	    return FileOpen(0, path, 0, 0, fileModeReadOnly, NULL);
71 }
72 
cst_fwrite(cst_file fh,const void * buf,long size,long count)73 long cst_fwrite(cst_file fh, const void *buf, long size, long count)
74 {
75     return FileWrite(fh, buf, size, count, NULL);
76 }
77 
cst_fread(cst_file fh,void * buf,long size,long count)78 long cst_fread(cst_file fh, void *buf, long size, long count)
79 {
80     return FileRead(fh,buf,size,count,NULL);
81 }
82 
cst_filesize(cst_file fh)83 long cst_filesize(cst_file fh)
84 {
85     long epos=0;
86 
87     FileTell(fh,&epos,NULL);
88 
89     return epos;
90 }
91 
cst_fgetc(cst_file fh)92 int cst_fgetc(cst_file fh)
93 {
94     return fgetc(fh);
95 }
96 
cst_ftell(cst_file fh)97 long cst_ftell(cst_file fh)
98 {
99     return FileTell(fh,NULL,NULL);
100 }
101 
cst_fseek(cst_file fh,long pos,int whence)102 long cst_fseek(cst_file fh, long pos, int whence)
103 {
104     FileOriginEnum w = fileOriginBeginning;
105 
106     if (whence == CST_SEEK_ABSOLUTE)
107 	w = fileOriginBeginning;
108     else if (whence == CST_SEEK_RELATIVE)
109 	w = fileOriginCurrent;
110     else if (whence == CST_SEEK_ENDREL)
111 	w = fileOriginEnd;
112 
113     return FileSeek(fh, pos, w);
114 }
115 
cst_fclose(cst_file fh)116 int cst_fclose(cst_file fh)
117 {
118     return FileClose(fh);
119 }
120 
po_itoa(char * s,int i,const char * modifier)121 static int po_itoa(char *s, int i, const char* modifier)
122 {    /* print ascii representation of i to s with any modifier (e.g. "03") */
123     char n[20];  /* numbers cannot be bigger than 20 places */
124     int ni, si;
125     int q;
126 
127     /* modifier currently ignored */
128 
129     /* construct the ascii backwards */
130     if (i == 0)
131     {
132 	n[0] = '0';
133 	ni=1;
134     }
135     else
136 	for (ni=0,q=(i < 0 ? -i : i); q > 0; q/=10,ni++)
137 	    n[ni] = q%10 + '0';
138     if (i < 0)
139     {
140 	n[ni] = '-';
141 	ni++;
142     }
143 
144     /* pop it off and onto the string */
145     for (si=0; ni>0; si++,ni--)
146 	s[si] = n[ni-1];
147 
148     return si;
149 }
150 
po_ftoa(char * s,float f,const char * modifier)151 static int po_ftoa(char *s, float f, const char* modifier)
152 {
153     char n[20];  /* numbers cannot be bigger than 30 places */
154     char p[20];
155     int ni, si, pi;
156     int q,i,d;
157     float pp;
158 
159     /* modifier currently ignored */
160 
161     /* construct the ascii backwards */
162     if (f == 0.0)
163     {
164 	n[0] = '0';
165 	n[1] = '.';
166 	n[2] = '0';
167 	ni=3;
168 	p[0] = '\0';
169     }
170     else
171     {
172 	/* above zero part */
173 	i = (f < 0 ? (int)-f : (int)f);
174 	for (ni=0,q=i; q > 0; q/=10,ni++)
175 	    n[ni] = q%10 + '0';
176 	/* point */
177 	p[0] = '.';
178 	/* below zero part */
179 	pp = (f < 0 ? -f : f) - (float)i;
180 	if (pp == 0)
181 	{
182 	    p[1] = '0'; pi = 2;
183 	}
184 	else
185 	    for (pi=1,pp*=10.0; (pp > 0) && (pi < 4); pp*=10.0,pi++)
186 	    {
187 		d = (int)pp;
188 		p[pi] = d + '0';
189 		pp -= d;
190 	    }
191 	p[pi] = '\0';
192     }
193 
194     /* sign */
195     if (f < 0)
196     {
197 	n[ni] = '-';
198 	ni++;
199     }
200 
201     /* pop it off and onto the string */
202     for (si=0; ni>0; si++,ni--)
203 	s[si] = n[ni-1];
204     for (pi=0; p[pi]; si++,pi++)
205 	s[si] = p[pi];
206 
207     return si;
208 }
209 
cst_vsprintf(char * s,const char * fmt,va_list args)210 int cst_vsprintf(char *s, const char *fmt, va_list args)
211 {
212     /* A simple sprintf that caters for what flite uses */
213     int sp=0,fp=0;
214     char *sa;
215     char ca;
216     int ia;
217     float fa;
218 
219     for (sp=0,fp=0; fmt[fp]; fp++)
220     {
221 	if (fmt[fp] == '%')
222 	{
223 	    if (fmt[fp+1] == '%')
224 	    {
225 		s[sp] = '%';
226 		sp++; fp++;
227 	    }
228 	    else if (fmt[fp+1] == 's')
229 	    {
230 		sa = va_arg(args, char *);
231 		memmove(s+sp,sa,cst_strlen(sa));
232 		sp+=cst_strlen(sa); fp++;
233 	    }
234 	    else if (fmt[fp+1] == '.')
235 	    {
236 		if (fmt[fp+2] == '*')
237 		{   /* When the length is specified on the stack */
238 		    ia = va_arg(args, int);
239 		    sa = va_arg(args, char *);
240 		    memmove(s+sp,sa,ia);
241 		    sp+=ia; fp+=3;
242 		}
243 		else
244 		{   /* When the length is specified in the format */
245 		    fp+=2;   /* skip over the field width */
246 		    while ((strchr("0123456789",fmt[fp]) != 0) &&
247 			   fmt[fp])
248 			fp++;
249 		    sa = va_arg(args, char *);
250 		    memmove(s+sp,sa,cst_strlen(sa));
251 		    sp+=cst_strlen(sa);
252 		}
253 	    }
254 	    else if (fmt[fp+1] == 'c')
255 	    {
256 		ca = (unsigned char)va_arg(args, unsigned int);
257 		s[sp] = ca;
258 		sp++; fp++;
259 	    }
260 	    else if (fmt[fp+1] == 'd')
261 	    {
262 		ia = va_arg(args, int);
263 		sp += po_itoa(s+sp,ia,"");
264 		fp++;
265 	    }
266 	    else if (fmt[fp+1] == 'f')
267 	    {
268 		fa = (float)va_arg(args, double);
269 		sp += po_ftoa(s+sp,fa,"");
270 		fp++;
271 	    }
272 	}
273 	else
274 	{
275 	    s[sp] = fmt[fp];
276 	    sp++;
277 	}
278     }
279     va_end(args);
280     s[sp] = '\0';
281 
282     return sp;
283 }
284 
cst_fprintf(cst_file fh,char * fmt,...)285 int cst_fprintf(cst_file fh, char *fmt, ...)
286 {
287     va_list args;
288     char outbuf[512];
289     int count;
290 
291     va_start(args,fmt);
292     count = cst_vsprintf(outbuf,fmt,args);
293     va_end(args);
294     return cst_fwrite(fh,outbuf,1,count);
295 }
296 
cst_sprintf(char * s,const char * fmt,...)297 int cst_sprintf(char *s, const char *fmt, ...)
298 {
299     va_list args;
300     int count;
301 
302     va_start(args,fmt);
303     count = cst_vsprintf(s,fmt,args);
304     va_end(args);
305 
306     return count;
307 }
308