END_TEST START_TEST (test_addValueEntry) { EXIStream testStrm; errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; String testStr = {"TEST-007", 8}; // IV: Initialize the stream { tmp_err_code = initAllocList(&(testStrm.memList)); testStrm.context.bitPointer = 0; testStrm.buffer.bufLen = 0; testStrm.buffer.bufContent = 0; tmp_err_code += createValueTable(&testStrm.valueTable); testStrm.schema = memManagedAllocate(&testStrm.memList, sizeof(EXIPSchema)); fail_unless (testStrm.schema != NULL, "Memory alloc error"); /* Create and initialize initial string table entries */ tmp_err_code += createDynArray(&testStrm.schema->uriTable.dynArray, sizeof(UriEntry), DEFAULT_URI_ENTRIES_NUMBER); tmp_err_code += createUriTableEntries(&testStrm.schema->uriTable, FALSE); } fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code); testStrm.gStack->currQNameID.uriId = 1; // http://www.w3.org/XML/1998/namespace testStrm.gStack->currQNameID.lnId = 2; // lang tmp_err_code = addValueEntry(&testStrm, testStr, testStrm.gStack->currQNameID); fail_unless (tmp_err_code == EXIP_OK, "addValueEntry returns an error code %d", tmp_err_code); #if VALUE_CROSSTABLE_USE fail_unless (testStrm.schema->uriTable.uri[testStrm.gStack->currQNameID.uriId].lnTable.ln[testStrm.gStack->currQNameID.lnId].vxTable != NULL, "addValueEntry does not create vxTable"); fail_unless (testStrm.schema->uriTable.uri[testStrm.gStack->currQNameID.uriId].lnTable.ln[testStrm.gStack->currQNameID.lnId].vxTable->count == 1, "addValueEntry does not create correct vxTable"); #endif fail_unless (testStrm.valueTable.count == 1, "addValueEntry does not create global value entry"); destroyDynArray(&testStrm.valueTable.dynArray); destroyDynArray(&testStrm.schema->uriTable.dynArray); freeAllocList(&testStrm.memList); }
errorCode decodeHeader(EXIStream* strm, boolean outOfBandOpts) { errorCode tmp_err_code = UNEXPECTED_ERROR; unsigned int bits_val = 0; boolean boolVal = FALSE; DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">Start EXI header decoding\n")); TRY(readBits(strm, 2, &bits_val)); if(bits_val == 2) // The header Distinguishing Bits i.e. no EXI Cookie { strm->header.has_cookie = 0; DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">No EXI cookie detected\n")); } else if(bits_val == 0)// ASCII code for $ = 00100100 (36) { TRY(readBits(strm, 6, &bits_val)); if(bits_val != 36) return INVALID_EXI_HEADER; TRY(readBits(strm, 8, &bits_val)); if(bits_val != 69) // ASCII code for E = 01000101 (69) return INVALID_EXI_HEADER; TRY(readBits(strm, 8, &bits_val)); if(bits_val != 88) // ASCII code for X = 01011000 (88) return INVALID_EXI_HEADER; TRY(readBits(strm, 8, &bits_val)); if(bits_val != 73) // ASCII code for I = 01001001 (73) return INVALID_EXI_HEADER; strm->header.has_cookie = 1; DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">EXI cookie detected\n")); TRY(readBits(strm, 2, &bits_val)); if(bits_val != 2) // The header Distinguishing Bits are required return INVALID_EXI_HEADER; } else { return INVALID_EXI_HEADER; } // Read the Presence Bit for EXI Options TRY(readNextBit(strm, &boolVal)); if(boolVal == TRUE) // There are EXI options { strm->header.has_options = TRUE; // validation checks. If the options are included then // they cannot be set by an out-of-band mechanism. // If out-of-band options are set - // rise a warning and overwrite them. // Only the options from the header will be used if(outOfBandOpts == TRUE) { DEBUG_MSG(WARNING, DEBUG_CONTENT_IO, (">Ignored out-of-band set EXI options\n")); makeDefaultOpts(&strm->header.opts); } } else // Out-of-band set EXI options { DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">No EXI options field in the header\n")); strm->header.has_options = FALSE; if(outOfBandOpts == FALSE) { DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, (">No EXI options in the header and no out-of-band options specified. \n")); return HEADER_OPTIONS_MISMATCH; } } // Read the Version type TRY(readNextBit(strm, &boolVal)); strm->header.is_preview_version = boolVal; strm->header.version_number = 1; do { TRY(readBits(strm, 4, &bits_val)); strm->header.version_number += bits_val; if(bits_val < 15) break; } while(1); DEBUG_MSG(INFO, DEBUG_CONTENT_IO, (">EXI version: %d\n", strm->header.version_number)); if(strm->header.has_options == 1) { Parser optionsParser; struct ops_AppData appD; TRY(initParser(&optionsParser, strm->buffer, &appD)); optionsParser.strm.context.bitPointer = strm->context.bitPointer; optionsParser.strm.context.bufferIndx = strm->context.bufferIndx; optionsParser.strm.gStack = NULL; makeDefaultOpts(&optionsParser.strm.header.opts); SET_STRICT(optionsParser.strm.header.opts.enumOpt); optionsParser.handler.fatalError = ops_fatalError; optionsParser.handler.error = ops_fatalError; optionsParser.handler.startDocument = ops_startDocument; optionsParser.handler.endDocument = ops_endDocument; optionsParser.handler.startElement = ops_startElement; optionsParser.handler.attribute = ops_attribute; optionsParser.handler.stringData = ops_stringData; optionsParser.handler.endElement = ops_endElement; optionsParser.handler.intData = ops_intData; optionsParser.handler.booleanData = ops_boolData; appD.o_strm = &optionsParser.strm; appD.parsed_ops = &strm->header.opts; appD.prevElementLnID = 0; appD.prevElementUriID = 0; appD.permanentAllocList = &strm->memList; TRY_CATCH(setSchema(&optionsParser, (EXIPSchema*) &ops_schema), destroyParser(&optionsParser)); TRY_CATCH(createValueTable(&optionsParser.strm.valueTable), destroyParser(&optionsParser)); while(tmp_err_code == ERR_OK) { tmp_err_code = parseNext(&optionsParser); } destroyParser(&optionsParser); if(tmp_err_code != PARSING_COMPLETE) return tmp_err_code; strm->buffer.bufContent = optionsParser.strm.buffer.bufContent; strm->context.bitPointer = optionsParser.strm.context.bitPointer; strm->context.bufferIndx = optionsParser.strm.context.bufferIndx; if(WITH_COMPRESSION(strm->header.opts.enumOpt) || GET_ALIGNMENT(strm->header.opts.enumOpt) != BIT_PACKED) { // Padding bits if(strm->context.bitPointer != 0) { strm->context.bitPointer = 0; strm->context.bufferIndx += 1; } } } return checkOptionValues(&strm->header.opts); }
errorCode parseHeader(Parser* parser) { errorCode tmp_err_code = UNEXPECTED_ERROR; tmp_err_code = decodeHeader(&parser->strm); if(tmp_err_code != ERR_OK) return tmp_err_code; parser->strm.gStack = NULL; if(parser->strm.schema != NULL) { /* Schema enabled mode*/ tmp_err_code = addUndeclaredProductionsToAll(&parser->strm.memList, parser->strm.schema, &parser->strm.header.opts); if(tmp_err_code != ERR_OK) return tmp_err_code; if(WITH_FRAGMENT(parser->strm.header.opts.enumOpt)) { /* Fragment document grammar */ // TODO: create a Schema-informed Fragment Grammar from the EXIP schema object return NOT_IMPLEMENTED_YET; } else { tmp_err_code = augmentDocGrammar(&parser->strm.memList, parser->strm.header.opts.preserve, &parser->strm.schema->docGrammar); if(tmp_err_code != ERR_OK) return tmp_err_code; } } else { parser->strm.schema = memManagedAllocate(&parser->strm.memList, sizeof(EXIPSchema)); if(parser->strm.schema == NULL) return MEMORY_ALLOCATION_ERROR; tmp_err_code = initSchema(parser->strm.schema, INIT_SCHEMA_SCHEMA_LESS_MODE); if(tmp_err_code != ERR_OK) return tmp_err_code; if(WITH_FRAGMENT(parser->strm.header.opts.enumOpt)) { tmp_err_code = createFragmentGrammar(parser->strm.schema, NULL, 0); if(tmp_err_code != ERR_OK) return tmp_err_code; tmp_err_code = augmentFragGrammar(&parser->strm.memList, parser->strm.header.opts.preserve, &parser->strm.schema->docGrammar); if(tmp_err_code != ERR_OK) return tmp_err_code; } else { tmp_err_code = createDocGrammar(parser->strm.schema, NULL, 0); if(tmp_err_code != ERR_OK) return tmp_err_code; tmp_err_code = augmentDocGrammar(&parser->strm.memList, parser->strm.header.opts.preserve, &parser->strm.schema->docGrammar); if(tmp_err_code != ERR_OK) return tmp_err_code; } } tmp_err_code = pushGrammar(&parser->strm.gStack, &parser->strm.schema->docGrammar); if(tmp_err_code != ERR_OK) return tmp_err_code; if(parser->strm.header.opts.valuePartitionCapacity > 0) { tmp_err_code = createValueTable(&parser->strm.valueTable); if(tmp_err_code != ERR_OK) return tmp_err_code; } return ERR_OK; }