Version 6.3
Copyright © 2005 - 2012 Lowell D. Thomas
APG
  … ABNF Parser Generator
All Data Structures Files Functions Variables Typedefs Macros Pages
TortureTestTranslator.c
Go to the documentation of this file.
1 /*******************************************************************************
2  APG Version 6.3
3  Copyright (C) 2005 - 2012 Lowell D. Thomas, all rights reserved
4 
5  author: Lowell D. Thomas
6  email: lowell@coasttocoastresearch.com
7  website: http://www.coasttocoastresearch.com
8 
9  This program is free software: you can redistribute it and/or modify
10  it under the terms of the GNU General Public License as published by
11  the Free Software Foundation, either version 2 of the License, or
12  (at your option) any later version.
13 
14  This program is distributed in the hope that it will be useful,
15  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  GNU General Public License for more details.
18 
19  You should have received a copy of the GNU General Public License
20  along with this program. If not, see
21  <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>
22  or write to the Free Software Foundation, Inc.,
23  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 *******************************************************************************/
25 #include "main.h"
29 typedef unsigned char uchar;
32 static apg_uint uiLongLines(void* vpMemCtx, BSTR* spMsg, void* vpTransCtx);
33 static apg_uint uiBinaryCharacters(void* vpMemctx, BSTR* spMsg, void* vpTransCtx);
34 static apg_uint uiRepeatingStrings(void* vpMemCtx, BSTR* spMsg, void* vpTransCtx);
35 
36 static char* g_cpLineEnd = "\n";
37 // quick convert from hex digit to integer
38 // quick character validation
39 static uchar ucaHexToInt[256] =
40 {
41  255,255,255,255,255,255,255,255,255,255, // 0
42  255,255,255,255,255,255,255,255,255,255, // 10
43  255,255,255,255,255,255,255,255,255,255, // 20
44  255,255,255,255,255,255,255,255,255,255, // 30
45  255,255,255,255,255,255,255,255, 0, 1, // 40
46  2, 3, 4, 5, 6, 7, 8, 9,255,255, // 50
47  255,255,255,255,255, 10, 11, 12, 13, 14, // 60
48  15,255,255,255,255,255,255,255,255,255, // 70
49  255,255,255,255,255,255,255,255,255,255, // 80
50  255,255,255,255,255,255,255, 10, 11, 12, // 90
51  13, 14, 15,255,255,255,255,255,255,255, // 100
52  255,255,255,255,255,255,255,255,255,255, // 110
53  255,255,255,255,255,255,255,255,255,255, // 120
54  255,255,255,255,255,255,255,255,255,255, // 130
55  255,255,255,255,255,255,255,255,255,255, // 140
56  255,255,255,255,255,255,255,255,255,255, // 150
57  255,255,255,255,255,255,255,255,255,255, // 160
58  255,255,255,255,255,255,255,255,255,255, // 170
59  255,255,255,255,255,255,255,255,255,255, // 180
60  255,255,255,255,255,255,255,255,255,255, // 190
61  255,255,255,255,255,255,255,255,255,255, // 200
62  255,255,255,255,255,255,255,255,255,255, // 210
63  255,255,255,255,255,255,255,255,255,255, // 220
64  255,255,255,255,255,255,255,255,255,255, // 230
65  255,255,255,255,255,255,255,255,255,255, // 240
66  255,255,255,255,255,255 // 250
67 };
68 
90 apg_uint uiTortureTestTranslator(void* vpMemCtx, const char* cpInput, void* vpVecMsgsBinary){
91  apg_uint uiReturn = 0;
92  BSTR sSrc;
93  apg_achar* acpOutput;
94  BSTR sTemp;
95  apg_uint uiTest;
96  void* vpMsgsInCtx = NULL;
97  void* vpMsgsOutCtx = NULL;
98  void* vpTransOneCtx = NULL;
99  void* vpTransTwoCtx = NULL;
100  apg_uint uiBytes;
101  apg_uint uiCheckPoint;
102 
103  // validate input
104  MASSERT(vpVecMsgsBinary);
105  MASSERT(uiVecValidate(vpVecMsgsBinary));
106  MASSERT(cpInput);
107  MASSERT(cpInput[0] != 0);
108  uiTest = uiMemValidate(vpMemCtx);
109  MASSERT(uiTest);
110  uiCheckPoint = uiMemCheckPoint(vpMemCtx);
111 
112  // get the list of messages
113  sSrc.uiLength = uiGetFileSize(cpInput);
114  MASSERT(sSrc.uiLength);
115  sSrc.cpStr = (char*)vpMemAlloc(vpMemCtx, sSrc.uiLength + 10);
116  MASSERT(sSrc.cpStr);
117  sSrc.uiLength = uiGetFile(cpInput, (void*)sSrc.cpStr);
118  MASSERT(sSrc.uiLength);
119  sSrc.cpStr[sSrc.uiLength] = 0;
120 
121  // get a vector contexts
122  vpMsgsInCtx = vpVecCtor(vpMemCtx, sizeof(BSTR), 0);
123  MASSERT(vpMsgsInCtx);
124  vpMsgsOutCtx = vpVecCtor(vpMemCtx, sizeof(BSTR), 0);
125  MASSERT(vpMsgsOutCtx);
126  vpTransOneCtx = vpVecCtor(vpMemCtx, sizeof(uchar), 0);
127  MASSERT(vpTransOneCtx);
128  vpTransTwoCtx = vpVecCtor(vpMemCtx, sizeof(uchar), 0);
129  MASSERT(vpTransTwoCtx);
130 
131  // translate the long lines
132  uiBytes = uiLongLines(vpMemCtx, &sSrc, vpTransOneCtx);
133  MASSERT(uiBytes);
134 
135  // translate the long repeating strings
136  sTemp.cpStr = (char*)vpVecFront(vpTransOneCtx);
137  MASSERT(sTemp.cpStr);
138  sTemp.uiLength = uiVecSize(vpTransOneCtx);
139  uiBytes = uiRepeatingStrings(vpMemCtx, &sTemp, vpTransTwoCtx);
140  MASSERT(uiBytes);
141 
142  // translate the non-printing characters
143  sTemp.cpStr = (char*)vpVecFront(vpTransTwoCtx);
144  MASSERT(sTemp.cpStr);
145  sTemp.uiLength = uiVecSize(vpTransTwoCtx);
146  vVecClear(vpTransOneCtx);
147  uiBytes = uiBinaryCharacters(vpMemCtx, &sTemp, vpTransOneCtx);
148  MASSERT(uiBytes);
149 
150  // convert the output string to alphabet characters (apg_achar)
151  sTemp.cpStr = vpVecFront(vpTransOneCtx);
152  sTemp.uiLength = uiVecSize(vpTransOneCtx);
153  vVecClear(vpVecMsgsBinary);
154  acpOutput = (apg_achar*)vpVecPushn(vpVecMsgsBinary, NULL, sTemp.uiLength);
155  MASSERT(acpOutput);
156  vCharToAChar(acpOutput, sTemp.cpStr, sTemp.uiLength);
157 
158  // success
159  vMemFreeToCheckPoint(vpMemCtx, uiCheckPoint);
160  uiReturn = APG_TRUE;
161  return uiReturn;
162 }
163 
165 // DESCRIPTION: Search for tagged long lines and replace them as directed.
166 //
167 // FUNCTION: static apg_uint uiLongLines
168 //
169 // ARG: 1) BSTR* spMsg
170 // : binary string defining a SIP message
171 //
172 // ARG: 2) void* vpTransCtx
173 // : vector component context for the output file
174 //
175 // RETURN: true on success
176 //
178 static apg_uint uiLongLines(void* vpMemCtx, BSTR* spMsg, void* vpTransCtx)
179 {
180  apg_uint uiReturn = APG_FALSE;
181  apg_uint uiPrefixLen;
182  char* cpPrefixEnd;
183  char* cpPhrasePrev;
184  char* cpPhraseNext;
185  char* cpPhraseEnd;
186  char* cpLineBeg;
187  char* cpLineEnd;
188  void* vpTest;
189  char cSave;
190  static char* cpStartTag = "<allOneLine>\n";
191  static char* cpEndTag = "</allOneLine>\n";
192  apg_uint uiStartTagLen = strlen(cpStartTag);
193  apg_uint uiEndTagLen = strlen(cpEndTag);
194 
195  // single-point-of-exit loop
196  cpPhrasePrev = (char*)spMsg->cpStr;
197  cpPrefixEnd = cpPhrasePrev + spMsg->uiLength;
198  while(APG_TRUE)
199  {
200  // find the next long line
201  cpPhraseNext = strstr(cpPhrasePrev, cpStartTag);
202  if(!cpPhraseNext){break;}
203  cpPhraseEnd = strstr(cpPhraseNext, cpEndTag);
204  MASSERT(cpPhraseEnd);
205 
206  // output the prefix, if any
207  uiPrefixLen = (apg_uint)(cpPhraseNext - cpPhrasePrev);
208  if(uiPrefixLen)
209  {
210  vpTest = vpVecPushn(vpTransCtx, (void*)cpPhrasePrev, uiPrefixLen);
211  MASSERT(vpTest);
212  }
213 
214  // remove the extra CRLFs
215  cSave = *cpPhraseEnd;
216  *cpPhraseEnd = 0;
217  cpPhraseNext += uiStartTagLen;
218  cpLineBeg = cpPhraseNext;
219  while(APG_TRUE)
220  {
221  cpLineEnd = strstr(cpLineBeg, g_cpLineEnd);
222  if(!cpLineEnd){break;}
223  uiPrefixLen = (apg_uint)(cpLineEnd - cpLineBeg);
224  if(uiPrefixLen)
225  {
226  vpTest = vpVecPushn(vpTransCtx, (void*)cpLineBeg, uiPrefixLen);
227  MASSERT(vpTest);
228  }
229 
230  cpLineBeg = cpLineEnd + strlen(g_cpLineEnd);
231  } // end of single-point-of-exit loop
232  *cpPhraseEnd = cSave;
233 
234  // output a line end
235  vpTest = vpVecPushn(vpTransCtx, (void*)g_cpLineEnd, strlen(g_cpLineEnd));
236  MASSERT(vpTest);
237 
238  // set up for next phrase
239  cpPhrasePrev = cpPhraseEnd + uiEndTagLen;
240  } // end of single-point-of-exit loop
241 
242  // output the tail
243  uiPrefixLen = (apg_uint)(cpPrefixEnd - cpPhrasePrev);
244  if(uiPrefixLen)
245  {
246  vpTest = vpVecPushn(vpTransCtx, (void*)cpPhrasePrev, uiPrefixLen);
247  MASSERT(vpTest);
248  }
249 
250  // success
251  uiReturn = APG_TRUE;
252  return uiReturn;
253 }
254 
256 // DESCRIPTION: Search for tagged repeating strings and replace as directed.
257 //
258 // FUNCTION: static apg_uint uiRepeatingStrings
259 //
260 // ARG: 1) BSTR* spMsg
261 // : binary string defining a SIP message
262 //
263 // ARG: 2) void* vpTransCtx
264 // : vector component context for the output file
265 //
266 // RETURN: true on success
267 //
269 static apg_uint uiRepeatingStrings(void* vpMemCtx, BSTR* spMsg, void* vpTransCtx)
270 {
271  apg_uint uiReturn = APG_FALSE;
272  apg_uint uiPrefixLen;
273  char* cpPrefixEnd;
274  char* cpPhrasePrev;
275  char* cpPhraseNext;
276  char* cpPhraseEnd;
277  void* vpTest;
278  char cSave;
279  apg_uint uiCount;
280  apg_uint uiIndex;
281  char* cpRepeat;
282  static char* cpStartTag = "<repeat count=";
283  static char* cpEndTag = "</repeat>";
284  apg_uint uiStartTagLen = strlen(cpStartTag);
285  apg_uint uiEndTagLen = strlen(cpEndTag);
286 
287  // single-point-of-exit loop
288  cpPhrasePrev = (char*)spMsg->cpStr;
289  cpPrefixEnd = cpPhrasePrev + spMsg->uiLength;
290  while(APG_TRUE)
291  {
292  // find the next long line
293  cpPhraseNext = strstr(cpPhrasePrev, cpStartTag);
294  if(!cpPhraseNext){break;}
295  cpPhraseEnd = strstr(cpPhraseNext, cpEndTag);
296  MASSERT(cpPhraseEnd);
297 
298  // output the prefix, if any
299  uiPrefixLen = (apg_uint)(cpPhraseNext - cpPhrasePrev);
300  if(uiPrefixLen)
301  {
302  vpTest = vpVecPushn(vpTransCtx, (void*)cpPhrasePrev, uiPrefixLen);
303  MASSERT(vpTest);
304  }
305 
306  // find the count
307  cpRepeat = strstr(cpPhraseNext, ">");
308  MASSERT(cpRepeat);
309  cSave = *cpRepeat;
310  *cpRepeat = 0;
311  uiCount = (apg_uint)atol(cpPhraseNext + uiStartTagLen);
312  *cpRepeat = cSave;
313 
314  // find the repeat string
315  ++cpRepeat;
316 
317  // write the repeated string
318  cSave = *cpPhraseEnd;
319  *cpPhraseEnd = 0;
320  uiPrefixLen = (apg_uint)strlen(cpRepeat);
321  for(uiIndex = 0; uiIndex < uiCount; ++uiIndex)
322  {
323  vpTest = vpVecPushn(vpTransCtx, (void*)cpRepeat, uiPrefixLen);
324  MASSERT(vpTest);
325  }
326  *cpPhraseEnd = cSave;
327 
328  // set up for next phrase
329  cpPhrasePrev = cpPhraseEnd + uiEndTagLen;
330  } // end of single-point-of-exit loop
331 
332  // output the tail
333  uiPrefixLen = (apg_uint)(cpPrefixEnd - cpPhrasePrev);
334  if(uiPrefixLen)
335  {
336  vpTest = vpVecPushn(vpTransCtx, (void*)cpPhrasePrev, uiPrefixLen);
337  MASSERT(vpTest);
338  }
339 
340  // success
341  uiReturn = APG_TRUE;
342  return uiReturn;
343 }
344 
346 // DESCRIPTION: Search for tagged binary characters and replace as directed.
347 //
348 // FUNCTION: static apg_uint uiBinaryCharacters
349 //
350 // ARG: 1) BSTR* spMsg
351 // : binary string defining a SIP message
352 //
353 // ARG: 2) void* vpTransCtx
354 // : vector component context for the output file
355 //
356 // RETURN: true on success
357 //
359 static apg_uint uiBinaryCharacters(void* vpMemCtx, BSTR* spMsg, void* vpTransCtx)
360 {
361  apg_uint uiReturn = APG_FALSE;
362  apg_uint uiPrefixLen;
363  char* cpPrefixEnd;
364  char* cpPhrasePrev;
365  char* cpPhraseNext;
366  char* cpPhraseEnd;
367  void* vpTest;
368  static char* cpStartTag = "<hex>";
369  static char* cpEndTag = "</hex>";
370  apg_uint uiStartTagLen = strlen(cpStartTag);
371  apg_uint uiEndTagLen = strlen(cpEndTag);
372 
373  // single-point-of-exit loop
374  cpPhrasePrev = (char*)spMsg->cpStr;
375  cpPrefixEnd = cpPhrasePrev + spMsg->uiLength;
376  while(APG_TRUE)
377  {
378  // find the next binary phrase
379  cpPhraseNext = strstr(cpPhrasePrev, cpStartTag);
380  if(!cpPhraseNext){break;}
381  cpPhraseEnd = strstr(cpPhraseNext, cpEndTag);
382  MASSERT(cpPhraseEnd);
383 
384  // output the prefix, if any
385  uiPrefixLen = (apg_uint)(cpPhraseNext - cpPhrasePrev);
386  if(uiPrefixLen)
387  {
388  vpTest = vpVecPushn(vpTransCtx, (void*)cpPhrasePrev, uiPrefixLen);
389  MASSERT(vpTest);
390  }
391 
392  // translate all hex characters
393  cpPhraseNext += uiStartTagLen;
394  while(APG_TRUE)
395  {
396  uchar ucBinary;
397  uchar ucDigit1;
398  uchar ucDigit2;
399 
400  if(cpPhraseNext == cpPhraseEnd){break;}
401  if(*cpPhraseNext == CR || *cpPhraseNext == LF)
402  {
403  // skip line enders
404  ++cpPhraseNext;
405  continue;
406  }
407 
408  // convert digit one
409  ucDigit1 = ucaHexToInt[(uchar)*cpPhraseNext];
410  MASSERT(ucDigit1 != 255);
411 
412  // convert digit two
413  ++cpPhraseNext;
414  MASSERT(cpPhraseNext < cpPhraseEnd);
415  ucDigit2 = ucaHexToInt[(uchar)*cpPhraseNext];
416  MASSERT(ucDigit2 != 255);
417 
418  // write the binary value
419  ucBinary = (ucDigit1 << 4) + ucDigit2;
420  vpTest = vpVecPush(vpTransCtx, (void*)&ucBinary);
421  MASSERT(vpTest);
422 
423  ++cpPhraseNext;
424  } // end of single-point-of-exit loop
425 
426  // set up for next phrase
427  cpPhrasePrev = cpPhraseEnd + uiEndTagLen;
428  } // end of single-point-of-exit loop
429 
430  // output the tail
431  uiPrefixLen = (apg_uint)(cpPrefixEnd - cpPhrasePrev);
432  if(uiPrefixLen)
433  {
434  vpTest = vpVecPushn(vpTransCtx, (void*)cpPhrasePrev, uiPrefixLen);
435  MASSERT(vpTest);
436  }
437 
438  // success
439  uiReturn = APG_TRUE;
440  return uiReturn;
441 }
vpVecFront
void * vpVecFront(void *vpCtx)
Definition: Vector.c:396
vVecClear
void vVecClear(void *vpCtx)
Definition: Vector.c:218
uiVecSize
apg_uint uiVecSize(void *vpCtx)
Definition: Vector.c:167
vpVecCtor
void * vpVecCtor(void *vpMemCtx, apg_uint uiElementSize, apg_uint uiInitialAlloc)
Definition: Vector.c:81
apg_uint
unsigned int apg_uint
Definition: Apg.h:169
vpMemAlloc
void * vpMemAlloc(void *vpCtx, apg_uint uiBytes)
Definition: Memory.c:130
uiGetFileSize
apg_uint uiGetFileSize(const char *cpFileName)
Definition: Files.c:40
vpVecPush
void * vpVecPush(void *vpVec, void *vpElement)
Definition: Vector.c:238
APG_TRUE
#define APG_TRUE
Definition: Apg.h:187
MASSERT
#define MASSERT(cond, msg)
Definition: main.cpp:33
apg_achar
unsigned char apg_achar
Definition: Apg.h:183
uiTortureTestTranslator
apg_uint uiTortureTestTranslator(void *vpMemCtx, const char *cpInput, void *vpVecMsgsBinary)
Definition: TortureTestTranslator.c:90
vMemFreeToCheckPoint
void vMemFreeToCheckPoint(void *vpCtx, apg_uint uiChk)
Definition: Memory.c:250
APG_FALSE
#define APG_FALSE
Definition: Apg.h:190
uiGetFile
apg_uint uiGetFile(const char *cpFileName, void *vpBuffer)
Definition: Files.c:71
vpVecPushn
void * vpVecPushn(void *vpCtx, void *vpElement, apg_uint uiCount)
Definition: Vector.c:276
vCharToAChar
void vCharToAChar(apg_achar *acpAChars, const char *cpChars, apg_uint uiLen)
Definition: Tools.c:79
uiMemCheckPoint
apg_uint uiMemCheckPoint(void *vpCtx)
Definition: Memory.c:230
uiVecValidate
apg_uint uiVecValidate(void *vpCtx)
Definition: Vector.c:142
uiMemValidate
apg_uint uiMemValidate(void *vpCtx)
Definition: Memory.c:115
This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/licenses.html or write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.