?? nxml_parser.c
字號:
(*buffer) += i; (*size) -= i; value_new = __nxml_trim (value); free (value); if (!value_new) { free (t); return NXML_ERR_POSIX; } t->value = value_new; t->type = NXML_TYPE_TEXT; *data = t; return NXML_OK;}static nxml_error_t__nxml_parse_close (nxml_t * doc, char **buffer, size_t * size, nxml_data_t ** data){ /* * Rule [42] - ETag ::= '</' Name S? '>' */ nxml_data_t *tag; char str[1024]; int i; int byte; int64_t ch; *data = NULL; if (!*size) return NXML_OK; if (!__NXML_NAMESTARTCHARS) { if (doc->priv.func) doc->priv.func ("%s: abnormal char '%c' (line %d)\n", doc->file ? doc->file : "", **buffer, doc->priv.line); return NXML_ERR_PARSER; } memcpy (&str[0], *buffer, byte); i = byte; (*buffer) += byte; (*size) -= byte; while (__NXML_NAMECHARS && *size && i < sizeof (str) - 1) { memcpy (&str[i], *buffer, byte); i += byte; (*buffer) += byte; (*size) -= byte; } str[i] = 0; __nxml_escape_spaces (doc, buffer, size); if (**buffer != '>') { if (doc->priv.func) doc->priv.func ("%s: expected char '>' after tag %s (line %d)\n", doc->file ? doc->file : "", str, doc->priv.line); return NXML_ERR_PARSER; } (*buffer) += 1; (*size) -= 1; if (!(tag = (nxml_data_t *) malloc (sizeof (nxml_data_t)))) return NXML_ERR_POSIX; memset (tag, 0, sizeof (nxml_data_t)); tag->doc = doc; if (!(tag->value = strdup (str))) { free (tag); return NXML_ERR_POSIX; } tag->type = NXML_TYPE_ELEMENT_CLOSE; *data = tag; return NXML_OK;}static nxml_error_t__nxml_parse_get_tag (nxml_t * doc, char **buffer, size_t * size, nxml_data_t ** data, int *doctype){ //* Parse the element... nxml_attr_t *attr, *last; nxml_data_t *tag, *child, *child_last; nxml_error_t err; char str[1024]; int i; int closed = 0; int byte; int64_t ch; *data = NULL; *doctype = 0; if (!*size) return NXML_OK; __nxml_escape_spaces (doc, buffer, size); //* Text if (**buffer != '<') return __nxml_parse_text (doc, buffer, size, data); (*buffer) += 1; (*size) -= 1; //* Comment, CData, DocType or other elements if (**buffer == '!') return __nxml_parse_other (doc, buffer, size, data, doctype); //* PI * else if (**buffer == '?') return __nxml_parse_pi (doc, buffer, size, data); //* Close tag * else if (**buffer == '/') { (*buffer) += 1; (*size) -= 1; return __nxml_parse_close (doc, buffer, size, data); } __nxml_escape_spaces (doc, buffer, size); if (!__NXML_NAMESTARTCHARS) { if (doc->priv.func) doc->priv.func ("%s: abnormal char '%c' (line %d)\n", doc->file ? doc->file : "", **buffer, doc->priv.line); return NXML_ERR_PARSER; } memcpy (&str[0], *buffer, byte); i = byte; (*buffer) += byte; (*size) -= byte; while (__NXML_NAMECHARS && *size && i < sizeof (str) - 1) { memcpy (&str[i], *buffer, byte); i += byte; (*buffer) += byte; (*size) -= byte; } str[i] = 0; if (**buffer != 0x20 && **buffer != 0x9 && **buffer != 0xa && **buffer != 0xd && **buffer != '>' && **buffer != '/') { (*buffer) -= i; (*size) += i; if (doc->priv.func) doc->priv.func ("%s: abnormal char '%c' after tag %s (line %d)\n", doc->file ? doc->file : "", *(*buffer + i), str, doc->priv.line); return NXML_ERR_PARSER; } if (!(tag = (nxml_data_t *) malloc (sizeof (nxml_data_t)))) return NXML_ERR_POSIX; memset (tag, 0, sizeof (nxml_data_t)); tag->doc = doc; if (!(tag->value = strdup (str))) { free (tag); return NXML_ERR_POSIX; } last = NULL; //* Get attribute: while (!(err = __nxml_parse_get_attribute (doc, buffer, size, &attr)) && attr) { if (__nxml_parse_unique_attribute (tag->attributes, attr->name)) { if (doc->priv.func) doc->priv. func ("%s: Duplicate attribute '%s' in tag '%s' (line %d)\n", doc->file ? doc->file : "", attr->name, tag->value, doc->priv.line); nxml_free_attribute (attr); nxml_free_data (tag); return NXML_ERR_PARSER; } if (last) last->next = attr; else tag->attributes = attr; last = attr; } if (err) { nxml_free_data (tag); return err; } //* Closed element * if (**buffer == '/') { closed++; (*buffer) += 1; (*size) -= 1; __nxml_escape_spaces (doc, buffer, size); } if (**buffer != '>') { if (doc->priv.func) doc->priv.func ("%s: expected char '>' after tag %s (line %d)\n", doc->file ? doc->file : "", tag->value, doc->priv.line); nxml_free_data (tag); return NXML_ERR_PARSER; } (*buffer) += 1; (*size) -= 1; if (!closed) { child_last = NULL; //* Search children: * while (! (err = __nxml_parse_get_tag (doc, buffer, size, &child, doctype)) && (*doctype || child)) { if (*doctype) continue; //* If the current child, break: * if (child->type == NXML_TYPE_ELEMENT_CLOSE) { if (!strcmp (child->value, tag->value)) { closed = 1; nxml_free_data (child); break; } else { if (doc->priv.func) doc->priv. func ("%s: expected tag '/%s' and not '%s' (line %d)\n", doc->file ? doc->file : "", tag->value, child->value, doc->priv.line); nxml_free_data (child); nxml_free_data (tag); return NXML_ERR_PARSER; } } //* Set the parent * child->parent = tag; if (child_last) child_last->next = child; else tag->children = child; child_last = child; } if (err) { nxml_free_data (tag); return err; } } tag->type = NXML_TYPE_ELEMENT; if (!closed) { if (doc->priv.func) doc->priv.func ("%s: expected tag '/%s' (line %d)\n", doc->file ? doc->file : "", tag->value, doc->priv.line); nxml_free_data (tag); return NXML_ERR_PARSER; } *data = tag; return NXML_OK;}static nxml_error_t__nxml_parse_buffer (nxml_t * nxml, char *r_buffer, size_t r_size){ /* * Rule [1] - Document ::= prolog element Misc* - Char* RestrictedChar Char* */ nxml_attr_t *attr; nxml_error_t err; nxml_charset_t charset; nxml_data_t *tag, *last, *root; int doctype; int freed; char *buffer = NULL; size_t size; if (!r_buffer || !nxml) return NXML_ERR_DATA; if (!r_size) r_size = strlen (r_buffer); switch ((freed = __nxml_utf_detection (r_buffer, r_size, &buffer, &size, &charset))) { case 0: buffer = r_buffer; size = r_size; break; case -1: return NXML_ERR_POSIX; } nxml->priv.line = 1; /* * Rule [22] - prolog ::= XMLDecl Misc* (doctypedecl Misc*)? * Rule [23] - XMLDecl ::= '<?xml' VersionInfo EncodingDecl? SDDecl? S? '?>' */ if (strncmp (buffer, "<?xml ", 6)) { if (nxml->priv.func) nxml->priv.func ("%s: expected char '<?xml' (line %d)\n", nxml->file ? nxml->file : "", nxml->priv.line); if (freed) free (buffer); return NXML_ERR_PARSER; } buffer += 6; size -= 6; if ((err = __nxml_parse_get_attribute (nxml, &buffer, &size, &attr)) != NXML_OK) { nxml_empty (nxml); if (freed) free (buffer); return err; } if (!attr) { if (nxml->priv.func) nxml->priv.func ("%s: expected 'version' attribute (line %d)\n", nxml->file ? nxml->file : "", nxml->priv.line); if (freed) free (buffer); return NXML_ERR_PARSER; } if (!strcmp (attr->value, "1.0")) nxml->version = NXML_VERSION_1_0; else if (!strcmp (attr->value, "1.1")) nxml->version = NXML_VERSION_1_1; else { if (nxml->priv.func) nxml->priv. func (PACKAGE " " VERSION " suports only xml 1.1 or 1.0 (line %d)\n", nxml->priv.line); if (freed) free (buffer); return NXML_ERR_PARSER; } nxml_free_attribute (attr); while (!(err = __nxml_parse_get_attribute (nxml, &buffer, &size, &attr)) && attr) { if (!strcmp (attr->name, "standalone")) { if (!strcmp (attr->value, "yes")) nxml->standalone = 1; else nxml->standalone = 0; } else if (!strcmp (attr->name, "encoding")) { nxml->encoding = strdup (attr->value); if (!nxml->encoding) { nxml_empty (nxml); nxml_free_attribute (attr); if (freed) free (buffer); return NXML_ERR_POSIX; } } else { if (nxml->priv.func) nxml->priv.func ("%s: unexpected attribute '%s' (line %d)\n", nxml->file ? nxml->file : "", attr->name, nxml->priv.line); nxml_empty (nxml); nxml_free_attribute (attr); if (freed) free (buffer); return NXML_ERR_PARSER; } nxml_free_attribute (attr); } if (err || strncmp (buffer, "?>", 2)) { if (nxml->priv.func) nxml->priv.func ("%s expected '?>' (line %d)\n", nxml->file ? nxml->file : "", nxml->priv.line); nxml_empty (nxml); if (freed) free (buffer); return NXML_ERR_PARSER; } buffer += 2; size -= 2; root = last = NULL; while (!(err = __nxml_parse_get_tag (nxml, &buffer, &size, &tag, &doctype)) && (doctype || tag)) { if (doctype) continue; if (tag->type == NXML_TYPE_ELEMENT && !root) root = tag; if (last) last->next = tag; else nxml->data = tag; last = tag; } if (err) { nxml_empty (nxml); if (freed) free (buffer); return NXML_ERR_PARSER; } if (!root) { if (nxml->priv.func) nxml->priv.func ("%s: No root element founded!\n", nxml->file ? nxml->file : ""); nxml_empty (nxml); if (freed) free (buffer); return NXML_ERR_PARSER; } if (freed) free (buffer); nxml->charset_detected = charset; __nxml_namespace_parse (nxml); return NXML_OK;}/* EXTERNAL FUNCTIONS *******************************************************//****************************************************************//****************************************************************nxml_error_tnxml_parse_url (nxml_t * nxml, char *url){ __nxml_download_t *download; nxml_error_t err; if (!url || !nxml) return NXML_ERR_DATA; if (!(download = __nxml_download_file (nxml, url))) return NXML_ERR_POSIX; if (nxml->file) free (nxml->file); if (!(nxml->file = strdup (url))) { nxml_empty (nxml); return NXML_ERR_POSIX; } nxml->size = download->size; nxml_empty (nxml); err = __nxml_parse_buffer (nxml, download->mm, download->size); free (download->mm); free (download); return err;}***********************************************************************/nxml_error_tnxml_parse_file (nxml_t * nxml, char *file){ nxml_error_t err; char *buffer; struct stat st; int fd, len, ret; if (!file || !nxml) return NXML_ERR_DATA; if (stat (file, &st)) return NXML_ERR_POSIX; if ((fd = open (file, O_RDONLY)) < 0) return NXML_ERR_POSIX; if (!(buffer = (char *) malloc (sizeof (char) * (st.st_size + 1)))) return NXML_ERR_POSIX; len = 0; while (len < st.st_size) { if ((ret = read (fd, buffer + len, st.st_size - len)) <= 0) { free (buffer); close (fd); return NXML_ERR_POSIX; } len += ret; } buffer[len] = 0; close (fd); nxml_empty (nxml); if (nxml->file) free (nxml->file); if (!(nxml->file = strdup (file))) { nxml_empty (nxml); free (buffer); return NXML_ERR_POSIX; } nxml->size = st.st_size; err = __nxml_parse_buffer (nxml, buffer, st.st_size); free (buffer); return err;}nxml_error_tnxml_parse_buffer (nxml_t * nxml, char *buffer, size_t size){ if (!buffer || !nxml) return NXML_ERR_DATA; nxml_empty (nxml); if (nxml->file) free (nxml->file); if (!(nxml->file = strdup ("buffer"))) { nxml_empty (nxml); return NXML_ERR_POSIX; } nxml->size = size; return __nxml_parse_buffer (nxml, buffer, size);}/* EOF */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -