#include #include static pbool_t mceQNameLevelLookupEx(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t *pos, pbool_t ignore_ln) { puint32_t i=0; puint32_t j=qname_level_set->list_items; while(ilist_array[m]; int const ns_cmp=(NULL==ns?(NULL==q2->ns?0:-1):(NULL==q2->ns?+1:xmlStrcmp(ns, q2->ns))); int const cmp=(ignore_ln?ns_cmp:(0==ns_cmp?xmlStrcmp(ln, q2->ln):ns_cmp)); if (cmp<0) { j=m; } else if (cmp>0) { i=m+1; } else { *pos=m; return PTRUE; } } PASSERT(i==j); *pos=i; return PFALSE; } mceQNameLevel_t* mceQNameLevelLookup(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, pbool_t ignore_ln) { puint32_t pos=0; return (mceQNameLevelLookupEx(qname_level_set, ns, ln, &pos, ignore_ln)?qname_level_set->list_array+pos:NULL); } pbool_t mceQNameLevelAdd(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t level) { puint32_t i=0; pbool_t ret=PFALSE; if (!mceQNameLevelLookupEx(qname_level_set, ns, ln, &i, PFALSE)) { mceQNameLevel_t *new_list_array=NULL; if (NULL!=(new_list_array=(mceQNameLevel_t *)xmlRealloc(qname_level_set->list_array, (1+qname_level_set->list_items)*sizeof(*qname_level_set->list_array)))) { qname_level_set->list_array=new_list_array; for (puint32_t k=qname_level_set->list_items;k>i;k--) { qname_level_set->list_array[k]=qname_level_set->list_array[k-1]; } qname_level_set->list_items++; PASSERT(i>=0 && ilist_items); memset(&qname_level_set->list_array[i], 0, sizeof(qname_level_set->list_array[i])); qname_level_set->list_array[i].level=level; qname_level_set->list_array[i].ln=(NULL!=ln?xmlStrdup(ln):NULL); qname_level_set->list_array[i].ns=xmlStrdup(ns); if (qname_level_set->max_levelmax_level=level; ret=PTRUE; } } else { ret=PTRUE; } return ret; } pbool_t mceQNameLevelCleanup(mceQNameLevelSet_t *qname_level_set, puint32_t level) { if (qname_level_set->max_level>=level) { qname_level_set->max_level=0; puint32_t i=0; for(puint32_t j=0;jlist_items;j++) { if (qname_level_set->list_array[j].level>=level) { PASSERT(qname_level_set->list_array[j].level==level); // cleanup should be called for every level... if (NULL!=qname_level_set->list_array[j].ln) xmlFree(qname_level_set->list_array[j].ln); if (NULL!=qname_level_set->list_array[j].ns) xmlFree(qname_level_set->list_array[j].ns); } else { if (qname_level_set->list_array[j].level>qname_level_set->max_level) { qname_level_set->max_level=qname_level_set->list_array[j].level; } qname_level_set->list_array[i++]=qname_level_set->list_array[j]; } } qname_level_set->list_items=i; } PASSERT(0==level || qname_level_set->max_levelstack_array, (1+skip_stack->stack_items)*sizeof(*skip_stack->stack_array)))) { skip_stack->stack_array=new_stack_array; memset(&skip_stack->stack_array[skip_stack->stack_items], 0, sizeof(skip_stack->stack_array[skip_stack->stack_items])); skip_stack->stack_array[skip_stack->stack_items].level_start=level_start; skip_stack->stack_array[skip_stack->stack_items].level_end=level_end; skip_stack->stack_array[skip_stack->stack_items].state=state; skip_stack->stack_items++; ret=PTRUE; } return ret; } void mceSkipStackPop(mceSkipStack_t *skip_stack) { PASSERT(skip_stack->stack_items>0); skip_stack->stack_items--; } mceSkipItem_t *mceSkipStackTop(mceSkipStack_t *skip_stack) { return NULL!=skip_stack->stack_array && skip_stack->stack_items>0 ? &skip_stack->stack_array[skip_stack->stack_items-1] : NULL; } pbool_t mceSkipStackSkip(mceSkipStack_t *skip_stack, puint32_t level) { return NULL!=skip_stack->stack_array && skip_stack->stack_items>0 && level>=skip_stack->stack_array[skip_stack->stack_items-1].level_start && levelstack_array[skip_stack->stack_items-1].level_end; } pbool_t mceCtxInit(mceCtx_t *ctx) { memset(ctx, 0, sizeof(*ctx)); mceCtxSuspendProcessing(ctx, _X("http://schemas.openxmlformats.org/presentationml/2006/main"), _X("extLst")); return PTRUE; } pbool_t mceCtxCleanup(mceCtx_t *ctx) { PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->ignorable_set.list_items); PENSURE(mceQNameLevelCleanup(&ctx->ignorable_set, 0)); PENSURE(mceQNameLevelCleanup(&ctx->understands_set, 0)); PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->skip_stack.stack_items); while (NULL!=mceSkipStackTop(&ctx->skip_stack)) mceSkipStackPop(&ctx->skip_stack); PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->processcontent_set.list_items); PENSURE(mceQNameLevelCleanup(&ctx->processcontent_set, 0)); PENSURE(mceQNameLevelCleanup(&ctx->suspended_set, 0)); PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->suspended_level); #if (MCE_NAMESPACE_SUBSUMPTION_ENABLED) PENSURE(mceQNameLevelCleanup(&ctx->subsume_namespace_set, 0)); PENSURE(mceQNameLevelCleanup(&ctx->subsume_exclude_set, 0)); PENSURE(mceQNameLevelCleanup(&ctx->subsume_prefix_set, 0)); #endif if (NULL!=ctx->ignorable_set.list_array) xmlFree(ctx->ignorable_set.list_array); if (NULL!=ctx->understands_set.list_array) xmlFree(ctx->understands_set.list_array); if (NULL!=ctx->skip_stack.stack_array) xmlFree(ctx->skip_stack.stack_array); if (NULL!=ctx->processcontent_set.list_array) xmlFree(ctx->processcontent_set.list_array); if (NULL!=ctx->suspended_set.list_array) xmlFree(ctx->suspended_set.list_array); #if (MCE_NAMESPACE_SUBSUMPTION_ENABLED) if (NULL!=ctx->subsume_namespace_set.list_array) xmlFree(ctx->subsume_namespace_set.list_array); if (NULL!=ctx->subsume_exclude_set.list_array) xmlFree(ctx->subsume_exclude_set.list_array); if (NULL!=ctx->subsume_prefix_set.list_array) xmlFree(ctx->subsume_prefix_set.list_array); #endif return PTRUE; } pbool_t mceCtxUnderstandsNamespace(mceCtx_t *ctx, const xmlChar *ns) { return mceQNameLevelAdd(&ctx->understands_set, ns, NULL, 0); } pbool_t mceCtxSuspendProcessing(mceCtx_t *ctx, const xmlChar *ns, const xmlChar *ln) { return mceQNameLevelAdd(&ctx->suspended_set, ns, ln, 0); } #if (MCE_NAMESPACE_SUBSUMPTION_ENABLED) pbool_t mceCtxSubsumeNamespace(mceCtx_t *ctx, const xmlChar *prefix_new, const xmlChar *ns_new, const xmlChar *ns_old) { return mceQNameLevelAdd(&ctx->subsume_namespace_set, ns_old, ns_new, 0) && mceQNameLevelAdd(&ctx->subsume_prefix_set, ns_new, prefix_new, 0); } #endif