home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 15 / AACD15.ISO / AACD / Programming / Python2 / Python20_source / expat / xmlwf / xmlfile.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-05-10  |  4.6 KB  |  218 lines

  1. /*
  2. Copyright (c) 1998, 1999 Thai Open Source Software Center Ltd
  3. See the file copying.txt for copying permission.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include <fcntl.h>
  11. #include "xmlparse.h"
  12. #include "xmlfile.h"
  13. #include "xmltchar.h"
  14. #include "filemap.h"
  15.  
  16. #ifdef _MSC_VER
  17. #include <io.h>
  18. #endif
  19.  
  20. #ifdef _POSIX_SOURCE
  21. #include <unistd.h>
  22. #endif
  23.  
  24. #ifndef O_BINARY
  25. #ifdef _O_BINARY
  26. #define O_BINARY _O_BINARY
  27. #else
  28. #define O_BINARY 0
  29. #endif
  30. #endif
  31.  
  32. #ifdef _DEBUG
  33. #define READ_SIZE 16
  34. #else
  35. #define READ_SIZE (1024*8)
  36. #endif
  37.  
  38.  
  39.  
  40. typedef struct {
  41.   XML_Parser parser;
  42.   int *retPtr;
  43. } PROCESS_ARGS;
  44.  
  45. static
  46. void reportError(XML_Parser parser, const XML_Char *filename)
  47. {
  48.   int code = XML_GetErrorCode(parser);
  49.   const XML_Char *message = XML_ErrorString(code);
  50.   if (message)
  51.     ftprintf(stdout, T("%s:%d:%d: %s\n"),
  52.          filename,
  53.          XML_GetErrorLineNumber(parser),
  54.          XML_GetErrorColumnNumber(parser),
  55.          message);
  56.   else
  57.     ftprintf(stderr, T("%s: (unknown message %d)\n"), filename, code);
  58. }
  59.  
  60. static
  61. void processFile(const void *data,
  62.          size_t size,
  63.          const XML_Char *filename,
  64.          void *args)
  65. {
  66.   XML_Parser parser = ((PROCESS_ARGS *)args)->parser;
  67.   int *retPtr = ((PROCESS_ARGS *)args)->retPtr;
  68.   if (!XML_Parse(parser, data, size, 1)) {
  69.     reportError(parser, filename);
  70.     *retPtr = 0;
  71.   }
  72.   else
  73.     *retPtr = 1;
  74. }
  75.  
  76. #ifdef WIN32
  77.  
  78. static
  79. int isAsciiLetter(XML_Char c)
  80. {
  81.   return (T('a') <= c && c <= T('z')) || (T('A') <= c && c <= T('Z'));
  82. }
  83.  
  84. #endif /* WIN32 */
  85.  
  86. static
  87. const XML_Char *resolveSystemId(const XML_Char *base, const XML_Char *systemId, XML_Char **toFree)
  88. {
  89.   XML_Char *s;
  90.   *toFree = 0;
  91.   if (!base
  92.       || *systemId == T('/')
  93. #ifdef WIN32
  94.       || *systemId == T('\\')
  95.       || (isAsciiLetter(systemId[0]) && systemId[1] == T(':'))
  96. #endif
  97.      )
  98.     return systemId;
  99.   *toFree = (XML_Char *)malloc((tcslen(base) + tcslen(systemId) + 2)*sizeof(XML_Char));
  100.   if (!*toFree)
  101.     return systemId;
  102.   tcscpy(*toFree, base);
  103.   s = *toFree;
  104.   if (tcsrchr(s, T('/')))
  105.     s = tcsrchr(s, T('/')) + 1;
  106. #ifdef WIN32
  107.   if (tcsrchr(s, T('\\')))
  108.     s = tcsrchr(s, T('\\')) + 1;
  109. #endif
  110.   tcscpy(s, systemId);
  111.   return *toFree;
  112. }
  113.  
  114. static
  115. int externalEntityRefFilemap(XML_Parser parser,
  116.                  const XML_Char *context,
  117.                  const XML_Char *base,
  118.                  const XML_Char *systemId,
  119.                  const XML_Char *publicId)
  120. {
  121.   int result;
  122.   XML_Char *s;
  123.   const XML_Char *filename;
  124.   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
  125.   PROCESS_ARGS args;
  126.   args.retPtr = &result;
  127.   args.parser = entParser;
  128.   filename = resolveSystemId(base, systemId, &s);
  129.   XML_SetBase(entParser, filename);
  130.   if (!filemap(filename, processFile, &args))
  131.     result = 0;
  132.   free(s);
  133.   XML_ParserFree(entParser);
  134.   return result;
  135. }
  136.  
  137. static
  138. int processStream(const XML_Char *filename, XML_Parser parser)
  139. {
  140.   int fd = topen(filename, O_BINARY|O_RDONLY);
  141.   if (fd < 0) {
  142.     tperror(filename);
  143.     return 0;
  144.   }
  145.   for (;;) {
  146.     int nread;
  147.     char *buf = XML_GetBuffer(parser, READ_SIZE);
  148.     if (!buf) {
  149.       close(fd);
  150.       ftprintf(stderr, T("%s: out of memory\n"), filename);
  151.       return 0;
  152.     }
  153.     nread = read(fd, buf, READ_SIZE);
  154.     if (nread < 0) {
  155.       tperror(filename);
  156.       close(fd);
  157.       return 0;
  158.     }
  159.     if (!XML_ParseBuffer(parser, nread, nread == 0)) {
  160.       reportError(parser, filename);
  161.       close(fd);
  162.       return 0;
  163.     }
  164.     if (nread == 0) {
  165.       close(fd);
  166.       break;;
  167.     }
  168.   }
  169.   return 1;
  170. }
  171.  
  172. static
  173. int externalEntityRefStream(XML_Parser parser,
  174.                 const XML_Char *context,
  175.                 const XML_Char *base,
  176.                 const XML_Char *systemId,
  177.                 const XML_Char *publicId)
  178. {
  179.   XML_Char *s;
  180.   const XML_Char *filename;
  181.   int ret;
  182.   XML_Parser entParser = XML_ExternalEntityParserCreate(parser, context, 0);
  183.   filename = resolveSystemId(base, systemId, &s);
  184.   XML_SetBase(entParser, filename);
  185.   ret = processStream(filename, entParser);
  186.   free(s);
  187.   XML_ParserFree(entParser);
  188.   return ret;
  189. }
  190.  
  191. int XML_ProcessFile(XML_Parser parser,
  192.             const XML_Char *filename,
  193.             unsigned flags)
  194. {
  195.   int result;
  196.  
  197.   if (!XML_SetBase(parser, filename)) {
  198.     ftprintf(stderr, T("%s: out of memory"), filename);
  199.     exit(1);
  200.   }
  201.  
  202.   if (flags & XML_EXTERNAL_ENTITIES)
  203.       XML_SetExternalEntityRefHandler(parser,
  204.                                   (flags & XML_MAP_FILE)
  205.                       ? externalEntityRefFilemap
  206.                       : externalEntityRefStream);
  207.   if (flags & XML_MAP_FILE) {
  208.     PROCESS_ARGS args;
  209.     args.retPtr = &result;
  210.     args.parser = parser;
  211.     if (!filemap(filename, processFile, &args))
  212.       result = 0;
  213.   }
  214.   else
  215.     result = processStream(filename, parser);
  216.   return result;
  217. }
  218.