helper.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. #include <mce/helper.h>
  2. #include <libxml/xmlmemory.h>
  3. static pbool_t mceQNameLevelLookupEx(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t *pos, pbool_t ignore_ln) {
  4. puint32_t i=0;
  5. puint32_t j=qname_level_set->list_items;
  6. while(i<j) {
  7. puint32_t m=i+(j-i)/2;
  8. PASSERT(i<=m && m<j);
  9. mceQNameLevel_t *q2=&qname_level_set->list_array[m];
  10. int const ns_cmp=(NULL==ns?(NULL==q2->ns?0:-1):(NULL==q2->ns?+1:xmlStrcmp(ns, q2->ns)));
  11. int const cmp=(ignore_ln?ns_cmp:(0==ns_cmp?xmlStrcmp(ln, q2->ln):ns_cmp));
  12. if (cmp<0) { j=m; } else if (cmp>0) { i=m+1; } else { *pos=m; return PTRUE; }
  13. }
  14. PASSERT(i==j);
  15. *pos=i;
  16. return PFALSE;
  17. }
  18. mceQNameLevel_t* mceQNameLevelLookup(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, pbool_t ignore_ln) {
  19. puint32_t pos=0;
  20. return (mceQNameLevelLookupEx(qname_level_set, ns, ln, &pos, ignore_ln)?qname_level_set->list_array+pos:NULL);
  21. }
  22. pbool_t mceQNameLevelAdd(mceQNameLevelSet_t *qname_level_set, const xmlChar *ns, const xmlChar *ln, puint32_t level) {
  23. puint32_t i=0;
  24. pbool_t ret=PFALSE;
  25. if (!mceQNameLevelLookupEx(qname_level_set, ns, ln, &i, PFALSE)) {
  26. mceQNameLevel_t *new_list_array=NULL;
  27. 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)))) {
  28. qname_level_set->list_array=new_list_array;
  29. for (puint32_t k=qname_level_set->list_items;k>i;k--) {
  30. qname_level_set->list_array[k]=qname_level_set->list_array[k-1];
  31. }
  32. qname_level_set->list_items++;
  33. PASSERT(i>=0 && i<qname_level_set->list_items);
  34. memset(&qname_level_set->list_array[i], 0, sizeof(qname_level_set->list_array[i]));
  35. qname_level_set->list_array[i].level=level;
  36. qname_level_set->list_array[i].ln=(NULL!=ln?xmlStrdup(ln):NULL);
  37. qname_level_set->list_array[i].ns=xmlStrdup(ns);
  38. if (qname_level_set->max_level<level) qname_level_set->max_level=level;
  39. ret=PTRUE;
  40. }
  41. } else {
  42. ret=PTRUE;
  43. }
  44. return ret;
  45. }
  46. pbool_t mceQNameLevelCleanup(mceQNameLevelSet_t *qname_level_set, puint32_t level) {
  47. if (qname_level_set->max_level>=level) {
  48. qname_level_set->max_level=0;
  49. puint32_t i=0;
  50. for(puint32_t j=0;j<qname_level_set->list_items;j++) {
  51. if (qname_level_set->list_array[j].level>=level) {
  52. PASSERT(qname_level_set->list_array[j].level==level); // cleanup should be called for every level...
  53. if (NULL!=qname_level_set->list_array[j].ln) xmlFree(qname_level_set->list_array[j].ln);
  54. if (NULL!=qname_level_set->list_array[j].ns) xmlFree(qname_level_set->list_array[j].ns);
  55. } else {
  56. if (qname_level_set->list_array[j].level>qname_level_set->max_level) {
  57. qname_level_set->max_level=qname_level_set->list_array[j].level;
  58. }
  59. qname_level_set->list_array[i++]=qname_level_set->list_array[j];
  60. }
  61. }
  62. qname_level_set->list_items=i;
  63. }
  64. PASSERT(0==level || qname_level_set->max_level<level);
  65. return PTRUE;
  66. }
  67. pbool_t mceSkipStackPush(mceSkipStack_t *skip_stack, puint32_t level_start, puint32_t level_end, mceSkipState_t state) {
  68. pbool_t ret=PFALSE;
  69. mceSkipItem_t *new_stack_array=NULL;
  70. if (NULL!=(new_stack_array=(mceSkipItem_t *)xmlRealloc(skip_stack->stack_array, (1+skip_stack->stack_items)*sizeof(*skip_stack->stack_array)))) {
  71. skip_stack->stack_array=new_stack_array;
  72. memset(&skip_stack->stack_array[skip_stack->stack_items], 0, sizeof(skip_stack->stack_array[skip_stack->stack_items]));
  73. skip_stack->stack_array[skip_stack->stack_items].level_start=level_start;
  74. skip_stack->stack_array[skip_stack->stack_items].level_end=level_end;
  75. skip_stack->stack_array[skip_stack->stack_items].state=state;
  76. skip_stack->stack_items++;
  77. ret=PTRUE;
  78. }
  79. return ret;
  80. }
  81. void mceSkipStackPop(mceSkipStack_t *skip_stack) {
  82. PASSERT(skip_stack->stack_items>0);
  83. skip_stack->stack_items--;
  84. }
  85. mceSkipItem_t *mceSkipStackTop(mceSkipStack_t *skip_stack) {
  86. return NULL!=skip_stack->stack_array && skip_stack->stack_items>0 ? &skip_stack->stack_array[skip_stack->stack_items-1] : NULL;
  87. }
  88. pbool_t mceSkipStackSkip(mceSkipStack_t *skip_stack, puint32_t level) {
  89. return NULL!=skip_stack->stack_array && skip_stack->stack_items>0
  90. && level>=skip_stack->stack_array[skip_stack->stack_items-1].level_start
  91. && level<skip_stack->stack_array[skip_stack->stack_items-1].level_end;
  92. }
  93. pbool_t mceCtxInit(mceCtx_t *ctx) {
  94. memset(ctx, 0, sizeof(*ctx));
  95. mceCtxSuspendProcessing(ctx, _X("http://schemas.openxmlformats.org/presentationml/2006/main"), _X("extLst"));
  96. return PTRUE;
  97. }
  98. pbool_t mceCtxCleanup(mceCtx_t *ctx) {
  99. PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->ignorable_set.list_items);
  100. PENSURE(mceQNameLevelCleanup(&ctx->ignorable_set, 0));
  101. PENSURE(mceQNameLevelCleanup(&ctx->understands_set, 0));
  102. PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->skip_stack.stack_items);
  103. while (NULL!=mceSkipStackTop(&ctx->skip_stack)) mceSkipStackPop(&ctx->skip_stack);
  104. PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->processcontent_set.list_items);
  105. PENSURE(mceQNameLevelCleanup(&ctx->processcontent_set, 0));
  106. PENSURE(mceQNameLevelCleanup(&ctx->suspended_set, 0));
  107. PASSERT(ctx->error!=MCE_ERROR_NONE || 0==ctx->suspended_level);
  108. #if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
  109. PENSURE(mceQNameLevelCleanup(&ctx->subsume_namespace_set, 0));
  110. PENSURE(mceQNameLevelCleanup(&ctx->subsume_exclude_set, 0));
  111. PENSURE(mceQNameLevelCleanup(&ctx->subsume_prefix_set, 0));
  112. #endif
  113. if (NULL!=ctx->ignorable_set.list_array) xmlFree(ctx->ignorable_set.list_array);
  114. if (NULL!=ctx->understands_set.list_array) xmlFree(ctx->understands_set.list_array);
  115. if (NULL!=ctx->skip_stack.stack_array) xmlFree(ctx->skip_stack.stack_array);
  116. if (NULL!=ctx->processcontent_set.list_array) xmlFree(ctx->processcontent_set.list_array);
  117. if (NULL!=ctx->suspended_set.list_array) xmlFree(ctx->suspended_set.list_array);
  118. #if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
  119. if (NULL!=ctx->subsume_namespace_set.list_array) xmlFree(ctx->subsume_namespace_set.list_array);
  120. if (NULL!=ctx->subsume_exclude_set.list_array) xmlFree(ctx->subsume_exclude_set.list_array);
  121. if (NULL!=ctx->subsume_prefix_set.list_array) xmlFree(ctx->subsume_prefix_set.list_array);
  122. #endif
  123. return PTRUE;
  124. }
  125. pbool_t mceCtxUnderstandsNamespace(mceCtx_t *ctx, const xmlChar *ns) {
  126. return mceQNameLevelAdd(&ctx->understands_set, ns, NULL, 0);
  127. }
  128. pbool_t mceCtxSuspendProcessing(mceCtx_t *ctx, const xmlChar *ns, const xmlChar *ln) {
  129. return mceQNameLevelAdd(&ctx->suspended_set, ns, ln, 0);
  130. }
  131. #if (MCE_NAMESPACE_SUBSUMPTION_ENABLED)
  132. pbool_t mceCtxSubsumeNamespace(mceCtx_t *ctx, const xmlChar *prefix_new, const xmlChar *ns_new, const xmlChar *ns_old) {
  133. return mceQNameLevelAdd(&ctx->subsume_namespace_set, ns_old, ns_new, 0)
  134. && mceQNameLevelAdd(&ctx->subsume_prefix_set, ns_new, prefix_new, 0);
  135. }
  136. #endif