static char sample_stringData(const String value, void* app_data) { appData* appD = (appData*) app_data; switch(appD->eventCount) { case 2: if(!stringEqualToAscii(value, "Ahaa")) { printf("\nInvalid decoding: Ahaa!"); return EXIP_HANDLER_STOP; } break; case 5: if(!stringEqualToAscii(value, "fooBass")) { printf("\nInvalid decoding: fooBass!"); return EXIP_HANDLER_STOP; } break; default: printf("\nInvalid decoding: stringData!"); return EXIP_HANDLER_STOP; break; } return EXIP_HANDLER_OK; }
static char sample_startElement(QName qname, void* app_data) { appData* appD = (appData*) app_data; if(!stringEqualToAscii(*qname.uri, "http://www.example.org/emptyTypeSchema")) { printf("\nInvalid namespace!"); return EXIP_HANDLER_STOP; } switch(appD->eventCount) { case 0: if(!stringEqualToAscii(*qname.localName, "rootElem")) { printf("\nInvalid doc: rootElem!"); return EXIP_HANDLER_STOP; } appD->eventCount++; break; case 2: if(!stringEqualToAscii(*qname.localName, "nilabElem")) { printf("\nInvalid doc: nilabElem!"); return EXIP_HANDLER_STOP; } appD->eventCount++; break; default: printf("\nInvalid decoding startElement!"); return EXIP_HANDLER_STOP; break; } return EXIP_HANDLER_OK; }
END_TEST #if PRINTOUTS static void printURI(const String *str) { if (stringEqualToAscii(*str, XSI)) printf ("xsi"); else if (stringEqualToAscii(*str, XS)) printf ("xs"); else if (stringEqualToAscii(*str, EXEMPLE)) printf ("ABC"); else fwrite (str->str, sizeof(CharType), str->length, stdout); }
static char lookupPrefix(struct appData* aData, String ns, unsigned char* prxHit, unsigned char* prefixIndex) { int i; for(i = 0; i < aData->prefixesCount; i++) { if(stringEqualToAscii(ns, aData->prefixes[i])) { *prefixIndex = i; *prxHit = 1; return 0; } } if(aData->prefixesCount == MAX_PREFIXES) return 1; else { memcpy(aData->prefixes[aData->prefixesCount], ns.str, ns.length); aData->prefixes[aData->prefixesCount][ns.length] = '\0'; *prefixIndex = aData->prefixesCount; aData->prefixesCount += 1; *prxHit = 0; return 0; } }
static char sample_attribute(QName qname, void* app_data) { appData* appD = (appData*) app_data; switch(appD->eventCount) { case 1: if(!stringEqualToAscii(*qname.localName, "basis")) { printf("\nInvalid doc: basis!"); return EXIP_HANDLER_STOP; } appD->eventCount++; break; case 3: if(!stringEqualToAscii(*qname.uri, "http://www.w3.org/2001/XMLSchema-instance") || !stringEqualToAscii(*qname.localName, "nil")) { printf("\nInvalid doc: xsi:nill!"); return EXIP_HANDLER_STOP; } appD->eventCount++; break; case 4: if(!stringEqualToAscii(*qname.localName, "bass")) { printf("\nInvalid doc: bass!"); return EXIP_HANDLER_STOP; } appD->eventCount++; break; case 5: if(!stringEqualToAscii(*qname.localName, "foo")) { printf("\nInvalid doc: foo!"); return EXIP_HANDLER_STOP; } appD->eventCount++; break; default: printf("\nInvalid decoding: attribute!"); return EXIP_HANDLER_STOP; break; } return EXIP_HANDLER_OK; }
char *getPrefixByNs_String(const String *ns) { int i; ns_t *pt; for (i=0; i<NSTABLE_SIZE; i++) { pt = &NSTable[i]; if (!pt->prefix) return NULL; if (stringEqualToAscii(*ns, pt->ns)) return pt->prefix; } return NULL; }
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; }
END_TEST /* Verifies a single global element also used as a reference. */ START_TEST (test_acceptance_for_A_01_exip1) { EXIPSchema schema; FILE *infile; Parser testParser; char buf[INPUT_BUFFER_SIZE]; const char *schemafname = "testStates/acceptance-xsd.exi"; const char *exifname = "testStates/acceptance_a_01a.exi"; char exipath[MAX_PATH_LEN + strlen(exifname)]; struct appData parsingData; errorCode tmp_err_code = EXIP_UNEXPECTED_ERROR; BinaryBuffer buffer; buffer.buf = buf; buffer.bufContent = 0; buffer.bufLen = INPUT_BUFFER_SIZE; // Parsing steps: // I.A: First, read in the schema parseSchema(schemafname, &schema); // I.B: Define an external stream for the input to the parser if any size_t pathlen = strlen(dataDir); memcpy(exipath, dataDir, pathlen); exipath[pathlen] = '/'; memcpy(&exipath[pathlen+1], exifname, strlen(exifname)+1); infile = fopen(exipath, "rb" ); if(!infile) fail("Unable to open file %s", exipath); buffer.ioStrm.readWriteToStream = readFileInputStream; buffer.ioStrm.stream = infile; // II: Second, initialize the parser object tmp_err_code = initParser(&testParser, buffer, &parsingData); fail_unless (tmp_err_code == EXIP_OK, "initParser returns an error code %d", tmp_err_code); // III: Initialize the parsing data and hook the callback handlers to the parser object parsingData.eventCount = 0; parsingData.expectAttributeData = 0; if (EXIP_OK != initAllocList(&parsingData.allocList)) fail("Memory allocation error!"); testParser.handler.fatalError = sample_fatalError; testParser.handler.error = sample_fatalError; testParser.handler.startDocument = sample_startDocument; testParser.handler.endDocument = sample_endDocument; testParser.handler.startElement = sample_startElement; testParser.handler.attribute = sample_attribute; testParser.handler.stringData = sample_stringData; testParser.handler.endElement = sample_endElement; testParser.handler.decimalData = sample_decimalData; testParser.handler.intData = sample_intData; testParser.handler.floatData = sample_floatData; // IV: Parse the header of the stream tmp_err_code = parseHeader(&testParser, FALSE); fail_unless (tmp_err_code == EXIP_OK, "parsing the header returns an error code %d", tmp_err_code); tmp_err_code = setSchema(&testParser, &schema); fail_unless (tmp_err_code == EXIP_OK, "setSchema() returns an error code %d", tmp_err_code); // V: Parse the body of the EXI stream while(tmp_err_code == EXIP_OK) { switch (parsingData.eventCount) { case 0: fail_unless(stringEqualToAscii(parsingData.eventCode, "SD")); break; case 1: fail_unless(stringEqualToAscii(parsingData.eventCode, "SE")); fail_unless(stringEqualToAscii(parsingData.uri, "urn:foo")); fail_unless(stringEqualToAscii(parsingData.localName, "AB")); break; case 2: fail_unless(stringEqualToAscii(parsingData.eventCode, "CH")); break; case 3: fail_unless(stringEqualToAscii(parsingData.eventCode, "EE")); break; case 4: fail_unless(stringEqualToAscii(parsingData.eventCode, "ED")); break; default: // Unexpected event count caught below. break; } tmp_err_code = parseNext(&testParser); parsingData.eventCount++; } fail_unless(stringEqualToAscii(parsingData.eventCode, "ED")); fail_unless(parsingData.eventCount == 4, "Unexpected event count: %u", parsingData.eventCount); // VI: Free the memory allocated by the parser object freeAllocList(&parsingData.allocList); destroyParser(&testParser); fclose(infile); fail_unless (tmp_err_code == EXIP_PARSING_COMPLETE, "Error during parsing of the EXI body %d", tmp_err_code); }