static errorCode ops_startElement(QName qname, void* app_data) { struct ops_AppData* o_appD = (struct ops_AppData*) app_data; if(o_appD->o_strm->context.currElem.uriId == 4) // URI == http://www.w3.org/2009/exi { o_appD->prevElementUriID = 4; switch(o_appD->o_strm->context.currElem.lnId) { case 33: // strict SET_STRICT(o_appD->parsed_ops->enumOpt); o_appD->prevElementLnID = 33; break; case 31: // schemaId o_appD->prevElementLnID = 31; o_appD->parsed_ops->schemaIDMode = SCHEMA_ID_EMPTY; break; case 7: // compression SET_COMPRESSION(o_appD->parsed_ops->enumOpt); o_appD->prevElementLnID = 7; break; case 14: // fragment SET_FRAGMENT(o_appD->parsed_ops->enumOpt); o_appD->prevElementLnID = 14; break; case 13: // dtd SET_PRESERVED(o_appD->parsed_ops->preserve, PRESERVE_DTD); o_appD->prevElementLnID = 13; break; case 29: // prefixes SET_PRESERVED(o_appD->parsed_ops->preserve, PRESERVE_PREFIXES); o_appD->prevElementLnID = 29; break; case 26: // lexicalValues SET_PRESERVED(o_appD->parsed_ops->preserve, PRESERVE_LEXVALUES); o_appD->prevElementLnID = 26; break; case 5: // comments SET_PRESERVED(o_appD->parsed_ops->preserve, PRESERVE_COMMENTS); o_appD->prevElementLnID = 5; break; case 27: // pis SET_PRESERVED(o_appD->parsed_ops->preserve, PRESERVE_PIS); o_appD->prevElementLnID = 27; break; case 4: // alignment->byte SET_ALIGNMENT(o_appD->parsed_ops->enumOpt, BYTE_ALIGNMENT); o_appD->prevElementLnID = 4; break; case 28: // alignment->pre-compress SET_ALIGNMENT(o_appD->parsed_ops->enumOpt, PRE_COMPRESSION); o_appD->prevElementLnID = 28; break; case 32: // selfContained SET_SELF_CONTAINED(o_appD->parsed_ops->enumOpt); o_appD->prevElementLnID = 32; break; case 8: // datatypeRepresentationMap o_appD->prevElementLnID = 8; break; case 36: // uncommon o_appD->prevElementLnID = 36; #if EXI_PROFILE_DEFAULT { // If the EXI Profile default behaviour is followed, then we expect // SE(*) <p/> indicating default EXI Profile parameters // If this is not the case rise an error // SE(*) has event code 5 in the uncommon grammar unsigned int tmp_bits_val; UnsignedInteger lnLen = 0; errorCode tmp_err_code = UNEXPECTED_ERROR; String lnStr; QNameID qnameId = {URI_MAX, LN_MAX}; // Next event code must be SE(*) TRY(decodeNBitUnsignedInteger(o_appD->o_strm, 3, &tmp_bits_val)); if(tmp_bits_val != 5) { DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, (">EXI Profile default active but <p> element missing\n")); return INVALID_EXIP_CONFIGURATION; } // The <p> element QName must be "http://www.w3.org/2009/exi:p" TRY(decodeUri(o_appD->o_strm, &qnameId.uriId)); TRY(decodeUnsignedInteger(o_appD->o_strm, &lnLen)); if(lnLen == 0) // local-name table hit -> should not be the case to have "p" in the local string table return INVALID_EXIP_CONFIGURATION; TRY(allocateStringMemoryManaged(&(lnStr.str),(Index) (lnLen - 1), &o_appD->o_strm->memList)); TRY(decodeStringOnly(o_appD->o_strm, (Index)lnLen - 1, &lnStr)); // NOTE: the "p" local name is in purpose not added to the // local name table of the http://www.w3.org/2009/exi uri, although it should be. // If there are more strings (24 or more) added there in the future // or the <p> element is encoded more than once - both are highly unlikely, // then there will be a problem with the encoding. if(qnameId.uriId != 4 || !stringEqualToAscii(lnStr, "p")) { DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, (">EXI Profile default active but <p> element missing\n")); return INVALID_EXIP_CONFIGURATION; } // The next event code must be EE -> 0.0 TRY(decodeNBitUnsignedInteger(o_appD->o_strm, 2, &tmp_bits_val)); if(tmp_bits_val != 0) { DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, (">EXI Profile default active but <p> element is not empty\n")); return INVALID_EXIP_CONFIGURATION; } } #endif break; } } else // URI != http://www.w3.org/2009/exi { // The previous element should be either uncommon or datatypeRepresentationMap otherwise it is an error // These are the only places where <any> element is allowed if(o_appD->prevElementUriID != 4 || o_appD->prevElementLnID != 36 || o_appD->prevElementLnID != 8) { DEBUG_MSG(ERROR, DEBUG_CONTENT_IO, (">Wrong namespace in the EXI Options\n")); return EXIP_HANDLER_STOP; } // Handle here the user defined meta-data that follows! http://www.w3.org/TR/2011/REC-exi-20110310/#key-userMetaData } return ERR_OK; }
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); }
int main(int argc, char *argv[]) { errorCode tmp_err_code = UNEXPECTED_ERROR; FILE *outfile; char sourceFile[50]; EXIPSchema schema; EXIPSchema* schemaPtr = NULL; if(argc > 1) { if(strcmp(argv[1], "-help") == 0) { printfHelp(); return 0; } else if(strcmp(argv[1], "-schema") == 0) { FILE *schemaFile; BinaryBuffer buffer[MAX_XSD_FILES_COUNT]; // up to 10 XSD files char schemaFileName[50]; unsigned int schemaFilesCount = 0; unsigned int i; if(argc <= 3) { printfHelp(); return 0; } else schemaFilesCount = argc - 3; if(schemaFilesCount > MAX_XSD_FILES_COUNT) { fprintf(stderr, "Too many xsd files given as an input: %d", schemaFilesCount); exit(1); } for(i = 0; i < schemaFilesCount; i++) { strcpy(schemaFileName, argv[2 + i]); schemaFile = fopen(schemaFileName, "rb" ); if(!schemaFile) { fprintf(stderr, "Unable to open file %s", schemaFileName); return 1; } else { //Get file length fseek(schemaFile, 0, SEEK_END); buffer[i].bufLen = ftell(schemaFile) + 1; fseek(schemaFile, 0, SEEK_SET); //Allocate memory buffer[i].buf = (char *) malloc(buffer[i].bufLen); if (!buffer[i].buf) { fprintf(stderr, "Memory allocation error!"); fclose(schemaFile); return 1; } //Read file contents into buffer fread(buffer[i].buf, buffer[i].bufLen, 1, schemaFile); fclose(schemaFile); buffer[i].bufContent = buffer[i].bufLen; buffer[i].ioStrm.readWriteToStream = NULL; buffer[i].ioStrm.stream = NULL; } } tmp_err_code = generateSchemaInformedGrammars(buffer, schemaFilesCount, SCHEMA_FORMAT_XSD_EXI, &schema); if(tmp_err_code != ERR_OK) { printf("\n Error occured: %d", tmp_err_code); return 1; } schemaPtr = &schema; for(i = 0; i < schemaFilesCount; i++) { free(buffer[i].buf); } } strcpy(sourceFile, argv[argc - 1]); outfile = fopen(sourceFile, "wb" ); if(!outfile) { fprintf(stderr, "Unable to open file %s", sourceFile); return 1; } else { EXIStream testStrm; String uri; String ln; QName qname = {&uri, &ln, NULL}; String chVal; char buf[OUTPUT_BUFFER_SIZE]; BinaryBuffer buffer; buffer.buf = buf; buffer.bufLen = OUTPUT_BUFFER_SIZE; buffer.bufContent = 0; // Serialization steps: // I: First initialize the header of the stream serialize.initHeader(&testStrm); // II: Set any options in the header, if different from the defaults testStrm.header.has_cookie = TRUE; testStrm.header.has_options = TRUE; testStrm.header.opts.valueMaxLength = 300; testStrm.header.opts.valuePartitionCapacity = 50; SET_STRICT(testStrm.header.opts.enumOpt); // III: Define an external stream for the output if any buffer.ioStrm.readWriteToStream = writeFileOutputStream; buffer.ioStrm.stream = outfile; // IV: Initialize the stream tmp_err_code = serialize.initStream(&testStrm, buffer, schemaPtr, SCHEMA_ID_ABSENT, NULL); if(tmp_err_code != ERR_OK) printError(tmp_err_code, &testStrm, outfile); // V: Start building the stream step by step: header, document, element etc... tmp_err_code += serialize.exiHeader(&testStrm); tmp_err_code += serialize.startDocument(&testStrm); qname.uri = &NS_STR; qname.localName = &ELEM_MULT_TEST_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <MultipleXSDsTest> qname.uri = &NS_STR; qname.localName = &ELEM_ENCODE_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <EXIPEncoder> // NOTE: attributes should come lexicographically sorted during serialization qname.uri = &NS_EMPTY_STR; qname.localName = &ATTR_BYTE_STR; if(schemaPtr != NULL) { // schema mode tmp_err_code += serialize.attribute(&testStrm, qname, VALUE_TYPE_SMALL_INTEGER); // testByte=" tmp_err_code += serialize.intData(&testStrm, 55); } else { // schema-less mode tmp_err_code += serialize.attribute(&testStrm, qname, VALUE_TYPE_STRING); // testByte=" tmp_err_code += asciiToString("55", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); } qname.localName = &ATTR_VERSION_STR; tmp_err_code += serialize.attribute(&testStrm, qname, VALUE_TYPE_STRING); // version=" tmp_err_code += asciiToString("0.2", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); tmp_err_code += asciiToString("This is an example of serializing EXI streams using EXIP low level API", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); tmp_err_code += serialize.endElement(&testStrm); // </EXIPEncoder> qname.uri = &NS_STR; qname.localName = &ELEM_DESCR_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <description> tmp_err_code += asciiToString("This is a test of processing XML schemes with multiple XSD files", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); tmp_err_code += serialize.endElement(&testStrm); // </description> qname.uri = &NS_NESTED_STR; qname.localName = &ELEM_TEST_SETUP_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <testSetup> qname.uri = &NS_EMPTY_STR; qname.localName = &ATTR_GOAL_STR; tmp_err_code += serialize.attribute(&testStrm, qname, VALUE_TYPE_STRING); // goal=" tmp_err_code += asciiToString("Verify that the implementation works!", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); tmp_err_code += asciiToString("Simple test element with single attribute", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); tmp_err_code += serialize.endElement(&testStrm); // </testSetup> qname.uri = &NS_STR; qname.localName = &ELEM_TYPE_TEST_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <type-test> if(schemaPtr != NULL) { // schema mode qname.uri = &NS_EMPTY_STR; qname.localName = &ATTR_ID_STR; tmp_err_code += serialize.attribute(&testStrm, qname, VALUE_TYPE_INTEGER); // id=" tmp_err_code += serialize.intData(&testStrm, 1001); } else { // schema-less mode qname.uri = &NS_EMPTY_STR; qname.localName = &ATTR_ID_STR; tmp_err_code += serialize.attribute(&testStrm, qname, VALUE_TYPE_STRING); // id=" tmp_err_code += asciiToString("1001", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); } qname.uri = &NS_NESTED_STR; qname.localName = &ELEM_BOOL_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <bool> if(schemaPtr != NULL) { // schema mode tmp_err_code += serialize.booleanData(&testStrm, TRUE); } else { // schema-less mode tmp_err_code += asciiToString("true", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); } tmp_err_code += serialize.endElement(&testStrm); // </bool> tmp_err_code += serialize.endElement(&testStrm); // </type-test> qname.uri = &NS_STR; qname.localName = &ELEM_EXT_TYPES_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <extendedTypeTest> qname.uri = &NS_EMPTY_STR; qname.localName = &ELEM_BYTE_TYPES_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <byteTest> if(schemaPtr != NULL) { // schema mode tmp_err_code += serialize.intData(&testStrm, 11); } else { // schema-less mode tmp_err_code += asciiToString("11", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); } tmp_err_code += serialize.endElement(&testStrm); // </byteTest> qname.uri = &NS_EMPTY_STR; qname.localName = &ELEM_DATE_TYPES_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <dateTimeTest> if(schemaPtr != NULL) { // schema mode EXIPDateTime dt; dt.presenceMask = 0; dt.presenceMask = dt.presenceMask | YEAR_PRESENCE; dt.presenceMask = dt.presenceMask | MON_PRESENCE; dt.presenceMask = dt.presenceMask | MDAY_PRESENCE; dt.presenceMask = dt.presenceMask | HOUR_PRESENCE; dt.presenceMask = dt.presenceMask | MIN_PRESENCE; dt.presenceMask = dt.presenceMask | SEC_PRESENCE; dt.presenceMask = dt.presenceMask | FRACT_PRESENCE; dt.dateTime.tm_year = 112; // 2012 dt.dateTime.tm_mon = 6; // July dt.dateTime.tm_mday = 31; dt.dateTime.tm_hour = 13; dt.dateTime.tm_min = 33; dt.dateTime.tm_sec = 55; dt.fSecs.value = 839; dt.fSecs.offset = 5; tmp_err_code += serialize.dateTimeData(&testStrm, dt); } else { // schema-less mode tmp_err_code += asciiToString("2012 Jul 31 13:33", &chVal, &testStrm.memList, FALSE); tmp_err_code += serialize.stringData(&testStrm, chVal); } tmp_err_code += serialize.endElement(&testStrm); // </dateTimeTest> qname.uri = &NS_EMPTY_STR; qname.localName = &ELEM_BIN_TYPES_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <binaryTest> if(schemaPtr != NULL) { // schema mode tmp_err_code += serialize.binaryData(&testStrm, SOME_BINARY_DATA, 10); } else { // schema-less mode tmp_err_code += serialize.stringData(&testStrm, SOME_BINARY_DATA_BASE64); } tmp_err_code += serialize.endElement(&testStrm); // </binaryTest> qname.uri = &NS_EMPTY_STR; qname.localName = &ELEM_ENUM_TYPES_STR; tmp_err_code += serialize.startElement(&testStrm, qname); // <enumTest> tmp_err_code += serialize.stringData(&testStrm, ENUM_DATA_4); tmp_err_code += serialize.endElement(&testStrm); // </enumTest> tmp_err_code += serialize.endElement(&testStrm); // </extendedTypeTest> tmp_err_code += serialize.endElement(&testStrm); // </MultipleXSDsTest> tmp_err_code += serialize.endDocument(&testStrm); if(tmp_err_code != ERR_OK) printError(tmp_err_code, &testStrm, outfile); // VI: Free the memory allocated by the EXI stream object tmp_err_code = serialize.closeEXIStream(&testStrm); fclose(outfile); if(schemaPtr != NULL) destroySchema(schemaPtr); } } else { printfHelp(); return 1; } return 0; }
static void parseOpsMask(char* mask, EXIOptions* ops) { unsigned int i; char *token; for (token = strtok(mask, "=%"), i = 0; token != NULL; token = strtok(NULL, "=%"), i++) { switch(i) { case 0: if(strcmp(token, "-")) { // Preservation Options: c - comments, d - dtds, l - lexicalvalues, p - pis, x- prefixes if(strstr(token, "c") != NULL) SET_PRESERVED(ops->preserve, PRESERVE_COMMENTS); if(strstr(token, "d") != NULL) SET_PRESERVED(ops->preserve, PRESERVE_DTD); if(strstr(token, "l") != NULL) SET_PRESERVED(ops->preserve, PRESERVE_LEXVALUES); if(strstr(token, "p") != NULL) SET_PRESERVED(ops->preserve, PRESERVE_PIS); if(strstr(token, "x") != NULL) SET_PRESERVED(ops->preserve, PRESERVE_PREFIXES); } break; case 1: if(strcmp(token, "-")) { // Other options: v - strict interpretation of schema, f - fragments // r - selfContained, c - compression, p - pre-compression, a - aligned to bytes\n"); if(strstr(token, "v") != NULL) SET_STRICT(ops->enumOpt); if(strstr(token, "f") != NULL) SET_FRAGMENT(ops->enumOpt); if(strstr(token, "r") != NULL) SET_SELF_CONTAINED(ops->enumOpt); if(strstr(token, "c") != NULL) SET_COMPRESSION(ops->enumOpt); if(strstr(token, "p") != NULL) SET_ALIGNMENT(ops->enumOpt, PRE_COMPRESSION); else if(strstr(token, "a") != NULL) SET_ALIGNMENT(ops->enumOpt, BYTE_ALIGNMENT); } break; case 2: if(strcmp(token, "-")) { // valuePartitionCapacity ops->valuePartitionCapacity = (Index) strtol(token, NULL, 10); } break; case 3: if(strcmp(token, "-")) { // valueMaxLength ops->valueMaxLength = (Index) strtol(token, NULL, 10); } break; case 4: if(strcmp(token, "-")) { // blockSize ops->blockSize = (uint32_t) strtol(token, NULL, 10); } break; default: { fprintf(stderr, "Wrong options mask: %s", mask); exit(1); } } } }
static error_code serializeDevDescMsg(char* buf, unsigned int buf_size, unsigned int* msg_size, DevDescribtion devDesc) { EXIStream strm; String uri; String ln; String ch; QName qname = {&uri, &ln, NULL}; errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; BinaryBuffer buffer; EXIPSchema lkab_schema; const char *schemafname = "SchemaStrict/lkab-devices-xsd.exi"; EXITypeClass valueType; buffer.buf = buf; buffer.bufLen = buf_size; buffer.bufContent = 0; // Serialization steps: // I.A: First, read in the schema parseSchema(schemafname, &lkab_schema); // I: First initialize the header of the stream serialize.initHeader(&strm); // II: Set any options in the header, if different from the defaults strm.header.has_options = TRUE; SET_STRICT(strm.header.opts.enumOpt); // III: Define an external stream for the output if any buffer.ioStrm.stream = NULL; buffer.ioStrm.readWriteToStream = NULL; // IV: Initialize the stream tmp_err_code = serialize.initStream(&strm, buffer, &lkab_schema); if(tmp_err_code != EXIP_OK) return tmp_err_code; // V: Start building the stream step by step: header, document, element etc... tmp_err_code += serialize.exiHeader(&strm); tmp_err_code += serialize.startDocument(&strm); qname.uri = &NS_STR; qname.localName = &ELEM_DEV_DESC_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <DeviceDescription> qname.uri = &NS_STR; qname.localName = &ELEM_ID_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <id> ch.str = devDesc.id; ch.length = strlen(devDesc.id); tmp_err_code += serialize.stringData(&strm, ch); // device id tmp_err_code += serialize.endElement(&strm); // </id> qname.uri = &NS_STR; qname.localName = &ELEM_NAME_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <name> ch.str = devDesc.name; ch.length = strlen(devDesc.name); tmp_err_code += serialize.stringData(&strm, ch); // device name tmp_err_code += serialize.endElement(&strm); // </name> qname.uri = &NS_STR; qname.localName = &ELEM_TYPE_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <type> ch.str = devDesc.type; ch.length = strlen(devDesc.type); tmp_err_code += serialize.stringData(&strm, ch); // device type tmp_err_code += serialize.endElement(&strm); // </type> qname.uri = &NS_STR; qname.localName = &ELEM_LOCATION_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <location> ch.str = devDesc.location; ch.length = strlen(devDesc.location); tmp_err_code += serialize.stringData(&strm, ch); // device location tmp_err_code += serialize.endElement(&strm); // </location> qname.uri = &NS_STR; qname.localName = &ELEM_PROSS_VAL_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <processValues> qname.uri = &NS_STR; qname.localName = &ELEM_NAME_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <name> ch.str = devDesc.processValue.name; ch.length = strlen(devDesc.processValue.name); tmp_err_code += serialize.stringData(&strm, ch); // processValues name tmp_err_code += serialize.endElement(&strm); // </name> qname.uri = &NS_STR; qname.localName = &ELEM_TYPE_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <type> tmp_err_code += serialize.stringData(&strm, ENUM_DATA_VAL_TYPE[devDesc.processValue.type]); // processValues type tmp_err_code += serialize.endElement(&strm); // </type> qname.uri = &NS_STR; qname.localName = &ELEM_IS_READONLY_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <isReadOnly> tmp_err_code += serialize.booleanData(&strm, 0); // processValues isReadOnly tmp_err_code += serialize.endElement(&strm); // </isReadOnly> qname.uri = &NS_STR; qname.localName = &ELEM_DESC_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <description> ch.str = devDesc.processValue.description; ch.length = strlen(devDesc.processValue.description); tmp_err_code += serialize.stringData(&strm, ch); // processValues description tmp_err_code += serialize.endElement(&strm); // </description> tmp_err_code += serialize.endElement(&strm); // </processValues> tmp_err_code += serialize.endElement(&strm); // </DeviceDescription> tmp_err_code += serialize.endDocument(&strm); if(tmp_err_code != EXIP_OK) return tmp_err_code; *msg_size = strm.context.bufferIndx + 1; // VI: Free the memory allocated by the EXI stream object tmp_err_code = serialize.closeEXIStream(&strm); return EXIP_OK; }
static error_code serializeIOMsg(char* buf, unsigned int buf_size, unsigned int* msg_size, BoolValue val) { EXIStream strm; String uri; String ln; QName qname = {&uri, &ln, NULL}; errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; BinaryBuffer buffer; EXIPDateTime dt; EXIPSchema lkab_schema; const char *schemafname = "SchemaStrict/lkab-devices-xsd.exi"; EXITypeClass valueType; buffer.buf = buf; buffer.bufLen = buf_size; buffer.bufContent = 0; // Serialization steps: // I.A: First, read in the schema parseSchema(schemafname, &lkab_schema); // I: First initialize the header of the stream serialize.initHeader(&strm); // II: Set any options in the header, if different from the defaults strm.header.has_options = TRUE; SET_STRICT(strm.header.opts.enumOpt); // III: Define an external stream for the output if any buffer.ioStrm.stream = NULL; buffer.ioStrm.readWriteToStream = NULL; // IV: Initialize the stream tmp_err_code = serialize.initStream(&strm, buffer, &lkab_schema); if(tmp_err_code != EXIP_OK) return tmp_err_code; // V: Start building the stream step by step: header, document, element etc... tmp_err_code += serialize.exiHeader(&strm); tmp_err_code += serialize.startDocument(&strm); qname.uri = &NS_STR; qname.localName = &ELEM_BOOL_VAL_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <BoolValue> qname.uri = &NS_STR; qname.localName = &ELEM_TIMESTAMP_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <timeStamp> dt.presenceMask = FRACT_PRESENCE; dt.dateTime.tm_year = val.ts.year; dt.dateTime.tm_mon = val.ts.month; dt.dateTime.tm_mday = val.ts.mday; dt.dateTime.tm_hour = val.ts.hour; dt.dateTime.tm_min = val.ts.min; dt.dateTime.tm_sec = val.ts.sec; dt.fSecs.value = val.ts.msec; dt.fSecs.offset = 2; tmp_err_code += serialize.dateTimeData(&strm, dt); tmp_err_code += serialize.endElement(&strm); // </timeStamp> qname.uri = &NS_STR; qname.localName = &ELEM_QUAL_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <quality> tmp_err_code += serialize.stringData(&strm, ENUM_DATA_QUALITY[val.quality]); // quality tmp_err_code += serialize.endElement(&strm); // </quality> qname.uri = &NS_STR; qname.localName = &ELEM_VALUE_STR; tmp_err_code += serialize.startElement(&strm, qname, &valueType); // <value> tmp_err_code += serialize.booleanData(&strm, val.val); tmp_err_code += serialize.endElement(&strm); // </value> tmp_err_code += serialize.endElement(&strm); // </BoolValue> tmp_err_code += serialize.endDocument(&strm); if(tmp_err_code != EXIP_OK) return tmp_err_code; *msg_size = strm.context.bufferIndx + 1; // VI: Free the memory allocated by the EXI stream object tmp_err_code = serialize.closeEXIStream(&strm); return EXIP_OK; }
END_TEST /* * Verifies error when more elements than schema maxOccurs permits. Attempts * to encode: * * <A xmlns='urn:foo'> * <AB/><AC/><AC/><AC/> * </A> */ START_TEST (test_acceptance_for_A_01b) { EXIPSchema schema; EXIStream testStrm; String uri; String ln; QName qname = {&uri, &ln, NULL}; char buf[OUTPUT_BUFFER_SIZE]; const char *schemafname = "testStates/acceptance-xsd.exi"; errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; EXITypeClass valueType; const String NS_STR = {"urn:foo", 7}; const String ELEM_A = {"A", 1}; const String ELEM_AB = {"AB", 2}; const String ELEM_AC = {"AC", 2}; const String CH = {"", 0}; BinaryBuffer buffer; buffer.buf = buf; buffer.bufLen = OUTPUT_BUFFER_SIZE; buffer.bufContent = 0; // Serialization steps: // I.A: First, read in the schema parseSchema(schemafname, &schema); // I: First initialize the header of the stream serialize.initHeader(&testStrm); // II: Set any options in the header, if different from the defaults testStrm.header.has_cookie = TRUE; testStrm.header.has_options = TRUE; testStrm.header.opts.valueMaxLength = 300; testStrm.header.opts.valuePartitionCapacity = 50; SET_STRICT(testStrm.header.opts.enumOpt); // III: Define an external stream for the output if any buffer.ioStrm.readWriteToStream = NULL; buffer.ioStrm.stream = NULL; // IV: Initialize the stream tmp_err_code = serialize.initStream(&testStrm, buffer, &schema); fail_unless (tmp_err_code == EXIP_OK, "initStream returns an error code %d", tmp_err_code); // V: Start building the stream step by step: header, document, element etc... tmp_err_code += serialize.exiHeader(&testStrm); tmp_err_code += serialize.startDocument(&testStrm); qname.uri = &NS_STR; qname.localName = &ELEM_A; tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code); qname.localName = &ELEM_AB; tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); tmp_err_code += serialize.stringData(&testStrm, CH); tmp_err_code += serialize.endElement(&testStrm); fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code); qname.localName = &ELEM_AC; tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); tmp_err_code += serialize.stringData(&testStrm, CH); tmp_err_code += serialize.endElement(&testStrm); fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code); tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); tmp_err_code += serialize.stringData(&testStrm, CH); tmp_err_code += serialize.endElement(&testStrm); fail_unless (tmp_err_code == EXIP_OK, "serialization returns an error code %d", tmp_err_code); /* Expect failure when start third AC element */ tmp_err_code += serialize.startElement(&testStrm, qname, &valueType); fail_unless (tmp_err_code == EXIP_INCONSISTENT_PROC_STATE, "Expected EXIP_INCONSISTENT_PROC_STATE, but returns an error code %d", tmp_err_code); // VI: Free the memory allocated by the EXI stream object tmp_err_code = serialize.closeEXIStream(&testStrm); }