00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <unistd.h>
00037 #include <fcntl.h>
00038
00039 #include "BUILD/bitc-runtime.h"
00040
00045 struct ty_bitc_stdioStream {
00059 bool isInit;
00060 FILE *f;
00061 } ;
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 static ty_bitc_stdioStream our_stdin = { false, 0 };
00078 static ty_bitc_stdioStream our_stdout = { false, 0 };
00079 static ty_bitc_stdioStream our_stderr = { false, 0 };
00080
00081 static inline void
00082 fix_stdio_stream(ty_bitc_stdioStream *ios)
00083 {
00084 if (ios->isInit)
00085 return;
00086
00087 if (ios == &our_stdin)
00088 ios->f = stdin;
00089 else if (ios == &our_stdout)
00090 ios->f = stdout;
00091 else if (ios == &our_stderr)
00092 ios->f = stderr;
00093 }
00094
00095 ty_bitc_stdioStream *bitc_stdio_stdin = &our_stdin;
00096 ty_bitc_stdioStream *bitc_stdio_stdout = &our_stdout;
00097 ty_bitc_stdioStream *bitc_stdio_stderr = &our_stderr;
00098
00099 ty_bitc_stdioStream *
00100 DEFUN(bitc_stdio_open, bitc_string_t *nm, bitc_string_t *mode)
00101 {
00102 ty_bitc_stdioStream *ios = GC_MALLOC_ATOMIC(sizeof(ty_bitc_stdioStream));
00103 ios->f = fopen(nm->s, mode->s);
00104 if (ios->f == NULL)
00105 BITC_THROW(&val_ExNoPermission);
00106
00107 ios->isInit = true;
00108
00109 return ios;
00110 }
00111 DEFCLOSURE(bitc_stdio_open);
00112
00113 void
00114 DEFUN(bitc_stdio_close, ty_bitc_stdioStream *ios)
00115 {
00116 fix_stdio_stream(ios);
00117
00118 if (ios->f) {
00119 fclose(ios->f);
00120 ios->f = NULL;
00121 }
00122 }
00123 DEFCLOSURE(bitc_stdio_close);
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 bitc_char_t
00135 DEFUN(bitc_stdio_read_char, ty_bitc_stdioStream *ios)
00136 {
00137 bitc_uns8_t encoded[6];
00138 bitc_char_t ucs4;
00139 ssize_t result;
00140
00141 fix_stdio_stream(ios);
00142
00143 if (ios->f == NULL)
00144 BITC_THROW(&val_ExFileIsClosed);
00145
00146
00147 result = fread(&encoded[0], 1, 1, ios->f);
00148 if (result != 1)
00149 BITC_THROW(&val_ExAtEOF);
00150
00151 if (encoded[0] <= 127) {
00152 ucs4 = encoded[0];
00153 }
00154 else if (encoded[0] <= 223) {
00155 result = fread(&encoded[1], 1, 1, ios->f);
00156 if (result != 1)
00157 BITC_THROW(&val_ExAtEOF);
00158 ucs4 =
00159 (encoded[0] - 192)*64
00160 + (encoded[1]-128);
00161 }
00162 else if (encoded[0] <= 239) {
00163 result = fread(&encoded[1], 2, 1, ios->f);
00164 if (result != 1)
00165 BITC_THROW(&val_ExAtEOF);
00166 ucs4 =
00167 (encoded[0] - 224)*4096
00168 + (encoded[1]-128)*64
00169 + (encoded[2]-128);
00170 }
00171 else if (encoded[0] <= 247) {
00172 result = fread(&encoded[1], 3, 1, ios->f);
00173 if (result != 1)
00174 BITC_THROW(&val_ExAtEOF);
00175 ucs4 =
00176 (encoded[0] - 240)*262144
00177 + (encoded[1]-128)*4096
00178 + (encoded[2]-128)*64
00179 + (encoded[3]-128);
00180 }
00181 else if (encoded[0] <= 251) {
00182 result = fread(&encoded[1], 4, 1, ios->f);
00183 if (result != 1)
00184 BITC_THROW(&val_ExAtEOF);
00185 ucs4 =
00186 (encoded[0] - 248)*16777216
00187 + (encoded[1]-128)*262144
00188 + (encoded[2]-128)*4096
00189 + (encoded[3]-128)*64
00190 + (encoded[4]-128);
00191 }
00192 else if (encoded[0] <= 253) {
00193 result = fread(&encoded[1], 5, 1, ios->f);
00194 if (result != 1)
00195 BITC_THROW(&val_ExAtEOF);
00196 ucs4 =
00197 (encoded[0] - 252)*1073741824
00198 + (encoded[1]-128)*16777216
00199 + (encoded[2]-128)*262144
00200 + (encoded[3]-128)*4096
00201 + (encoded[4]-128)*64
00202 + (encoded[5]-128);
00203 }
00204 else
00205 BITC_THROW(&val_ExNotUTF8);
00206
00207 return ucs4;
00208 }
00209 DEFCLOSURE(bitc_stdio_read_char);
00210
00211
00212
00213 void
00214 DEFUN(bitc_stdio_write_char, ty_bitc_stdioStream *ios, bitc_char_t ucs4)
00215 {
00216 ssize_t result;
00217 fix_stdio_stream(ios);
00218
00219 if (ios->f == NULL)
00220 BITC_THROW(&val_ExFileIsClosed);
00221
00222 bitc_uns8_t encoded[6];
00223 bitc_uns8_t *utf8 = encoded;
00224
00225 if (ucs4 <= 0x7f) {
00226 *utf8++ = ucs4;
00227 }
00228 else if (ucs4 <= 0x7ff) {
00229 *utf8++ = 192u + (ucs4 / 64);
00230 *utf8++ = 128u + (ucs4 % 64);
00231 }
00232 else if (ucs4 <= 0xffff) {
00233 *utf8++ = 224u + (ucs4 / 4096);
00234 *utf8++ = 128u + ((ucs4 / 64) % 64);
00235 *utf8++ = 128u + (ucs4 % 64);
00236 }
00237 else if (ucs4 <= 0x1fffff) {
00238 *utf8++ = 240 + (ucs4 / 262144);
00239 *utf8++ = 128u + ((ucs4 / 4096) % 64);
00240 *utf8++ = 128u + ((ucs4 / 64) % 64);
00241 *utf8++ = 128u + (ucs4 % 64);
00242 }
00243 else if (ucs4 <= 0x3ffffff) {
00244 *utf8++ = 248u + (ucs4 / 16777216);
00245 *utf8++ = 128u + ((ucs4 / 262144) % 64);
00246 *utf8++ = 128u + ((ucs4 / 4096) % 64);
00247 *utf8++ = 128u + ((ucs4 / 64) % 64);
00248 *utf8++ = 128u + (ucs4 % 64);
00249 }
00250 else if (ucs4 <= 0x7fffffff) {
00251 *utf8++ = 252u + (ucs4 / 1073741824);
00252 *utf8++ = 128u + ((ucs4 / 16777216) % 64);
00253 *utf8++ = 128u + ((ucs4 / 262144) % 64);
00254 *utf8++ = 128u + ((ucs4 / 4096) % 64);
00255 *utf8++ = 128u + ((ucs4 / 64) % 64);
00256 *utf8++ = 128u + (ucs4 % 64);
00257 }
00258
00259 result = fwrite(encoded, utf8-encoded, 1, ios->f);
00260
00261 if (result == 0)
00262 BITC_THROW(&val_ExAtEOF);
00263 else if (result < 0)
00264 BITC_THROW(&val_ExNoPermission);
00265 }
00266 DEFCLOSURE(bitc_stdio_write_char);
00267
00268
00269
00270 bitc_uns8_t
00271 DEFUN(bitc_stdio_read_byte, ty_bitc_stdioStream *ios)
00272 {
00273 unsigned char c;
00274
00275 fix_stdio_stream(ios);
00276
00277 if (ios->f == NULL)
00278 BITC_THROW(&val_ExFileIsClosed);
00279
00280 if ( fread(&c, 1, 1, ios->f) != 1 )
00281 BITC_THROW(&val_ExNoPermission);
00282
00283 return c;
00284 }
00285 DEFCLOSURE(bitc_stdio_read_byte);
00286
00287
00288
00289 void
00290 DEFUN(bitc_stdio_write_byte, ty_bitc_stdioStream *ios, bitc_uns8_t c)
00291 {
00292 fix_stdio_stream(ios);
00293
00294 if (ios->f == NULL)
00295 BITC_THROW(&val_ExFileIsClosed);
00296
00297 if ( fwrite(&c, 1, 1, ios->f) != 1 )
00298 BITC_THROW(&val_ExNoPermission);
00299 }
00300 DEFCLOSURE(bitc_stdio_write_byte);
00301
00302 bitc_bool_t
00303 DEFUN(bitc_stdio_eofp, ty_bitc_stdioStream *ios)
00304 {
00305 fix_stdio_stream(ios);
00306
00307 if (ios->f == NULL)
00308 BITC_THROW(&val_ExFileIsClosed);
00309
00310 return (feof(ios->f) ? true : false);
00311 }
00312 DEFCLOSURE(bitc_stdio_eofp);
00313