📄 xml.c
字号:
}/* }}} *//* {{{ xml_encode_iso_8859_1() */inline static unsigned short xml_encode_iso_8859_1(unsigned char c){ return (unsigned short)c;}/* }}} *//* {{{ xml_decode_iso_8859_1() */inline static char xml_decode_iso_8859_1(unsigned short c){ return (char)(c > 0xff ? '?' : c);}/* }}} *//* {{{ xml_encode_us_ascii() */inline static unsigned short xml_encode_us_ascii(unsigned char c){ return (unsigned short)c;}/* }}} *//* {{{ xml_decode_us_ascii() */inline static char xml_decode_us_ascii(unsigned short c){ return (char)(c > 0x7f ? '?' : c);}/* }}} *//* {{{ xml_get_encoding() */static xml_encoding *xml_get_encoding(const XML_Char *name){ xml_encoding *enc = &xml_encodings[0]; while (enc && enc->name) { if (strcasecmp(name, enc->name) == 0) { return enc; } enc++; } return NULL;}/* }}} *//* {{{ xml_utf8_encode */static XML_Char *xml_utf8_encode(const char *s, int len, int *newlen, const XML_Char *encoding){ int pos = len; char *newbuf; unsigned int c; unsigned short (*encoder)(unsigned char) = NULL; xml_encoding *enc = xml_get_encoding(encoding); *newlen = 0; if (enc) { encoder = enc->encoding_function; } else { /* If the target encoding was unknown, fail */ return NULL; } if (encoder == NULL) { /* If no encoder function was specified, return the data as-is. */ newbuf = emalloc(len + 1); memcpy(newbuf, s, len); *newlen = len; newbuf[*newlen] = '\0'; return newbuf; } /* This is the theoretical max (will never get beyond len * 2 as long * as we are converting from single-byte characters, though) */ newbuf = emalloc(len * 4 + 1); while (pos > 0) { c = encoder ? encoder((unsigned char)(*s)) : (unsigned short)(*s); if (c < 0x80) { newbuf[(*newlen)++] = (char) c; } else if (c < 0x800) { newbuf[(*newlen)++] = (0xc0 | (c >> 6)); newbuf[(*newlen)++] = (0x80 | (c & 0x3f)); } else if (c < 0x10000) { newbuf[(*newlen)++] = (0xe0 | (c >> 12)); newbuf[(*newlen)++] = (0xc0 | ((c >> 6) & 0x3f)); newbuf[(*newlen)++] = (0x80 | (c & 0x3f)); } else if (c < 0x200000) { newbuf[(*newlen)++] = (0xf0 | (c >> 18)); newbuf[(*newlen)++] = (0xe0 | ((c >> 12) & 0x3f)); newbuf[(*newlen)++] = (0xc0 | ((c >> 6) & 0x3f)); newbuf[(*newlen)++] = (0x80 | (c & 0x3f)); } pos--; s++; } newbuf[*newlen] = 0; newbuf = erealloc(newbuf, (*newlen)+1); return newbuf;}/* }}} *//* {{{ xml_utf8_decode */PHPAPI char *xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_Char *encoding){ int pos = len; char *newbuf = emalloc(len + 1); unsigned short c; char (*decoder)(unsigned short) = NULL; xml_encoding *enc = xml_get_encoding(encoding); *newlen = 0; if (enc) { decoder = enc->decoding_function; } if (decoder == NULL) { /* If the target encoding was unknown, or no decoder function * was specified, return the UTF-8-encoded data as-is. */ memcpy(newbuf, s, len); *newlen = len; newbuf[*newlen] = '\0'; return newbuf; } while (pos > 0) { c = (unsigned char)(*s); if (c >= 0xf0) { /* four bytes encoded, 21 bits */ c = ((s[0]&7)<<18) | ((s[1]&63)<<12) | ((s[2]&63)<<6) | (s[3]&63); s += 4; pos -= 4; } else if (c >= 0xe0) { /* three bytes encoded, 16 bits */ c = ((s[0]&63)<<12) | ((s[1]&63)<<6) | (s[2]&63); s += 3; pos -= 3; } else if (c >= 0xc0) { /* two bytes encoded, 11 bits */ c = ((s[0]&63)<<6) | (s[1]&63); s += 2; pos -= 2; } else { s++; pos--; } newbuf[*newlen] = decoder ? decoder(c) : c; ++*newlen; } if (*newlen < len) { newbuf = erealloc(newbuf, *newlen + 1); } newbuf[*newlen] = '\0'; return newbuf;}/* }}} *//* {{{ _xml_xmlcharlen() */static int _xml_xmlcharlen(const XML_Char *s){ int len = 0; while (*s) { len++; s++; } return len;}/* }}} *//* {{{ _xml_zval_strdup() */PHPAPI char *_xml_zval_strdup(zval *val){ if (Z_TYPE_P(val) == IS_STRING) { char *buf = emalloc(Z_STRLEN_P(val) + 1); memcpy(buf, Z_STRVAL_P(val), Z_STRLEN_P(val)); buf[Z_STRLEN_P(val)] = '\0'; return buf; } return NULL;}/* }}} *//* {{{ _xml_add_to_info */static void _xml_add_to_info(xml_parser *parser,char *name){ zval **element, *values; if (! parser->info) { return; } if (zend_hash_find(Z_ARRVAL_P(parser->info),name,strlen(name) + 1,(void **) &element) == FAILURE) { MAKE_STD_ZVAL(values); if (array_init(values) == FAILURE) { TSRMLS_FETCH(); php_error_docref(NULL TSRMLS_CC, E_ERROR, "Unable to initialize array"); return; } zend_hash_update(Z_ARRVAL_P(parser->info), name, strlen(name)+1, (void *) &values, sizeof(zval*), (void **) &element); } add_next_index_long(*element,parser->curtag); parser->curtag++;}/* }}} *//* {{{ _xml_decode_tag() */static char *_xml_decode_tag(xml_parser *parser, const char *tag){ char *newstr; int out_len; newstr = xml_utf8_decode(tag, strlen(tag), &out_len, parser->target_encoding); if (parser->case_folding) { php_strtoupper(newstr, out_len); } return newstr;}/* }}} *//* {{{ _xml_startElementHandler() */void _xml_startElementHandler(void *userData, const char *name, const char **attributes){ xml_parser *parser = (xml_parser *)userData; const char **attrs = attributes; char *tag_name; char *att, *val; int val_len; zval *retval, *args[3]; if (parser) { parser->level++; tag_name = _xml_decode_tag(parser, name); if (parser->startElementHandler) { args[0] = _xml_resource_zval(parser->index); args[1] = _xml_string_zval(tag_name); MAKE_STD_ZVAL(args[2]); array_init(args[2]); while (attributes && *attributes) { att = _xml_decode_tag(parser, attributes[0]); val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); add_assoc_stringl(args[2], att, val, val_len, 0); attributes += 2; efree(att); } if ((retval = xml_call_handler(parser, parser->startElementHandler, 3, args))) { zval_dtor(retval); efree(retval); } } if (parser->data) { zval *tag, *atr; int atcnt = 0; MAKE_STD_ZVAL(tag); MAKE_STD_ZVAL(atr); array_init(tag); array_init(atr); _xml_add_to_info(parser,((char *) tag_name) + parser->toffset); add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ add_assoc_string(tag,"type","open",1); add_assoc_long(tag,"level",parser->level); parser->ltags[parser->level-1] = estrdup(tag_name); parser->lastwasopen = 1; attributes = attrs; while (attributes && *attributes) { att = _xml_decode_tag(parser, attributes[0]); val = xml_utf8_decode(attributes[1], strlen(attributes[1]), &val_len, parser->target_encoding); add_assoc_stringl(atr,att,val,val_len,0); atcnt++; attributes += 2; efree(att); } if (atcnt) { zend_hash_add(Z_ARRVAL_P(tag),"attributes",sizeof("attributes"),&atr,sizeof(zval*),NULL); } else { zval_dtor(atr); FREE_ZVAL(atr); } zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),(void *) &parser->ctag); } efree(tag_name); }}/* }}} *//* {{{ _xml_endElementHandler() */void _xml_endElementHandler(void *userData, const char *name){ xml_parser *parser = (xml_parser *)userData; char *tag_name; if (parser) { zval *retval, *args[2]; tag_name = _xml_decode_tag(parser, name); if (parser->endElementHandler) { args[0] = _xml_resource_zval(parser->index); args[1] = _xml_string_zval(tag_name); if ((retval = xml_call_handler(parser, parser->endElementHandler, 2, args))) { zval_dtor(retval); efree(retval); } } if (parser->data) { zval *tag; if (parser->lastwasopen) { add_assoc_string(*(parser->ctag),"type","complete",1); } else { MAKE_STD_ZVAL(tag); array_init(tag); _xml_add_to_info(parser,((char *) tag_name) + parser->toffset); add_assoc_string(tag,"tag",((char *) tag_name) + parser->toffset,1); /* cast to avoid gcc-warning */ add_assoc_string(tag,"type","close",1); add_assoc_long(tag,"level",parser->level); zend_hash_next_index_insert(Z_ARRVAL_P(parser->data),&tag,sizeof(zval*),NULL); } parser->lastwasopen = 0; } efree(tag_name); if (parser->ltags) { efree(parser->ltags[parser->level-1]); } parser->level--; }}/* }}} *//* {{{ _xml_characterDataHandler() */void _xml_characterDataHandler(void *userData, const XML_Char *s, int len){ xml_parser *parser = (xml_parser *)userData; if (parser) { zval *retval, *args[2]; if (parser->characterDataHandler) { args[0] = _xml_resource_zval(parser->index); args[1] = _xml_xmlchar_zval(s, len, parser->target_encoding); if ((retval = xml_call_handler(parser, parser->characterDataHandler, 2, args))) { zval_dtor(retval); efree(retval); } } if (parser->data) { int i; int doprint = 0; char *decoded_value; int decoded_len; decoded_value = xml_utf8_decode(s,len,&decoded_len,parser->target_encoding); for (i = 0; i < decoded_len; i++) { switch (decoded_value[i]) { case ' ': case '\t': case '\n': continue; default: doprint = 1; break; } if (doprint) { break; } } if (doprint || (! parser->skipwhite)) { if (parser->lastwasopen) { zval **myval; /* check if the current tag already has a value - if yes append to that! */ if (zend_hash_find(Z_ARRVAL_PP(parser->ctag),"value",sizeof("value"),(void **) &myval) == SUCCESS) { int newlen = Z_STRLEN_PP(myval) + decoded_len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -