/** * * * Generated by Enunciate. */ #include #include #include #include #include #ifndef DEBUG_ENUNCIATE #define DEBUG_ENUNCIATE 0 #endif #ifndef ENUNCIATE_C_UTILITIES #define ENUNCIATE_C_UTILITIES /** * A basic xml node, used when (de)serializing unknown or "any" xml type. * We can't use the libxml xmlNodePtr because we can't reliably "free" it. */ struct xmlBasicNode { /** * The (local) name of the node. */ xmlChar *name; /** * The namespace of the node. */ xmlChar *ns; /** * The namespace prefix of the node. */ xmlChar *prefix; /** * The (text) value of the node. */ xmlChar *value; /** * The child elements of the node. */ struct xmlBasicNode *child_elements; /** * The attributes of the node. */ struct xmlBasicNode *attributes; /** * The next sibling (for a list of nodes). */ struct xmlBasicNode *sibling; }; /** * A QName */ struct QName { /** * The local name part of the qname. */ xmlChar *localPart; /** * The namespace URI of the node. */ xmlChar *namespaceURI; /** * The prefix assigned to the qname. */ xmlChar *prefix; }; /*******************xml utilities************************************/ static int xmlTextReaderAdvanceToNextStartOrEndElement(xmlTextReaderPtr reader) { int status = xmlTextReaderRead(reader); while (status && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT && xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT) { status = xmlTextReaderRead(reader); } return status; } static int xmlTextReaderSkipElement(xmlTextReaderPtr reader) { int status = xmlTextReaderNext(reader); while (status && xmlTextReaderNodeType(reader) != XML_READER_TYPE_ELEMENT && xmlTextReaderNodeType(reader) != XML_READER_TYPE_END_ELEMENT) { status = xmlTextReaderRead(reader); } return status; } static xmlChar *xmlTextReaderReadEntireNodeValue(xmlTextReaderPtr reader) { xmlChar *buffer = calloc(1, sizeof(xmlChar)); const xmlChar *snippet; int status; if (xmlTextReaderNodeType(reader) == XML_READER_TYPE_ATTRIBUTE) { return xmlTextReaderValue(reader); } else if (xmlTextReaderIsEmptyElement(reader) == 0) { status = xmlTextReaderRead(reader); while (status && (xmlTextReaderNodeType(reader) == XML_READER_TYPE_TEXT || xmlTextReaderNodeType(reader) == XML_READER_TYPE_CDATA || xmlTextReaderNodeType(reader) == XML_READER_TYPE_ENTITY_REFERENCE)) { snippet = xmlTextReaderConstValue(reader); buffer = realloc(buffer, (xmlStrlen(buffer) + xmlStrlen(snippet) + 1) * sizeof(xmlChar)); xmlStrcat(buffer, snippet); status = xmlTextReaderRead(reader); } } return buffer; } /*******************base 64 utilities************************************/ /* * Base64 Translation Table as described in RFC1113. * * This code was graciously ripped from http://base64.sourceforge.net */ static const char cb64[]="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /* * Base64 Translation Table to decode (created by author) * * This code was graciously ripped from http://base64.sourceforge.net */ static const char cd64[]="|$$$}rstuvwxyz{$$$$$$$>?@ABCDEFGHIJKLMNOPQRSTUVW$$$$$$XYZ[\\]^_`abcdefghijklmnopq"; /* * encode 3 8-bit binary bytes as 4 '6-bit' characters * * This code was graciously ripped from http://base64.sourceforge.net * * @param in the block to encode * @param out the block to encode to * @param len the length of the 'in' block. */ static void _encode_base64_block(unsigned char in[3], unsigned char out[4], int len) { out[0] = cb64[ in[0] >> 2 ]; out[1] = cb64[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ]; out[2] = (unsigned char) (len > 1 ? cb64[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '='); out[3] = (unsigned char) (len > 2 ? cb64[ in[2] & 0x3f ] : '='); } /* * decode 4 '6-bit' characters into 3 8-bit binary bytes * * This code was graciously ripped from http://base64.sourceforge.net */ static void _decode_base64_block( unsigned char in[4], unsigned char out[3] ) { out[ 0 ] = (unsigned char ) (in[0] << 2 | in[1] >> 4); out[ 1 ] = (unsigned char ) (in[1] << 4 | in[2] >> 2); out[ 2 ] = (unsigned char ) (((in[2] << 6) & 0xc0) | in[3]); } /* * base64 encode a stream adding padding and line breaks as per spec. * * This code was graciously ripped from http://base64.sourceforge.net * * @param instream The stream to encode. * @param insize The size of the stream to encode. * @return The encoded string. */ xmlChar *_encode_base64(unsigned char *instream, int insize) { unsigned char in[3]; unsigned char out[4]; xmlChar *encoded; int i, in_index = 0, out_index = 0, blocklen; if (insize == 0) { return BAD_CAST "\0"; } encoded = calloc(((insize / 3) * 4) + 10, sizeof(xmlChar)); while (in_index <= insize) { blocklen = 0; for (i = 0; i < 3; i++) { in[i] = instream[in_index++]; if (in_index <= insize) { blocklen++; } else { in[i] = 0; } } if (blocklen) { _encode_base64_block(in, out, blocklen); for( i = 0; i < 4; i++ ) { encoded[out_index++] = out[i]; } } } return encoded; } /* * Decode a base64 encoded stream discarding padding, line breaks and noise * * This code was graciously ripped from http://base64.sourceforge.net * * @param invalue The string to decode. * @param outsize Holder for the length of the returned data. * @return The decoded data. */ unsigned char *_decode_base64( const xmlChar *invalue, int *outsize ) { xmlChar in[4]; unsigned char out[3], v; int i, in_index = 0, out_index = 0, blocklen; unsigned char *outstream; if (invalue == NULL) { return NULL; } outstream = calloc(((xmlStrlen(invalue) / 4) * 3) + 1, sizeof(unsigned char)); while (invalue[in_index] != '\0') { for (blocklen = 0, i = 0; i < 4 && invalue[in_index]; i++) { v = 0; while (invalue[in_index] != '\0' && v == 0) { v = (unsigned char) invalue[in_index++]; v = (unsigned char) ((v < 43 || v > 122) ? 0 : cd64[ v - 43 ]); if (v) { v = (unsigned char) ((v == '$') ? 0 : v - 61); } } if (v) { blocklen++; in[i] = (unsigned char) (v - 1); } else { in[i] = 0; } } if (blocklen) { _decode_base64_block( in, out ); for( i = 0; i < blocklen - 1; i++ ) { outstream[out_index++] = out[i]; } } } if (outsize != NULL) { *outsize = out_index; } return outstream; } #endif /* ENUNCIATE_C_UTILITIES */ #ifndef BASIC_XML_FUNCTIONS_Xs #define BASIC_XML_FUNCTIONS_Xs /*******************xs:boolean************************************/ /** * Read a boolean value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to 1 if "true" was read. pointer to 0 otherwise. */ static int *xmlTextReaderReadXsBooleanType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); int *value = malloc(sizeof(int)); *value = (xmlStrcmp(BAD_CAST "true", nodeValue) == 0) ? 1 : 0; free(nodeValue); return value; } /** * Write a boolean value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsBooleanType(xmlTextWriterPtr writer, int *value) { if (*value) { return xmlTextWriterWriteString(writer, BAD_CAST "true"); } else { return xmlTextWriterWriteString(writer, BAD_CAST "false"); } } /** * Frees a boolean type from memory. * * @param value The value to free. */ static void freeXsBooleanType(int *value) { //no-op } /*******************xs:byte************************************/ /** * Read a byte value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the byte. */ static unsigned char *xmlTextReaderReadXsByteType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); unsigned char *value = malloc(sizeof(unsigned char)); *value = (unsigned char) atoi((char *) nodeValue); free(nodeValue); return value; } /** * Write a byte value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsByteType(xmlTextWriterPtr writer, unsigned char *value) { return xmlTextWriterWriteFormatString(writer, "%i", *value); } /** * Frees a byte type from memory. * * @param value The value to free. */ static void freeXsByteType(unsigned char *value) { //no-op } /*******************xs:double************************************/ /** * Read a double value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the double. */ static double *xmlTextReaderReadXsDoubleType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); double *value = malloc(sizeof(double)); *value = atof((char *) nodeValue); free(nodeValue); return value; } /** * Write a double value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsDoubleType(xmlTextWriterPtr writer, double *value) { return xmlTextWriterWriteFormatString(writer, "%f", *value); } /** * Frees a double type from memory. * * @param value The value to free. */ static void freeXsDoubleType(double *value) { //no-op } /*******************xs:float************************************/ /** * Read a float value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the float. */ static float *xmlTextReaderReadXsFloatType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); float *value = malloc(sizeof(float)); *value = atof((char *)nodeValue); free(nodeValue); return value; } /** * Write a float value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsFloatType(xmlTextWriterPtr writer, float *value) { return xmlTextWriterWriteFormatString(writer, "%f", *value); } /** * Frees a float type from memory. * * @param value The value to free. */ static void freeXsFloatType(float *value) { //no-op } /*******************xs:int************************************/ /** * Read a int value from the reader. * * @param reader The reader (pointing at a node with a value). * @param value The value to be written. * @return pointer to the int. */ static int *xmlTextReaderReadXsIntType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); int *value = malloc(sizeof(int)); *value = atoi((char *)nodeValue); free(nodeValue); return value; } /** * Write a int value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsIntType(xmlTextWriterPtr writer, int *value) { return xmlTextWriterWriteFormatString(writer, "%i", *value); } /** * Frees a int type from memory. * * @param value The value to free. */ static void freeXsIntType(int *value) { //no-op } /*******************xs:long************************************/ /** * Read a long value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the long. */ static long long *xmlTextReaderReadXsLongType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); long long *value = malloc(sizeof(long long)); *value = atoll((char *)nodeValue); free(nodeValue); return value; } /** * Write a long value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsLongType(xmlTextWriterPtr writer, long long *value) { return xmlTextWriterWriteFormatString(writer, "%lld", *value); } /** * Frees a long type from memory. * * @param value The value to free. */ static void freeXsLongType(long long *value) { //no-op } /*******************xs:short************************************/ /** * Read a short value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the short. */ static short *xmlTextReaderReadXsShortType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); short *value = malloc(sizeof(short)); *value = atoi((char *)nodeValue); return value; } /** * Write a short value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsShortType(xmlTextWriterPtr writer, short *value) { return xmlTextWriterWriteFormatString(writer, "%hi", *value); } /** * Frees a short type from memory. * * @param value The value to free. */ static void freeXsShortType(short *value) { //no-op } /*******************xs:unsignedShort************************************/ /** * Read an unsigned short value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the unsigned short. */ static unsigned short *xmlTextReaderReadXsUnsignedShortType(xmlTextReaderPtr reader) { xmlChar *nodeValue = xmlTextReaderReadEntireNodeValue(reader); unsigned short *value = malloc(sizeof(unsigned short)); *value = atoi((char *)nodeValue); return value; } /** * Write a short value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsUnsignedShortType(xmlTextWriterPtr writer, unsigned short *value) { return xmlTextWriterWriteFormatString(writer, "%hi", *value); } /** * Frees a short type from memory. * * @param value The value to free. */ static void freeXsUnsignedShortType(unsigned short *value) { //no-op } /*******************xs:string************************************/ /** * Read a string value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the string. */ static xmlChar *xmlTextReaderReadXsStringType(xmlTextReaderPtr reader) { return xmlTextReaderReadEntireNodeValue(reader); } /** * Write a string value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsStringType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a string type from memory. * * @param value The value to free. */ static void freeXsStringType(xmlChar *value) { //no-op } /*******************xs:ID************************************/ /** * Read a ID value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the ID. */ static xmlChar *xmlTextReaderReadXsIDType(xmlTextReaderPtr reader) { return xmlTextReaderReadXsStringType(reader); } /** * Write a ID value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsIDType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a ID type from memory. * * @param value The value to free. */ static void freeXsIDType(xmlChar *value) { freeXsStringType(value); } /*******************xs:IDREF************************************/ /** * Read a IDREF value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the IDREF. */ static xmlChar *xmlTextReaderReadXsIDREFType(xmlTextReaderPtr reader) { return xmlTextReaderReadXsStringType(reader); } /** * Write a IDREF value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsIDREFType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a IDREF type from memory. * * @param value The value to free. */ static void freeXsIDREFType(xmlChar *value) { freeXsStringType(value); } /*******************xs:integer************************************/ /** * Read a (big) integer value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the integer. */ static xmlChar *xmlTextReaderReadXsIntegerType(xmlTextReaderPtr reader) { return xmlTextReaderReadXsStringType(reader); } /** * Write a integer value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsIntegerType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a integer type from memory. * * @param value The value to free. */ static void freeXsIntegerType(xmlChar *value) { freeXsStringType(value); } /*******************xs:decimal************************************/ /** * Read a (big) decimal value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the decimal. */ static xmlChar *xmlTextReaderReadXsDecimalType(xmlTextReaderPtr reader) { return xmlTextReaderReadXsStringType(reader); } /** * Write a decimal value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsDecimalType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a decimal type from memory. * * @param value The value to free. */ static void freeXsDecimalType(xmlChar *value) { freeXsStringType(value); } /*******************xs:duration************************************/ /** * Read a duration value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the duration. */ static xmlChar *xmlTextReaderReadXsDurationType(xmlTextReaderPtr reader) { return xmlTextReaderReadXsStringType(reader); } /** * Write a duration value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsDurationType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a duration type from memory. * * @param value The value to free. */ static void freeXsDurationType(xmlChar *value) { freeXsStringType(value); } /*******************xs:QName************************************/ /** * Frees a QName type from memory. * * @param value The value to free. */ static void freeXsQNameType(struct QName *value) { if (value->namespaceURI != NULL) { #if DEBUG_ENUNCIATE printf("Freeing QName namespaceURI...\n"); #endif free(value->namespaceURI); } if (value->localPart != NULL) { #if DEBUG_ENUNCIATE printf("Freeing QName localPart...\n"); #endif free(value->localPart); } if (value->prefix != NULL) { #if DEBUG_ENUNCIATE printf("Freeing QName prefix...\n"); #endif free(value->prefix); } } /** * Read a QName value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the QName, or NULL if error. */ static struct QName *xmlTextReaderReadXsQNameType(xmlTextReaderPtr reader) { xmlChar *value = xmlTextReaderReadEntireNodeValue(reader); struct QName * qname = calloc(1, sizeof(struct QName)); int len = 0; xmlChar *prefix; #if DEBUG_ENUNCIATE > 1 printf("Reading QName value %s...\n", value); #endif if (value[len] == 0) { #if DEBUG_ENUNCIATE printf("Error: empty qname value.\n"); #endif free(value); free(qname); return NULL; } else if (value[0] == ':') { #if DEBUG_ENUNCIATE > 1 printf("QName value that starts with ':'. Weird.\n"); #endif /* nasty but valid */ qname->namespaceURI = xmlStrdup(BAD_CAST ""); qname->localPart = xmlStrsub(value, 1, xmlStrlen(value) - 1); } else { /* * look for the ':' */ while ((value[len] != 0) && (value[len] != ':')) { len++; } #if DEBUG_ENUNCIATE > 1 printf("QName ':' character found at %i.\n", len); #endif if (value[len] == 0) { qname->namespaceURI = xmlStrdup(BAD_CAST ""); qname->localPart = xmlStrdup(value); } else { prefix = xmlStrsub(value, 0, len); qname->namespaceURI = xmlTextReaderLookupNamespace(reader, prefix); qname->localPart = xmlStrsub(value, len + 1, xmlStrlen(value) - len - 1); free(prefix); } } if ((qname->namespaceURI == NULL) || (qname->localPart == NULL)) { #if DEBUG_ENUNCIATE > 1 printf("Error in QName: NULL namespaceURI or localPart.\n"); #endif freeXsQNameType(qname); free(qname); free(value); return NULL; } #if DEBUG_ENUNCIATE > 1 printf("Read QName {%s}%s.\n", qname->namespaceURI, qname->localPart); #endif free(value); return qname; } /** * Write a QName value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsQNameType(xmlTextWriterPtr writer, struct QName *value) { if (value->localPart == NULL) { #if DEBUG_ENUNCIATE printf("Cannot write QName: no local part specified."); #endif return -1; } if ((value->namespaceURI == NULL) || (xmlStrlen(value->namespaceURI) == 0) || (value->prefix == NULL)) { return xmlTextWriterWriteString(writer, value->localPart); } else { return xmlTextWriterWriteFormatString(writer, "%s:%s", value->prefix, value->localPart); } } /*******************xs:anyURI************************************/ /** * Read a anyURI value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the anyURI. */ static xmlChar *xmlTextReaderReadXsAnyURIType(xmlTextReaderPtr reader) { return xmlTextReaderReadXsStringType(reader); } /** * Write a anyURI value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsAnyURIType(xmlTextWriterPtr writer, xmlChar *value) { return xmlTextWriterWriteString(writer, value); } /** * Frees a anyURI type from memory. * * @param value The value to free. */ static void freeXsAnyURIType(xmlChar *value) { freeXsStringType(value); } /*******************xs:dateTime************************************/ /** * Read a dateTime value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the dateTime. */ static struct tm *xmlTextReaderReadXsDateTimeType(xmlTextReaderPtr reader) { struct tm * time = calloc(1, sizeof(struct tm)); xmlChar *timevalue = xmlTextReaderReadEntireNodeValue(reader); int success = 0, index = 0, token_index = 0, len = xmlStrlen(timevalue), offset_hours = 0, offset_min = 0; char token[len]; //date time format: yyyy-mm-ddThh:MM:ss+oo:oo //go to first '-' character. token_index = 0; while (index < len && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_year = atoi(token) - 1900; if (token_index > 0) { success++; //assume 'year' was successfully read. index++; } //go to next '-' character. token_index = 0; while (index < len && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_mon = atoi(token) - 1; if (token_index > 0) { success++; //assume 'month' was successfully read. index++; } //go to 'T' character. token_index = 0; while (index < len && timevalue[index] != 'T') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_mday = atoi(token); if (token_index > 0) { success++; //assume 'day' was successfully read. index++; } //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_hour = atoi(token); if (token_index > 0) { success++; //assume 'hour' was successfully read. index++; } //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_min = atoi(token); if (token_index > 0) { success++; //assume 'minutes' was successfully read. index++; } //go to '+' or '-' character. token_index = 0; while (index < len && timevalue[index] != '+' && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_sec = atof(token); if (token_index > 0) { success++; //assume 'seconds' was successfully read. if (timevalue[index] == '+') { index++; } } //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; offset_hours = atoi(token); if (token_index > 0) { success++; //assume gmt offset hours was successfully read. index++; } //go to end. token_index = 0; while (index < len) { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; offset_min = atoi(token); if (token_index > 0) { success++; //assume gmt offset minutes was successfully read. index++; } time->tm_gmtoff = ((offset_hours * 60) + offset_min) * 60; free(timevalue); return time; } /** * Write a dateTime value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsDateTimeType(xmlTextWriterPtr writer, struct tm *value) { return xmlTextWriterWriteFormatString(writer, "%04i-%02i-%02iT%02i:%02i:%02i.000%+03i:%02i", value->tm_year + 1900, value->tm_mon + 1, value->tm_mday, value->tm_hour, value->tm_min, value->tm_sec, (int) (value->tm_gmtoff / 3600), (int) ((value->tm_gmtoff / 60) % 60)); } /** * Frees a dateTime type from memory. * * @param value The value to free. */ static void freeXsDateTimeType(struct tm *value) { //no-op } /*******************xs:time************************************/ /** * Read a time value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the time. */ static struct tm *xmlTextReaderReadXsTimeType(xmlTextReaderPtr reader) { struct tm * time = calloc(1, sizeof(struct tm)); xmlChar *timevalue = xmlTextReaderReadEntireNodeValue(reader); int success = 0, index = 0, token_index = 0, len = xmlStrlen(timevalue), offset_hours = 0, offset_min = 0; char token[len]; //date time format: hh:MM:ss+oo:oo //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_hour = atoi(token); if (token_index > 0) { success++; //assume 'hour' was successfully read. index++; } //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_min = atoi(token); if (token_index > 0) { success++; //assume 'minutes' was successfully read. index++; } //go to '+' or '-' character. token_index = 0; while (index < len && timevalue[index] != '+' && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_sec = atof(token); if (token_index > 0) { success++; //assume 'seconds' was successfully read. if (timevalue[index] == '+') { index++; } } //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; offset_hours = atoi(token); if (token_index > 0) { success++; //assume gmt offset hours was successfully read. index++; } //go to end. token_index = 0; while (index < len) { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; offset_min = atoi(token); if (token_index > 0) { success++; //assume gmt offset minutes was successfully read. index++; } time->tm_gmtoff = ((offset_hours * 60) + offset_min) * 60; free(timevalue); return time; } /** * Write a time value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsTimeType(xmlTextWriterPtr writer, struct tm *value) { return xmlTextWriterWriteFormatString(writer, "%02i:%02i:%02i.000%+03i:%02i", value->tm_hour, value->tm_min, value->tm_sec, (int) (value->tm_gmtoff / 3600), (int) ((value->tm_gmtoff / 60) % 60)); } /** * Frees a time type from memory. * * @param value The value to free. */ static void freeXsTimeType(struct tm *value) { //no-op } /*******************xs:date************************************/ /** * Read a date value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the date. */ static struct tm *xmlTextReaderReadXsDateType(xmlTextReaderPtr reader) { struct tm * time = calloc(1, sizeof(struct tm)); xmlChar *timevalue = xmlTextReaderReadEntireNodeValue(reader); int success = 0, index = 0, token_index = 0, len = xmlStrlen(timevalue), offset_hours = 0, offset_min = 0; char token[len]; //date time format: yyyy-mm-dd+oo:oo //go to first '-' character. token_index = 0; while (index < len && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_year = atoi(token) - 1900; if (token_index > 0) { success++; //assume 'year' was successfully read. index++; } //go to next '-' character. token_index = 0; while (index < len && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_mon = atoi(token) - 1; if (token_index > 0) { success++; //assume 'month' was successfully read. index++; } //go to '+' or '-' character. token_index = 0; while (index < len && timevalue[index] != '+' && timevalue[index] != '-') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; time->tm_sec = atof(token); if (token_index > 0) { success++; //assume 'seconds' was successfully read. if (timevalue[index] == '+') { index++; } } //go to ':' character. token_index = 0; while (index < len && timevalue[index] != ':') { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; offset_hours = atoi(token); if (token_index > 0) { success++; //assume gmt offset hours was successfully read. index++; } //go to end. token_index = 0; while (index < len) { token[token_index++] = timevalue[index++]; } token[token_index] = '\n'; offset_min = atoi(token); if (token_index > 0) { success++; //assume gmt offset minutes was successfully read. index++; } time->tm_gmtoff = ((offset_hours * 60) + offset_min) * 60; free(timevalue); return time; } /** * Write a date value to the writer. * * @param writer The writer. * @param value The value to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsDateType(xmlTextWriterPtr writer, struct tm *value) { return xmlTextWriterWriteFormatString(writer, "%04i-%02i-%02i%+03i:%02i", value->tm_year + 1900, value->tm_mon + 1, value->tm_mday, (int) (value->tm_gmtoff / 3600), (int) ((value->tm_gmtoff / 60) % 60)); } /** * Frees a date type from memory. * * @param value The value to free. */ static void freeXsDateType(struct tm *value) { //no-op } /*******************xs:anyType************************************/ /** * Frees a anyType type from memory. * * @param node The node to free. */ static void freeXsAnyTypeType(struct xmlBasicNode *node) { if (node->attributes != NULL) { freeXsAnyTypeType(node->attributes); } if (node->value != NULL) { free(node->value); } if (node->child_elements != NULL) { freeXsAnyTypeType(node->child_elements); } if (node->name != NULL) { free(node->name); } if (node->prefix != NULL) { free(node->prefix); } if (node->ns != NULL) { free(node->ns); } if (node->sibling != NULL) { freeXsAnyTypeType(node->sibling); free(node->sibling); } } /** * Read a anyType value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the anyType., or NULL if error. */ static struct xmlBasicNode *xmlTextReaderReadXsAnyTypeType(xmlTextReaderPtr reader) { struct xmlBasicNode *child, *next, *node = calloc(1, sizeof(struct xmlBasicNode)); int status, depth = xmlTextReaderDepth(reader); const xmlChar *text; node->name = xmlTextReaderLocalName(reader); node->ns = xmlTextReaderNamespaceUri(reader); node->prefix = xmlTextReaderPrefix(reader); if (xmlTextReaderHasAttributes(reader)) { child = NULL; while (xmlTextReaderMoveToNextAttribute(reader)) { next = calloc(1, sizeof(struct xmlBasicNode)); if (child == NULL) { node->attributes = next; } else { child->sibling = next; } child = next; child->name = xmlTextReaderLocalName(reader); child->ns = xmlTextReaderNamespaceUri(reader); child->prefix = xmlTextReaderPrefix(reader); child->value = xmlTextReaderValue(reader); } status = xmlTextReaderMoveToElement(reader); if (status < 1) { //panic: unable to return to the element node. freeXsAnyTypeType(node); free(node); return NULL; } } if (xmlTextReaderIsEmptyElement(reader) == 0) { status = xmlTextReaderRead(reader); while (status == 1 && xmlTextReaderDepth(reader) > depth) { switch (xmlTextReaderNodeType(reader)) { case XML_READER_TYPE_ELEMENT: child = xmlTextReaderReadXsAnyTypeType(reader); if (child == NULL) { //panic: xml read error freeXsAnyTypeType(node); free(node); return NULL; } next = node->child_elements; if (next == NULL) { node->child_elements = child; } else { while (1) { if (next->sibling == NULL) { next->sibling = child; break; } next = next->sibling; } } break; case XML_READER_TYPE_TEXT: case XML_READER_TYPE_CDATA: text = xmlTextReaderConstValue(reader); node->value = xmlStrncat(node->value, text, xmlStrlen(text)); break; default: //skip anything else. break; } status = xmlTextReaderRead(reader); } if (status < 1) { //panic: xml read error freeXsAnyTypeType(node); free(node); return NULL; } } return node; } /** * Write a anyType value to the writer. * * @param writer The writer. * @param node The node to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsAnyTypeType(xmlTextWriterPtr writer, struct xmlBasicNode *node) { int status; int totalBytes = 0; struct xmlBasicNode *next; status = xmlTextWriterStartElementNS(writer, node->prefix, node->name, node->ns); if (status < 0) { return status; } totalBytes += status; next = node->attributes; while (next != NULL) { status = xmlTextWriterWriteAttributeNS(writer, next->prefix, next->name, next->ns, next->value); if (status < 0) { return status; } totalBytes += status; next = next->sibling; } if (node->value != NULL) { status = xmlTextWriterWriteString(writer, node->value); if (status < 0) { //panic: xml write error return status; } totalBytes += status; } next = node->child_elements; while (next != NULL) { status = xmlTextWriterWriteXsAnyTypeType(writer, next); if (status < 0) { return status; } totalBytes += status; next = next->sibling; } status = xmlTextWriterEndElement(writer); if (status < 0) { return status; } totalBytes += status; return totalBytes; } /** * Read a anyType element value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the anyType., or NULL if error. */ static struct xmlBasicNode *xmlTextReaderReadXsAnyTypeElement(xmlTextReaderPtr reader) { return xmlTextReaderReadXsAnyTypeType(reader); } /** * Write a anyType element value to the writer. * * @param writer The writer. * @param node The node to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsAnyTypeElement(xmlTextWriterPtr writer, struct xmlBasicNode *node) { return xmlTextWriterWriteXsAnyTypeType(writer, node); } /** * Write a anyType element value to the writer. * * @param writer The writer. * @param node The node to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsAnyTypeElementNS(xmlTextWriterPtr writer, struct xmlBasicNode *node, int writeNamespaces) { return xmlTextWriterWriteXsAnyTypeType(writer, node); } /** * Free a anyType element value. * * @param node The node. */ static void freeXsAnyTypeElement(struct xmlBasicNode *node) { freeXsAnyTypeType(node); } /*******************xs:anySimpleType************************************/ /** * Frees a anyType type from memory. * * @param node The node to free. */ static void freeXsAnySimpleTypeType(struct xmlBasicNode *node) { freeXsAnyTypeType(node); } /** * Read a anyType value from the reader. * * @param reader The reader (pointing at a node with a value). * @return pointer to the anyType., or NULL if error. */ static struct xmlBasicNode *xmlTextReaderReadXsAnySimpleTypeType(xmlTextReaderPtr reader) { struct xmlBasicNode *node = calloc(1, sizeof(struct xmlBasicNode)); node->name = xmlTextReaderLocalName(reader); node->ns = xmlTextReaderNamespaceUri(reader); node->prefix = xmlTextReaderPrefix(reader); node->value = xmlTextReaderReadEntireNodeValue(reader); return node; } /** * Write a anyType value to the writer. * * @param writer The writer. * @param node The node to be written. * @return the bytes written (may be 0 because of buffering) or -1 in case of error. */ static int xmlTextWriterWriteXsAnySimpleTypeType(xmlTextWriterPtr writer, struct xmlBasicNode *node) { if (node->value != NULL) { return xmlTextWriterWriteXsStringType(writer, node->value); } return 0; } #endif /* BASIC_XML_FUNCTIONS_Xs */