/* * canonizes all range specs within a set preserving the order * returns true if the set is valid after canonization; * the set is valid if * - all range specs are valid and * - there is at least one range spec */ int httpHdrRangeCanonize(HttpHdrRange * range, ssize_t clen) { int i; HttpHdrRangeSpec *spec; HttpHdrRangePos pos = HttpHdrRangeInitPos; Stack goods; assert(range); assert(clen >= 0); stackInit(&goods); debug(64, 3) ("httpHdrRangeCanonize: started with %d specs, clen: %d\n", range->specs.count, clen); /* canonize each entry and destroy bad ones if any */ while ((spec = httpHdrRangeGetSpec(range, &pos))) { if (httpHdrRangeSpecCanonize(spec, clen)) stackPush(&goods, spec); else httpHdrRangeSpecDestroy(spec); } debug(64, 3) ("httpHdrRangeCanonize: found %d bad specs\n", range->specs.count - goods.count); /* reset old array */ stackClean(&range->specs); stackInit(&range->specs); spec = NULL; /* merge specs: * take one spec from "goods" and merge it with specs from * "range->specs" (if any) until there is no overlap */ for (i = 0; i < goods.count;) { HttpHdrRangeSpec *prev_spec = stackTop(&range->specs); spec = goods.items[i]; if (prev_spec) { if (httpHdrRangeSpecMergeWith(spec, prev_spec)) { /* merged with current so get rid of the prev one */ assert(prev_spec == stackPop(&range->specs)); httpHdrRangeSpecDestroy(prev_spec); continue; /* re-iterate */ } } stackPush(&range->specs, spec); spec = NULL; i++; /* progress */ } if (spec) /* last "merge" may not be pushed yet */ stackPush(&range->specs, spec); debug(64, 3) ("httpHdrRangeCanonize: had %d specs, merged %d specs\n", goods.count, goods.count - range->specs.count); debug(64, 3) ("httpHdrRangeCanonize: finished with %d specs\n", range->specs.count); stackClean(&goods); return range->specs.count > 0; }
void httpHdrRangeDestroy(HttpHdrRange * range) { assert(range); while (range->specs.count) httpHdrRangeSpecDestroy(stackPop(&range->specs)); stackClean(&range->specs); memFree(range, MEM_HTTP_HDR_RANGE); }
int tableClean(tableT *tableP, stackT *destP) { // clean attack stack if (stackClean(tableP->att,destP) == EXIT_FAILURE) { return(EXIT_FAILURE); } // clean defend stack if (stackClean(tableP->def,destP) == EXIT_FAILURE) { return(EXIT_FAILURE); } // reset `beats` array int size = stackSize(tableP->att); for (int i = 0; i < size; ++i) { tableP->beats[i] = -1; } return(EXIT_SUCCESS); }
void stackDestroy(Stack *stack) { stackClean(stack); free(stack); }