/* WARNING: This file was generated by dkct. Changes you make here will be lost if dkct is run again! You should modify the original source and run dkct on it. Original source: dk3strm.ctr */ /* Copyright (C) 2011-2017, Dirk Krause Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above opyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * Neither the name of the author nor the names of contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ /** @file dk3strm.c The dk3strm module. */ #line 424 "dk3strm.ctr" #include "dk3all.h" #line 429 "dk3strm.ctr" #ifndef BUFSIZ #define BUFSIZ 8192 #endif #if 0 /** Low-level stream function to deal with bzip2 compression. Closing the stream also closes the bzip2-file. @param api API structure. */ static void dk3stream_bz_fct(dk3_stream_api_t *api) { #if DK3_HAVE_BZLIB_H BZFILE *b = NULL; /* Low level I/O object. */ int res = 0; /* Operation result. */ #endif api->suc = 0; (api->res).sz = 0; (api->res).ec = DK3_ERROR_NOT_SUPPORTED; #if DK3_HAVE_BZLIB_H b = (BZFILE *)((api->arg).d); (api->res).ec = 0; switch(api->cmd) { case DK3_STREAM_API_READ: { if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) { res = BZ2_bzread(b, (api->arg).b, (api->arg).sz); if(res > 0) { api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res; } } } break; case DK3_STREAM_API_WRITE: { if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) { res = BZ2_bzwrite(b, (api->arg).b, (api->arg).sz); if(res > 0) { (api->res).sz = (size_t)res; if((size_t)res == (api->arg).sz) { api->suc = 1; (api->res).ec = 0; } } } } break; case DK3_STREAM_API_FLUSH: { if((api->arg).d) { BZ2_bzflush(b); api->suc = 1; (api->res).ec = 0; /* As the library manual explains BZ2_bzflush() does nothing. So we always return success. */ } } break; case DK3_STREAM_API_AT_END: { } break; case DK3_STREAM_API_CLOSE: { if((api->arg).d) { BZ2_bzclose(b); api->suc = 1; (api->res).ec = 0; } } break; case DK3_STREAM_API_ZERO_IS_END: { api->suc = 1; (api->res).ec = 0; /* Correct if necessary */ } break; case DK3_STREAM_API_ERROR: { } break; } #endif } /** Low-level stream function to deal with bzip2 compression. Closing the stream does not close the bzip2 file. @param api API structure. */ static void dk3stream_bz_fct_no_close(dk3_stream_api_t *api) { if(api->cmd != DK3_STREAM_API_CLOSE) { dk3stream_bz_fct(api); } else { api->suc = 1; (api->res).ec = 0; } } #endif #if 0 /** Low-level stream function to deal with gzip compression. Closing the stream also closes the gzip-file. @param api API structure. */ static void dk3stream_gz_fct(dk3_stream_api_t *api) { #if DK3_HAVE_ZLIB_H int res = 0; /* Operation result. */ gzFile g = NULL; /* Low-level I/O object. */ #endif api->suc = 0; (api->res).sz = 0; (api->res).ec = DK3_ERROR_NOT_SUPPORTED; #if DK3_HAVE_ZLIB_H (api->res).ec = 0; g = (gzFile)((api->arg).d); switch(api->cmd) { case DK3_STREAM_API_READ: { if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) { res = gzread(g, (api->arg).b, (api->arg).sz); if(res > 0) { api->suc = 1; (api->res).ec = 0; (api->res).sz = (size_t)res; } } } break; case DK3_STREAM_API_WRITE: { if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) { res = gzwrite(g, (api->arg).b, (api->arg).sz); (api->res).sz = (size_t)res; if((size_t)res == (api->arg).sz) { api->suc = 1; (api->res).ec = 0; } } } break; case DK3_STREAM_API_FLUSH: { if((api->arg).d) { if(gzflush(g, Z_FULL_FLUSH) == Z_OK) { api->suc = 1; (api->res).ec = 0; } } } break; case DK3_STREAM_API_AT_END: { if((api->arg).d) { if(gzeof(g) == 1) { api->suc = 1; } } } break; case DK3_STREAM_API_CLOSE: { if((api->arg).d) { if(gzclose(g) == Z_OK) { api->suc = 1; } } } break; case DK3_STREAM_API_ZERO_IS_END: { api->suc = 0; } break; case DK3_STREAM_API_ERROR: { api->suc = 0; } break; } #endif } /** Low-level stream function to deal with gzip compression. Closing the stream does not close the gzip-file. @param api API structure. */ static void dk3stream_gz_fct_no_close(dk3_stream_api_t *api) { if(api->cmd != DK3_STREAM_API_CLOSE) { dk3stream_gz_fct(api); } else { api->suc = 1; (api->res).ec = 0; } } #endif /** Low-level stream function to deal with plain files. Closing the stream also closes the file. @param api API structure. */ static void dk3stream_file_fct(dk3_stream_api_t *api) { FILE *fipo = NULL; /* Low-level I/O object. */ size_t res = 0; /* Operation result. */ #line 625 "dk3strm.ctr" api->suc = 0; (api->res).sz = 0; (api->res).ec = 0; switch(api->cmd) { case DK3_STREAM_API_READ: { #line 630 "dk3strm.ctr" if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) { fipo = (FILE *)((api->arg).d); #if DK3_ON_WINDOWS res = fread((api->arg).b, 1, (api->arg).sz, fipo); if(res) { api->suc = 1; (api->res).ec = 0; (api->res).sz = res; } else { if(!ferror(fipo)) { api->suc = 1; (api->res).ec = 0; } } #else #if DK3_HAVE_FREAD res = fread((api->arg).b, 1, (api->arg).sz, fipo); if(res) { api->suc = 1; (api->res).ec = 0; (api->res).sz = res; } else { if(!ferror(fipo)) { api->suc = 1; (api->res).ec = 0; } } #else #if DK3_HAVE__FREAD res = _fread((api->arg).b, 1, (api->arg).sz, fipo); if(res) { api->suc = 1; (api->res).ec = 0; (api->res).sz = res; } else { if(!ferror(fipo)) { api->suc = 1; (api->res).ec = 0; } } #else #error "No fread() function!" #endif #endif #endif } } break; case DK3_STREAM_API_WRITE: { #line 669 "dk3strm.ctr" if(((api->arg).b) && ((api->arg).sz) && ((api->arg).d)) { fipo = (FILE *)((api->arg).d); #if DK3_ON_WINDOWS res = fwrite((api->arg).b, 1, (api->arg).sz, fipo); (api->res).sz = res; if(res == (api->arg).sz) { api->suc = 1; (api->res).ec = 0; } #else #if DK3_HAVE_FWRITE res = fwrite((api->arg).b, 1, (api->arg).sz, fipo); (api->res).sz = res; if(res == (api->arg).sz) { api->suc = 1; (api->res).ec = 0; } #else #if DK3_HAVE__FWRITE res = _fwrite((api->arg).b, 1, (api->arg).sz, fipo); if(res == (api->arg).sz) { api->suc = 1; (api->res).ec = 0; (api->res).sz = res; } #else #error "No fwrite() function!" #endif #endif #endif } } break; case DK3_STREAM_API_FLUSH: { #line 698 "dk3strm.ctr" if((api->arg).d) { fipo = (FILE *)((api->arg).d); if(fflush(fipo) == 0) { api->suc = 1; (api->res).ec = 0; } } } break; case DK3_STREAM_API_AT_END: { #line 706 "dk3strm.ctr" if((api->arg).d) { fipo = (FILE *)((api->arg).d); if(feof(fipo)) { api->suc = 1; (api->res).ec = 0; } } } break; case DK3_STREAM_API_CLOSE: { #line 714 "dk3strm.ctr" if((api->arg).d) { fipo = (FILE *)((api->arg).d); if(fclose(fipo) == 0) { api->suc = 1; (api->res).ec = 0; } } } break; case DK3_STREAM_API_ZERO_IS_END: { #line 722 "dk3strm.ctr" if((api->arg).d) { api->suc = 1; (api->res).ec = 0; } } break; case DK3_STREAM_API_ERROR: { #line 727 "dk3strm.ctr" if((api->arg).d) { fipo = (FILE *)((api->arg).d); if(ferror(fipo)) { api->suc = 1; (api->res).ec = 0; } } } break; } #line 735 "dk3strm.ctr" } /** Low-level stream function to deal with plain files. Closing the stream does not close the file. @param api API structure. */ static void dk3stream_file_fct_no_close(dk3_stream_api_t *api) { #line 747 "dk3strm.ctr" if(api->cmd != DK3_STREAM_API_CLOSE) { dk3stream_file_fct(api); } else { api->suc = 1; (api->res).ec = 0; } #line 752 "dk3strm.ctr" } /** Initialize stream API structure. @param api Structure to initialize. */ static void dk3stream_api_init(dk3_stream_api_t *api) { #line 763 "dk3strm.ctr" if(api) { api->cmd = 0; api->suc = 0; (api->arg).b = NULL; (api->arg).sz = 0; (api->arg).d = NULL; (api->res).sz = 0; (api->res).ec = 0; } #line 772 "dk3strm.ctr" } /** Delete stream, release memory. @param st Stream to delete. */ static void dk3stream_delete_stream(dk3_stream_t *st) { #line 783 "dk3strm.ctr" if(st) { dk3_release(st->ib); dk3_release(st->ob); dk3_delete(st); } #line 788 "dk3strm.ctr" } /** Flush stream. @param st Stream to flush. @param fd Flag: Flush downstream object. @return 1 on success, 0 on error. */ static int dk3stream_do_flush(dk3_stream_t *st, int fd) { int back = 0; dk3_stream_api_t api; #line 804 "dk3strm.ctr" if(st) { back = 1; st->ec = 0; if((st->fl) & DK3_STREAM_FLAG_WRITE) { if(st->us_ob) { dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_WRITE; api.arg.b = st->ob; api.arg.sz = st->us_ob; api.arg.d = st->d; (*(st->f))(&api); if(!(api.suc)) { st->ec = api.res.ec; back = 0; if(st->app) { /* ERROR: Failed to write data! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 120); } } } st->us_ob = 0; if(fd) { dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_FLUSH; api.arg.d = st->d; (*(st->f))(&api); if(!(api.suc)) { if(back) { if(st->app) { /* ERROR: Flush failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 121); } st->ec = api.res.ec; } back = 0; } } } } #line 843 "dk3strm.ctr" return back; } /** Open new stream, allocate memory. @param app Application structure, used for diagnostics. @return Pointer to new stream on success, NULL on error. */ static dk3_stream_t * dk3stream_new_stream(dk3_app_t *app) { dk3_stream_t *back = NULL; #line 858 "dk3strm.ctr" back = dk3_new_app(dk3_stream_t,1,app); if(back) { back->app = NULL; back->d = NULL; back->f = NULL; back->ib = NULL; back->ob = NULL; back->wr = DK3_UM_0; back->sz_ib = 0; back->av_ib = 0; back->us_ib = 0; back->sz_ob = 0; back->us_ob = 0; back->fl = 0; back->lf = 0; back->fe = 0; back->ec = 0; back->oe = 0; back->ze = 0; back->er = 0; back->ib = dk3_new_app(char,4096,app); back->ob = dk3_new_app(char,4096,app); if((back->ib) && (back->ob)) { back->sz_ib = 4096; back->sz_ob = 4096; } else { dk3stream_delete_stream(back); back = NULL; } } #line 888 "dk3strm.ctr" return back; } int dk3stream_close(dk3_stream_t *st) { int back = 0; dk3_stream_api_t api; #line 899 "dk3strm.ctr" if(st) { back = dk3stream_do_flush(st, 1); dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_CLOSE; api.arg.d = st->d; (*(st->f))(&api); if(!(api.suc)) { back = 0; if(st->app) { /* ERROR: Failed to close stream data object! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 122); } } st->d = NULL; st->f = NULL; st->app = NULL; dk3stream_delete_stream(st); } #line 915 "dk3strm.ctr" return back; } dk3_stream_t * dk3stream_open_app(void *d, dk3_stream_api_fct_t *f, int fl, dk3_app_t *app) { dk3_stream_t *back = NULL; dk3_stream_api_t api; #line 926 "dk3strm.ctr" if((d) && (f)) { back = dk3stream_new_stream(app); if(back) { back->app = app; back->d = d; back->f = f; back->fl = fl; dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_ZERO_IS_END; api.arg.d = d; (*f)(&api); if(api.suc) { back->ze = 1; } } } #line 942 "dk3strm.ctr" return back; } /** Write one byte. @param st Stream to write to. @param ch Byte to write. @return 1 on success, 0 on error. */ static int dk3stream_my_write_byte(dk3_stream_t *st, char ch) { int back = 1; int fld = 0; /* Flag: Flush downwards. */ #line 959 "dk3strm.ctr" (st->ob)[st->us_ob] = ch; st->us_ob += 1; st->wr += DK3_UM_1; if((st->us_ob == st->sz_ob) || ((ch == '\n') && (st->lf))) { if(ch == '\n') { if(st->lf == 2) { fld = 1; } } back = dk3stream_do_flush(st, fld); } #line 967 "dk3strm.ctr" return back; } size_t dk3stream_write_bytes(dk3_stream_t *st, char const *sb, size_t sz) { size_t back = 0; char const *sp = NULL; /* Source pointer. */ size_t l = 0; /* Bytes remaining. */ #line 979 "dk3strm.ctr" if((st) && (sb) && (sz)) { if((st->fl) & DK3_STREAM_FLAG_WRITE) { sp = sb; l = sz; while(l--) { if(dk3stream_my_write_byte(st, *sp)) { back++; } sp++; } } else { if(st->app) { /* ERROR: Stream not opened for write operations! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 123); } } } #line 995 "dk3strm.ctr" return back; } /** Read one byte from buffer, reload buffer if necessary. @param st Stream to read from. @param cp One-byte buffer for destination. @return 1 on success, 0 on error. */ static int dk3stream_my_read_byte(dk3_stream_t *st, char *cp) { int back = 0; dk3_stream_api_t api; #line 1012 "dk3strm.ctr" if(st->us_ib >= st->av_ib) { #line 1013 "dk3strm.ctr" st->us_ib = 0; st->av_ib = 0; dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_READ; api.arg.b = st->ib; api.arg.sz = st->sz_ib; api.arg.d = st->d; (*(st->f))(&api); if(api.suc) { #line 1022 "dk3strm.ctr" st->av_ib = api.res.sz; if(st->av_ib) { #line 1024 "dk3strm.ctr" if(st->av_ib < st->sz_ib) { #line 1025 "dk3strm.ctr" dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_AT_END; api.arg.d = st->d; (*(st->f))(&api); if(api.suc) { #line 1030 "dk3strm.ctr" st->fe = 1; } } } else { #line 1034 "dk3strm.ctr" if(st->ze) { st->fe = 1; /* End of input reached. */ } else { dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_ERROR; api.arg.d = st->d; (*(st->f))(&api); if(api.suc) { st->er = 1; st->fe = 1; } } } } else { #line 1048 "dk3strm.ctr" st->ec = api.res.ec; st->fe = 1; /* Error found, end of input data. */ dk3stream_api_init(&api); api.cmd = DK3_STREAM_API_AT_END; api.arg.d = st->d; (*(st->f))(&api); if(api.suc) { st->ec = 0; } else { if(st->app) { /* ERROR: Read operation failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 124); } st->er = 1; } } } if(st->us_ib < st->av_ib) { #line 1066 "dk3strm.ctr" *cp = (st->ib)[st->us_ib]; st->us_ib += 1; back = 1; } #line 1070 "dk3strm.ctr" return back; } size_t dk3stream_read_bytes(dk3_stream_t *st, char *db, size_t sz) { size_t back = 0; char c = 0x00; /* Current byte read. */ char *dp = NULL; /* Destination pointer. */ int cc = 0; /* Flag: Can continue. */ #line 1083 "dk3strm.ctr" if((st) && (db) && (sz)) { dp = db; cc = 1; while((back < sz) && (cc)) { if(dk3stream_my_read_byte(st, &c)) { *(dp++) = c; back++; } else { cc = 0; } } } #line 1093 "dk3strm.ctr" return back; } int dk3stream_feof(dk3_stream_t const *st) { int back = 0; if(st) { if(st->fe) { if(st->us_ib >= st->av_ib) { back = 1; } } } return back; } int dk3stream_c8_fgets(dk3_stream_t *st, char *db, size_t sz) { int back = 0; char *dp = NULL; /* Destination pointer. */ size_t l = 0; /* Number of bytes already found. */ int cc = 0; /* Flag: Can continue. */ char c = 0x00; /* Current character. */ #line 1123 "dk3strm.ctr" if((st) && (db) && (sz)) { *db = '\0'; dp = db; l = 0; cc = 1; while((l < (sz - 1)) && (cc)) { if(dk3stream_my_read_byte(st, &c)) { *(dp++) = c; l++; if(c == '\n') { cc = 0; } } else { cc = 0; } } if(l < sz) { *dp = '\0'; } else { db[sz - 1] = '\0'; } if(l) { back = 1; } } #line 1141 "dk3strm.ctr" return back; } int dk3stream_c8_fputs(dk3_stream_t *st, char const *str) { int back = 0; char const *sp = NULL; /* Source pointer. */ if((st) && (str)) { back = 1; sp = str; while(*sp) { if(!dk3stream_my_write_byte(st, *(sp++))) { back = 0; } } } return back; } int dk3stream_c16_fgets(dk3_stream_t *st, dk3_c16_t *db, size_t sz, int msbfirst) { int back = 0; int cc = 1; /* Flag: Can continue. */ int eo = 0; /* Flag: 0=first byte, 1=second byte */ int res = 0; /* Result from my_read_byte. */ int msbf = 0; /* Flag: MSB first. */ char c1 = 0x00; /* First byte. */ char c2 = 0x00; /* Second byte. */ dk3_c16_t *ptr = NULL; /* Pointer into destination buffer. */ size_t bt = 0; /* Number of characters read. */ unsigned char uc1; /* First byte as unsigned char. */ unsigned char uc2; /* Second byte as unsigned char. */ unsigned u1; /* First byte as unsigned. */ unsigned u2; /* Second byte as unsigned. */ if((st) && (db) && (sz)) { back = 1; ptr = db; bt = 0; msbf = msbfirst; cc = 1; eo = 0; while(cc) { #if VERSION_BEFORE_20150821 res = 0; #endif if(eo) { res = dk3stream_my_read_byte(st, &c2); } else { res = dk3stream_my_read_byte(st, &c1); } if(res) { if(eo) { eo = 0; uc1 = (unsigned char)c1; uc2 = (unsigned char)c2; u1 = (unsigned)uc1; u2 = (unsigned)uc2; u1 &= 0x00FFU; u2 &= 0x00FFU; if(msbf) { u1 = ((u1 << 8) & 0xFF00U) | u2; } else { u1 = ((u2 << 8) & 0xFF00U) | u1; } if(u1 != 0xFEFFU) { if(u1 == 0xFFFEU) { msbf = (msbf ? 0 : 1); } else { *(ptr++) = (dk3_c16_t)u1; bt++; if(u1 == (dk3_c16_t)'\n') { cc = 0; } } } } else { eo = 1; } } else { cc = 0; if(eo) { back = 0; } } if(bt >= (sz - 1)) { cc = 0; } } if(bt < sz) { *ptr = 0U; } db[sz - 1] = 0U; } if(bt == 0) { back = 0; } return back; } int dk3stream_c32_fgets(dk3_stream_t *st, dk3_c32_t *db, size_t sz, int msbfirst) { int back = 0; int cc = 1; /* Flag: Can continue. */ int eo = 0; /* Flag: 0=first byte, 1=second byte */ int res = 0; /* Result from my_read_byte. */ int msbf = 0; /* Flag: MSB first. */ char c1 = 0x00; /* First byte. */ char c2 = 0x00; /* Second byte. */ char c3 = 0x00; /* Third byte. */ char c4 = 0x00; /* Fourth byte. */ dk3_c32_t *ptr = NULL; /* Pointer into destination buffer. */ size_t bt = 0; /* Number of characters read. */ unsigned char uc1; /* First byte as unsigned char. */ unsigned char uc2; /* Second byte as unsigned char. */ unsigned char uc3; /* Third byte as unsigned char. */ unsigned char uc4; /* Fourth byte as unsigned char. */ unsigned long u1; /* First byte as unsigned. */ unsigned long u2; /* Second byte as unsigned. */ unsigned long u3; /* Third byte as unsigned. */ unsigned long u4; /* Fourth byte as unsigned. */ if((st) && (db) && (sz)) { back = 1; ptr = db; bt = 0; msbf = msbfirst; cc = 1; eo = 0; while(cc) { res = 0; switch(eo) { case 0: { res = dk3stream_my_read_byte(st, &c1); } break; case 1: { res = dk3stream_my_read_byte(st, &c2); } break; case 2: { res = dk3stream_my_read_byte(st, &c3); } break; case 3: { res = dk3stream_my_read_byte(st, &c4); } break; } if(res) { eo++; if(eo >= 4) { eo = 0; uc1 = (unsigned char)c1; uc2 = (unsigned char)c2; uc3 = (unsigned char)c3; uc4 = (unsigned char)c4; u1 = (unsigned long)uc1; u2 = (unsigned long)uc2; u3 = (unsigned long)uc3; u4 = (unsigned long)uc4; if(msbf) { u1 = (u1 << 24) & 0xFF000000UL; u2 = (u2 << 16) & 0x00FF0000UL; u3 = (u2 << 8) & 0x0000FF00UL; u4 = u4 & 0x000000FFUL; } else { u1 = u1 & 0x000000FFUL; u2 = (u2 << 8) & 0x0000FF00UL; u3 = (u3 << 16) & 0x00FF0000UL; u4 = (u4 << 24) & 0xFF000000UL; } u1 = (u1 | u2 | u3 | u4); if(u1 != 0x0000FEFFUL) { if(u1 == 0x0000FFFEUL) { msbf = (msbf ? 0 : 1); } else { *(ptr++) = u1; bt++; if(u1 == 0x0000000AUL) { cc = 0; } } } } } else { cc = 0; if(eo) { back = 0; } } if(bt >= (sz - 1)) { cc = 0; } } if(bt < sz) { *ptr = 0UL; } db[sz - 1] = 0UL; } if(bt == 0) { back = 0; } return back; } void dk3stream_set_output_encoding(dk3_stream_t *st, int oe) { if(st) { switch(oe) { case DK3_FILE_ENCODING_ASCII: case DK3_FILE_ENCODING_UTF8: case DK3_FILE_ENCODING_UTF16_MSB_FIRST: case DK3_FILE_ENCODING_UTF16_LSB_FIRST: case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { st->oe = oe; } break; default: { if(st->app) { /* ERROR: Illegal output encoding! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 114); } } break; } } } /** Write one 16-bit character to stream. @param st Output stream. @param c16 Character to write. @return 1 on success, 0 on error. */ static int dk3stream_my_write_16(dk3_stream_t *st, dk3_c16_t c16) { int back = 0; switch(st->oe) { case DK3_FILE_ENCODING_UTF16_MSB_FIRST: { if(dk3stream_my_write_byte(st, (char)((c16 >> 8) & 0x00FFU))) { if(dk3stream_my_write_byte(st, (char)(c16 & 0x00FFU))) { back = 1; } } } break; case DK3_FILE_ENCODING_UTF16_LSB_FIRST: { if(dk3stream_my_write_byte(st, (char)(c16 & 0x00FFU))) { if(dk3stream_my_write_byte(st, (char)((c16 >> 8) & 0x00FFU))) { back = 1; } } } break; } return back; } /** Write one 32-bit character to output stream. @param st Stream. @param c32 Character to write. @return 1 on success, 0 on error. */ static int dk3stream_my_write_32(dk3_stream_t *st, dk3_c32_t c32) { int back = 0; switch(st->oe) { case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: { if(dk3stream_my_write_byte(st, (char)((c32 >> 24) & 0x000000FFUL))) { if(dk3stream_my_write_byte(st, (char)((c32 >> 16) & 0x000000FFUL))) { if(dk3stream_my_write_byte(st, (char)((c32 >> 8) & 0x000000FFUL))) { if(dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL))) { back = 1; } } } } } break; case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { if(dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL))) { if(dk3stream_my_write_byte(st, (char)((c32 >> 8) & 0x000000FFUL))) { if(dk3stream_my_write_byte(st, (char)((c32 >> 16) & 0x000000FFUL))) { if(dk3stream_my_write_byte(st, (char)((c32 >> 24) & 0x000000FFUL))) { back = 1; } } } } } break; } return back; } int dk3stream_fputc_c32(dk3_stream_t *st, dk3_c32_t c32, int *err_enc_rep) { int back = 0; dk3_c16_t myc16[4]; /* Buffer for UTF-16 encoding. */ unsigned char myuc[16]; /* Buffer for UTF-8 encoding. */ size_t l = 0; /* Length of encoded string. */ size_t i = 0; /* Index of current element to write. */ #line 1431 "dk3strm.ctr" switch(st->oe) { case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { back = dk3stream_my_write_32(st, c32); } break; case DK3_FILE_ENCODING_UTF16_MSB_FIRST: case DK3_FILE_ENCODING_UTF16_LSB_FIRST: { l = dk3enc_uc2utf16(c32, myc16, 4); if(l) { back = 1; for(i = 0; i < l; i++) { if(!dk3stream_my_write_16(st, myc16[i])) { back = 1; } } } else { if(!(*err_enc_rep)) { if(st->app) { #line 1449 "dk3strm.ctr" /* ERROR: UTF-16 encode failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 116); } } *err_enc_rep = 1; } } break; case DK3_FILE_ENCODING_ASCII: { if(c32 < (dk3_c32_t)0x00000100UL) { back = dk3stream_my_write_byte(st, (char)(c32 & 0x000000FFUL)); } else { if(!(*err_enc_rep)) { if(st->app) { /* ERROR: Character out of range! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 117); } } *err_enc_rep = 1; } } break; case DK3_FILE_ENCODING_UTF8: { l = dk3enc_uc2utf8(c32, myuc, 16); if(l) { i = dk3stream_write_bytes(st, (char const *)myuc, l); if(i == l) { back = 1; } } else { if(!(*err_enc_rep)) { if(st->app) { /* ERROR: UTF-8 encode failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 115); } } *err_enc_rep = 1; } } break; } #line 1482 "dk3strm.ctr" return back; } int dk3stream_write_byte_order_marker(dk3_stream_t *st) { int back = 0; if(st) { switch(st->oe) { case DK3_FILE_ENCODING_UTF16_MSB_FIRST: case DK3_FILE_ENCODING_UTF16_LSB_FIRST: { back = dk3stream_my_write_16(st, 0xFEFFU); } break; case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { back = dk3stream_my_write_32(st, 0x0000FEFFUL); } break; default: { back = 1; } break; } } return back; } int dk3stream_write_byte_order_marker_if_necessary(dk3_stream_t *st, int se) { int back = 1; switch(st->oe) { case DK3_FILE_ENCODING_UTF16_MSB_FIRST: case DK3_FILE_ENCODING_UTF16_LSB_FIRST: case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { back = dk3stream_write_byte_order_marker(st); } break; case DK3_FILE_ENCODING_UTF8: { if(DK3_FILE_ENCODING_UTF8 != se) { back = dk3stream_write_byte_order_marker(st); } } break; default: { } break; } return back; } int dk3stream_fputs_c8_plain(dk3_stream_t *st, char const *s) { int back = 0; int err_rep_enc = 0; /* Flag: Encoding error reported. */ char const *sp = NULL; /* Source pointer. */ char c = 0x00; /* Current character. */ unsigned char uc = 0x00; /* Unsigned version of current char. */ unsigned long ul = 0UL; /* 32-bit version of current char. */ if((st) && (s)) { switch(st->oe) { case DK3_FILE_ENCODING_ASCII: { back = dk3stream_c8_fputs(st, s); } break; default: { back = 1; sp = s; while(*sp) { c = *(sp++); uc = (unsigned char)c; ul = (unsigned long)uc; ul &= 0x000000FFUL; if(!dk3stream_fputc_c32(st, ul, &err_rep_enc)) { back = 0; } } } break; } } return back; } int dk3stream_fputs_c8_utf8(dk3_stream_t *st, char const *s) { int back = 0; int err_rep_dec = 0; /* Flag: Decoding error reported. */ int err_rep_enc = 0; /* Flag: Encoding error reported. */ unsigned char const *sp = NULL; /* Source pointer. */ dk3_c32_t c32 = 0UL; /* 32-bit version of current char. */ size_t sl = 0; /* Remaining source bytes. */ size_t used = 0; /* Bytes used. */ if((st) && (s)) { switch(st->oe) { case DK3_FILE_ENCODING_UTF8: { back = dk3stream_c8_fputs(st, s); } break; default: { back = 1; sp = (unsigned char const *)s; sl = dk3str_c8_len(s); while(sl) { used = 0; if(dk3enc_utf82uc(&c32, sp, sl, &used)) { if(used) { if(!dk3stream_fputc_c32(st, c32, &err_rep_enc)) { back = 0; } if(sl >= used) { sl = sl - used; sp = &(sp[used]); } else { sl = 0; } } else { sl = 0; back = 0; if(!err_rep_dec) { if(st->app) { /* ERROR: UTF-8 decode failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } err_rep_dec = 1; } } else { sl = 0; back = 0; if(!err_rep_dec) { if(st->app) { /* ERROR: UTF-8 decode failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } err_rep_dec = 1; } } } break; } } return back; } int dk3stream_fputs_c16(dk3_stream_t *st, dk3_c16_t const *s) { int back = 0; int err_rep_dec = 0; /* Flag: Decoding error reported. */ int err_rep_enc = 0; /* Flag: Encoding error reported. */ dk3_c16_t const *sp = NULL; /* Source pointer. */ dk3_c32_t c32 = 0UL; /* 32-bit version of current char. */ size_t sl = 0; /* Remaining source bytes. */ size_t used = 0; /* Source bytes used. */ if((st) && (s)) { switch(st->oe) { case DK3_FILE_ENCODING_UTF16_MSB_FIRST: case DK3_FILE_ENCODING_UTF16_LSB_FIRST: { sp = s; back = 1; while(*sp) { if(!dk3stream_my_write_16(st, *(sp++))) { back = 0; } } } break; default: { sp = s; sl = dk3str_c16_len(s); while(sl) { used = 0; if(dk3enc_utf162uc(&c32, sp, sl, &used)) { if(used) { if(!dk3stream_fputc_c32(st, c32, &err_rep_enc)) { back = 0; } if(sl >= used) { sl = sl - used; sp = &(sp[used]); } else { sl = 0; } } else { back = 0; sl = 0; if(!err_rep_dec) { if(st->app) { /* ERROR: Decode UTF-16 failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } err_rep_dec = 1; } } else { back = 0; sl = 0; if(!err_rep_dec) { if(st->app) { /* ERROR: Decode UTF-16 failed! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } err_rep_dec = 1; } } } break; } } return back; } int dk3stream_fputs_c32(dk3_stream_t *st, dk3_c32_t const *s) { int back = 0; int err_rep_enc = 0; /* Flag: Encoding error reported. */ dk3_c32_t const *sp = NULL; /* Source pointer. */ if((st) && (s)) { sp = s; back = 1; while(*sp) { if(!dk3stream_fputc_c32(st, *(sp++), &err_rep_enc)) { back = 0; } } } return back; } int dk3stream_strputs(dk3_stream_t *st, dkChar const *s, int ie) { int back = 0; #line 1704 "dk3strm.ctr" if((st) && (s)) { #if DK3_CHAR_SIZE > 1 #if DK3_CHAR_SIZE > 2 if(ie == DK3_ENCODING_UNICODE) { back = dk3stream_fputs_c32(st, s); } else { if(st->app) { /* ERROR: Encoding does not match character size! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125); } } #else if(ie == DK3_ENCODING_UTF16) { back = dk3stream_fputs_c16(st, s); } else { if(st->app) { /* ERROR: Encoding does not match character size! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125); } } #endif #else switch(ie) { case DK3_ENCODING_PLAIN: { back = dk3stream_fputs_c8_plain(st, s); } break; case DK3_ENCODING_UTF8: { back = dk3stream_fputs_c8_utf8(st, s); } break; default: { if(st->app) { /* ERROR: Encoding does not match character size! */ dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 125); } } break; } #endif } #line 1742 "dk3strm.ctr" return back; } int dk3stream_strnl(dk3_stream_t *st) { int back = 1; int err_enc_rep = 0; /* Flag: Encoding error reported. */ #if DK3_ON_WINDOWS if(!dk3stream_fputc_c32(st, 0x0000000DUL, &err_enc_rep)) { back = 0; } #endif if(!dk3stream_fputc_c32(st, 0x0000000AUL, &err_enc_rep)) { back = 0; } return back; } int dk3stream_set_line_flush(dk3_stream_t *st, int fl) { int back = 0; #line 1770 "dk3strm.ctr" if(st) { st->lf = fl; back = 1; } #line 1771 "dk3strm.ctr" return back; } dk3_um_t dk3stream_bytes_written(dk3_stream_t const *st) { dk3_um_t back = DK3_UM_0; #line 1781 "dk3strm.ctr" if(st) { back = st->wr; } #line 1784 "dk3strm.ctr" return back; } dk3_stream_t * dk3stream_open_file_app(FILE *fi, int fl, dk3_app_t *app) { dk3_stream_t *back = NULL; #line 1794 "dk3strm.ctr" if(fi) { back = dk3stream_open_app((void *)fi, dk3stream_file_fct_no_close, fl, app); } #line 1797 "dk3strm.ctr" return back; } #if 0 #if DK3_HAVE_ZLIB_H dk3_stream_t * dk3stream_open_gz_app(gzFile g, int fl, dk3_app_t *app) { dk3_stream_t *back = NULL; if(g) { back = dk3stream_open_app((void *)g, dk3stream_gz_fct_no_close, fl, app); } return back; } #endif #endif #if 0 #if DK3_HAVE_BZLIB_H dk3_stream_t * dk3stream_open_bz2_app(BZFILE *b, int fl, dk3_app_t *app) { dk3_stream_t *back = NULL; if(b) { back = dk3stream_open_app((void *)b, dk3stream_bz_fct_no_close, fl, app); } return back; } #endif #endif int dk3stream_process_chars( dk3_stream_t *st, void *obj, dk3_char_handler_t *hf, int ie ) { int back = 0; int res; /* Handler function result. */ int cc; /* Flag: Can continue. */ int myie; /* Input encoding. */ int done; /* Flag: Character already handled. */ #if VERSION_BEFORE_20150821 int surrogate; /* UTF-16 surrogate type. */ #endif char c1; /* First byte. */ char c2; /* Second byte. */ char c3; /* Third byte. */ char c4; /* Fourth byte. */ unsigned char u1; /* Current byte. */ dk3_c32_t uc1; /* First part of result. */ dk3_c32_t uc2; /* Second part of result. */ dk3_c32_t uc3; /* Third part of result. */ dk3_c32_t uc4; /* Fourth part of result. */ dk3_c32_t c32; /* Character found in decoding. */ unsigned long lineno; /* Current line number. */ unsigned long oldlineno = 0UL; /* Line number before start. */ #line 1865 "dk3strm.ctr" if((st) && (hf)) { if(st->app) { #line 1867 "dk3strm.ctr" oldlineno = dk3app_get_source_line((dk3_app_t *)(st->app)); dk3app_set_source_line((dk3_app_t *)(st->app), 1UL); } lineno = 1UL; back = 1; #if VERSION_BEFORE_20150821 cc = 1; #endif myie = ie; #line 1876 "dk3strm.ctr" do { #line 1877 "dk3strm.ctr" cc = 0; done = 0; c32 = 0UL; switch(myie) { case DK3_FILE_ENCODING_ASCII: { #line 1882 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c1)) { #line 1883 "dk3strm.ctr" cc = 1; c32 = (dk3_c32_t)c1; c32 &= 0x000000FFUL; } } break; case DK3_FILE_ENCODING_UTF8: { #line 1889 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c1)) { #line 1890 "dk3strm.ctr" u1 = (unsigned char)c1; if(u1 > 0x7F) { #line 1892 "dk3strm.ctr" if((u1 & 0xE0) == 0xC0) { #line 1893 "dk3strm.ctr" c32 = ((((dk3_c32_t)u1) << 6) & 0x000007C0UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1895 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= (((dk3_c32_t)u1) & 0x0000003FUL); cc = 1; } else { /* ERROR: Incomplete sequence! */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { if((u1 & 0xF0) == 0xE0) { #line 1906 "dk3strm.ctr" c32 = ((((dk3_c32_t)u1) << 12) & 0x0000F000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1908 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1911 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= (((dk3_c32_t)u1) & 0x0000003FUL); cc = 1; } else { /* ERROR: Incomplete sequence! */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence! */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { if((u1 & 0xF8) == 0xF0) { #line 1928 "dk3strm.ctr" c32 = ((((dk3_c32_t)u1) << 18) & 0x001C0000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1930 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1933 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1936 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= (((dk3_c32_t)u1) & 0x0000003FUL); cc = 1; } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { if((u1 & 0xFC) == 0xF8) { #line 1959 "dk3strm.ctr" c32 = ((((dk3_c32_t)u1) << 24) & 0x03000000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1961 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 18) & 0x00FC0000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1964 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1967 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL); if(dk3stream_my_read_byte(st, &c1)) { #line 1970 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= (((dk3_c32_t)u1) & 0x0000003FUL); cc = 1; } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { if((u1 & 0xFE) == 0xFC) { #line 1999 "dk3strm.ctr" c32 = 0x40000000UL; if(dk3stream_my_read_byte(st, &c1)) { #line 2001 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 24) & 0x3F000000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 2004 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 18) & 0x00FC0000UL); if(dk3stream_my_read_byte(st, &c1)) { #line 2007 "dk3strm.ctr" u1 = (unsigned char)c1; c32 |= ((((dk3_c32_t)u1) << 12) & 0x0003F000UL); if(dk3stream_my_read_byte(st, &c1)) { u1 = (unsigned char)c1; #line 2011 "dk3strm.ctr" c32 |= ((((dk3_c32_t)u1) << 6) & 0x00000FC0UL); if(dk3stream_my_read_byte(st, &c1)) { u1 = (unsigned char)c1; #line 2014 "dk3strm.ctr" c32 |= (((dk3_c32_t)u1) & 0x0000003FUL); cc = 1; } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 118); } } } else { } } } } } } else { c32 = ((dk3_c32_t)u1) & 0x000000FFUL; cc = 1; } } } break; case DK3_FILE_ENCODING_UTF16_MSB_FIRST: case DK3_FILE_ENCODING_UTF16_LSB_FIRST: { #line 2061 "dk3strm.ctr" #if VERSION_BEFORE_20150821 surrogate = 0; #endif if(dk3stream_my_read_byte(st, &c1)) { #line 2065 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c2)) { #line 2066 "dk3strm.ctr" if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) { uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL; uc2 = ((dk3_c32_t)c2) & 0x000000FFUL; } else { uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL; uc2 = ((dk3_c32_t)c1) & 0x000000FFUL; } c32 = (uc1 | uc2); #line 2074 "dk3strm.ctr" #if 0 if((c32 & 0x0000DC00UL) == 0x0000DC00UL) #else if((c32 & 0x0000FC00UL) == 0x0000DC00UL) #endif { #line 2080 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c1)) { #line 2081 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c2)) { #line 2082 "dk3strm.ctr" if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) { uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL; uc2 = ((dk3_c32_t)c2) & 0x000000FFUL; } else { uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL; uc2 = ((dk3_c32_t)c1) & 0x000000FFUL; } uc1 |= uc2; #if 0 if((uc1 & 0x0000DC00UL) == 0x0000D800UL) #else if((uc1 & 0x0000FC00UL) == 0x0000D800UL) #endif { uc1 &= 0x000003FFUL; uc1 = (uc1 << 10); uc1 &= 0x000FFC00UL; c32 &= 0x000003FFUL; c32 |= uc1; c32 += 0x00010000UL; cc = 1; } else { /* ERROR: Decoding. */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } else { #if 0 if((c32 & 0x0000DC00UL) == 0x0000D800UL) #else if((c32 & 0x0000FC00UL) == 0x0000D800UL) #endif { #line 2128 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c1)) { #line 2129 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c2)) { #line 2130 "dk3strm.ctr" if(myie == DK3_FILE_ENCODING_UTF16_MSB_FIRST) { uc1 = (((dk3_c32_t)c1) << 8) & 0x0000FF00UL; uc2 = ((dk3_c32_t)c2) & 0x000000FFUL; } else { uc1 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL; uc2 = ((dk3_c32_t)c1) & 0x000000FFUL; } uc1 |= uc2; #if 0 if((uc1 & 0x0000DC00UL) == 0x0000DC00UL) #else if((uc1 & 0x0000DF00UL) == 0x0000DC00UL) #endif { c32 &= 0x000003FFUL; c32 = (c32 << 10); c32 &= 0x000FFC00UL; uc1 &= 0x000003FFUL; c32 |= uc1; c32 += 0x00010000UL; cc = 1; } else { /* ERROR: Decoding. */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } else { /* ERROR: Incomplete sequence */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } else { #line 2170 "dk3strm.ctr" cc = 1; } } } else { /* ERROR: Incomplete word. */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 119); } } } } break; case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { #line 2185 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c1)) { #line 2186 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c2)) { #line 2187 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c3)) { #line 2188 "dk3strm.ctr" if(dk3stream_my_read_byte(st, &c4)) { #line 2189 "dk3strm.ctr" if(myie == DK3_FILE_ENCODING_UNICODE_MSB_FIRST) { uc1 = (((dk3_c32_t)c1) << 24) & 0xFF000000UL; uc2 = (((dk3_c32_t)c2) << 16) & 0x00FF0000UL; uc3 = (((dk3_c32_t)c3) << 8) & 0x0000FF00UL; uc4 = (((dk3_c32_t)c4) ) & 0x000000FFUL; } else { uc1 = (((dk3_c32_t)c4) << 24) & 0xFF000000UL; uc2 = (((dk3_c32_t)c3) << 16) & 0x00FF0000UL; uc3 = (((dk3_c32_t)c2) << 8) & 0x0000FF00UL; uc4 = (((dk3_c32_t)c1) ) & 0x000000FFUL; } cc = 1; c32 = (uc1 | uc2 | uc3 | uc4); } else { /* ERROR: Incomplete DWORD */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218); } } } else { /* ERROR: Incomplete DWORD */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218); } } } else { /* ERROR: Incomplete DWORD */ if(st->app) { dk3app_log_i1((dk3_app_t *)(st->app), DK3_LL_ERROR, 218); } } } } break; } if(cc) { #line 2225 "dk3strm.ctr" if(c32 != 0x0000FEFFUL) { #line 2226 "dk3strm.ctr" switch(myie) { case DK3_FILE_ENCODING_UTF16_MSB_FIRST: { if(c32 == 0x0000FFFEUL) { #line 2229 "dk3strm.ctr" myie = DK3_FILE_ENCODING_UTF16_LSB_FIRST; done = 1; #line 2231 "dk3strm.ctr" } } break; case DK3_FILE_ENCODING_UTF16_LSB_FIRST: { if(c32 == 0x0000FFFEUL) { #line 2235 "dk3strm.ctr" myie = DK3_FILE_ENCODING_UTF16_MSB_FIRST; done = 1; #line 2237 "dk3strm.ctr" } } break; case DK3_FILE_ENCODING_UNICODE_MSB_FIRST: { if((unsigned long)c32 == 0xFFFE0000UL) { #line 2241 "dk3strm.ctr" myie = DK3_FILE_ENCODING_UNICODE_LSB_FIRST; done = 1; #line 2243 "dk3strm.ctr" } } break; case DK3_FILE_ENCODING_UNICODE_LSB_FIRST: { if((unsigned long)c32 == 0xFFFE0000UL) { #line 2247 "dk3strm.ctr" myie = DK3_FILE_ENCODING_UNICODE_MSB_FIRST; done = 1; #line 2249 "dk3strm.ctr" } } break; } if(!done) { #line 2253 "dk3strm.ctr" res = (*hf)(obj, c32); if(res < 1) { back = 0; if(res < 0) { cc = 0; } } } if(c32 == 0x0000000AUL) { #line 2257 "dk3strm.ctr" lineno++; /* Set line number */ if(st->app) { dk3app_set_source_line((dk3_app_t *)(st->app), lineno); } } } } } while(cc); if(st->app) { dk3app_set_source_line((dk3_app_t *)(st->app), oldlineno); } } #line 2270 "dk3strm.ctr" return back; } /* NOTE: This function does not check the BOM at start of files. Whenever applicable, use dk3stream_process_filename_chars_app() instead. */ int dk3stream_process_file_chars_app( void *obj, dk3_char_handler_t *hf, FILE *fipo, dkChar const *fn, int ie, dk3_app_t *app ) { int back = 0; dkChar const *oldsourcefile = NULL; unsigned long oldsourceline = 0UL; dk3_stream_t *is = NULL; #line 2294 "dk3strm.ctr" if((hf) && (fipo)) { #line 2295 "dk3strm.ctr" if(app) { oldsourcefile = dk3app_get_source_file(app); oldsourceline = dk3app_get_source_line(app); dk3app_set_source_file(app, fn); } is = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app); if(is) { back = dk3stream_process_chars(is, obj, hf, ie); dk3stream_close(is); } if(app) { dk3app_set_source_file(app, oldsourcefile); dk3app_set_source_line(app, oldsourceline); } } #line 2310 "dk3strm.ctr" return back; } int dk3stream_process_filename_chars_app( void *obj, dk3_char_handler_t *hf, dkChar const *fn, int de, dk3_app_t *app ) { char bombuf[4]; FILE *fipo; /* Input file. */ size_t skb; int back = 0; int ie; /* Input encoding. */ #line 2330 "dk3strm.ctr" if((hf) && (fn)) { ie = de; #line 2332 "dk3strm.ctr" skb = 0; ie = dk3sf_inspect_bom_skip_app(fn, ie, &skb, NULL); #line 2334 "dk3strm.ctr" fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app); if(fipo) { if((skb > 0) && (skb <=4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, app); } back = dk3stream_process_file_chars_app(obj, hf, fipo, fn, ie, app); fclose(fipo); } } #line 2343 "dk3strm.ctr" return back; } /** Add one found 32-bit character to input line, process input line if newline found or if buffer is full. @param lhv A dk3_line_handler_data_t pointer. @param c32 Current character to process. @return 1=OK, can continue, 0=error, can continue, -1=error, abort. */ static int dk3stream_add_character_to_line(void *lhv, dk3_c32_t c32) { int back = 1; dk3_line_handler_data_t *lh; dkChar *cp; /* Current position. */ int res; /* Handler result. */ #if DK3_CHAR_SIZE > 1 dk3_c16_t u16p[8]; /* Buffer UTF-16 */ size_t used; /* Elements used in u16p. */ size_t i; /* Running index. */ #else unsigned char uc; /* Unsigned char. */ char c; /* Current char. */ unsigned char u8p[8]; /* Buffer UTF-8. */ size_t used; /* Elements used in u8p. */ size_t i; /* Running index. */ #endif #line 2374 "dk3strm.ctr" lh = (dk3_line_handler_data_t *)lhv; #if DK3_CHAR_SIZE > 1 used = dk3enc_uc2utf16(c32, u16p, DK3_SIZEOF(u16p,dk3_c16_t)); if(used > 0) { if((lh->bufus + used) < (lh->szbuf - 1)) { cp = lh->cp; for(i = 0; i < used; i++) { cp[i] = u16p[i]; } cp = &(cp[used]); *cp = dkT('\0'); lh->cp = cp; lh->bufus += used; if(c32 == 0x0000000AUL) { /* FLUSH OUTPUT */ (lh->buf)[lh->szbuf - 1] = dkT('\0'); res = (*(lh->hf))(lh->obj, lh->buf); if(res < 1) { back = 0; if(res < 0) { back = -1; } } /* Start new line */ lh->cp = lh->buf; (lh->buf)[0] = '\0'; lh->bufus = 0; } } else { back = 0; /* Warning: Line too long */ if(lh->app) { dk3app_log_i1((dk3_app_t *)(lh->app), DK3_LL_WARNING, 108); } (lh->buf)[lh->szbuf - 1] = dkT('\0'); res = (*(lh->hf))(lh->obj, lh->buf); if(res < -1) { back = -1; } cp = lh->buf; for(i = 0; i < used; i++) { cp[i] = u16p[i]; } cp = &(cp[used]); *cp = dkT('\0'); lh->cp = cp; lh->bufus = used; if(c32 == 0x0000000AUL) { lh->cp = lh->buf; *(lh->buf) = dkT('\0'); lh->bufus = 0; } } } else { /* ERROR: Encoding failed! */ if(lh->app) { dk3app_log_i1((dk3_app_t *)(lh->app), DK3_LL_ERROR, 119); } } #else #line 2429 "dk3strm.ctr" if(lh->se == DK3_ENCODING_UTF8) { #line 2430 "dk3strm.ctr" used = dk3enc_uc2utf8(c32, u8p, sizeof(u8p)); if(used > 0) { #line 2432 "dk3strm.ctr" if((lh->bufus + used) < (lh->szbuf - 1)) { #line 2433 "dk3strm.ctr" cp = lh->cp; #line 2434 "dk3strm.ctr" for(i = 0; i < used; i++) { cp[i] = u8p[i]; } cp = &(cp[used]); #line 2436 "dk3strm.ctr" *cp = '\0'; lh->cp = cp; lh->bufus += used; #line 2439 "dk3strm.ctr" if(c32 == 0x0000000AUL) { #line 2440 "dk3strm.ctr" /* FLUSH OUTPUT */ (lh->buf)[lh->szbuf - 1] = dkT('\0'); res = (*(lh->hf))(lh->obj, lh->buf); if(res < 1) { back = 0; if(res < 0) { back = -1; } } /* Start new line */ lh->cp = lh->buf; (lh->buf)[0] = '\0'; lh->bufus = 0; } #line 2454 "dk3strm.ctr" } else { #line 2455 "dk3strm.ctr" back = 0; /* Warning: Line too long! */ if(lh->app) { dk3app_log_i1(lh->app, DK3_LL_WARNING, 108); } /* FLUSH OUTPUT */ (lh->buf)[lh->szbuf - 1] = dkT('\0'); res = (*(lh->hf))(lh->obj, lh->buf); if(res < -1) { back = -1; } /* Start new line. */ cp = lh->buf; for(i = 0; i < used; i++) { cp[i] = u8p[i]; } cp = &(cp[used]); *cp = '\0'; lh->cp = cp; lh->bufus = used; if(c32 == 0x0000000AUL) { *(lh->buf) = '\0'; lh->cp = lh->buf; lh->bufus = 0; } } } else { #line 2478 "dk3strm.ctr" back = 0; /* ERROR: Encoding failed! */ if(lh->app) { #line 2481 "dk3strm.ctr" dk3app_log_i1(lh->app, DK3_LL_ERROR, 115); } } } else { #line 2485 "dk3strm.ctr" if((unsigned long)c32 > 0x000000FFUL) { /* Warning: Character out of range. */ if(lh->app) { dk3app_log_i1(lh->app, DK3_LL_WARNING, 219); } } uc = (unsigned char)c32; c = (char)uc; if((lh->bufus + 1) < (lh->szbuf - 1)) { cp = lh->cp; *(cp++) = c; *cp = '\0'; lh->cp = cp; lh->bufus += 1; if(c32 == 0x0000000AUL) { /* FLUSH OUTPUT */ (lh->buf)[lh->szbuf - 1] = dkT('\0'); res = (*(lh->hf))(lh->obj, lh->buf); if(res < 1) { back = 0; if(res < 0) { back = -1; } } /* Start new line */ lh->cp = lh->buf; (lh->buf)[0] = '\0'; lh->bufus = 0; } } else { back = 0; /* Warning: Line too long! */ if(lh->app) { dk3app_log_i1(lh->app, DK3_LL_WARNING, 108); } /* FLUSH OUTPUT */ (lh->buf)[lh->szbuf - 1] = dkT('\0'); res = (*(lh->hf))(lh->obj, lh->buf); if(res < -1) { back = -1; } /* Start new line. */ cp = lh->buf; *(cp++) = c; *cp = '\0'; lh->cp = cp; lh->bufus = 1; if(c32 == 0x0000000AUL) { *(lh->buf) = '\0'; lh->cp = lh->buf; lh->bufus = 0; } } } #endif #line 2539 "dk3strm.ctr" return back; } int dk3stream_process_lines( dk3_stream_t *st, void *obj, dk3_line_handler_t *hf, dkChar *buf, size_t szbuf, int se, int ie ) { int back = 0; dk3_line_handler_data_t lh; #line 2558 "dk3strm.ctr" if((st) && (hf) && (buf) && (szbuf)) { lh.app = (dk3_app_t *)(st->app); lh.obj = obj; lh.hf = hf; lh.buf = buf; buf[0] = dkT('\0'); lh.szbuf = szbuf; lh.cp = lh.buf; lh.bufus = 0; lh.se = se; back = dk3stream_process_chars( st, (void *)(&lh), dk3stream_add_character_to_line, ie ); } #line 2572 "dk3strm.ctr" return back; } /* NOTE: This function does not check for a BOM at the beginning of the file. Whenever applicable, use dk3stream_process_filename_lines_app() instead. */ int dk3stream_process_file_lines_app( void *obj, dk3_line_handler_t *hf, FILE *fipo, dkChar const *fn, dkChar *buf, size_t szbuf, int se, int ie, dk3_app_t *app ) { int back = 0; dkChar const *oldsourcename = NULL; unsigned long oldsourceline = 0UL; dk3_stream_t *is; #line 2599 "dk3strm.ctr" if((hf) && (fipo)) { #line 2600 "dk3strm.ctr" if(app) { #line 2601 "dk3strm.ctr" oldsourcename = dk3app_get_source_file(app); oldsourceline = dk3app_get_source_line(app); dk3app_set_source_file(app, fn); dk3app_set_source_line(app, 1UL); } is = dk3stream_open_file_app(fipo, DK3_STREAM_FLAG_READ, app); if(is) { #line 2608 "dk3strm.ctr" back = dk3stream_process_lines(is, obj, hf, buf, szbuf, se, ie); dk3stream_close(is); } else { #line 2611 "dk3strm.ctr" } if(app) { #line 2613 "dk3strm.ctr" dk3app_set_source_file(app, oldsourcename); dk3app_set_source_line(app, oldsourceline); } } #line 2617 "dk3strm.ctr" return back; } int dk3stream_process_filename_lines_app( void *obj, dk3_line_handler_t *hf, dkChar const *fn, dkChar *buf, size_t szbuf, int se, int de, dk3_app_t *app ) { char bombuf[4]; FILE *fipo; /* Input file. */ size_t skb; /* Bytes to skip at start of input. */ int ie; /* Input encoding. */ int back = 0; #line 2640 "dk3strm.ctr" if((hf) && (fn)) { ie = dk3sf_inspect_bom_skip_app(fn, de, &skb, app); #line 2642 "dk3strm.ctr" fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app); if(fipo) { #line 2644 "dk3strm.ctr" if((skb > 0) && (skb <= 4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, app); } back = dk3stream_process_file_lines_app( obj, hf, fipo, fn, buf, szbuf, se, ie, app ); fclose(fipo); } } #line 2653 "dk3strm.ctr" return back; } int dk3stream_process_filename_sanitized_lines_app( void *obj, dk3_line_handler_t *hf, dkChar const *fn, dkChar *buf, size_t szbuf, int se, int de, dk3_app_t *app ) { char bombuf[4]; #if DK3_HAVE_SETVBUF char *filebuf = NULL; /* File buffer. */ #endif FILE *fipo; /* Input file. */ size_t skb; /* Bytes to skip at start of input. */ int ie; /* Input encoding. */ int back = 0; #line 2679 "dk3strm.ctr" if((hf) && (fn)) { ie = dk3sf_inspect_bom_skip_app(fn, de, &skb, app); #line 2681 "dk3strm.ctr" #if DK3_HAVE_SETVBUF filebuf = dk3_new_app(char,BUFSIZ,app); if (NULL != filebuf) { #endif fipo = dk3sf_fopen_app(fn, dk3app_not_localized(36), app); if(fipo) { #line 2687 "dk3strm.ctr" #if DK3_HAVE_SETVBUF if (0 == setvbuf(fipo, filebuf, _IOFBF, BUFSIZ)) { #endif if((skb > 0) && (skb <= 4)) { dk3sf_fread_app(bombuf, 1, skb, fipo, app); } back = dk3stream_process_file_lines_app( obj, hf, fipo, fn, buf, szbuf, se, ie, app ); #if DK3_HAVE_SETVBUF } else { /* ERROR: Failed to set buffer for file */ dk3app_log_i3(app, DK3_LL_ERROR, 412, 413, fn); } #endif fclose(fipo); } #if DK3_HAVE_SETVBUF dk3mem_reset_secure(filebuf, BUFSIZ); dk3mem_free(filebuf); filebuf = NULL; } #endif } #line 2710 "dk3strm.ctr" return back; } int dk3strm_double_c8_str_no_sci(dk3_stream_t *os, char *buffer) { char *start; /* Start of string. */ char *eptr; /* Start of exponent substring. */ char *ptr; /* Traverse string. */ size_t lgt; /* String length. */ int dp; /* Decimal dot position. */ int exponent; /* Exponent. */ int i; /* Traverse the string. */ int back = 1; /* Result */ char chr; /* Character to write out */ #line 2727 "dk3strm.ctr" if((os) && (buffer)) { eptr = NULL; start = buffer; /* Print sign. */ switch(*start) { case '-': { if (1 != dk3stream_write_bytes(os, start, 1)) { back = 0; } start++; } break; case '+': { start++; } break; } /* Find exponent substring and exponent. */ eptr = NULL; ptr = start; while(*ptr) { switch(*ptr) { case 'e': case 'E': { eptr = ptr; } break; } ptr++; } if(eptr) { *(eptr++) = '\0'; #if VERSION_BEFORE_20140716 if(sscanf(eptr, "%d", &exponent) != 1) #else if (0 == dk3ma_i_from_c8_string(&exponent, eptr, NULL)) #endif { exponent = 0; } } else { exponent = 0; } /* Find decimal dot. */ eptr = strchr(start, '.'); if(eptr) { /* Keep dot position in dp, squeeze string. */ *eptr = '\0'; dp = (int)strlen(start); *eptr = '.'; while(*eptr) { eptr[0] = eptr[1]; eptr++; } } else { /* Dot position is after the string. */ dp = (int)strlen(start); } /* Correct dot position. */ dp = dp + exponent; /* Remove leading zeroes (if any). */ while('0' == *start) { start++; dp--; } /* Remove trailing zeroes (if any). */ eptr = NULL; ptr = start; while(*ptr) { if('0' == *ptr) { if(!(eptr)) { eptr = ptr; } } else { eptr = NULL; } ptr++; } if(eptr) { *eptr = '\0'; } lgt = strlen(start); if(0 < lgt) { if(dp >= (int)lgt) { /* Decimal dot is at end or after string. */ if (1 != dk3stream_c8_fputs(os, start)) { back = 0; } /* Decimal dot is after the string. */ for(i = 0; i < (dp - (int)lgt); i++) { chr = '0'; if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; } } } else { if(dp <= 0) { /* Decimal dot is before the string. */ chr = '0'; if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; } chr = '.'; if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; } chr = 0; while(dp++ < 0) { if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; } } if (1 != dk3stream_c8_fputs(os, start)) { back = 0; } } else { /* Decimal dot is in the string. */ for(i = 0; i < (int)lgt; i++) { if(dp == i) { chr = '.'; if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; } } if (1 != dk3stream_write_bytes(os, &(start[i]), 1)) { back = 0; } } } } } else { /* No non-zero digits in string. */ chr = '0'; if (1 != dk3stream_write_bytes(os, &chr, 1)) { back = 0; } } } #line 2862 "dk3strm.ctr" return back; } int dk3strm_double_c8_no_sci(dk3_stream_t *os, double x) { char buffer[64]; char *ptr; int back = 0; if (NULL != os) { if (1 == sprintf(buffer, "%g", x)) { ptr = buffer; while(*ptr) { if (',' == *ptr) { *ptr = '.'; } ptr++; } back = dk3strm_double_c8_str_no_sci(os, buffer); } } return back; } /* vim: set ai sw=2 : */