qboolean Stats_TrackerImageLoaded(char *in) { int error; if (in) return Font_TrackerValid(unicode_decode(&error, in, &in, true)); return false; }
char unicode_prev(struct unicode_parser* parser) { if (parser->current.ptr == parser->current.str) return 0; // Try to move to previous symbol parser->next = parser->current; parser->current = parser->prev; utf8_prev(&parser->prev); unicode_decode(parser); return 1; }
char unicode_next(struct unicode_parser* parser) { if (utf8_current(&parser->current)) { // Try to move to next symbol parser->prev = parser->current; parser->current = parser->next; utf8_next(&parser->next); unicode_decode(parser); return 1; } return 0; }
// Open physical file OLE2* ole2_open(const BYTE *file) { //BYTE buf[1024]; OLE2Header* oleh; OLE2* ole; OLE2Stream* olest; PSS* pss; BYTE* name = NULL; #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("ole2_open %s\n", file); #endif if(xls_debug) printf("ole2_open: %s\n", file); ole=(OLE2*)calloc(1, sizeof(OLE2)); if (!(ole->file=fopen((char *)file,"rb"))) { if(xls_debug) printf("File not found\n"); free(ole); return(NULL); } // read header and check magic numbers oleh=(OLE2Header*)malloc(512); fread(oleh,1,512,ole->file); xlsConvertHeader(oleh); // make sure the file looks good. Note: this code only works on Little Endian machines if(oleh->id[0] != 0xE011CFD0 || oleh->id[1] != 0xE11AB1A1 || oleh->byteorder != 0xFFFE) { fclose(ole->file); printf("Not an excel file\n"); free(ole); return NULL; } //ole->lsector=(WORD)pow(2,oleh->lsector); //ole->lssector=(WORD)pow(2,oleh->lssector); ole->lsector=512; ole->lssector=64; assert(oleh->lsectorB==9); // 2**9 == 512 assert(oleh->lssectorB==6); // 2**6 == 64 ole->cfat=oleh->cfat; ole->dirstart=oleh->dirstart; ole->sectorcutoff=oleh->sectorcutoff; ole->sfatstart=oleh->sfatstart; ole->csfat=oleh->csfat; ole->difstart=oleh->difstart; ole->cdif=oleh->cdif; ole->files.count=0; #ifdef OLE_DEBUG printf("==== OLE HEADER ====\n"); //printf ("Header Size: %i \n", sizeof(OLE2Header)); //printf ("id[0]-id[1]: %X-%X \n", oleh->id[0], oleh->id[1]); printf ("verminor: %X \n",oleh->verminor); printf ("verdll: %X \n",oleh->verdll); //printf ("Byte order: %X \n",oleh->byteorder); printf ("sect len: %X (%i)\n",ole->lsector,ole->lsector); // ole printf ("mini len: %X (%i)\n",ole->lssector,ole->lssector); // ole printf ("Fat sect.: %i \n",oleh->cfat); printf ("Dir Start: %i \n",oleh->dirstart); printf ("Mini Cutoff: %i \n",oleh->sectorcutoff); printf ("MiniFat Start: %X \n",oleh->sfatstart); printf ("Count MFat: %i \n",oleh->csfat); printf ("Dif start: %X \n",oleh->difstart); printf ("Count Dif: %i \n",oleh->cdif); printf ("Fat Size: %u (0x%X) \n",oleh->cfat*ole->lsector,oleh->cfat*ole->lsector); #endif // read directory entries read_MSAT(ole, oleh); // reuse this buffer pss = (PSS*)oleh; // oleh = (void *)NULL; // Not needed as oleh not used from here on olest=ole2_sopen(ole,ole->dirstart, -1); do { ole2_read(pss,1,sizeof(PSS),olest); xlsConvertPss(pss); name=unicode_decode(pss->name, pss->bsize, 0, "UTF-8"); #ifdef OLE_DEBUG printf("OLE NAME: %s count=%d\n", name, ole->files.count); #endif if (pss->type == PS_USER_ROOT || pss->type == PS_USER_STREAM) // (name!=NULL) // { #ifdef OLE_DEBUG printf("OLE TYPE: %s file=%d \n", pss->type == PS_USER_ROOT ? "root" : "user", ole->files.count); #endif if (ole->files.count==0) { ole->files.file=malloc(sizeof(struct st_olefiles_data)); } else { ole->files.file=realloc(ole->files.file,(ole->files.count+1)*sizeof(struct st_olefiles_data)); } ole->files.file[ole->files.count].name=name; ole->files.file[ole->files.count].start=pss->sstart; ole->files.file[ole->files.count].size=pss->size; ole->files.count++; if(pss->sstart == ENDOFCHAIN) { if (xls_debug) verbose("END OF CHAIN\n"); } else if(pss->type == PS_USER_STREAM) { #ifdef OLE_DEBUG printf("----------------------------------------------\n"); printf("name: %s (size=%d [c=%c])\n", name, pss->bsize, name ? name[0]:' '); printf("bsize %i\n",pss->bsize); printf("type %i\n",pss->type); printf("flag %i\n",pss->flag); printf("left %X\n",pss->left); printf("right %X\n",pss->right); printf("child %X\n",pss->child); printf("guid %.4X-%.4X-%.4X-%.4X %.4X-%.4X-%.4X-%.4X\n",pss->guid[0],pss->guid[1],pss->guid[2],pss->guid[3], pss->guid[4],pss->guid[5],pss->guid[6],pss->guid[7]); printf("user flag %.4X\n",pss->userflags); printf("sstart %.4d\n",pss->sstart); printf("size %.4d\n",pss->size); #endif } else if(pss->type == PS_USER_ROOT) { DWORD sector, k, blocks; BYTE *wptr; blocks = (pss->size + (ole->lsector - 1)) / ole->lsector; // count partial ole->SSAT = (BYTE *)malloc(blocks*ole->lsector); // printf("blocks %d\n", blocks); assert(ole->SSecID); sector = pss->sstart; wptr=(BYTE*)ole->SSAT; for(k=0; k<blocks; ++k) { // printf("block %d sector %d\n", k, sector); assert(sector != ENDOFCHAIN); fseek(ole->file,sector*ole->lsector+512,0); fread(wptr,1,ole->lsector,ole->file); wptr += ole->lsector; sector = xlsIntVal(ole->SecID[sector]); } } } else { free(name); } } while (!olest->eof); ole2_fclose(olest); free(pss); return ole; }
void xls_appendSST(xlsWorkBook* pWB,XLSBYTE* buf,XLSDWORD size) { XLSDWORD ln; // String character count XLSDWORD ofs; // Current offset in SST buffer XLSDWORD rt; // Count or rich text formatting runs XLSDWORD sz; // Size of asian phonetic settings block XLSBYTE flag; // String flags char* ret; if (xls_debug) { printf("xls_appendSST %u\n", size); } sz = rt = ln = 0; // kch ofs=0; while(ofs<size) { int ln_toread; // Restore state when we're in a continue record // or read string length if (pWB->sst.continued) { ln=pWB->sst.lastln; rt=pWB->sst.lastrt; sz=pWB->sst.lastsz; } else { ln=*(XLSWORD*)(buf+ofs); rt = 0; sz = 0; ofs+=2; } if (xls_debug) { printf("ln=%u\n", ln); } // Read flags if ( (!pWB->sst.continued) ||( (pWB->sst.continued) &&(ln != 0) ) ) { flag=*(XLSBYTE*)(buf+ofs); ofs++; // Count of rich text formatting runs if (flag & 0x8) { rt=*(XLSWORD*)(buf+ofs); ofs+=2; } // Size of asian phonetic settings block if (flag & 0x4) { sz=*(XLSDWORD*)(buf+ofs); ofs+=4; if (xls_debug) { printf("sz=%u\n", sz); } } } else { flag = 0; } // Read characters (compressed or not) ln_toread = 0; if (ln > 0) { if (flag & 0x1) { int new_len = 0; ln_toread = min((size-ofs)/2, ln); ret=unicode_decode(buf+ofs,ln_toread*2, &new_len,pWB->charset); if (ret == NULL) { const char *str = "*failed to decode utf16*"; ret = strdup(str); new_len = strlen(str); } ret = (char *)realloc(ret,new_len+1); *(char*)(ret+new_len)=0; ln -= ln_toread; ofs+=ln_toread*2; if (xls_debug) { printf("String16: %s(%i)\n",ret,new_len); } } else { ln_toread = min((size-ofs), ln); ret = (char *)malloc(ln_toread + 1); memcpy (ret, (buf+ofs),ln_toread); *(char*)(ret+ln_toread)=0; ln -= ln_toread; ofs+=ln_toread; if (xls_debug) { printf("String8: %s(%u) \n",ret,ln); } } } else { ret = strdup(""); } if ( (ln_toread > 0) ||(!pWB->sst.continued) ) { // Concat string if it's a continue, or add string in table if (!pWB->sst.continued) { pWB->sst.lastid++; pWB->sst.string[pWB->sst.lastid-1].str=ret; } else { char *tmp; tmp=pWB->sst.string[pWB->sst.lastid-1].str; tmp=(char *)realloc(tmp,strlen(tmp)+strlen(ret)+1); pWB->sst.string[pWB->sst.lastid-1].str=tmp; memcpy(tmp+strlen(tmp),ret,strlen(ret)+1); } if (xls_debug) { printf("String %u: %s<end>\n", pWB->sst.lastid-1, pWB->sst.string[pWB->sst.lastid-1].str); } } // Jump list of rich text formatting runs if ( (ofs < size) &&(rt > 0) ) { int rt_toread = min((size-ofs)/4, rt); rt -= rt_toread; ofs += rt_toread*4; } // Jump asian phonetic settings block if ( (ofs < size) &&(sz > 0) ) { int sz_toread = min((size-ofs), sz); sz -= sz_toread; ofs += sz_toread; } pWB->sst.continued=0; } // Save current character count and count of rich text formatting runs and size of asian phonetic settings block if (ln > 0 || rt > 0 || sz > 0) { pWB->sst.continued = 1; pWB->sst.lastln = ln; pWB->sst.lastrt = rt; pWB->sst.lastsz = sz; if (xls_debug) { printf("continued: ln=%u, rt=%u, sz=%u\n", ln, rt, sz); } } }
// Read and decode string char* get_string(XLSBYTE *s, XLSBYTE is2, XLSBYTE fmt, char *charset) { XLSWORD ln; XLSDWORD ofs; XLSDWORD sz; XLSWORD rt; XLSBYTE flag; XLSBYTE* str; char* ret; int new_len; new_len = 0; flag = 0; str=s; ofs=0; if (is2) { ln=*(XLSWORD*)str; ofs+=2; } else { ln=*(XLSBYTE*)str; ofs++; } if(fmt) { flag=*(XLSBYTE*)(str+ofs); ofs++; } if (flag&0x8) { rt=*(XLSWORD*)(str+ofs); ofs+=2; } if (flag&0x4) { sz=*(XLSDWORD*)(str+ofs); ofs+=4; } if (flag&0x1) { ret=unicode_decode(str+ofs,ln*2, &new_len,charset); ofs+=ln*2; } else { ret=(char *)malloc(ln+1); memcpy (ret,(str+ofs),ln); *(char*)(ret+ln)=0; ofs+=ln; } if (flag&0x8) ofs+=4*rt; if (flag&0x4) ofs+=sz; return ret; }