static void xsltNumberFormatDecimal(xmlBufferPtr buffer, double number, xmlChar digit_zero, int width, int digitsPerGroup, xmlChar groupingCharacter) { xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 1]; xmlChar *pointer; int i; /* Build buffer from back */ pointer = &temp_string[sizeof(temp_string)]; *(--pointer) = 0; for (i = 1; i < (int)sizeof(temp_string); i++) { *(--pointer) = digit_zero + (int)fmod(number, 10.0); number /= 10.0; if ((i >= width) && (fabs(number) < 1.0)) break; /* for */ if ((groupingCharacter != 0) && (digitsPerGroup > 0) && ((i % digitsPerGroup) == 0)) { *(--pointer) = groupingCharacter; } } xmlBufferCat(buffer, pointer); }
static int xsltNumberFormatGetValue(xmlXPathContextPtr context, xmlNodePtr node, xmlChar *value, double *number) { int amount = 0; xmlBufferPtr pattern; xmlXPathObjectPtr obj; pattern = xmlBufferCreate(); if (pattern != NULL) { xmlBufferCCat(pattern, "number("); xmlBufferCat(pattern, value); xmlBufferCCat(pattern, ")"); context->node = node; obj = xmlXPathEvalExpression(xmlBufferContent(pattern), context); if (obj != NULL) { *number = obj->floatval; amount++; xmlXPathFreeObject(obj); } xmlBufferFree(pattern); } return amount; }
xmlChar* PmmFastDecodeString( int charset, const xmlChar *string, const xmlChar *encoding) { xmlCharEncodingHandlerPtr coder = NULL; xmlChar *retval = NULL; xmlBufferPtr in = NULL, out = NULL; if ( charset == XML_CHAR_ENCODING_UTF8 ) { return xmlStrdup( string ); } else if ( charset == XML_CHAR_ENCODING_ERROR ) { coder = xmlFindCharEncodingHandler( (const char *) encoding ); } else if ( charset == XML_CHAR_ENCODING_NONE ) { xs_warn("PmmFastDecodeString: no encoding found\n"); } else { coder= xmlGetCharEncodingHandler( charset ); } if ( coder != NULL ) { /* warn( "do encoding %s", string ); */ in = xmlBufferCreate(); out = xmlBufferCreate(); xmlBufferCat( in, string ); if ( xmlCharEncOutFunc( coder, out, in ) >= 0 ) { retval = xmlCharStrndup((const char *)xmlBufferContent(out), xmlBufferLength(out)); } else { xs_warn("PmmFastEncodeString: decoding error\n"); } xmlBufferFree( in ); xmlBufferFree( out ); xmlCharEncCloseFunc( coder ); } return retval; }
/*Modified libxml code to avoid truncating text of child elements*/ static xmlChar * MyxmlNodeGetContent(xmlNodePtr cur) { if (cur == NULL) return(NULL); switch (cur->type) { case XML_DOCUMENT_FRAG_NODE: case XML_ELEMENT_NODE: { xmlNodePtr tmp = cur; xmlBufferPtr buffer; xmlChar *ret; buffer = xmlBufferCreate(); if (buffer == NULL) return(NULL); while (tmp != NULL) { switch (tmp->type) { case XML_CDATA_SECTION_NODE: case XML_TEXT_NODE: if (tmp->content != NULL) #ifndef XML_USE_BUFFER_CONTENT xmlBufferCat(buffer, tmp->content); #else xmlBufferCat(buffer, xmlBufferContent(tmp->content)); #endif break; case XML_ENTITY_REF_NODE: { xmlEntityPtr ent; ent = xmlGetDocEntity(cur->doc, tmp->name); if (ent != NULL) xmlBufferCat(buffer, ent->content); } default: break; } /* * Skip to next node */ if (tmp->children != NULL) { if (tmp->children->type != XML_ENTITY_DECL && tmp->children->type != XML_ELEMENT_NODE) { tmp = tmp->children; continue; } } if (tmp == cur) break; if (tmp->next != NULL) { tmp = tmp->next; continue; } do { tmp = tmp->parent; if (tmp == NULL) break; if (tmp == cur) { tmp = NULL; break; } if (tmp->next != NULL) { tmp = tmp->next; break; } } while (tmp != NULL); } ret = buffer->content; buffer->content = NULL; xmlBufferFree(buffer); return(ret); } case XML_ATTRIBUTE_NODE: { xmlAttrPtr attr = (xmlAttrPtr) cur; if (attr->parent != NULL) return(xmlNodeListGetString(attr->parent->doc, attr->children, 1)); else return(xmlNodeListGetString(NULL, attr->children, 1)); break; } case XML_COMMENT_NODE: case XML_PI_NODE: if (cur->content != NULL) #ifndef XML_USE_BUFFER_CONTENT return(xmlStrdup(cur->content)); #else return(xmlStrdup(xmlBufferContent(cur->content))); #endif return(NULL); case XML_ENTITY_REF_NODE: /* * Locate the entity, and get it's content * @@@ */ return(NULL); case XML_ENTITY_NODE: case XML_DOCUMENT_NODE: case XML_HTML_DOCUMENT_NODE: case XML_DOCUMENT_TYPE_NODE: case XML_NOTATION_NODE: case XML_DTD_NODE: case XML_XINCLUDE_START: case XML_XINCLUDE_END: #ifdef LIBXML_DOCB_ENABLED case XML_DOCB_DOCUMENT_NODE: #endif return(NULL); case XML_NAMESPACE_DECL: return(xmlStrdup(((xmlNsPtr)cur)->href)); case XML_ELEMENT_DECL: /* UNIMPLEMENTED */ return(NULL); case XML_ATTRIBUTE_DECL: /* UNIMPLEMENTED */ return(NULL); case XML_ENTITY_DECL: /* UNIMPLEMENTED */ return(NULL); case XML_CDATA_SECTION_NODE: case XML_TEXT_NODE: if (cur->content != NULL) #ifndef XML_USE_BUFFER_CONTENT return(xmlStrdup(cur->content)); #else return(xmlStrdup(xmlBufferContent(cur->content))); #endif return(NULL); } return(NULL); }
static void xsltNumberFormatInsertNumbers(xsltNumberDataPtr data, double *numbers, int numbers_max, xsltFormatPtr tokens, xmlBufferPtr buffer) { int i = 0; double number; xsltFormatTokenPtr token; /* * Handle initial non-alphanumeric token */ if (tokens->start != NULL) xmlBufferCat(buffer, tokens->start); for (i = 0; i < numbers_max; i++) { /* Insert number */ number = numbers[(numbers_max - 1) - i]; if (i < tokens->nTokens) { /* The "n"th format token will be used to format the "n"th * number in the list */ token = &(tokens->tokens[i]); } else if (tokens->nTokens > 0) { /* If there are more numbers than format tokens, then the * last format token will be used to format the remaining * numbers. */ token = &(tokens->tokens[tokens->nTokens - 1]); } else { /* If there are no format tokens, then a format token of * 1 is used to format all numbers. */ token = &default_token; } /* Print separator, except for the first number */ if (i > 0) { if (token->separator != NULL) xmlBufferCat(buffer, token->separator); else xmlBufferCCat(buffer, DEFAULT_SEPARATOR); } switch (xmlXPathIsInf(number)) { case -1: xmlBufferCCat(buffer, "-Infinity"); break; case 1: xmlBufferCCat(buffer, "Infinity"); break; default: if (xmlXPathIsNaN(number)) { xmlBufferCCat(buffer, "NaN"); } else { switch (token->token) { case 'A': xsltNumberFormatAlpha(buffer, number, TRUE); break; case 'a': xsltNumberFormatAlpha(buffer, number, FALSE); break; case 'I': xsltNumberFormatRoman(buffer, number, TRUE); break; case 'i': xsltNumberFormatRoman(buffer, number, FALSE); break; default: if (IS_DIGIT_ZERO(token->token)) { xsltNumberFormatDecimal(buffer, number, token->token, token->width, data->digitsPerGroup, data->groupingCharacter); } break; } } } } /* * Handle final non-alphanumeric token */ if (tokens->end != NULL) xmlBufferCat(buffer, tokens->end); }
static void xsltNumberFormatInsertNumbers(xsltNumberDataPtr data, double *numbers, int numbers_max, xsltFormatPtr tokens, xmlBufferPtr buffer) { int i = 0; double number; xsltFormatTokenPtr token; /* * Handle initial non-alphanumeric token */ if (tokens->start != NULL) xmlBufferCat(buffer, tokens->start); for (i = 0; i < numbers_max; i++) { /* Insert number */ number = numbers[(numbers_max - 1) - i]; /* Round to nearest like XSLT 2.0 */ number = floor(number + 0.5); /* * XSLT 1.0 isn't clear on how to handle negative numbers, but XSLT * 2.0 says: * * It is a non-recoverable dynamic error if any undiscarded item * in the atomized sequence supplied as the value of the value * attribute of xsl:number cannot be converted to an integer, or * if the resulting integer is less than 0 (zero). */ if (number < 0.0) { xsltTransformError(NULL, NULL, NULL, "xsl-number : negative value\n"); /* Recover by treating negative values as zero. */ number = 0.0; } if (i < tokens->nTokens) { /* * The "n"th format token will be used to format the "n"th * number in the list */ token = &(tokens->tokens[i]); } else if (tokens->nTokens > 0) { /* * If there are more numbers than format tokens, then the * last format token will be used to format the remaining * numbers. */ token = &(tokens->tokens[tokens->nTokens - 1]); } else { /* * If there are no format tokens, then a format token of * 1 is used to format all numbers. */ token = &default_token; } /* Print separator, except for the first number */ if (i > 0) { if (token->separator != NULL) xmlBufferCat(buffer, token->separator); else xmlBufferCCat(buffer, DEFAULT_SEPARATOR); } switch (xmlXPathIsInf(number)) { case -1: xmlBufferCCat(buffer, "-Infinity"); break; case 1: xmlBufferCCat(buffer, "Infinity"); break; default: if (xmlXPathIsNaN(number)) { xmlBufferCCat(buffer, "NaN"); } else { switch (token->token) { case 'A': xsltNumberFormatAlpha(data, buffer, number, TRUE); break; case 'a': xsltNumberFormatAlpha(data, buffer, number, FALSE); break; case 'I': xsltNumberFormatRoman(data, buffer, number, TRUE); break; case 'i': xsltNumberFormatRoman(data, buffer, number, FALSE); break; default: if (IS_DIGIT_ZERO(token->token)) { xsltNumberFormatDecimal(buffer, number, token->token, token->width, data->digitsPerGroup, data->groupingCharacter, data->groupingCharacterLen); } break; } } } } /* * Handle final non-alphanumeric token */ if (tokens->end != NULL) xmlBufferCat(buffer, tokens->end); }
static void xsltNumberFormatDecimal(xmlBufferPtr buffer, double number, int digit_zero, int width, int digitsPerGroup, int groupingCharacter, int groupingCharacterLen) { /* * This used to be * xmlChar temp_string[sizeof(double) * CHAR_BIT * sizeof(xmlChar) + 4]; * which would be length 68 on x86 arch. It was changed to be a longer, * fixed length in order to try to cater for (reasonable) UTF8 * separators and numeric characters. The max UTF8 char size will be * 6 or less, so the value used [500] should be *much* larger than needed */ xmlChar temp_string[500]; xmlChar *pointer; xmlChar temp_char[6]; int i; int val; int len; /* Build buffer from back */ pointer = &temp_string[sizeof(temp_string)] - 1; /* last char */ *pointer = 0; i = 0; while (pointer > temp_string) { if ((i >= width) && (fabs(number) < 1.0)) break; /* for */ if ((i > 0) && (groupingCharacter != 0) && (digitsPerGroup > 0) && ((i % digitsPerGroup) == 0)) { if (pointer - groupingCharacterLen < temp_string) { i = -1; /* flag error */ break; } pointer -= groupingCharacterLen; xmlCopyCharMultiByte(pointer, groupingCharacter); } val = digit_zero + (int)fmod(number, 10.0); if (val < 0x80) { /* shortcut if ASCII */ if (pointer <= temp_string) { /* Check enough room */ i = -1; break; } *(--pointer) = val; } else { /* * Here we have a multibyte character. It's a little messy, * because until we generate the char we don't know how long * it is. So, we generate it into the buffer temp_char, then * copy from there into temp_string. */ len = xmlCopyCharMultiByte(temp_char, val); if ( (pointer - len) < temp_string ) { i = -1; break; } pointer -= len; memcpy(pointer, temp_char, len); } number /= 10.0; ++i; } if (i < 0) xsltGenericError(xsltGenericErrorContext, "xsltNumberFormatDecimal: Internal buffer size exceeded\n"); xmlBufferCat(buffer, pointer); }