static int cdata_hook(void *udata, char *data, size_t len) { int ret; int nw_off, nw_len; char *nw_data, *cur, *dlr; sax_usrdata_t *ptSaxUsrData; xdf4c_df_t *pDf; xdf4c_field_t *a_field; xdf4c_record_t *a_record; char tmp[64 + 1]; int i; char x; ptSaxUsrData = (sax_usrdata_t *)udata; pDf = ptSaxUsrData->pDf; for (i = 0; i < len; i ++) { x = data[i]; if (NOT_WHITESPACE(x)) { break; } } if (i == len) { return SAX_OK; } nw_off = i; nw_len = len - nw_off; nw_data = data + nw_off; if (ptSaxUsrData->depth < 3) return SAX_OK; switch (ptSaxUsrData->tNode[ptSaxUsrData->depth - 2].type) { case TAG_TYPE_DH: if (nw_len >= sizeof(tmp)) { xdf4c_error("length [%d] of data is too larger than max [%d]", len, sizeof(tmp) - 1); return SAX_HOOK; } memcpy(tmp, nw_data, nw_len); tmp[nw_len] = 0; if (!strcmp(ptSaxUsrData->tNode[ptSaxUsrData->depth - 1].name, XML_TAG_DATA_NAME)) { snprintf(pDf->mass.data_name, sizeof(pDf->mass.data_name), "%s", tmp); pDf->pInstance = xdf4c_instance_get(pDf->mass.data_name); if (!pDf->pInstance) { xdf4c_error("xdf4c_instance_get fail: name = %s", ptSaxUsrData->tNode[ptSaxUsrData->depth - 1].name); return SAX_HOOK; } break; } if (!strcmp(ptSaxUsrData->tNode[ptSaxUsrData->depth - 1].name, XML_TAG_DATA_TYPE)) { snprintf(pDf->mass.data_type, sizeof(pDf->mass.data_type), "%s", tmp); break; } if (!strcmp(ptSaxUsrData->tNode[ptSaxUsrData->depth - 1].name, XML_TAG_ROW_NUM)) { pDf->mass.row_num = atoi(tmp); break; } if (!strncmp(ptSaxUsrData->tNode[ptSaxUsrData->depth - 1].name, XML_TAG_FIELD_NAME, strlen(XML_TAG_FIELD_NAME))) { if (!pDf->mass.record->rec_name[0]) { strcpy(pDf->mass.record->rec_name, pDf->pInstance->ins_record->rec_name); strcpy(pDf->mass.record->rec_delimiter, pDf->pInstance->ins_record->rec_delimiter); strcpy(pDf->mass.record->rec_terminator, pDf->pInstance->ins_record->rec_terminator); pDf->pSax->user_tag = pDf->mass.record->rec_terminator; } a_field = xdf4c_record_get_field(pDf->pInstance->ins_record, tmp); if (!a_field) { xdf4c_error("xdf4c_record_get_field fail: name = %s", tmp); return SAX_HOOK; } if (xdf4c_record_add_field(pDf->mass.record, a_field)) { xdf4c_error("xdf4c_record_add_field fail: name = %s", a_field->fld_name); return SAX_HOOK; } break; } break; case TAG_TYPE_DB: if (!strcmp(ptSaxUsrData->tNode[ptSaxUsrData->depth - 1].name, XML_TAG_PAGE)) { char field_data[FIELD_DATA_SIZE + 1]; int field_data_len = 0; json_object *obj = pDf->objs.record_list[pDf->objs.record_count ++]; if (gpXdf4cCfg->config.needcheck) { pDf->mass.row_num --; pDf->page.record_num --; } a_record = pDf->mass.record; for (cur = nw_data, i = 0; cur < nw_data + nw_len && i < a_record->fields_count; cur += strlen(a_record->rec_delimiter), i ++) { dlr = strstr(cur, a_record->rec_delimiter); if (dlr && dlr < nw_data + nw_len) { field_data_len = xdf4c_format_txt_content(field_data, sizeof(field_data), cur, dlr - cur); } else { field_data_len = xdf4c_format_txt_content(field_data, sizeof(field_data), cur, nw_len - (cur - nw_data)); } if (0 > field_data_len) { xdf4c_error("xdf4c_format_txt_content fail: %d", field_data_len); return SAX_HOOK; } else { field_data[field_data_len] = 0; } json_object_object_add(obj, a_record->fields_list[i].fld_name, json_object_new_string(field_data)); if (!(cur = dlr)) break; } json_object_array_set_length(pDf->objs.user_record, pDf->objs.record_count); if (pDf->objs.record_count >= gpXdf4cCfg->config.cachesize) { xdf4c_debug("%s", json_object_to_json_string(pDf->objs.user_data)); if (pDf->user.deal_func && (ret = pDf->user.deal_func(pDf->user.user_data, json_object_to_json_string(pDf->objs.user_data), 0))) { if (pDf->user.done_func) pDf->user.done_func(pDf->user.user_data, ret); xdf4c_error("call user.before_func fail"); return SAX_HOOK; } pDf->objs.record_count = 0; } break; } break; default: break; } return SAX_OK; }
static enum ikserror sax_core (iksparser *prs, char *buf, int len) { enum ikserror err; int pos = 0, old = 0, re, stack_old = -1; unsigned char c; while (pos < len) { re = 0; c = buf[pos]; if (0 == c || 0xFE == c || 0xFF == c) return IKS_BADXML; if (prs->uni_max) { if ((c & 0xC0) != 0x80) return IKS_BADXML; prs->uni_char <<= 6; prs->uni_char += (c & 0x3f); prs->uni_len++; if (prs->uni_len == prs->uni_max) { /* Security check: avoid overlong sequences */ if (prs->uni_max == 2 && prs->uni_char < 0x80) return IKS_BADXML; if (prs->uni_max == 3 && prs->uni_char < 0x7FF) return IKS_BADXML; if (prs->uni_max == 4 && prs->uni_char < 0xffff) return IKS_BADXML; if (prs->uni_max == 5 && prs->uni_char < 0x1fffff) return IKS_BADXML; if (prs->uni_max == 6 && prs->uni_char < 0x3ffffff) return IKS_BADXML; prs->uni_max = 0; prs->uni_char = 0; } goto cont; } else { if (c & 0x80) { unsigned char mask; if ((c & 0x60) == 0x40) { prs->uni_max = 2; mask = 0x1F; } else if ((c & 0x70) == 0x60) { prs->uni_max = 3; mask = 0x0F; } else if ((c & 0x78) == 0x70) { prs->uni_max = 4; mask = 0x07; } else if ((c & 0x7C) == 0x78) { prs->uni_max = 5; mask = 0x03; } else if ((c & 0x7E) == 0x7C) { prs->uni_max = 6; mask = 0x01; } else { return IKS_BADXML; } prs->uni_char = c & mask; prs->uni_len = 1; if (stack_old == -1 && (prs->context == C_TAG || prs->context == C_ATTRIBUTE_1 || prs->context == C_VALUE_APOS || prs->context == C_VALUE_QUOT)) stack_old = pos; goto cont; } } switch (prs->context) { case C_CDATA: if ('&' == c) { if (old < pos && prs->cdataHook) { err = prs->cdataHook (prs->user_data, &buf[old], pos - old); if (IKS_OK != err) return err; } prs->context = C_ENTITY; prs->entpos = 0; break; } if ('<' == c) { if (old < pos && prs->cdataHook) { err = prs->cdataHook (prs->user_data, &buf[old], pos - old); if (IKS_OK != err) return err; } STACK_INIT; prs->tag_name = STACK_PUSH_START; if (!prs->tag_name) return IKS_NOMEM; prs->context = C_TAG_START; } break; case C_TAG_START: prs->context = C_TAG; if ('/' == c) { prs->tagtype = IKS_CLOSE; break; } if ('?' == c) { prs->context = C_PI; break; } if ('!' == c) { prs->context = C_MARKUP; break; } prs->tagtype = IKS_OPEN; stack_old = pos; break; case C_TAG: if (IS_WHITESPACE(c)) { if (IKS_CLOSE == prs->tagtype) prs->oldcontext = C_TAG_END; else prs->oldcontext = C_ATTRIBUTE; prs->context = C_WHITESPACE; if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; break; } if ('/' == c) { if (IKS_CLOSE == prs->tagtype) return IKS_BADXML; prs->tagtype = IKS_SINGLE; prs->context = C_TAG_END; if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; break; } if ('>' == c) { prs->context = C_TAG_END; if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; re = 1; break; } if (stack_old == -1) stack_old = pos; break; case C_TAG_END: if (c != '>') return IKS_BADXML; if (prs->tagHook) { char **tmp; if (prs->attcur == 0) tmp = NULL; else tmp = prs->atts; err = prs->tagHook (prs->user_data, prs->tag_name, tmp, prs->tagtype); if (IKS_OK != err) return err; } prs->stack_pos = 0; stack_old = -1; prs->attcur = 0; prs->attflag = 0; prs->context = C_CDATA; old = pos + 1; break; case C_ATTRIBUTE: if ('/' == c) { prs->tagtype = IKS_SINGLE; prs->context = C_TAG_END; break; } if ('>' == c) { prs->context = C_TAG_END; re = 1; break; } if (!prs->atts) { prs->attmax = 12; prs->atts = iks_malloc (sizeof(char *) * 2 * 12); if (!prs->atts) return IKS_NOMEM; memset (prs->atts, 0, sizeof(char *) * 2 * 12); prs->attcur = 0; } else { if (prs->attcur >= ((prs->attmax - 1) * 2)) { void *tmp; prs->attmax += 12; tmp = iks_malloc (sizeof(char *) * 2 * prs->attmax); if (!tmp) return IKS_NOMEM; memset (tmp, 0, sizeof(char *) * 2 * prs->attmax); memcpy (tmp, prs->atts, sizeof(char *) * prs->attcur); free (prs->atts); prs->atts = tmp; } } prs->attflag = 1; prs->atts[prs->attcur] = STACK_PUSH_START; stack_old = pos; prs->context = C_ATTRIBUTE_1; break; case C_ATTRIBUTE_1: if ('=' == c) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->context = C_VALUE; break; } if (IS_WHITESPACE(c)) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->oldcontext = C_ATTRIBUTE_1; prs->context = C_WHITESPACE; break; } if (stack_old == -1) stack_old = pos; break; case C_ATTRIBUTE_2: if ('/' == c) { prs->tagtype = IKS_SINGLE; prs->atts[prs->attcur] = NULL; prs->context = C_TAG_END; break; } if ('>' == c) { prs->atts[prs->attcur] = NULL; prs->context = C_TAG_END; re = 1; break; } prs->context = C_ATTRIBUTE; re = 1; break; case C_VALUE: if (IS_WHITESPACE(c)) break; prs->atts[prs->attcur + 1] = STACK_PUSH_START; if ('\'' == c) { prs->context = C_VALUE_APOS; break; } if ('"' == c) { prs->context = C_VALUE_QUOT; break; } return IKS_BADXML; case C_VALUE_APOS: if ('\'' == c) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->oldcontext = C_ATTRIBUTE_2; prs->context = C_WHITESPACE; prs->attcur += 2; } if (stack_old == -1) stack_old = pos; break; case C_VALUE_QUOT: if ('"' == c) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->oldcontext = C_ATTRIBUTE_2; prs->context = C_WHITESPACE; prs->attcur += 2; } if (stack_old == -1) stack_old = pos; break; case C_WHITESPACE: if (NOT_WHITESPACE(c)) { prs->context = prs->oldcontext; re = 1; } break; case C_ENTITY: if (';' == c) { char hede[2]; char t = '?'; prs->entity[prs->entpos] = '\0'; if (strcmp(prs->entity, "amp") == 0) t = '&'; else if (strcmp(prs->entity, "quot") == 0) t = '"'; else if (strcmp(prs->entity, "apos") == 0) t = '\''; else if (strcmp(prs->entity, "lt") == 0) t = '<'; else if (strcmp(prs->entity, "gt") == 0) t = '>'; old = pos + 1; hede[0] = t; if (prs->cdataHook) { err = prs->cdataHook (prs->user_data, &hede[0], 1); if (IKS_OK != err) return err; } prs->context = C_CDATA; } else { prs->entity[prs->entpos++] = buf[pos]; if (prs->entpos > 7) return IKS_BADXML; } break; case C_COMMENT: if ('-' != c) return IKS_BADXML; prs->context = C_COMMENT_1; break; case C_COMMENT_1: if ('-' == c) prs->context = C_COMMENT_2; break; case C_COMMENT_2: if ('-' == c) prs->context = C_COMMENT_3; else prs->context = C_COMMENT_1; break; case C_COMMENT_3: if ('>' != c) return IKS_BADXML; prs->context = C_CDATA; old = pos + 1; break; case C_MARKUP: if ('[' == c) { prs->context = C_SECT; break; } if ('-' == c) { prs->context = C_COMMENT; break; } prs->context = C_MARKUP_1; case C_MARKUP_1: if ('>' == c) { old = pos + 1; prs->context = C_CDATA; } break; case C_SECT: if ('C' == c) { prs->context = C_SECT_CDATA; break; } return IKS_BADXML; case C_SECT_CDATA: if ('D' != c) return IKS_BADXML; prs->context = C_SECT_CDATA_1; break; case C_SECT_CDATA_1: if ('A' != c) return IKS_BADXML; prs->context = C_SECT_CDATA_2; break; case C_SECT_CDATA_2: if ('T' != c) return IKS_BADXML; prs->context = C_SECT_CDATA_3; break; case C_SECT_CDATA_3: if ('A' != c) return IKS_BADXML; prs->context = C_SECT_CDATA_4; break; case C_SECT_CDATA_4: if ('[' != c) return IKS_BADXML; old = pos + 1; prs->context = C_SECT_CDATA_C; break; case C_SECT_CDATA_C: if (']' == c) { prs->context = C_SECT_CDATA_E; if (prs->cdataHook && old < pos) { err = prs->cdataHook (prs->user_data, &buf[old], pos - old); if (IKS_OK != err) return err; } } break; case C_SECT_CDATA_E: if (']' == c) { prs->context = C_SECT_CDATA_E2; } else { if (prs->cdataHook) { err = prs->cdataHook (prs->user_data, "]", 1); if (IKS_OK != err) return err; } old = pos; prs->context = C_SECT_CDATA_C; } break; case C_SECT_CDATA_E2: if ('>' == c) { old = pos + 1; prs->context = C_CDATA; } else { if (prs->cdataHook) { err = prs->cdataHook (prs->user_data, "]]", 2); if (IKS_OK != err) return err; } old = pos; prs->context = C_SECT_CDATA_C; } break; case C_PI: old = pos + 1; if ('>' == c) prs->context = C_CDATA; break; } cont: if (0 == re) { pos++; prs->nr_bytes++; if ('\n' == c) prs->nr_lines++; } } if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); err = IKS_OK; if (prs->cdataHook && (prs->context == C_CDATA || prs->context == C_SECT_CDATA_C) && old < pos) err = prs->cdataHook (prs->user_data, &buf[old], pos - old); return err; }
static enum saxerror sax_core (sax_parser_t *prs, char *buf, int len) { enum saxerror err; int pos = 0, old = 0, re, stack_old = -1; unsigned char c; while (pos < len) { re = 0; c = buf[pos]; if (0 == c) return SAX_BADXML; if (prs->encode_max) { prs->encode_len++; if (prs->encode_len == prs->encode_max) prs->encode_max = 0; goto cont; } else { if (c & 0x80) { /* only support ANSI */ prs->encode_max = 2; prs->encode_len = 1; if (stack_old == -1 && (prs->context == C_TAG || prs->context == C_ATTRIBUTE_1 || prs->context == C_VALUE_APOS || prs->context == C_VALUE_QUOT)) stack_old = pos; goto cont; } } switch (prs->context) { case C_CDATA: #if 0 if ('&' == c) { if (old < pos && prs->cdataHook) { err = prs->cdataHook (prs->user_data, &buf[old], pos - old); if (SAX_OK != err) return err; } prs->context = C_ENTITY; prs->entpos = 0; break; } #endif if ('<' == c) { if (old < pos && prs->cdataHook) { err = prs->cdataHook (prs->user_data, &buf[old], pos - old); if (SAX_OK != err) return err; } STACK_INIT; prs->tag_name = STACK_PUSH_START; if (!prs->tag_name) return SAX_NOMEM; prs->context = C_TAG_START; } if (is_tail_user_tag(buf, old, pos, prs->user_tag)) { if (old < pos && prs->cdataHook) { err = prs->cdataHook (prs->user_data, &buf[old], pos - old - strlen(prs->user_tag) + 1); if (SAX_OK != err) return err; } old = pos + 1; } break; case C_TAG_START: prs->context = C_TAG; if ('/' == c) { prs->tagtype = TAG_CLOSE; break; } if ('?' == c) { prs->context = C_PI; break; } if ('!' == c) { prs->context = C_MARKUP; break; } prs->tagtype = TAG_OPEN; stack_old = pos; break; case C_TAG: if (IS_WHITESPACE(c)) { if (TAG_CLOSE == prs->tagtype) prs->oldcontext = C_TAG_END; else prs->oldcontext = C_ATTRIBUTE; prs->context = C_WHITESPACE; if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; break; } if ('/' == c) { if (TAG_CLOSE == prs->tagtype) return SAX_BADXML; prs->tagtype = TAG_SINGLE; prs->context = C_TAG_END; if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; break; } if ('>' == c) { prs->context = C_TAG_END; if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; re = 1; break; } if (stack_old == -1) stack_old = pos; break; case C_TAG_END: if (c != '>') return SAX_BADXML; if (prs->tagHook) { char **tmp; if (prs->attcur == 0) tmp = NULL; else tmp = prs->atts; err = prs->tagHook (prs->user_data, prs->tag_name, tmp, prs->tagtype); if (SAX_OK != err) return err; } prs->stack_pos = 0; stack_old = -1; prs->attcur = 0; prs->attflag = 0; prs->context = C_CDATA; old = pos + 1; break; case C_ATTRIBUTE: if ('/' == c) { prs->tagtype = TAG_SINGLE; prs->context = C_TAG_END; break; } if ('>' == c) { prs->context = C_TAG_END; re = 1; break; } if (!prs->atts) { prs->attmax = 12; prs->atts = malloc(sizeof(char *) * 2 * 12); if (!prs->atts) return SAX_NOMEM; memset(prs->atts, 0, sizeof(char *) * 2 * 12); prs->attcur = 0; } else { if (prs->attcur >= (prs->attmax * 2)) { void *tmp; prs->attmax += 12; tmp = malloc(sizeof(char *) * 2 * prs->attmax); if (!tmp) return SAX_NOMEM; memset(tmp, 0, sizeof(char *) * 2 * prs->attmax); memcpy(tmp, prs->atts, sizeof(char *) * prs->attcur); free(prs->atts); prs->atts = tmp; } } prs->attflag = 1; prs->atts[prs->attcur] = STACK_PUSH_START; stack_old = pos; prs->context = C_ATTRIBUTE_1; break; case C_ATTRIBUTE_1: if ('=' == c) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->context = C_VALUE; break; } if (stack_old == -1) stack_old = pos; break; case C_ATTRIBUTE_2: if ('/' == c) { prs->tagtype = TAG_SINGLE; prs->atts[prs->attcur] = NULL; prs->context = C_TAG_END; break; } if ('>' == c) { prs->atts[prs->attcur] = NULL; prs->context = C_TAG_END; re = 1; break; } prs->context = C_ATTRIBUTE; re = 1; break; case C_VALUE: prs->atts[prs->attcur + 1] = STACK_PUSH_START; if ('\'' == c) { prs->context = C_VALUE_APOS; break; } if ('"' == c) { prs->context = C_VALUE_QUOT; break; } return SAX_BADXML; case C_VALUE_APOS: if ('\'' == c) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->oldcontext = C_ATTRIBUTE_2; prs->context = C_WHITESPACE; prs->attcur += 2; } if (stack_old == -1) stack_old = pos; break; case C_VALUE_QUOT: if ('"' == c) { if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); stack_old = -1; STACK_PUSH_END; prs->oldcontext = C_ATTRIBUTE_2; prs->context = C_WHITESPACE; prs->attcur += 2; } if (stack_old == -1) stack_old = pos; break; case C_WHITESPACE: if (NOT_WHITESPACE(c)) { prs->context = prs->oldcontext; re = 1; } break; case C_ENTITY: if (';' == c) { char hede[2]; char t = '?'; prs->entity[prs->entpos] = 0; if (strcmp(prs->entity, "amp") == 0) t = '&'; else if (strcmp(prs->entity, "quot") == 0) t = '"'; else if (strcmp(prs->entity, "apos") == 0) t = '\''; else if (strcmp(prs->entity, "lt") == 0) t = '<'; else if (strcmp(prs->entity, "gt") == 0) t = '>'; old = pos + 1; hede[0] = t; if (prs->cdataHook) { err = prs->cdataHook (prs->user_data, &hede[0], 1); if (SAX_OK != err) return err; } prs->context = C_CDATA; } else { prs->entity[prs->entpos++] = buf[pos]; if (prs->entpos > 7) return SAX_BADXML; } break; case C_COMMENT: if ('-' != c) return SAX_BADXML; prs->context = C_COMMENT_1; break; case C_COMMENT_1: if ('-' == c) prs->context = C_COMMENT_2; break; case C_COMMENT_2: if ('-' == c) prs->context = C_COMMENT_3; else prs->context = C_COMMENT_1; break; case C_COMMENT_3: if ('>' != c) return SAX_BADXML; prs->context = C_CDATA; old = pos + 1; break; case C_MARKUP: if ('[' == c) { prs->context = C_SECT; break; } if ('-' == c) { prs->context = C_COMMENT; break; } prs->context = C_MARKUP_1; case C_MARKUP_1: if ('>' == c) { old = pos + 1; prs->context = C_CDATA; } break; case C_SECT: if ('C' == c) { prs->context = C_SECT_CDATA; break; } return SAX_BADXML; case C_SECT_CDATA: if ('D' != c) return SAX_BADXML; prs->context = C_SECT_CDATA_1; break; case C_SECT_CDATA_1: if ('A' != c) return SAX_BADXML; prs->context = C_SECT_CDATA_2; break; case C_SECT_CDATA_2: if ('T' != c) return SAX_BADXML; prs->context = C_SECT_CDATA_3; break; case C_SECT_CDATA_3: if ('A' != c) return SAX_BADXML; prs->context = C_SECT_CDATA_4; break; case C_SECT_CDATA_4: if ('[' != c) return SAX_BADXML; old = pos + 1; prs->context = C_SECT_CDATA_C; break; case C_SECT_CDATA_C: if (']' == c) { prs->context = C_SECT_CDATA_E; if (prs->ctxtHook && old < pos) { err = prs->ctxtHook (prs->user_data, &buf[old], pos - old); if (SAX_OK != err) return err; } } break; case C_SECT_CDATA_E: if (']' == c) { prs->context = C_SECT_CDATA_E2; } else { if (prs->ctxtHook) { err = prs->ctxtHook (prs->user_data, "]", 1); if (SAX_OK != err) return err; } old = pos; prs->context = C_SECT_CDATA_C; } break; case C_SECT_CDATA_E2: if ('>' == c) { old = pos + 1; prs->context = C_CDATA; } else { if (prs->ctxtHook) { err = prs->ctxtHook (prs->user_data, "]]", 2); if (SAX_OK != err) return err; } old = pos; prs->context = C_SECT_CDATA_C; } break; case C_PI: old = pos + 1; if ('>' == c) prs->context = C_CDATA; break; } cont: if (0 == re) { pos++; prs->nr_bytes++; if ('\n' == c) prs->nr_lines++; } } if (stack_old != -1) STACK_PUSH (buf + stack_old, pos - stack_old); err = SAX_OK; if (prs->context == C_CDATA || prs->context == C_SECT_CDATA_C) { prs->rewind_bytes = old - pos; } return err; }