| /** |
| * |
| * |
| * Generated by <a href="http://enunciate.webcohesion.com">Enunciate</a>. |
| */ |
| #include <time.h> |
| #include <string.h> |
| #include <stdlib.h> |
| #include <libxml/xmlwriter.h> |
| #include <libxml/xmlreader.h> |
| |
| #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 */ |