Version 7.0
Copyright © 2021 Lowell D. Thomas
APG
… an ABNF Parser Generator
main.c
Go to the documentation of this file.
1 /* *************************************************************************************
2  Copyright (c) 2021, Lowell D. Thomas
3  All rights reserved.
4 
5  This file is part of APG Version 7.0.
6  APG Version 7.0 may be used under the terms of the BSD 2-Clause License.
7 
8  Redistribution and use in source and binary forms, with or without
9  modification, are permitted provided that the following conditions are met:
10 
11  1. Redistributions of source code must retain the above copyright notice, this
12  list of conditions and the following disclaimer.
13 
14  2. Redistributions in binary form must reproduce the above copyright notice,
15  this list of conditions and the following disclaimer in the documentation
16  and/or other materials provided with the distribution.
17 
18  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21  DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22  FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26  OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 * *************************************************************************************/
75 #include <limits.h>
76 #include "../../utilities/utilities.h"
77 
78 #include "source.h"
79 
80 static const char* cpMakeFileName(char* cpBuffer, const char* cpBase, const char* cpDivider, const char* cpName){
81  strcpy(cpBuffer, cpBase);
82  strcat(cpBuffer, cpDivider);
83  strcat(cpBuffer, cpName);
84  return cpBuffer;
85 }
86 
87 static char s_caBuf[5*PATH_MAX];
88 
89 static char* s_cpDescription =
90  "Illustrate the construction and use of the data conversion utility object.";
91 
92 static char* s_cppCases[] = {
93  "Display application information.",
94  "Compare the conversion object results with the Linux iconv command-line application.",
95  "Get the raw, 32-bit decoded data.",
96  "Encode raw, 32-bit data.",
97  "Add base64 encoding and decoding.",
98 };
99 static long int s_iCaseCount = (long int)(sizeof(s_cppCases) / sizeof(s_cppCases[0]));
100 
101 static int iHelp(void){
102  long int i = 0;
104  printf("description: %s\n", s_cpDescription);
105  printf(" usage: ex-api arg\n");
106  printf(" arg = n, 1 <= n <= %ld\n", s_iCaseCount);
107  printf(" execute case number n\n");
108  printf(" arg = anthing else\n");
109  printf(" print this help screen\n");
110  printf("\n");
111  for(; i < s_iCaseCount; i++){
112  printf("case %ld %s\n", (i + 1), s_cppCases[i]);
113  }
114  return EXIT_SUCCESS;
115 }
116 
117 static int iApp() {
118  // print the current working directory
120  printf("\n");
121 
122  // display the current APG sizes and macros
123  vUtilApgInfo();
124  return EXIT_SUCCESS;
125 }
126 
127 typedef struct{
128  const char* cpName;
129  uint8_t* ucpData;
132 } conv_file;
133 static int iConv() {
134  int iReturn = EXIT_SUCCESS;
135  static void* vpMem = NULL;
136  static void* vpConv = NULL;
137  char caBuf[1024];
138  aint uiFileSize = 1024;
139  conv_file saFiles[] = {
140  { cpMakeFileName(s_caBuf, SOURCE_DIR, "/../input/", "data8"), NULL, 0, UTF_8},
141  { cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR, "/../input/", "data16le"), NULL, 0, UTF_16LE},
142  { cpMakeFileName(&s_caBuf[2*PATH_MAX], SOURCE_DIR, "/../input/", "data16be"), NULL, 0, UTF_16BE},
143  { cpMakeFileName(&s_caBuf[3*PATH_MAX], SOURCE_DIR, "/../input/", "data32le"), NULL, 0, UTF_32LE},
144  };
145  conv_file* spFileIn, *spFileOut;
146  aint uiFileCount = (aint)(sizeof(saFiles) / sizeof(saFiles[0]));
147  aint ui, uj;
148  conv_src sSrc;
149  conv_dst sDst;
150  exception e;
151  XCTOR(e);
152  if(e.try){
153  // try block
154  vpMem = vpMemCtor(&e);
155  vpConv = vpConvCtor(&e);
156 
157  // get the Linux iconv data
158  char* cpHeader =
159  "The Linux command \"iconv\" has been used to convert a simple array of data spanning\n"
160  "the full range of Unicode characters. The files and formats are:\n"
161  " - UTF-8, data8\n"
162  " - UTF-16LE, data16le\n"
163  " - UTF-16BE, data16be\n"
164  " - UTF-32LE, data32le\n"
165  " - UTF-32BE, data32be\n"
166  "\n"
167  "This example case uses the utilities conv object to do all possible conversions\n"
168  "and compare the converted data to the Linux file data.\n\n";
169  printf("\n%s", cpHeader);
170  for(ui = 0; ui < uiFileCount; ui++){
171  spFileIn = &saFiles[ui];
172  spFileIn->ucpData = vpMemAlloc(vpMem, uiFileSize);
173  spFileIn->uiBytes = uiFileSize;
174  vUtilFileRead(vpMem, spFileIn->cpName, spFileIn->ucpData, &spFileIn->uiBytes);
175  if(spFileIn->uiBytes > uiFileSize){
176  snprintf(caBuf, uiFileSize, "buffer not big enough for input file %s", spFileIn->cpName);
177  XTHROW(&e, caBuf);
178  }
179  }
180 
181  // make all possible conversions and compare result with Linux iconv data
182  printf("Make all possible comparisons doing the encoding and decoding steps separately.\n");
183  for(ui = 0; ui < uiFileCount; ui++){
184  spFileIn = &saFiles[ui];
185  sSrc.ucpData = spFileIn->ucpData;
186  sSrc.uiDataLen = spFileIn->uiBytes;
187  sSrc.uiDataType = spFileIn->uiFormat;
188  vConvDecode(vpConv, &sSrc);
189  for(uj = 0; uj < uiFileCount; uj++){
190  spFileOut = &saFiles[uj];
191  memset(&sDst, 0, sizeof(sDst));
192  sDst.uiDataType = spFileOut->uiFormat;
193  vConvEncode(vpConv, &sDst);
194  if(sDst.uiDataLen != spFileOut->uiBytes){
195  snprintf(caBuf, uiFileSize, "source (%s), destination (%s) conversion lengths not the same",
196  cpUtilUtfTypeName(spFileIn->uiFormat), cpUtilUtfTypeName(spFileOut->uiFormat));
197  XTHROW(&e, caBuf);
198  }
199  if(memcmp(sDst.ucpData, spFileOut->ucpData, spFileOut->uiBytes) != 0){
200  snprintf(caBuf, uiFileSize, "source (%s), destination (%s) conversion comparison failed",
201  cpUtilUtfTypeName(spFileIn->uiFormat), cpUtilUtfTypeName(spFileOut->uiFormat));
202  XTHROW(&e, caBuf);
203  }
204  printf("conversion (%s) -> (%s) successful\n",
205  cpUtilUtfTypeName(spFileIn->uiFormat), cpUtilUtfTypeName(spFileOut->uiFormat));
206  }
207  }
208 
209  printf("\nMake all possible comparisons encoding and decoding in a single step.\n");
210  for(ui = 0; ui < uiFileCount; ui++){
211  spFileIn = &saFiles[ui];
212  sSrc.ucpData = spFileIn->ucpData;
213  sSrc.uiDataLen = spFileIn->uiBytes;
214  sSrc.uiDataType = spFileIn->uiFormat;
215  for(uj = 0; uj < uiFileCount; uj++){
216  spFileOut = &saFiles[uj];
217  memset(&sDst, 0, sizeof(sDst));
218  sDst.uiDataType = spFileOut->uiFormat;
219  vConvConvert(vpConv, &sSrc, &sDst);
220  if(sDst.uiDataLen != spFileOut->uiBytes){
221  snprintf(caBuf, uiFileSize, "source (%s), destination (%s) conversion lengths not the same",
222  cpUtilUtfTypeName(spFileIn->uiFormat), cpUtilUtfTypeName(spFileOut->uiFormat));
223  XTHROW(&e, caBuf);
224  }
225  if(memcmp(sDst.ucpData, spFileOut->ucpData, spFileOut->uiBytes) != 0){
226  snprintf(caBuf, uiFileSize, "source (%s), destination (%s) conversion comparison failed",
227  cpUtilUtfTypeName(spFileIn->uiFormat), cpUtilUtfTypeName(spFileOut->uiFormat));
228  XTHROW(&e, caBuf);
229  }
230  printf("conversion (%s) -> (%s) successful\n",
231  cpUtilUtfTypeName(spFileIn->uiFormat), cpUtilUtfTypeName(spFileOut->uiFormat));
232  }
233  }
234 
235  }else{
236  // catch block - display the exception location and message
238  iReturn = EXIT_FAILURE;
239  }
240 
241  // clean up resources
242  vConvDtor(vpConv);
243  vMemDtor(vpMem);
244  return iReturn;
245 }
246 
247 static int iGet() {
248  int iReturn = EXIT_SUCCESS;
249  static void* vpMem = NULL;
250  static void* vpConv = NULL;
251  char caBuf[1024];
252  aint uiFileSize = 1024;
253  uint32_t uiaGetCodePoints[1024];
254  uint32_t uiLength;
255  uint32_t* uipCodePoints = &uiaGetCodePoints[0];
256  conv_file saFiles[] = {
257  { cpMakeFileName(s_caBuf, SOURCE_DIR, "/../input/", "data8"), NULL, 0, UTF_8},
258  { cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR, "/../input/", "data16le"), NULL, 0, UTF_16LE},
259  { cpMakeFileName(&s_caBuf[2*PATH_MAX], SOURCE_DIR, "/../input/", "data16be"), NULL, 0, UTF_16BE},
260  { cpMakeFileName(&s_caBuf[3*PATH_MAX], SOURCE_DIR, "/../input/", "data32le"), NULL, 0, UTF_32LE},
261  };
262  conv_file* spFileIn;
263  aint uiFileCount = (aint)(sizeof(saFiles) / sizeof(saFiles[0]));
264  aint ui;
265  uint32_t uiaOriginalData[] = {
266  0, 126, 127, 128, 0xff, 0x1ff, 0x1fff, 0xd7ff, 0xe000, 0xffff, 0x10ffff
267  };
268  aint uiOriginalLength = (aint)(sizeof(uiaOriginalData) / sizeof(uiaOriginalData[0]));
269  conv_src sSrc;
270  exception e;
271  XCTOR(e);
272  if(e.try){
273  // try block
274  vpMem = vpMemCtor(&e);
275  vpConv = vpConvCtor(&e);
276 
277  // get the Linux iconv data
278  char* cpHeader =
279  "The Linux command \"iconv\" has been used to convert a simple array of data spanning\n"
280  "the full range of Unicode characters. The files and formats are:\n"
281  " - UTF-8, data8\n"
282  " - UTF-16LE, data16le\n"
283  " - UTF-16BE, data16be\n"
284  " - UTF-32LE, data32le\n"
285  " - UTF-32BE, data32be\n"
286  "\n"
287  "This example case uses the utilities conv object to decode the files and compare the\n"
288  "decoded data to the original data used to create the files.\n\n";
289  printf("\n%s", cpHeader);
290  printf("Original Code Points\n");
291  for(ui = 0; ui < uiOriginalLength; ui++){
292  printf("0x%06X ", uiaOriginalData[ui]);
293  }
294  printf("\n");
295 
296  for(ui = 0; ui < uiFileCount; ui++){
297  spFileIn = &saFiles[ui];
298  spFileIn->ucpData = vpMemAlloc(vpMem, uiFileSize);
299  spFileIn->uiBytes = uiFileSize;
300  vUtilFileRead(vpMem, spFileIn->cpName, spFileIn->ucpData, &spFileIn->uiBytes);
301  if(spFileIn->uiBytes > uiFileSize){
302  snprintf(caBuf, uiFileSize, "buffer not big enough for input file %s", spFileIn->cpName);
303  XTHROW(&e, caBuf);
304  }
305  }
306 
307  // make all possible conversions and compare result with Linux iconv data
308  printf("\nDecode all files, get decoded code points and compare to original.\n");
309  for(ui = 0; ui < uiFileCount; ui++){
310  spFileIn = &saFiles[ui];
311  sSrc.ucpData = spFileIn->ucpData;
312  sSrc.uiDataLen = spFileIn->uiBytes;
313  sSrc.uiDataType = spFileIn->uiFormat;
314  vConvDecode(vpConv, &sSrc);
315  uiLength = uiFileSize;
316  vConvGetCodePoints(vpConv, uipCodePoints, &uiLength);
317  if(uiLength > (uint32_t)uiFileSize){
318  XTHROW(&e, "Code point buffer too small for converted data.");
319  }
320  if(uiLength != uiOriginalLength){
321  snprintf(caBuf, uiFileSize, "source (%s), converted code points length incorrect",
322  spFileIn->cpName);
323  XTHROW(&e, caBuf);
324  }
325  if(memcmp(uipCodePoints, uiaOriginalData, (uiLength * sizeof(*uipCodePoints))) != 0){
326  snprintf(caBuf, uiFileSize, "source (%s), conversion failed",
327  spFileIn->cpName);
328  XTHROW(&e, caBuf);
329  }
330  printf("conversion (%s) successful\n",
331  spFileIn->cpName);
332  }
333 
334 
335  }else{
336  // catch block - display the exception location and message
338  iReturn = EXIT_FAILURE;
339  }
340 
341  // clean up resources
342  vConvDtor(vpConv);
343  vMemDtor(vpMem);
344  return iReturn;
345 }
346 static int iUse() {
347  int iReturn = EXIT_SUCCESS;
348  static void* vpMem = NULL;
349  static void* vpConv = NULL;
350  static void* vpFmt = NULL;
351  char caBuf[1024];
352  aint uiFileSize = 1024;
353  conv_file saFiles[] = {
354  { cpMakeFileName(s_caBuf, SOURCE_DIR, "/../input/", "data8"), NULL, 0, UTF_8},
355  { cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR, "/../input/", "data16le"), NULL, 0, UTF_16LE},
356  { cpMakeFileName(&s_caBuf[2*PATH_MAX], SOURCE_DIR, "/../input/", "data16be"), NULL, 0, UTF_16BE},
357  { cpMakeFileName(&s_caBuf[3*PATH_MAX], SOURCE_DIR, "/../input/", "data32le"), NULL, 0, UTF_32LE},
358  };
359  conv_file* spFileIn;
360  aint uiFileCount = (aint)(sizeof(saFiles) / sizeof(saFiles[0]));
361  aint ui;
362  uint32_t uiaOriginalData[] = {
363  0, 126, 127, 128, 0xff, 0x1ff, 0x1fff, 0xd7ff, 0xe000, 0xffff, 0x10ffff
364  };
365  aint uiOriginalLength = (aint)(sizeof(uiaOriginalData) / sizeof(uiaOriginalData[0]));
366  conv_dst sDst;
367  exception e;
368  XCTOR(e);
369  if(e.try){
370  // try block
371  vpMem = vpMemCtor(&e);
372  vpConv = vpConvCtor(&e);
373  vpFmt = vpFmtCtor(&e);
374 
375  // get the Linux iconv data
376  char* cpHeader =
377  "The Linux command \"iconv\" has been used to convert a simple array of data spanning\n"
378  "the full range of Unicode characters. The files and formats are:\n"
379  " - UTF-8, data8\n"
380  " - UTF-16LE, data16le\n"
381  " - UTF-16BE, data16be\n"
382  " - UTF-32LE, data32le\n"
383  " - UTF-32BE, data32be\n"
384  "\n"
385  "This example case uses the utilities conv object endocde the original data\n"
386  "and compare the results to the files.\n\n";
387  printf("\n%s", cpHeader);
388  printf("Original Code Points\n");
389  for(ui = 0; ui < uiOriginalLength; ui++){
390  printf("0x%06X ", uiaOriginalData[ui]);
391  }
392  printf("\n");
393 
394  // read the files into memory
395  for(ui = 0; ui < uiFileCount; ui++){
396  spFileIn = &saFiles[ui];
397  spFileIn->ucpData = vpMemAlloc(vpMem, uiFileSize);
398  spFileIn->uiBytes = uiFileSize;
399  vUtilFileRead(vpMem, spFileIn->cpName, spFileIn->ucpData, &spFileIn->uiBytes);
400  if(spFileIn->uiBytes > uiFileSize){
401  snprintf(caBuf, uiFileSize, "buffer not big enough for input file %s", spFileIn->cpName);
402  XTHROW(&e, caBuf);
403  }
404  }
405 
406  // encode the original data to all formats and compare the results with Linux iconv data
407  printf("\nCompare encoded original data to Linux iconv files.\n");
408  for(ui = 0; ui < uiFileCount; ui++){
409  spFileIn = &saFiles[ui];
410  memset(&sDst, 0, sizeof(sDst));
411  sDst.uiDataType = spFileIn->uiFormat;
412  vConvUseCodePoints(vpConv, uiaOriginalData, uiOriginalLength);
413  vConvEncode(vpConv, &sDst);
414  if(sDst.uiDataLen != spFileIn->uiBytes){
415  snprintf(caBuf, uiFileSize, "%s conversion lengths not the same", spFileIn->cpName);
416  XTHROW(&e, caBuf);
417  }
418  if(memcmp(sDst.ucpData, spFileIn->ucpData, spFileIn->uiBytes) != 0){
419  snprintf(caBuf, uiFileSize, "%s conversion data not the same", spFileIn->cpName);
420  XTHROW(&e, caBuf);
421  }
422  printf("%s encoding successful\n", spFileIn->cpName);
423  }
424 
425 
426  }else{
427  // catch block - display the exception location and message
429  iReturn = EXIT_FAILURE;
430  }
431 
432  // clean up resources
433  vFmtDtor(vpFmt);
434  vConvDtor(vpConv);
435  vMemDtor(vpMem);
436  return iReturn;
437 }
438 static void vRemoveLineEnds(uint8_t* ucpData, aint uiLen, uint8_t* ucpBuf, aint* uipBufLen){
439  // skip the validity checks
440  aint ui = 0;
441  aint uiLength = 0;
442  for(; ui < uiLen; ui++){
443  uint8_t ucChar = ucpData[ui];
444  if(ucChar == 9 || ucChar == 13){
445  continue;
446  }
447  ucpBuf[uiLength] = ucChar;
448  uiLength++;
449  }
450  *uipBufLen = uiLength;
451 }
452 static int iBase64() {
453  int iReturn = EXIT_SUCCESS;
454  static void* vpMem = NULL;
455  static void* vpConv = NULL;
456  static void* vpFmt = NULL;
457  char caBuf[1024];
458  aint uiBufSize = 1024;
459  uint8_t *ucpRand, *ucpRand64, *ucpRandBuf1, *ucpRandBuf2;
460  aint uiRandLen, uiRand64Len, uiBuf1Len, uiBuf2Len;
461  const char* cpRandFile = cpMakeFileName(&s_caBuf[0], SOURCE_DIR, "/../input/", "rand512");
462  const char* cpRand64File = cpMakeFileName(&s_caBuf[PATH_MAX], SOURCE_DIR, "/../input/", "rand512b64");
463  conv_src sSrc;
464  conv_dst sDst;
465  exception e;
466  XCTOR(e);
467  if(e.try){
468  // try block
469  vpMem = vpMemCtor(&e);
470  vpConv = vpConvCtor(&e);
471  vpFmt = vpFmtCtor(&e);
472 
473  // display the header
474  char* cpHeader =
475  "The Linux command \"base64\" has been used to convert a file of 512 random bytes\n"
476  "to base64 format. The files are \"rand512\" and \"rand512b64\", respectively.\n"
477  "\n"
478  "This example case uses the utilities conv object to do a base64 encoding of \"rand512\"\n"
479  "and compare to \"rand512b64\".\n"
480  "Note that the set of 256 8-bit bytes constitute ISO-8859-1 encoding.\n"
481  "ISO_8859_1, LATIN1 and BINARY are used by the conv object as aliases.\n\n";
482  printf("\n%s", cpHeader);
483 
484  // allocate all of the buffer space needed
485  ucpRand = (uint8_t*)vpMemAlloc(vpMem, uiBufSize);
486  ucpRand64 = (uint8_t*)vpMemAlloc(vpMem, uiBufSize);
487  ucpRandBuf1 = (uint8_t*)vpMemAlloc(vpMem, uiBufSize);
488  ucpRandBuf2 = (uint8_t*)vpMemAlloc(vpMem, uiBufSize);
489  uiRandLen = uiBufSize;
490 
491  // read the files
492  vUtilFileRead(vpMem, cpRandFile, ucpRand, &uiRandLen);
493  if(uiRandLen > uiBufSize){
494  snprintf(caBuf, uiBufSize, "buffer not big enough for input file %s", cpRandFile);
495  XTHROW(&e, caBuf);
496  }
497  uiRand64Len = uiBufSize;
498  vUtilFileRead(vpMem, cpRand64File, ucpRand64, &uiRand64Len);
499  if(uiRand64Len > uiBufSize){
500  snprintf(caBuf, uiBufSize, "buffer not big enough for input file %s", cpRand64File);
501  XTHROW(&e, caBuf);
502  }
503 
504  // base64 encode the file and compare
505  sSrc.ucpData = ucpRand;
506  sSrc.uiDataLen = uiRandLen;
507  sSrc.uiDataType = BINARY;
508  memset(&sDst, 0, sizeof(sDst));
509  sDst.uiDataType = BINARY | BASE64;
510  vConvConvert(vpConv, &sSrc, &sDst);
511  if(sDst.uiDataLen > uiBufSize){
512  XTHROW(&e, "buffer not big enough for input converted data");
513  }
514  vRemoveLineEnds(ucpRand64, uiRand64Len, ucpRandBuf1, &uiBuf1Len);
515  vRemoveLineEnds(sDst.ucpData, sDst.uiDataLen, ucpRandBuf2, &uiBuf2Len);
516  if(uiBuf1Len != uiBuf2Len){
517  XTHROW(&e, "converted data not correct length");
518  }
519  if(memcmp(ucpRandBuf1, ucpRandBuf2, uiBuf1Len) != 0){
520  XTHROW(&e, "converted data does not match file data");
521  }
522  printf("base64 conversion success\n");
523 
524  // configure the base64 output line length
525  printf("\nThe default base64 file is has line feed line breaks at 76 characters.\n");
526  printf("The line length and line ending can be configured with the conv utility.\n");
527 
528  printf("\nDefault conversion.\n");
529  memcpy(ucpRandBuf1, sDst.ucpData, sDst.uiDataLen);
530  ucpRandBuf1[sDst.uiDataLen] = 0;
531  printf("%s\n", (char*)ucpRandBuf1);
532 
533  printf("Conversion with 100 characters per line.\n");
534  vConvConfigureBase64(vpConv, 100, BASE64_LF);
535  memset(&sDst, 0, sizeof(sDst));
536  sDst.uiDataType = BINARY | BASE64;
537  vConvConvert(vpConv, &sSrc, &sDst);
538  if(sDst.uiDataLen > uiBufSize){
539  XTHROW(&e, "buffer not big enough for input converted data");
540  }
541  memcpy(ucpRandBuf1, sDst.ucpData, sDst.uiDataLen);
542  ucpRandBuf1[sDst.uiDataLen] = 0;
543  printf("%s\n", (char*)ucpRandBuf1);
544 
545  printf("Conversion with 50 characters per line.\n");
546  vConvConfigureBase64(vpConv, 50, BASE64_LF);
547  memset(&sDst, 0, sizeof(sDst));
548  sDst.uiDataType = BINARY | BASE64;
549  vConvConvert(vpConv, &sSrc, &sDst);
550  if(sDst.uiDataLen > uiBufSize){
551  XTHROW(&e, "buffer not big enough for input converted data");
552  }
553  memcpy(ucpRandBuf1, sDst.ucpData, sDst.uiDataLen);
554  ucpRandBuf1[sDst.uiDataLen] = 0;
555  printf("%s\n", (char*)ucpRandBuf1);
556 
557  }else{
558  // catch block - display the exception location and message
560  iReturn = EXIT_FAILURE;
561  }
562 
563  // clean up resources
564  vFmtDtor(vpFmt);
565  vConvDtor(vpConv);
566  vMemDtor(vpMem);
567  return iReturn;
568 }
576 int main(int argc, char **argv) {
577  long int iCase = 0;
578  if(argc > 1){
579  iCase = atol(argv[1]);
580  }
581  if((iCase > 0) && (iCase <= s_iCaseCount)){
582  printf("%s\n", s_cppCases[iCase -1]);
583  }
584  switch(iCase){
585  case 1:
586  return iApp();
587  case 2:
588  return iConv();
589  case 3:
590  return iGet();
591  case 4:
592  return iUse();
593  case 5:
594  return iBase64();
595  default:
596  return iHelp();
597  }
598 }
599 
conv_src::uiDataType
aint uiDataType
One of the encoding type identifiers, UTF_8, etc. If or'ed (|) with BASE64, the source data stream is...
Definition: conv.h:110
XCTOR
#define XCTOR(e)
This macro will initialize an exception structure and prepare entry to the "try" block.
Definition: exception.h:77
conv_file
Definition: main.c:127
vUtilFileRead
void vUtilFileRead(void *vpMem, const char *cpFileName, uint8_t *ucpData, aint *uipLen)
Read a file into the caller's data area.
Definition: utilities.c:252
vMemDtor
void vMemDtor(void *vpCtx)
Destroys a Memory component. Frees all memory allocated.
Definition: memory.c:141
conv_file::cpName
const char * cpName
Definition: main.c:128
exception::try
abool try
True for the try block, false for the catch block.
Definition: exception.h:49
conv_file::uiFormat
aint uiFormat
Definition: main.c:131
vpConvCtor
void * vpConvCtor(exception *spEx)
The data conversion object constructor.
Definition: conv.c:134
XTHROW
#define XTHROW(ctx, msg)
Exception throw macro.
Definition: exception.h:67
conv_src::ucpData
uint8_t * ucpData
Pointer to the byte stream to decode,.
Definition: conv.h:113
vConvConfigureBase64
void vConvConfigureBase64(void *vpCtx, aint uiLineLen, aint uiLineEnd)
Configures base64 output format.
Definition: conv.c:186
UTF_16BE
#define UTF_16BE
Data type macro for UTF-16BE encoding/decoding.
Definition: conv.h:81
aint
uint_fast32_t aint
The APG parser's unsigned integer type.
Definition: apg.h:79
vConvGetCodePoints
void vConvGetCodePoints(void *vpCtx, uint32_t *uipData, uint32_t *uipDataLen)
Access the intermediate 32-bit data following a call to vConvDecode() or vConvUseCodePoints().
Definition: conv.c:361
main
int main(int argc, char **argv)
The executable from this main function is the ABNF Parser Generator application, APG.
Definition: main.c:61
conv_dst::uiDataType
aint uiDataType
[in] One of the encoding type identifiers, UTF_8, etc.
Definition: conv.h:121
vpMemAlloc
void * vpMemAlloc(void *vpCtx, aint uiBytes)
Allocates memory.
Definition: memory.c:196
conv_dst
Defines the output data type, location, length and whether or not to preface with a Byte Order Mark (...
Definition: conv.h:120
UTF_32LE
#define UTF_32LE
Data type macro for UTF-32LE encoding/decoding.
Definition: conv.h:89
cpUtilUtfTypeName
const char * cpUtilUtfTypeName(aint uiType)
Convert a conversion type identifier to a readable, printable ASCII string. Conversion type identifie...
Definition: utilities.c:607
exception
A structure to describe the type and location of a caught exception.
Definition: exception.h:47
vConvConvert
void vConvConvert(void *vpCtx, conv_src *spSrc, conv_dst *spDst)
Decodes and encodes in a single functions call.
Definition: conv.c:422
conv_src::uiDataLen
aint uiDataLen
Number of bytes in the byte stream.
Definition: conv.h:114
UTF_16LE
#define UTF_16LE
Data type macro for UTF-16LE encoding/decoding.
Definition: conv.h:83
vConvDecode
void vConvDecode(void *vpCtx, conv_src *spSrc)
Decode a source byte stream to 32-bit Unicode code points.
Definition: conv.c:205
vpMemCtor
void * vpMemCtor(exception *spException)
Construct a memory component.
Definition: memory.c:121
vConvEncode
void vConvEncode(void *vpCtx, conv_dst *spDst)
Encode the 32-bit Unicode code points to a byte stream.
Definition: conv.c:302
BASE64_LF
#define BASE64_LF
For configuring base64 destinations, indicates line breaks as line feed (\n, 0x0A).
Definition: conv.h:101
conv_file::uiBytes
aint uiBytes
Definition: main.c:130
UTF_8
#define UTF_8
Data type macro for UTF-8 encoding/decoding.
Definition: conv.h:77
conv_dst::uiDataLen
aint uiDataLen
[out] Number of bytes in the byte stream.
Definition: conv.h:124
vUtilApgInfo
void vUtilApgInfo(void)
Display the current state of apg.h.
Definition: utilities.c:60
BASE64
#define BASE64
The base64 bit. Or (|) with data type for base64 encoding/decoding.
Definition: conv.h:44
conv_src
Defines the input data type, location and length.
Definition: conv.h:109
vFmtDtor
void vFmtDtor(void *vpCtx)
The object destructor.
Definition: format.c:146
vConvDtor
void vConvDtor(void *vpCtx)
Conversion object destructor.
Definition: conv.c:161
vUtilPrintException
void vUtilPrintException(exception *spEx)
Prints exception information from an exception structure.
Definition: utilities.c:415
conv_dst::ucpData
uint8_t * ucpData
[out] Pointer to the output byte stream. Valid until another function call on the context handle.
Definition: conv.h:123
vpFmtCtor
void * vpFmtCtor(exception *spEx)
The object constructor.
Definition: format.c:118
vConvUseCodePoints
void vConvUseCodePoints(void *vpCtx, uint32_t *uipSrc, aint uiSrcLen)
Insert a stream of 32-bit Unicode code points as the intermediate data.
Definition: conv.c:395
vUtilCurrentWorkingDirectory
void vUtilCurrentWorkingDirectory(void)
Display the current working directory.
Definition: utilities.c:191
BINARY
#define BINARY
Alias for ISO_8895_1.
Definition: conv.h:64
conv_file::ucpData
uint8_t * ucpData
Definition: main.c:129
APG Version 7.0 is licensed under the 2-Clause BSD License,
an Open Source Initiative Approved License.