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