Edinburgh Speech Tools  2.1-release
stdio16.c
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Copyright (c) 1997-98 Richard Tobin, Language Technology Group, HCRC, */
4 /* University of Edinburgh. */
5 /* */
6 /* THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, */
7 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
8 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
9 /* IN NO EVENT SHALL THE AUTHOR OR THE UNIVERSITY OF EDINBURGH BE LIABLE */
10 /* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF */
11 /* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION */
12 /* WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
13 /* */
14 /*************************************************************************/
15 /*
16  * An implementation of printf that
17  * - allows printing of 16-bit unicode characters and strings
18  * - translates output to a specified character set
19  *
20  * "char8" is 8 bits and contains ISO-Latin-1 (or ASCII) values
21  * "char16" is 16 bits and contains UTF-16 values
22  * "Char" is char8 or char16 depending on whether CHAR_SIZE is 8 or 16
23  *
24  * Author: Richard Tobin
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <string.h>
30 #include <stdarg.h>
31 
32 #ifdef FOR_LT
33 
34 #include "lt-memory.h"
35 #include "nsl-err.h"
36 
37 #define ERR(m) LT_ERROR(NECHAR,m)
38 #define ERR1(m,x) LT_ERROR1(NECHAR,m,x)
39 #define ERR2(m,x,y) LT_ERROR2(NECHAR,m,x,y)
40 
41 #define Malloc salloc
42 #define Realloc srealloc
43 #define Free sfree
44 
45 #else
46 
47 #include "system.h"
48 #define WIN_IMP
49 
50 #define ERR(m) fprintf(stderr,m)
51 #define ERR1(m,x) fprintf(stderr,m,x)
52 #define ERR2(m,x,y) fprintf(stderr,m,x,y)
53 #endif
54 
55 #ifdef WIN32
56 #undef boolean
57 #include <winsock.h>
58 #include <fcntl.h>
59 #endif
60 
61 #include "charset.h"
62 #include "string16.h"
63 #include "stdio16.h"
64 
65 /* When we return -1 for non-io errors, we set errno to 0 to avoid confusion */
66 #include <errno.h>
67 
68 #define BufferSize 4096
69 
70 typedef int ReadProc(FILE16 *file, unsigned char *buf, int max_count);
71 typedef int WriteProc(FILE16 *file, const unsigned char *buf, int count);
72 typedef int SeekProc(FILE16 *file, long offset, int ptrname);
73 typedef int FlushProc(FILE16 *file);
74 typedef int CloseProc(FILE16 *file);
75 
76 struct _FILE16 {
77  void *handle;
78  int handle2, handle3;
79  ReadProc *read;
80  WriteProc *write;
81  SeekProc *seek;
82  FlushProc *flush;
83  CloseProc *close;
84  int flags;
86  char16 save;
87 };
88 
89 #define FILE16_read 0x01
90 #define FILE16_write 0x02
91 #define FILE16_close_underlying 0x04
92 
93 static int FileRead(FILE16 *file, unsigned char *buf, int max_count);
94 static int FileWrite(FILE16 *file, const unsigned char *buf, int count);
95 static int FileSeek(FILE16 *file, long offset, int ptrname);
96 static int FileClose(FILE16 *file);
97 static int FileFlush(FILE16 *file);
98 
99 static int StringRead(FILE16 *file, unsigned char *buf, int max_count);
100 static int StringWrite(FILE16 *file, const unsigned char *buf, int count);
101 static int StringSeek(FILE16 *file, long offset, int ptrname);
102 static int StringClose(FILE16 *file);
103 static int StringFlush(FILE16 *file);
104 
105 #ifdef WIN32
106 #ifdef SOCKETS_IMPLEMENTED
107 static int WinsockRead(FILE16 *file, unsigned char *buf, int max_count);
108 static int WinsockWrite(FILE16 *file, const unsigned char *buf, int count);
109 static int WinsockSeek(FILE16 *file, long offset, int ptrname);
110 static int WinsockClose(FILE16 *file);
111 static int WinsockFlush(FILE16 *file);
112 #endif
113 #endif
114 
115 #ifdef HAVE_LIBZ
116 static int GzipRead(FILE16 *file, unsigned char *buf, int max_count);
117 static int GzipWrite(FILE16 *file, const unsigned char *buf, int count);
118 static int GzipSeek(FILE16 *file, long offset, int ptrname);
119 static int GzipClose(FILE16 *file);
120 static int GzipFlush(FILE16 *file);
121 #endif
122 
123 FILE16 *Stdin, *Stdout, *Stderr;
124 
125 void init_stdio16(void) {
126  Stdin = MakeFILE16FromFILE(stdin, "r");
128  Stdout = MakeFILE16FromFILE(stdout, "w");
130  Stderr = MakeFILE16FromFILE(stderr, "w");
132 }
133 
134 static int ConvertASCII(const char8 *buf, int count, FILE16 *file);
135 static int ConvertUTF16(const char16 *buf, int count, FILE16 *file);
136 
137 /* Output an ASCII buffer in the specified encoding */
138 
139 /* In fact, we don't translate the buffer at all if we are outputting
140  an 8-bit encoding, and we treat it as Latin-1 is we are outputting
141  a 16-bit encoding. This means that all the various ASCII supersets
142  will be passed through unaltered in the usual case, since we don't
143  translate them on input either. */
144 
145 static int ConvertASCII(const char8 *buf, int count, FILE16 *file)
146 {
147  unsigned char outbuf[BufferSize*2];
148  int i, j;
149 
150  switch(file->enc)
151  {
152  case CE_ISO_8859_1:
153  case CE_ISO_8859_2:
154  case CE_ISO_8859_3:
155  case CE_ISO_8859_4:
156  case CE_ISO_8859_5:
157  case CE_ISO_8859_6:
158  case CE_ISO_8859_7:
159  case CE_ISO_8859_8:
160  case CE_ISO_8859_9:
162  return file->write(file, (unsigned char *)buf, count);
163 
164  case CE_UTF_8:
165  for(i=j=0; i<count; i++)
166  {
167  unsigned char c = buf[i];
168  if(c < 128)
169  outbuf[j++] = c;
170  else
171  {
172  outbuf[j++] = 0xc0 + (c >> 6);
173  outbuf[j++] = 0x80 + (c & 0x3f);
174  }
175  }
176  return file->write(file, outbuf, j);
177 
178  case CE_UTF_16B:
179  case CE_ISO_10646_UCS_2B:
180  for(i=j=0; i<count; i++)
181  {
182  outbuf[j++] = 0;
183  outbuf[j++] = buf[i];
184  }
185  return file->write(file, outbuf, count*2);
186 
187  case CE_UTF_16L:
188  case CE_ISO_10646_UCS_2L:
189  for(i=j=0; i<count; i++)
190  {
191  outbuf[j++] = buf[i];
192  outbuf[j++] = 0;
193  }
194  return file->write(file, outbuf, count*2);
195 
196  default:
197  ERR2("Bad output character encoding %d (%s)\n",
198  file->enc,
199  file->enc < CE_enum_count ? CharacterEncodingName[file->enc] :
200  "unknown");
201  errno = 0;
202  return -1;
203  }
204 }
205 
206 /* Output a UTF-16 buffer in the specified encoding */
207 
208 static int ConvertUTF16(const char16 *buf, int count, FILE16 *file)
209 {
210  /* size is max for UTF-8 with saved first half */
211  unsigned char outbuf[BufferSize*3 + 1];
212  int i, j, tablenum, max;
213  char8 *from_unicode;
214  char32 big;
215 
216  switch(file->enc)
217  {
218  case CE_ISO_8859_1:
220  for(i=0; i<count; i++)
221  {
222  if(buf[i] < 256)
223  outbuf[i] = (unsigned char)buf[i];
224  else
225  outbuf[i] = '?';
226  }
227  return file->write(file, outbuf, count);
228 
229  case CE_ISO_8859_2:
230  case CE_ISO_8859_3:
231  case CE_ISO_8859_4:
232  case CE_ISO_8859_5:
233  case CE_ISO_8859_6:
234  case CE_ISO_8859_7:
235  case CE_ISO_8859_8:
236  case CE_ISO_8859_9:
237  tablenum = (file->enc - CE_ISO_8859_2);
238  max = iso_max_val[tablenum];
239  from_unicode = unicode_to_iso[tablenum];
240  for(i=0; i<count; i++)
241  {
242  if(buf[i] <= max)
243  outbuf[i] = (unsigned char)from_unicode[buf[i]];
244  else
245  outbuf[i] = '?';
246  }
247  return file->write(file, outbuf, count);
248 
249  case CE_UTF_8:
250  for(i=j=0; i<count; i++)
251  {
252  if(buf[i] < 0x80)
253  outbuf[j++] = (unsigned char)buf[i];
254  else if(buf[i] < 0x800)
255  {
256  outbuf[j++] = 0xc0 + (buf[i] >> 6);
257  outbuf[j++] = 0x80 + (buf[i] & 0x3f);
258  }
259  else if(buf[i] >= 0xd800 && buf[i] <= 0xdbff)
260  file->save = buf[i];
261  else if(buf[i] >= 0xdc00 && buf[i] <= 0xdfff)
262  {
263  big = 0x10000 +
264  ((file->save - 0xd800) << 10) + (buf[i] - 0xdc00);
265  outbuf[j++] = 0xf0 + (big >> 18);
266  outbuf[j++] = 0x80 + ((big >> 12) & 0x3f);
267  outbuf[j++] = 0x80 + ((big >> 6) & 0x3f);
268  outbuf[j++] = 0x80 + (big & 0x3f);
269  }
270  else
271  {
272  outbuf[j++] = 0xe0 + (buf[i] >> 12);
273  outbuf[j++] = 0x80 + ((buf[i] >> 6) & 0x3f);
274  outbuf[j++] = 0x80 + (buf[i] & 0x3f);
275  }
276  }
277  return file->write(file, outbuf, j);
278 
279  case CE_UTF_16B:
280  case CE_ISO_10646_UCS_2B:
281  for(i=j=0; i<count; i++)
282  {
283  outbuf[j++] = (buf[i] >> 8);
284  outbuf[j++] = (buf[i] & 0xff);
285 
286  }
287  return file->write(file, outbuf, count*2);
288 
289  case CE_UTF_16L:
290  case CE_ISO_10646_UCS_2L:
291  for(i=j=0; i<count; i++)
292  {
293  outbuf[j++] = (buf[i] & 0xff);
294  outbuf[j++] = (buf[i] >> 8);
295 
296  }
297  return file->write(file, outbuf, count*2);
298 
299  default:
300  ERR2("Bad output character encoding %d (%s)\n",
301  file->enc,
302  file->enc < CE_enum_count ? CharacterEncodingName[file->enc] :
303  "unknown");
304  errno = 0;
305  return -1;
306  }
307 }
308 
309 int Readu(FILE16 *file, unsigned char *buf, int max_count)
310 {
311  return file->read(file, buf, max_count);
312 }
313 
314 int Writeu(FILE16 *file, unsigned char *buf, int count)
315 {
316  return file->write(file, buf, count);
317 }
318 
319 int Fclose(FILE16 *file)
320 {
321  int ret = 0;
322 
323  ret = file->close(file);
324  Free(file);
325 
326  return ret;
327 }
328 
329 int Fseek(FILE16 *file, long offset, int ptrname)
330 {
331  return file->seek(file, offset, ptrname);
332 }
333 
334 int Fflush(FILE16 *file)
335 {
336  return file->flush(file);
337 }
338 
339 FILE *GetFILE(FILE16 *file)
340 {
341  if(file->read == FileRead)
342  return (FILE *)file->handle;
343  else
344  return 0;
345 }
346 
347 void SetCloseUnderlying(FILE16 *file, int cu)
348 {
349  if(cu)
350  file->flags |= FILE16_close_underlying;
351  else
352  file->flags &= ~FILE16_close_underlying;
353 }
354 
356 {
357  file->enc = encoding;
358 }
359 
361 {
362  return file->enc;
363 }
364 
365 int Fprintf(FILE16 *file, const char *format, ...)
366 {
367  int nchars;
368  va_list args;
369  va_start(args, format);
370  nchars = Vfprintf(file, format, args);
371  va_end(args);
372  return nchars;
373 }
374 
375 int Printf(const char *format, ...)
376 {
377  int nchars;
378  va_list args;
379  va_start(args, format);
380  nchars = Vfprintf(Stdout, format, args);
381  va_end(args);
382  return nchars;
383 }
384 
385 int Sprintf(void *buf, CharacterEncoding enc, const char *format, ...)
386 {
387  int nchars;
388  va_list args;
389  va_start(args, format);
390  nchars = Vsprintf(buf, enc, format, args);
391  va_end(args);
392  return nchars;
393 }
394 
395 int Vprintf(const char *format, va_list args)
396 {
397  return Vfprintf(Stdout, format, args);
398 }
399 
400 int Vsprintf(void *buf, CharacterEncoding enc, const char *format,
401  va_list args)
402 {
403  int nchars;
404  FILE16 file = {0, 0, -1, StringRead, StringWrite, StringSeek, StringFlush, StringClose, FILE16_write, 0,0};
405 
406  file.handle = buf;
407  file.enc = enc;
408 
409  nchars = Vfprintf(&file, format, args);
410  file.close(&file); /* Fclose would try to free it */
411 
412  return nchars;
413 }
414 
415 #define put(x) {nchars++; if(count == sizeof(buf)) {if(ConvertASCII(buf, count, file) == -1) return -1; count = 0;} buf[count++] = x;}
416 
417 int Vfprintf(FILE16 *file, const char *format, va_list args)
418 {
419  char8 buf[BufferSize];
420  int count = 0;
421  int c, i, n, width, prec;
422  char fmt[200];
423  char8 val[200];
424  const char8 *start;
425  const char8 *p;
426  const char16 *q;
427  char16 cbuf[1];
428  int mflag;
429  int l, h;
430  #ifdef HAVE_LONG_DOUBLE
431  int L;
432  #endif
433  int nchars = 0;
434  memset(buf, 0, BufferSize*sizeof(char8));
435 
436  while((c = *format++))
437  {
438  if(c != '%')
439  {
440  put(c);
441  continue;
442  }
443 
444  start = format-1;
445  width = 0;
446  prec = -1;
447  mflag=0;
448  l=0, h=0;
449  #ifdef HAVE_LONG_DOUBLE
450  L=0;
451  #endif
452 
453  while(1)
454  {
455  switch(c = *format++)
456  {
457  case '-':
458  mflag = 1;
459  break;
460  case '+':
461  case ' ':
462  case '#':
463  case '0':
464  break;
465  default:
466  goto flags_done;
467  }
468  }
469  flags_done:
470 
471  if(c == '*')
472  {
473  width = va_arg(args, int);
474  c = *format++;
475  }
476  else if(c >= '0' && c <= '9')
477  {
478  width = c - '0';
479  while((c = *format++) >= '0' && c <= '9')
480  width = width * 10 + c - '0';
481  }
482 
483  if(c == '.')
484  {
485  c = *format++;
486  if(c == '*')
487  {
488  prec = va_arg(args, int);
489  c = *format++;
490  }
491  else if(c >= '0' && c <= '9')
492  {
493  prec = c - '0';
494  while((c = *format++) >= '0' && c <= '9')
495  prec = prec * 10 + c - '0';
496  }
497  else
498  prec = 0;
499  }
500 
501  switch(c)
502  {
503  case 'l':
504  l = 1;
505  c = *format++;
506  break;
507  case 'h':
508  h = 1;
509  c = *format++;
510  break;
511 #ifdef HAVE_LONG_DOUBLE
512  case 'L':
513  L = 1;
514  c = *format++;
515  break;
516 #endif
517  }
518 
519  if(format - start + 1 > (int) sizeof(fmt))
520  {
521  ERR("Printf: format specifier too long");
522  errno = 0;
523  return -1;
524  }
525 
526  strncpy(fmt, start, format - start);
527  fmt[format - start] = '\0';
528 
529  /* XXX should check it fits in val */
530 
531  switch(c)
532  {
533  case 'n':
534  *va_arg(args, int *) = nchars;
535  break;
536  case 'd':
537  case 'i':
538  case 'o':
539  case 'u':
540  case 'x':
541  case 'X':
542  if(h)
543  sprintf(val, fmt, va_arg(args, int)); /* promoted to int */
544  else if(l)
545  sprintf(val, fmt, va_arg(args, long));
546  else
547  sprintf(val, fmt, va_arg(args, int));
548  for(p=val; *p; p++)
549  put(*p);
550  break;
551  case 'f':
552  case 'e':
553  case 'E':
554  case 'g':
555  case 'G':
556 #ifdef HAVE_LONG_DOUBLE
557  if(L)
558  sprintf(val, fmt, va_arg(args, long double));
559  else
560 #endif
561  sprintf(val, fmt, va_arg(args, double));
562  for(p=val; *p; p++)
563  put(*p);
564  break;
565  case 'c':
566 #if CHAR_SIZE == 16
567  if(ConvertASCII(buf, count, file) == -1)
568  return -1;
569  count = 0;
570  cbuf[0] = va_arg(args, int);
571  if(ConvertUTF16(cbuf, 1, file) == -1)
572  return -1;
573 #else
574  (void)cbuf;
575  put(va_arg(args, int));
576 #endif
577  break;
578  case 'p':
579  sprintf(val, fmt, va_arg(args, void *));
580  for(p=val; *p; p++)
581  put(*p);
582  break;
583  case '%':
584  put('%');
585  break;
586  case 's':
587  if(l)
588  {
589  static char16 sNULL[] = {'(','N','U','L','L',')',0};
590 #if CHAR_SIZE == 16
591  string:
592 #endif
593  q = va_arg(args, char16 *);
594  if(!q)
595  q = sNULL;
596  n = strlen16(q);
597  if(prec >= 0 && n > prec)
598  n = prec;
599  if(n < width && !mflag)
600  for(i=width-n; i>0; i--)
601  put(' ');
602  if(ConvertASCII(buf, count, file) == -1)
603  return -1;
604  count = 0;
605  nchars += n;
606  while(n > 0)
607  {
608  /* ConvertUTF16 can only handle <= BufferSize chars */
609  if(ConvertUTF16(q, n > BufferSize ? BufferSize : n, file) == -1)
610  return -1;
611  n -= BufferSize;
612  q += BufferSize;
613  }
614  }
615  else
616  {
617 #if CHAR_SIZE == 8
618  string:
619 #endif
620  p = va_arg(args, char8 *);
621  if(!p)
622  p = "(null)";
623  n = strlen(p);
624  if(prec >= 0 && n > prec)
625  n = prec;
626  if(n < width && !mflag)
627  for(i=width-n; i>0; i--)
628  put(' ');
629  for(i=0; i<n; i++)
630  put(p[i]);
631  }
632  if(n < width && mflag)
633  for(i=width-n; i>0; i--)
634  put(' ');
635  break;
636  case 'S':
637  goto string;
638  default:
639  ERR1("unknown format character %c\n", c);
640  errno = 0;
641  return -1;
642  }
643  }
644 
645  if(count > 0)
646  if(ConvertASCII(buf, count, file) == -1)
647  return -1;
648 
649  return nchars;
650 }
651 
652 static FILE16 *MakeFILE16(const char *type)
653 {
654  FILE16 *file;
655 
656  if(!(file = Malloc(sizeof(*file))))
657  return 0;
658 
659  file->flags = 0;
660  if(*type == 'r')
661  file->flags |= FILE16_read;
662  else
663  file->flags |= FILE16_write;
664 
665  file->enc = InternalCharacterEncoding;
666 
667  return file;
668 }
669 
670 FILE16 *MakeFILE16FromFILE(FILE *f, const char *type)
671 {
672  FILE16 *file;
673 
674  if(!(file = MakeFILE16(type)))
675  return 0;
676 
677  file->read = FileRead;
678  file->write = FileWrite;
679  file->seek = FileSeek;
680  file->close = FileClose;
681  file->flush = FileFlush;
682  file->handle = f;
683 
684  return file;
685 }
686 
687 static int FileRead(FILE16 *file, unsigned char *buf, int max_count)
688 {
689  FILE *f = file->handle;
690  int count = 0;
691 
692  count = fread(buf, 1, max_count, f);
693 
694  return ferror(f) ? -1 : count;
695 }
696 
697 static int FileWrite(FILE16 *file, const unsigned char *buf, int count)
698 {
699  FILE *f = file->handle;
700 
701  if(count == 0)
702  return 0;
703  return fwrite(buf, 1, count, f) == 0 ? -1 : 0;
704 }
705 
706 static int FileSeek(FILE16 *file, long offset, int ptrname)
707 {
708  FILE *f = file->handle;
709 
710  return fseek(f, offset, ptrname);
711 }
712 
713 static int FileClose(FILE16 *file)
714 {
715  FILE *f = file->handle;
716 
717  return (file->flags & FILE16_close_underlying) ? fclose(f) : 0;
718 }
719 
720 static int FileFlush(FILE16 *file)
721 {
722  FILE *f = file->handle;
723 
724  return fflush(f);
725 }
726 
727 FILE16 *MakeFILE16FromString(void *buf, long size, const char *type)
728 {
729  FILE16 *file;
730 
731  if(!(file = MakeFILE16(type)))
732  return 0;
733 
734  file->read = StringRead;
735  file->write = StringWrite;
736  file->seek = StringSeek;
737  file->close = StringClose;
738  file->flush = StringFlush;
739 
740  file->handle = buf;
741  file->handle2 = 0;
742  file->handle3 = size;
743 
744  return file;
745 }
746 
747 static int StringRead(FILE16 *file, unsigned char *buf, int max_count)
748 {
749  char *p = (char *)file->handle + file->handle2;
750 
751  if(file->handle3 >= 0 && file->handle2 + max_count > file->handle3)
752  max_count = file->handle3 - file->handle2;
753 
754  if(max_count <= 0)
755  return 0;
756 
757  memcpy(buf, p, max_count);
758  file->handle2 += max_count;
759 
760  return max_count;
761 }
762 
763 static int StringWrite(FILE16 *file, const unsigned char *buf, int count)
764 {
765  char *p = (char *)file->handle + file->handle2;
766 
767  if(file->handle3 >= 0 && file->handle2 + count > file->handle3)
768  return -1;
769 
770  memcpy(p, buf, count);
771  file->handle2 += count;
772 
773  return 0;
774 }
775 
776 static int StringSeek(FILE16 *file, long offset, int ptrname)
777 {
778  switch(ptrname)
779  {
780  case SEEK_CUR:
781  offset = file->handle2 + offset;
782  break;
783  case SEEK_END:
784  if(file->handle3 < 0)
785  return -1;
786  offset = file->handle3 + offset;
787  break;
788  }
789 
790  if(file->handle3 >= 0 && offset > file->handle3)
791  return -1;
792 
793  file->handle2 = offset;
794 
795  return 0;
796 }
797 
798 static int StringClose(FILE16 *file)
799 {
800  static char8 null = 0;
801 
802  if(file->flags & FILE16_write)
803  ConvertASCII(&null, 1, file); /* null terminate */
804 
805  if(file->flags & FILE16_close_underlying)
806  Free((char *)file->handle);
807 
808  return 0;
809 }
810 
811 static int StringFlush(FILE16 *file)
812 {
813  (void) file;
814  return 0;
815 }
816 
817 
818 #ifdef WIN32
819 #ifdef SOCKETS_IMPLEMENTED
820 
821 FILE16 *MakeFILE16FromWinsock(int sock, const char *type)
822 {
823  FILE16 *file;
824 
825  if(!(file = MakeFILE16(type)))
826  return 0;
827 
828  file->read = WinsockRead;
829  file->write = WinsockWrite;
830  file->seek = WinsockSeek;
831  file->close = WinsockClose;
832  file->flush = WinsockFlush;
833  file->handle2 = sock;
834 
835  return file;
836 }
837 
838 static int WinsockRead(FILE16 *file, unsigned char *buf, int max_count)
839 {
840  int f = (int)file->handle2;
841  int count;
842 
843  /* "Relax" said the nightman, we are programmed to recv() */
844  count = recv(f, buf, max_count, 0);
845 
846  return count;
847 }
848 
849 static int WinsockWrite(FILE16 *file, const unsigned char *buf, int count)
850 {
851  /* Not yet implemented */
852 
853  return -1;
854 }
855 
856 static int WinsockSeek(FILE16 *file, long offset, int ptrname)
857 {
858  return -1;
859 }
860 
861 static int WinsockClose(FILE16 *file)
862 {
863  /* What should happen here? XXX */
864 
865  return 0;
866 }
867 
868 static int WinsockFlush(FILE16 *file)
869 {
870  return 0;
871 }
872 
873 #endif
874 #endif
875 
876 #ifdef HAVE_LIBZ
877 
878 FILE16 *MakeFILE16FromGzip(gzFile f, const char *type)
879 {
880  FILE16 *file;
881 
882  if(!(file = MakeFILE16(type)))
883  return 0;
884 
885  file->read = GzipRead;
886  file->write = GzipWrite;
887  file->seek = GzipSeek;
888  file->close = GzipClose;
889  file->flush = GzipFlush;
890  file->handle = (void *)f;
891 
892  return file;
893 }
894 
895 static int GzipRead(FILE16 *file, unsigned char *buf, int max_count)
896 {
897  gzFile f = (gzFile)file->handle;
898  int count = 0;
899  int gzerr;
900  const char *errorString;
901 
902  count = gzread(f, buf, max_count);
903 
904  errorString = gzerror(f, &gzerr);
905  if(gzerr != 0 && gzerr != Z_STREAM_END)
906  return -1;
907 
908  return count;
909 }
910 
911 static int GzipWrite(FILE16 *file, const unsigned char *buf, int count)
912 {
913  gzFile f = (gzFile)file->handle;
914  int gzerr;
915  const char *errorString;
916 
917  count = gzwrite(f, (char *)buf, count);
918 
919  errorString = gzerror(f, &gzerr);
920  if(gzerr != 0 && gzerr != Z_STREAM_END)
921  return -1;
922 
923  return count;
924 }
925 
926 static int GzipSeek(FILE16 *file, long offset, int ptrname)
927 {
928  return -1;
929 }
930 
931 static int GzipClose(FILE16 *file)
932 {
933  gzFile f = (gzFile)file->handle;
934 
935  return (file->flags & FILE16_close_underlying) ? gzclose(f) : 0;
936 }
937 
938 static int GzipFlush(FILE16 *file)
939 {
940  return 0;
941 }
942 
943 #endif
944 
945 #ifdef test
946 
947 int main(int argc, char **argv)
948 {
949  short s=3;
950  int n, c;
951  char16 S[] = {'w', 'o', 'r', 'l', 'd', ' ', '£' & 0xff, 0xd841, 0xdc42, 0};
952 
953  n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L, "÷hello", S);
954  printf("\nreturned %d, c=%d\n", n, c);
955  n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L, "÷hello", S);
956  printf("\nreturned %d, c=%d\n", n, c);
957  n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L, "÷hello", S);
958  printf("\nreturned %d, c=%d\n", n, c);
959  n=Printf(argv[1], s, 98765432, &c, 5.3, 3.2L, "÷hello", S);
960  printf("\nreturned %d, c=%d\n", n, c);
961 
962  return 0;
963 }
964 
965 #endif
966 
FILE * GetFILE(FILE16 *file)
Definition: stdio16.c:339
int CloseProc(FILE16 *file)
Definition: stdio16.c:74
int Fprintf(FILE16 *file, const char *format,...)
Definition: stdio16.c:365
#define FILE16_write
Definition: stdio16.c:90
int SeekProc(FILE16 *file, long offset, int ptrname)
Definition: stdio16.c:72
int Writeu(FILE16 *file, unsigned char *buf, int count)
Definition: stdio16.c:314
STD_API const char8 * CharacterEncodingName[CE_enum_count]
Definition: charset.c:170
#define SEEK_CUR
Definition: system.h:24
STD_API char8 * unicode_to_iso[8]
Definition: charset.c:35
bool save(Lattice &lattice, EST_String filename)
#define ERR1(m, x)
Definition: stdio16.c:51
FILE16 * Stderr
Definition: stdio16.c:123
void Free(void *mem)
Definition: system.c:35
CharacterEncoding GetFileEncoding(FILE16 *file)
Definition: stdio16.c:360
#define FILE16_close_underlying
Definition: stdio16.c:91
int Sprintf(void *buf, CharacterEncoding enc, const char *format,...)
Definition: stdio16.c:385
unsigned short char16
Definition: charset.h:32
float max(float a, float b)
Definition: EST_cluster.cc:143
int Fflush(FILE16 *file)
Definition: stdio16.c:334
int Printf(const char *format,...)
Definition: stdio16.c:375
int Vprintf(const char *format, va_list args)
Definition: stdio16.c:395
#define ERR2(m, x, y)
Definition: stdio16.c:52
STD_API CharacterEncoding InternalCharacterEncoding
Definition: charset.c:231
int main(int argc, char **argv)
Definition: align_main.cc:69
#define ERR(m)
Definition: stdio16.c:50
#define SEEK_END
Definition: system.h:28
int Vfprintf(FILE16 *file, const char *format, va_list args)
Definition: stdio16.c:417
STD_API int iso_max_val[8]
Definition: charset.c:34
STD_API size_t strlen16(const char16 *)
Definition: string16.c:173
FILE16 * MakeFILE16FromString(void *buf, long size, const char *type)
Definition: stdio16.c:727
void SetFileEncoding(FILE16 *file, CharacterEncoding encoding)
Definition: stdio16.c:355
FILE16 * MakeFILE16FromFILE(FILE *f, const char *type)
Definition: stdio16.c:670
int ReadProc(FILE16 *file, unsigned char *buf, int max_count)
Definition: stdio16.c:70
#define put(x)
Definition: stdio16.c:415
int WriteProc(FILE16 *file, const unsigned char *buf, int count)
Definition: stdio16.c:71
#define FILE16_read
Definition: stdio16.c:89
void init_stdio16(void)
Definition: stdio16.c:125
int Readu(FILE16 *file, unsigned char *buf, int max_count)
Definition: stdio16.c:309
CharacterEncoding encoding
Definition: rxp.c:23
f
Definition: EST_item_aux.cc:48
getString int
Definition: EST_item_aux.cc:50
int Fseek(FILE16 *file, long offset, int ptrname)
Definition: stdio16.c:329
float start(const EST_Item &item)
Definition: EST_item_aux.cc:52
void SetCloseUnderlying(FILE16 *file, int cu)
Definition: stdio16.c:347
enum character_encoding CharacterEncoding
Definition: charset.h:61
unsigned int char32
Definition: charset.h:33
FILE16 * Stdin
Definition: stdio16.c:123
FILE16 * Stdout
Definition: stdio16.c:123
int Fclose(FILE16 *file)
Definition: stdio16.c:319
char char8
Definition: charset.h:31
#define BufferSize
Definition: stdio16.c:68
void * Malloc(int bytes)
Definition: system.c:19
int FlushProc(FILE16 *file)
Definition: stdio16.c:73
int Vsprintf(void *buf, CharacterEncoding enc, const char *format, va_list args)
Definition: stdio16.c:400