1 /* maximum sizes */ 2 #define BUFLEN 1024*1024 // 1 MiB, initial read buffer size 3 #define MAXCONTAINERS 2048 4 5 /* states */ 6 #define XMIINS_READ_HEADER 1 7 #define XMIINS_READ_RUN_HEADER 2 8 #define XMIINS_READ_GLOBAL_BLOCK 3 9 #define XMIINS_READ_CONTAINER_BLOCK 4 10 11 /* error codes */ 12 #define XMIINS_ERR_NONE 0 13 #define XMIINS_ERR_EXCEPTION 1 // C++ exception raised (XMill or otherwise) 14 #define XMIINS_ERR_GLOBALSIZE 2 // large global block size mismatch 15 #define XMIINS_ERR_CONTAINERSIZE 3 // large container block size mismatch 16 #define XMIINS_ERR_BUFFERTOOSMALL 4 // internal error: read buffer too small 17 #define XMIINS_ERR_TOOMANYCONTAINERS 5 // internal error: MAXCONTAINERS too small 18 #define XMIINS_ERR_GLOBALNOTFOUND 6 // large global block not found 19 #define XMIINS_ERR_CONTAINERNOTFOUND 7 // large container block not found 20 #define XMIINS_ERR_STATE 8 // internal error: illegal state 21 #define XMIINS_ERR_XMLFILE 9 // XML file, not XMI 22 #define XMIINS_ERR_MAGIC 10 // incorrect XMill magic 23 #define XMIINS_ERR_VERSION 11 // unknown XMill version 24 #define XMIINS_ERR_TOTALSIZE 12 // sizes mismatch 25 #define XMIINS_ERR_GLOBALCONTAINER 13 // the special container block 0 has more than 3 containers 26 #define XMIINS_ERR_ZERO 14 // no Bytes decompressed 27 #define XMIINS_ERR_UNKNOWNLABEL 15 // label id out of range 28 #define XMIINS_ERR_DATA_INDEX_UNKNOWN 16 // data container index out of range 29 #define XMIINS_ERR_CONTAINER_INDEX_UNKNOWN 17 30 // container index out of range 31 #define XMIINS_ERR_NUM_CONTAINERS_MISMATCH 18 32 // # containers does not match the # that the associated path expression expects 33 #define XMIINS_ERR_OPENCLOSE_MISMATCH 19 // open and close XML tags don't match 34 #define XMIINS_ERR_SPECIALREF 20 // the special container is referenced for normal data 35 #define XMIINS_ERR_FILENOTFOUND 21 // XMI file could not be opened 36 #define XMIINS_ERR_XMISIZEMISMATCH 22 // XMI file size is not equal to processed size 37 #define XMIINS_ERR_SEMCOMPUNKNOWN 23 // semantic compressor unknown 38 #define XMIINS_ERR_PATHEXPR_PARSE 24 // path expression parse error 39 #define XMIINS_ERR_INTERNAL 25 // internal error aka detected a bug 40 #define XMIINS_ERR_DATASIZE 26 // wrong container data size 41 #define XMIINS_ERR_OR 27 // 'or' compressor choice value out of range 42 #define XMIINS_ERR_E 28 // 'e' compressor dictionary index out of range 43 //#define XMIINS_ERR_ 44 45 /* reporting levels */ 46 #define XMIINS_REPORT_NONE 0 47 #define XMIINS_REPORT_ERRORS 1 48 #define XMIINS_REPORT_WARNINGS 2 49 #define XMIINS_REPORT_MININFO 3 50 #define XMIINS_REPORT_SOMEINFO 4 51 #define XMIINS_REPORT_INFO 5 52 #define XMIINS_REPORT_MOREINFO 6 53 #define XMIINS_REPORT_CONTENTS 7 54 #define XMIINS_REPORT_ALL 8 55 #define XMIINS_REPORT_DEBUG 9 56 #define XMIINS_REPORT_VERYMUCH 10 // kludge. never use, please! 57 58 /* semantic compressor types */ 59 #define XMIINS_SC_UNKNOWN -1 60 /* basic */ 61 #define XMIINS_SC_T 0 // text 62 #define XMIINS_SC_E 1 // dictionary 63 #define XMIINS_SC_U 2 // uint32 64 #define XMIINS_SC_I 3 // sint32 65 #define XMIINS_SC_RL 4 // runlength 66 #define XMIINS_SC_U8 5 // byte 67 #define XMIINS_SC_DI 11 // delta sint32 68 /* basic, added for v0.8beta */ 69 #define XMIINS_SC_BASEX 6 // baseX 70 #define XMIINS_SC_BASE2 7 // binary 71 #define XMIINS_SC_BASE16 8 // hex 72 #define XMIINS_SC_BASE22 9 // case-sensitive hex 73 #define XMIINS_SC_BASE64 10 // base64 74 /* non-data */ 75 #define XMIINS_SC_C 16 // constant 76 #define XMIINS_SC_P 17 // print 77 /* combining */ 78 #define XMIINS_SC_OR 12 // or 79 #define XMIINS_SC_SEQ 13 // sequence 80 #define XMIINS_SC_REP 14 // repeat 81 #define XMIINS_SC_SEQCOMB 15 // combined sequence 82 /* mixed subtype for seqcomb */ 83 #define XMIINS_SC_MIXED 18 // mixed 84 85 #define XMIINS_SC_T_STR "t" 86 #define XMIINS_SC_E_STR "e" 87 #define XMIINS_SC_U_STR "u" 88 #define XMIINS_SC_I_STR "i" 89 #define XMIINS_SC_RL_STR "rl" 90 #define XMIINS_SC_U8_STR "u8" 91 #define XMIINS_SC_DI_STR "di" 92 #define XMIINS_SC_BASEX_STR "basex" 93 #define XMIINS_SC_BASE2_STR "b" 94 #define XMIINS_SC_BASE16_STR "x" 95 #define XMIINS_SC_BASE22_STR "X" 96 #define XMIINS_SC_BASE64_STR "base64" 97 #define XMIINS_SC_P_STR "p" 98 #define XMIINS_SC_OR_STR "or" 99 #define XMIINS_SC_SEQ_STR "seq" 100 #define XMIINS_SC_REP_STR "rep" 101 #define XMIINS_SC_SEQCOMB_STR "seqcomb" 102 103 #define MAXSUBS 1024 104 105 class XMIInspect; 106 107 /* I intended this to be a tree, but I ended up only using the subs attribute in the top element.. 108 */ 109 class ExprInfo 110 { 111 int numcontainers; 112 int containertype; 113 ExprInfo **subs; 114 int numsubs, usedsubs; 115 int eindex, eindextotal; 116 char *constant_or_param; 117 118 public: 119 ExprInfo(); 120 ~ExprInfo(); 121 122 ExprInfo** createSubs(); 123 ExprInfo** getSubs(int offset = 0); 124 125 void setCorP(char *s, int len = 0, bool isconstant = false); 126 char* getCorP(); 127 128 int getUsedSubs(); 129 int getUsedSubs(int subnum); 130 void setUsedSubs(int num); 131 132 ExprInfo* getTranslatedExpr(int contnum, int *subnump); 133 int getTranslatedUsedSubs(int contnum); 134 int getTranslatedContainers(int contnum, ExprInfo **exprs, int maxexprs); 135 136 void calcEnumIndexes(XMIInspect *inspect, int pathexprnum, int &cureindex); 137 int getEnumIndex(int blocknum, int contnum, int numprec); 138 139 ExprInfo* getSubContainer(int sub); 140 141 void setNumContainers(int numcontainers, bool takemax = false); 142 int getNumContainers(); 143 144 int getSubContainerType(int container); 145 void setSubContainerType(int container, int type); 146 147 int getContainerType(); 148 void setContainerType (int type); 149 150 int getTranslatedContainerType(int contnum); 151 152 static int token2type(char *dum); 153 static char* type2text(int type); 154 static bool isCombining(int type); 155 static int numContainers(int type); 156 }; 157 158 class XMIInspect 159 { 160 friend class ExprInfo; 161 162 int state; 163 int level; 164 165 /* global header data, data sizes */ 166 long version, magic, datasize, numblocks, numglobals, curglobal, curcontainer, curblock, indexnr, numbuffers, 167 compsize, totalcompsize, totaluncompsize, totalrunsize, runsize, 168 headersize, totalheadersize, numheaders, totaldatasize, globalsfound, numlargeglobals, 169 bytesleft, smallglobalsize, globalheadersize, preheadersize, globaldatasize, xmifilesize; 170 char *gpc; 171 /* arrays to store global & run header data */ 172 long *statesize, *numcontainers, *containersize, *index, *pathindex;// *dictionarysizes; 173 char **labels, **exprs; 174 int numlabels, numexprs; 175 /* # containers */ 176 int expectedcontainers, foundcontainers; 177 /* path expression info */ 178 ExprInfo **exprinfo; 179 /* XML element & data counts */ 180 int numopen, numclose, numdata, numspecial, *numcontdata, numwhite, *numrealcontdata; 181 182 /* uncompress buffer */ 183 unsigned char *buffer, *curptr; 184 unsigned long buflen, len; 185 bool realloc; 186 187 /* private methods */ 188 char* printlstring(unsigned char *&curptr, bool sign = false, int level = XMIINS_REPORT_CONTENTS); 189 void printslist(unsigned char *&curptr, bool sign = false, char ***array = NULL, int *numstrings = NULL, bool extendlist = false); 190 191 int guessGPC(Input *input, char *&gpc, char &gpctype, unsigned char &idx); 192 193 int readGlobalHeader(); 194 int readRunHeader(); 195 196 int readSmallGlobalBlock(); 197 int readLargeGlobalBlock(); 198 199 int readContainerInfo(); 200 int readSmallContainerBlock(); 201 int readLargeContainerBlock(); 202 int inspectContainerBlock(int block, int container, bool issmall = false); 203 int processContainerData(int block, int container, int size, int type, int subnum, int eindex, int *count); 204 205 int buildExprInfo(ExprInfo *info, char *expr, ExprInfo **infos, int *numsubsused, 206 int *charsused = NULL, int *numcont = NULL, bool overlayed = false); 207 int buildExprInfo(char **exprs, int numexprs); 208 int matchEnumIndexes(); 209 210 int numReferringBlocks(int pathexprnum); 211 int numPrecedingBlocks(int blocknum, int pathexprnum); 212 213 int endThisRun(); 214 int endReport(Input *input); 215 216 void newBuffer(long size); 217 218 public: 219 /* (de)constructors */ 220 XMIInspect(int level); 221 ~XMIInspect(); 222 223 /* internal data reset */ 224 void reset(); 225 226 /* main method */ 227 int inspectFile(char *xmifile); 228 }; 229