📄 mxml-file.c
字号:
temp = *(buf->current)++; if ((temp & 0xc0) != 0x80) return (EOF); ch = (ch << 6) | (temp & 0x3f); if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); temp = *(buf->current)++; if ((temp & 0xc0) != 0x80) return (EOF); ch = (ch << 6) | (temp & 0x3f); if (ch < 0x10000) return (EOF); } else return (EOF); break; case ENCODE_UTF16BE : /* * Read UTF-16 big-endian char... */ if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); temp = *(buf->current)++; ch = (ch << 8) | temp; if (mxml_bad_char(ch)) { mxml_error("Bad control character 0x%02x not allowed by XML standard!", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { /* * Multi-word UTF-16 char... */ int lch; if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); lch = *(buf->current)++; if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); temp = *(buf->current)++; lch = (lch << 8) | temp; if (lch < 0xdc00 || lch >= 0xdfff) return (EOF); ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; } break; case ENCODE_UTF16LE : /* * Read UTF-16 little-endian char... */ if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); temp = *(buf->current)++; ch |= (temp << 8); if (mxml_bad_char(ch)) { mxml_error("Bad control character 0x%02x not allowed by XML standard!", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { /* * Multi-word UTF-16 char... */ int lch; if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); lch = *(buf->current)++; if (buf->current >= buf->end) if (mxml_fd_read(buf) < 0) return (EOF); temp = *(buf->current)++; lch |= (temp << 8); if (lch < 0xdc00 || lch >= 0xdfff) return (EOF); ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; } break; }#if DEBUG > 1 printf("mxml_fd_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);#endif /* DEBUG > 1 */ return (ch);}/* * 'mxml_fd_putc()' - Write a character to a file descriptor. */static int /* O - 0 on success, -1 on error */mxml_fd_putc(int ch, /* I - Character */ void *p) /* I - File descriptor buffer */{ mxml_fdbuf_t *buf; /* File descriptor buffer */ /* * Flush the write buffer as needed - note above that "end" still leaves * 4 characters at the end so that we can avoid a lot of extra tests... */ buf = (mxml_fdbuf_t *)p; if (buf->current >= buf->end) if (mxml_fd_write(buf) < 0) return (-1); if (ch < 0x80) { /* * Write ASCII character directly... */ *(buf->current)++ = ch; } else if (ch < 0x800) { /* * Two-byte UTF-8 character... */ *(buf->current)++ = 0xc0 | (ch >> 6); *(buf->current)++ = 0x80 | (ch & 0x3f); } else if (ch < 0x10000) { /* * Three-byte UTF-8 character... */ *(buf->current)++ = 0xe0 | (ch >> 12); *(buf->current)++ = 0x80 | ((ch >> 6) & 0x3f); *(buf->current)++ = 0x80 | (ch & 0x3f); } else { /* * Four-byte UTF-8 character... */ *(buf->current)++ = 0xf0 | (ch >> 18); *(buf->current)++ = 0x80 | ((ch >> 12) & 0x3f); *(buf->current)++ = 0x80 | ((ch >> 6) & 0x3f); *(buf->current)++ = 0x80 | (ch & 0x3f); } /* * Return successfully... */ return (0);}/* * 'mxml_fd_read()' - Read a buffer of data from a file descriptor. */static int /* O - 0 on success, -1 on error */mxml_fd_read(mxml_fdbuf_t *buf) /* I - File descriptor buffer */{ int bytes; /* Bytes read... */ /* * Range check input... */ if (!buf) return (-1); /* * Read from the file descriptor... */ while ((bytes = read(buf->fd, buf->buffer, sizeof(buf->buffer))) < 0) if (errno != EAGAIN && errno != EINTR) return (-1); if (bytes == 0) return (-1); /* * Update the pointers and return success... */ buf->current = buf->buffer; buf->end = buf->buffer + bytes; return (0);}/* * 'mxml_fd_write()' - Write a buffer of data to a file descriptor. */static int /* O - 0 on success, -1 on error */mxml_fd_write(mxml_fdbuf_t *buf) /* I - File descriptor buffer */{ int bytes; /* Bytes written */ unsigned char *ptr; /* Pointer into buffer */ /* * Range check... */ if (!buf) return (-1); /* * Return 0 if there is nothing to write... */ if (buf->current == buf->buffer) return (0); /* * Loop until we have written everything... */ for (ptr = buf->buffer; ptr < buf->current; ptr += bytes) if ((bytes = write(buf->fd, ptr, buf->current - ptr)) < 0) return (-1); /* * All done, reset pointers and return success... */ buf->current = buf->buffer; return (0);}/* * 'mxml_file_getc()' - Get a character from a file. */static int /* O - Character or EOF */mxml_file_getc(void *p, /* I - Pointer to file */ int *encoding) /* IO - Encoding */{ int ch, /* Character from file */ temp; /* Temporary character */ FILE *fp; /* Pointer to file */ /* * Read a character from the file and see if it is EOF or ASCII... */ fp = (FILE *)p; ch = getc(fp); if (ch == EOF) return (EOF); switch (*encoding) { case ENCODE_UTF8 : /* * Got a UTF-8 character; convert UTF-8 to Unicode and return... */ if (!(ch & 0x80)) { if (mxml_bad_char(ch)) { mxml_error("Bad control character 0x%02x not allowed by XML standard!", ch); return (EOF); }#if DEBUG > 1 printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);#endif /* DEBUG > 1 */ return (ch); } else if (ch == 0xfe) { /* * UTF-16 big-endian BOM? */ ch = getc(fp); if (ch != 0xff) return (EOF); *encoding = ENCODE_UTF16BE; return (mxml_file_getc(p, encoding)); } else if (ch == 0xff) { /* * UTF-16 little-endian BOM? */ ch = getc(fp); if (ch != 0xfe) return (EOF); *encoding = ENCODE_UTF16LE; return (mxml_file_getc(p, encoding)); } else if ((ch & 0xe0) == 0xc0) { /* * Two-byte value... */ if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); ch = ((ch & 0x1f) << 6) | (temp & 0x3f); if (ch < 0x80) return (EOF); } else if ((ch & 0xf0) == 0xe0) { /* * Three-byte value... */ if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); ch = ((ch & 0x0f) << 6) | (temp & 0x3f); if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); ch = (ch << 6) | (temp & 0x3f); if (ch < 0x800) return (EOF); } else if ((ch & 0xf8) == 0xf0) { /* * Four-byte value... */ if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); ch = ((ch & 0x07) << 6) | (temp & 0x3f); if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); ch = (ch << 6) | (temp & 0x3f); if ((temp = getc(fp)) == EOF || (temp & 0xc0) != 0x80) return (EOF); ch = (ch << 6) | (temp & 0x3f); if (ch < 0x10000) return (EOF); } else return (EOF); break; case ENCODE_UTF16BE : /* * Read UTF-16 big-endian char... */ ch = (ch << 8) | getc(fp); if (mxml_bad_char(ch)) { mxml_error("Bad control character 0x%02x not allowed by XML standard!", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { /* * Multi-word UTF-16 char... */ int lch = (getc(fp) << 8) | getc(fp); if (lch < 0xdc00 || lch >= 0xdfff) return (EOF); ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; } break; case ENCODE_UTF16LE : /* * Read UTF-16 little-endian char... */ ch |= (getc(fp) << 8); if (mxml_bad_char(ch)) { mxml_error("Bad control character 0x%02x not allowed by XML standard!", ch); return (EOF); } else if (ch >= 0xd800 && ch <= 0xdbff) { /* * Multi-word UTF-16 char... */ int lch = getc(fp) | (getc(fp) << 8); if (lch < 0xdc00 || lch >= 0xdfff) return (EOF); ch = (((ch & 0x3ff) << 10) | (lch & 0x3ff)) + 0x10000; } break; }#if DEBUG > 1 printf("mxml_file_getc: %c (0x%04x)\n", ch < ' ' ? '.' : ch, ch);#endif /* DEBUG > 1 */ return (ch);}/* * 'mxml_file_putc()' - Write a character to a file. */static int /* O - 0 on success, -1 on failure */mxml_file_putc(int ch, /* I - Character to write */ void *p) /* I - Pointer to file */{ char buffer[4], /* Buffer for character */ *bufptr; /* Pointer into buffer */ int buflen; /* Number of bytes to write */ if (ch < 0x80) return (putc(ch, (FILE *)p) == EOF ? -1 : 0); bufptr = buffer; if (ch < 0x800) { /* * Two-byte UTF-8 character... */ *bufptr++ = 0xc0 | (ch >> 6); *bufptr++ = 0x80 | (ch & 0x3f); } else if (ch < 0x10000) { /* * Three-byte UTF-8 character... */ *bufptr++ = 0xe0 | (ch >> 12); *bufptr++ = 0x80 | ((ch >> 6) & 0x3f); *bufptr++ = 0x80 | (ch & 0x3f); } else { /* * Four-byte UTF-8 character... */ *bufptr++ = 0xf0 | (ch >> 18); *bufptr++ = 0x80 | ((ch >> 12) & 0x3f); *bufptr++ = 0x80 | ((ch >> 6) & 0x3f); *bufptr++ = 0x80 | (ch & 0x3f); } buflen = bufptr - buffer; return (fwrite(buffer, 1, buflen, (FILE *)p) < buflen ? -1 : 0);}/* * 'mxml_get_entity()' - Get the character corresponding to an entity... */static int /* O - Character value or EOF on error */mxml_get_entity(mxml_node_t *parent, /* I - Parent node */ void *p, /* I - Pointer to source */ int *encoding, /* IO - Character encoding */ int (*getc_cb)(void *, int *)) /* I - Get character function */{ int ch; /* Current character */ char entity[64], /* Entity string */ *entptr; /* Pointer into entity */ entptr = entity; while ((ch = (*getc_cb)(p, encoding)) != EOF) if (ch > 126 || (!isalnum(ch) && ch != '#')) break; else if (entptr < (entity + sizeof(entity) - 1)) *entptr++ = ch; else { mxml_error("Entity name too long under parent <%s>!", parent ? parent->value.element.name : "null"); break; } *entptr = '\0'; if (ch != ';') { mxml_error("Character entity \"%s\" not terminated under parent <%s>!", entity, parent ? parent->value.element.name : "null"); return (EOF); } if (entity[0] == '#') { if (entity[1] == 'x') ch = strtol(entity + 2, NULL, 16); else ch = strtol(entity + 1, NULL, 10); } else if ((ch = mxmlEntityGetValue(entity)) < 0) mxml_error("Entity name \"%s;\" not supported under parent <%s>!", entity, parent ? parent->value.element.name : "null"); if (mxml_bad_char(ch)) { mxml_error("Bad control character 0x%02x under parent <%s> not allowed by XML standard!", ch, parent ? parent->value.element.name : "null"); return (EOF); } return (ch);}/* * 'mxml_load_data()' - Load data into an XML node tree. */static mxml_node_t * /* O - First node or NULL if the file could not be read. */mxml_load_data(mxml_node_t *top, /* I - Top node */ void *p, /* I - Pointer to data */ mxml_type_t (*cb)(mxml_node_t *), /* I - Callback function or MXML_NO_CALLBACK */ int (*getc_cb)(void *, int *)) /* I - Read function */{ mxml_node_t *node, /* Current node */ *first, /* First node added */ *parent; /* Current parent node */ int ch, /* Character from file */ whitespace; /* Non-zero if whitespace seen */ char *buffer, /* String buffer */ *bufptr; /* Pointer into buffer */ int bufsize; /* Size of buffer */ mxml_type_t type; /* Current node type */ int encoding; /* Character encoding */ static const char * const types[] = /* Type strings... */ { "MXML_ELEMENT", /* XML element with attributes */ "MXML_INTEGER", /* Integer value */ "MXML_OPAQUE", /* Opaque string */ "MXML_REAL", /* Real value */ "MXML_TEXT", /* Text fragment */ "MXML_CUSTOM" /* Custom data */ }; /* * Read elements and other nodes from the file... */ if ((buffer = malloc(64)) == NULL) { mxml_error("Unable to allocate string buffer!"); return (NULL); } bufsize = 64; bufptr = buffer; parent = top; first = NULL; whitespace = 0; encoding = ENCODE_UTF8; if (cb && parent) type = (*cb)(parent); else type = MXML_TEXT; while ((ch = (*getc_cb)(p, &encoding)) != EOF) { if ((ch == '<' || (isspace(ch) && type != MXML_OPAQUE && type != MXML_CUSTOM)) && bufptr > buffer) { /* * Add a new value node... */ *bufptr = '\0'; switch (type) { case MXML_INTEGER : node = mxmlNewInteger(parent, strtol(buffer, &bufptr, 0)); break; case MXML_OPAQUE : node = mxmlNewOpaque(parent, buffer); break; case MXML_REAL : node = mxmlNewReal(parent, strtod(buffer, &bufptr)); break; case MXML_TEXT : node = mxmlNewText(parent, whitespace, buffer); break; case MXML_CUSTOM : if (mxml_custom_load_cb) { /* * Use the callback to fill in the custom data... */ node = mxmlNewCustom(parent, NULL, NULL); if ((*mxml_custom_load_cb)(node, buffer)) { mxml_error("Bad custom value '%s' in parent <%s>!", buffer, parent ? parent->value.element.name : "null"); mxmlDelete(node); node = NULL; } break; } default : /* Should never happen... */ node = NULL; break; } if (*bufptr) { /* * Bad integer/real number value... */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -