Blame xmlstring.c

Packit Service a31ea6
/*
Packit Service a31ea6
 * string.c : an XML string utilities module
Packit Service a31ea6
 *
Packit Service a31ea6
 * This module provides various utility functions for manipulating
Packit Service a31ea6
 * the xmlChar* type. All functions named xmlStr* have been moved here
Packit Service a31ea6
 * from the parser.c file (their original home).
Packit Service a31ea6
 *
Packit Service a31ea6
 * See Copyright for the status of this software.
Packit Service a31ea6
 *
Packit Service a31ea6
 * UTF8 string routines from:
Packit Service a31ea6
 * William Brack <wbrack@mmm.com.hk>
Packit Service a31ea6
 *
Packit Service a31ea6
 * daniel@veillard.com
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
#define IN_LIBXML
Packit Service a31ea6
#include "libxml.h"
Packit Service a31ea6
Packit Service a31ea6
#include <stdlib.h>
Packit Service a31ea6
#include <string.h>
Packit Service a31ea6
#include <libxml/xmlmemory.h>
Packit Service a31ea6
#include <libxml/parserInternals.h>
Packit Service a31ea6
#include <libxml/xmlstring.h>
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 *                Commodity functions to handle xmlChars                *
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrndup:
Packit Service a31ea6
 * @cur:  the input xmlChar *
Packit Service a31ea6
 * @len:  the len of @cur
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strndup for array of xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar * or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlStrndup(const xmlChar *cur, int len) {
Packit Service a31ea6
    xmlChar *ret;
Packit Service a31ea6
Packit Service a31ea6
    if ((cur == NULL) || (len < 0)) return(NULL);
Packit Service a31ea6
    ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
Packit Service a31ea6
    if (ret == NULL) {
Packit Service a31ea6
        xmlErrMemory(NULL, NULL);
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    }
Packit Service a31ea6
    memcpy(ret, cur, len * sizeof(xmlChar));
Packit Service a31ea6
    ret[len] = 0;
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrdup:
Packit Service a31ea6
 * @cur:  the input xmlChar *
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strdup for array of xmlChar's. Since they are supposed to be
Packit Service a31ea6
 * encoded in UTF-8 or an encoding with 8bit based chars, we assume
Packit Service a31ea6
 * a termination mark of '0'.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar * or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlStrdup(const xmlChar *cur) {
Packit Service a31ea6
    const xmlChar *p = cur;
Packit Service a31ea6
Packit Service a31ea6
    if (cur == NULL) return(NULL);
Packit Service a31ea6
    while (*p != 0) p++; /* non input consuming */
Packit Service a31ea6
    return(xmlStrndup(cur, p - cur));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlCharStrndup:
Packit Service a31ea6
 * @cur:  the input char *
Packit Service a31ea6
 * @len:  the len of @cur
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strndup for char's to xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar * or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlCharStrndup(const char *cur, int len) {
Packit Service a31ea6
    int i;
Packit Service a31ea6
    xmlChar *ret;
Packit Service a31ea6
Packit Service a31ea6
    if ((cur == NULL) || (len < 0)) return(NULL);
Packit Service a31ea6
    ret = (xmlChar *) xmlMallocAtomic((len + 1) * sizeof(xmlChar));
Packit Service a31ea6
    if (ret == NULL) {
Packit Service a31ea6
        xmlErrMemory(NULL, NULL);
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    }
Packit Service a31ea6
    for (i = 0;i < len;i++) {
Packit Service a31ea6
        ret[i] = (xmlChar) cur[i];
Packit Service a31ea6
        if (ret[i] == 0) return(ret);
Packit Service a31ea6
    }
Packit Service a31ea6
    ret[len] = 0;
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlCharStrdup:
Packit Service a31ea6
 * @cur:  the input char *
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strdup for char's to xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar * or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlCharStrdup(const char *cur) {
Packit Service a31ea6
    const char *p = cur;
Packit Service a31ea6
Packit Service a31ea6
    if (cur == NULL) return(NULL);
Packit Service a31ea6
    while (*p != '\0') p++; /* non input consuming */
Packit Service a31ea6
    return(xmlCharStrndup(cur, p - cur));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrcmp:
Packit Service a31ea6
 * @str1:  the first xmlChar *
Packit Service a31ea6
 * @str2:  the second xmlChar *
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strcmp for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the integer result of the comparison
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrcmp(const xmlChar *str1, const xmlChar *str2) {
Packit Service a31ea6
    register int tmp;
Packit Service a31ea6
Packit Service a31ea6
    if (str1 == str2) return(0);
Packit Service a31ea6
    if (str1 == NULL) return(-1);
Packit Service a31ea6
    if (str2 == NULL) return(1);
Packit Service a31ea6
    do {
Packit Service a31ea6
        tmp = *str1++ - *str2;
Packit Service a31ea6
        if (tmp != 0) return(tmp);
Packit Service a31ea6
    } while (*str2++ != 0);
Packit Service a31ea6
    return 0;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrEqual:
Packit Service a31ea6
 * @str1:  the first xmlChar *
Packit Service a31ea6
 * @str2:  the second xmlChar *
Packit Service a31ea6
 *
Packit Service a31ea6
 * Check if both strings are equal of have same content.
Packit Service a31ea6
 * Should be a bit more readable and faster than xmlStrcmp()
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if they are equal, 0 if they are different
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrEqual(const xmlChar *str1, const xmlChar *str2) {
Packit Service a31ea6
    if (str1 == str2) return(1);
Packit Service a31ea6
    if (str1 == NULL) return(0);
Packit Service a31ea6
    if (str2 == NULL) return(0);
Packit Service a31ea6
    do {
Packit Service a31ea6
        if (*str1++ != *str2) return(0);
Packit Service a31ea6
    } while (*str2++);
Packit Service a31ea6
    return(1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrQEqual:
Packit Service a31ea6
 * @pref:  the prefix of the QName
Packit Service a31ea6
 * @name:  the localname of the QName
Packit Service a31ea6
 * @str:  the second xmlChar *
Packit Service a31ea6
 *
Packit Service a31ea6
 * Check if a QName is Equal to a given string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns 1 if they are equal, 0 if they are different
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrQEqual(const xmlChar *pref, const xmlChar *name, const xmlChar *str) {
Packit Service a31ea6
    if (pref == NULL) return(xmlStrEqual(name, str));
Packit Service a31ea6
    if (name == NULL) return(0);
Packit Service a31ea6
    if (str == NULL) return(0);
Packit Service a31ea6
Packit Service a31ea6
    do {
Packit Service a31ea6
        if (*pref++ != *str) return(0);
Packit Service a31ea6
    } while ((*str++) && (*pref));
Packit Service a31ea6
    if (*str++ != ':') return(0);
Packit Service a31ea6
    do {
Packit Service a31ea6
        if (*name++ != *str) return(0);
Packit Service a31ea6
    } while (*str++);
Packit Service a31ea6
    return(1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrncmp:
Packit Service a31ea6
 * @str1:  the first xmlChar *
Packit Service a31ea6
 * @str2:  the second xmlChar *
Packit Service a31ea6
 * @len:  the max comparison length
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strncmp for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the integer result of the comparison
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrncmp(const xmlChar *str1, const xmlChar *str2, int len) {
Packit Service a31ea6
    register int tmp;
Packit Service a31ea6
Packit Service a31ea6
    if (len <= 0) return(0);
Packit Service a31ea6
    if (str1 == str2) return(0);
Packit Service a31ea6
    if (str1 == NULL) return(-1);
Packit Service a31ea6
    if (str2 == NULL) return(1);
Packit Service a31ea6
#ifdef __GNUC__
Packit Service a31ea6
    tmp = strncmp((const char *)str1, (const char *)str2, len);
Packit Service a31ea6
    return tmp;
Packit Service a31ea6
#else
Packit Service a31ea6
    do {
Packit Service a31ea6
        tmp = *str1++ - *str2;
Packit Service a31ea6
        if (tmp != 0 || --len == 0) return(tmp);
Packit Service a31ea6
    } while (*str2++ != 0);
Packit Service a31ea6
    return 0;
Packit Service a31ea6
#endif
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
static const xmlChar casemap[256] = {
Packit Service a31ea6
    0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
Packit Service a31ea6
    0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,0x0F,
Packit Service a31ea6
    0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,
Packit Service a31ea6
    0x18,0x19,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,
Packit Service a31ea6
    0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,
Packit Service a31ea6
    0x28,0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,
Packit Service a31ea6
    0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,
Packit Service a31ea6
    0x38,0x39,0x3A,0x3B,0x3C,0x3D,0x3E,0x3F,
Packit Service a31ea6
    0x40,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
Packit Service a31ea6
    0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
Packit Service a31ea6
    0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
Packit Service a31ea6
    0x78,0x79,0x7A,0x7B,0x5C,0x5D,0x5E,0x5F,
Packit Service a31ea6
    0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67,
Packit Service a31ea6
    0x68,0x69,0x6A,0x6B,0x6C,0x6D,0x6E,0x6F,
Packit Service a31ea6
    0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77,
Packit Service a31ea6
    0x78,0x79,0x7A,0x7B,0x7C,0x7D,0x7E,0x7F,
Packit Service a31ea6
    0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,
Packit Service a31ea6
    0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,
Packit Service a31ea6
    0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97,
Packit Service a31ea6
    0x98,0x99,0x9A,0x9B,0x9C,0x9D,0x9E,0x9F,
Packit Service a31ea6
    0xA0,0xA1,0xA2,0xA3,0xA4,0xA5,0xA6,0xA7,
Packit Service a31ea6
    0xA8,0xA9,0xAA,0xAB,0xAC,0xAD,0xAE,0xAF,
Packit Service a31ea6
    0xB0,0xB1,0xB2,0xB3,0xB4,0xB5,0xB6,0xB7,
Packit Service a31ea6
    0xB8,0xB9,0xBA,0xBB,0xBC,0xBD,0xBE,0xBF,
Packit Service a31ea6
    0xC0,0xC1,0xC2,0xC3,0xC4,0xC5,0xC6,0xC7,
Packit Service a31ea6
    0xC8,0xC9,0xCA,0xCB,0xCC,0xCD,0xCE,0xCF,
Packit Service a31ea6
    0xD0,0xD1,0xD2,0xD3,0xD4,0xD5,0xD6,0xD7,
Packit Service a31ea6
    0xD8,0xD9,0xDA,0xDB,0xDC,0xDD,0xDE,0xDF,
Packit Service a31ea6
    0xE0,0xE1,0xE2,0xE3,0xE4,0xE5,0xE6,0xE7,
Packit Service a31ea6
    0xE8,0xE9,0xEA,0xEB,0xEC,0xED,0xEE,0xEF,
Packit Service a31ea6
    0xF0,0xF1,0xF2,0xF3,0xF4,0xF5,0xF6,0xF7,
Packit Service a31ea6
    0xF8,0xF9,0xFA,0xFB,0xFC,0xFD,0xFE,0xFF
Packit Service a31ea6
};
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrcasecmp:
Packit Service a31ea6
 * @str1:  the first xmlChar *
Packit Service a31ea6
 * @str2:  the second xmlChar *
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strcasecmp for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the integer result of the comparison
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrcasecmp(const xmlChar *str1, const xmlChar *str2) {
Packit Service a31ea6
    register int tmp;
Packit Service a31ea6
Packit Service a31ea6
    if (str1 == str2) return(0);
Packit Service a31ea6
    if (str1 == NULL) return(-1);
Packit Service a31ea6
    if (str2 == NULL) return(1);
Packit Service a31ea6
    do {
Packit Service a31ea6
        tmp = casemap[*str1++] - casemap[*str2];
Packit Service a31ea6
        if (tmp != 0) return(tmp);
Packit Service a31ea6
    } while (*str2++ != 0);
Packit Service a31ea6
    return 0;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrncasecmp:
Packit Service a31ea6
 * @str1:  the first xmlChar *
Packit Service a31ea6
 * @str2:  the second xmlChar *
Packit Service a31ea6
 * @len:  the max comparison length
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strncasecmp for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the integer result of the comparison
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrncasecmp(const xmlChar *str1, const xmlChar *str2, int len) {
Packit Service a31ea6
    register int tmp;
Packit Service a31ea6
Packit Service a31ea6
    if (len <= 0) return(0);
Packit Service a31ea6
    if (str1 == str2) return(0);
Packit Service a31ea6
    if (str1 == NULL) return(-1);
Packit Service a31ea6
    if (str2 == NULL) return(1);
Packit Service a31ea6
    do {
Packit Service a31ea6
        tmp = casemap[*str1++] - casemap[*str2];
Packit Service a31ea6
        if (tmp != 0 || --len == 0) return(tmp);
Packit Service a31ea6
    } while (*str2++ != 0);
Packit Service a31ea6
    return 0;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrchr:
Packit Service a31ea6
 * @str:  the xmlChar * array
Packit Service a31ea6
 * @val:  the xmlChar to search
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strchr for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlChar * for the first occurrence or NULL.
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
const xmlChar *
Packit Service a31ea6
xmlStrchr(const xmlChar *str, xmlChar val) {
Packit Service a31ea6
    if (str == NULL) return(NULL);
Packit Service a31ea6
    while (*str != 0) { /* non input consuming */
Packit Service a31ea6
        if (*str == val) return((xmlChar *) str);
Packit Service a31ea6
        str++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(NULL);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrstr:
Packit Service a31ea6
 * @str:  the xmlChar * array (haystack)
Packit Service a31ea6
 * @val:  the xmlChar to search (needle)
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strstr for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlChar * for the first occurrence or NULL.
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
const xmlChar *
Packit Service a31ea6
xmlStrstr(const xmlChar *str, const xmlChar *val) {
Packit Service a31ea6
    int n;
Packit Service a31ea6
Packit Service a31ea6
    if (str == NULL) return(NULL);
Packit Service a31ea6
    if (val == NULL) return(NULL);
Packit Service a31ea6
    n = xmlStrlen(val);
Packit Service a31ea6
Packit Service a31ea6
    if (n == 0) return(str);
Packit Service a31ea6
    while (*str != 0) { /* non input consuming */
Packit Service a31ea6
        if (*str == *val) {
Packit Service a31ea6
            if (!xmlStrncmp(str, val, n)) return((const xmlChar *) str);
Packit Service a31ea6
        }
Packit Service a31ea6
        str++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(NULL);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrcasestr:
Packit Service a31ea6
 * @str:  the xmlChar * array (haystack)
Packit Service a31ea6
 * @val:  the xmlChar to search (needle)
Packit Service a31ea6
 *
Packit Service a31ea6
 * a case-ignoring strstr for xmlChar's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlChar * for the first occurrence or NULL.
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
const xmlChar *
Packit Service a31ea6
xmlStrcasestr(const xmlChar *str, const xmlChar *val) {
Packit Service a31ea6
    int n;
Packit Service a31ea6
Packit Service a31ea6
    if (str == NULL) return(NULL);
Packit Service a31ea6
    if (val == NULL) return(NULL);
Packit Service a31ea6
    n = xmlStrlen(val);
Packit Service a31ea6
Packit Service a31ea6
    if (n == 0) return(str);
Packit Service a31ea6
    while (*str != 0) { /* non input consuming */
Packit Service a31ea6
        if (casemap[*str] == casemap[*val])
Packit Service a31ea6
            if (!xmlStrncasecmp(str, val, n)) return(str);
Packit Service a31ea6
        str++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(NULL);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrsub:
Packit Service a31ea6
 * @str:  the xmlChar * array (haystack)
Packit Service a31ea6
 * @start:  the index of the first char (zero based)
Packit Service a31ea6
 * @len:  the length of the substring
Packit Service a31ea6
 *
Packit Service a31ea6
 * Extract a substring of a given string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the xmlChar * for the first occurrence or NULL.
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlStrsub(const xmlChar *str, int start, int len) {
Packit Service a31ea6
    int i;
Packit Service a31ea6
Packit Service a31ea6
    if (str == NULL) return(NULL);
Packit Service a31ea6
    if (start < 0) return(NULL);
Packit Service a31ea6
    if (len < 0) return(NULL);
Packit Service a31ea6
Packit Service a31ea6
    for (i = 0;i < start;i++) {
Packit Service a31ea6
        if (*str == 0) return(NULL);
Packit Service a31ea6
        str++;
Packit Service a31ea6
    }
Packit Service a31ea6
    if (*str == 0) return(NULL);
Packit Service a31ea6
    return(xmlStrndup(str, len));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrlen:
Packit Service a31ea6
 * @str:  the xmlChar * array
Packit Service a31ea6
 *
Packit Service a31ea6
 * length of a xmlChar's string
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of xmlChar contained in the ARRAY.
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrlen(const xmlChar *str) {
Packit Service a31ea6
    int len = 0;
Packit Service a31ea6
Packit Service a31ea6
    if (str == NULL) return(0);
Packit Service a31ea6
    while (*str != 0) { /* non input consuming */
Packit Service a31ea6
        str++;
Packit Service a31ea6
        len++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(len);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrncat:
Packit Service a31ea6
 * @cur:  the original xmlChar * array
Packit Service a31ea6
 * @add:  the xmlChar * array added
Packit Service a31ea6
 * @len:  the length of @add
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strncat for array of xmlChar's, it will extend @cur with the len
Packit Service a31ea6
 * first bytes of @add. Note that if @len < 0 then this is an API error
Packit Service a31ea6
 * and NULL will be returned.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar *, the original @cur is reallocated and should
Packit Service a31ea6
 * not be freed.
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlStrncat(xmlChar *cur, const xmlChar *add, int len) {
Packit Service a31ea6
    int size;
Packit Service a31ea6
    xmlChar *ret;
Packit Service a31ea6
Packit Service a31ea6
    if ((add == NULL) || (len == 0))
Packit Service a31ea6
        return(cur);
Packit Service a31ea6
    if (len < 0)
Packit Service a31ea6
	return(NULL);
Packit Service a31ea6
    if (cur == NULL)
Packit Service a31ea6
        return(xmlStrndup(add, len));
Packit Service a31ea6
Packit Service a31ea6
    size = xmlStrlen(cur);
Packit Service a31ea6
    if (size < 0)
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    ret = (xmlChar *) xmlRealloc(cur, (size + len + 1) * sizeof(xmlChar));
Packit Service a31ea6
    if (ret == NULL) {
Packit Service a31ea6
        xmlErrMemory(NULL, NULL);
Packit Service a31ea6
        return(cur);
Packit Service a31ea6
    }
Packit Service a31ea6
    memcpy(&ret[size], add, len * sizeof(xmlChar));
Packit Service a31ea6
    ret[size + len] = 0;
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrncatNew:
Packit Service a31ea6
 * @str1:  first xmlChar string
Packit Service a31ea6
 * @str2:  second xmlChar string
Packit Service a31ea6
 * @len:  the len of @str2 or < 0
Packit Service a31ea6
 *
Packit Service a31ea6
 * same as xmlStrncat, but creates a new string.  The original
Packit Service a31ea6
 * two strings are not freed. If @len is < 0 then the length
Packit Service a31ea6
 * will be calculated automatically.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar * or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlStrncatNew(const xmlChar *str1, const xmlChar *str2, int len) {
Packit Service a31ea6
    int size;
Packit Service a31ea6
    xmlChar *ret;
Packit Service a31ea6
Packit Service a31ea6
    if (len < 0) {
Packit Service a31ea6
        len = xmlStrlen(str2);
Packit Service a31ea6
        if (len < 0)
Packit Service a31ea6
            return(NULL);
Packit Service a31ea6
    }
Packit Service a31ea6
    if ((str2 == NULL) || (len == 0))
Packit Service a31ea6
        return(xmlStrdup(str1));
Packit Service a31ea6
    if (str1 == NULL)
Packit Service a31ea6
        return(xmlStrndup(str2, len));
Packit Service a31ea6
Packit Service a31ea6
    size = xmlStrlen(str1);
Packit Service a31ea6
    if (size < 0)
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    ret = (xmlChar *) xmlMalloc((size + len + 1) * sizeof(xmlChar));
Packit Service a31ea6
    if (ret == NULL) {
Packit Service a31ea6
        xmlErrMemory(NULL, NULL);
Packit Service a31ea6
        return(xmlStrndup(str1, size));
Packit Service a31ea6
    }
Packit Service a31ea6
    memcpy(ret, str1, size * sizeof(xmlChar));
Packit Service a31ea6
    memcpy(&ret[size], str2, len * sizeof(xmlChar));
Packit Service a31ea6
    ret[size + len] = 0;
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrcat:
Packit Service a31ea6
 * @cur:  the original xmlChar * array
Packit Service a31ea6
 * @add:  the xmlChar * array added
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strcat for array of xmlChar's. Since they are supposed to be
Packit Service a31ea6
 * encoded in UTF-8 or an encoding with 8bit based chars, we assume
Packit Service a31ea6
 * a termination mark of '0'.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new xmlChar * containing the concatenated string. The original
Packit Service a31ea6
 * @cur is reallocated and should not be freed.
Packit Service a31ea6
 */
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlStrcat(xmlChar *cur, const xmlChar *add) {
Packit Service a31ea6
    const xmlChar *p = add;
Packit Service a31ea6
Packit Service a31ea6
    if (add == NULL) return(cur);
Packit Service a31ea6
    if (cur == NULL)
Packit Service a31ea6
        return(xmlStrdup(add));
Packit Service a31ea6
Packit Service a31ea6
    while (*p != 0) p++; /* non input consuming */
Packit Service a31ea6
    return(xmlStrncat(cur, add, p - add));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrPrintf:
Packit Service a31ea6
 * @buf:   the result buffer.
Packit Service a31ea6
 * @len:   the result buffer length.
Packit Service a31ea6
 * @msg:   the message with printf formatting.
Packit Service a31ea6
 * @...:   extra parameters for the message.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Formats @msg and places result into @buf.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of characters written to @buf or -1 if an error occurs.
Packit Service a31ea6
 */
Packit Service a31ea6
int XMLCDECL
Packit Service a31ea6
xmlStrPrintf(xmlChar *buf, int len, const char *msg, ...) {
Packit Service a31ea6
    va_list args;
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    if((buf == NULL) || (msg == NULL)) {
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    va_start(args, msg);
Packit Service a31ea6
    ret = vsnprintf((char *) buf, len, (const char *) msg, args);
Packit Service a31ea6
    va_end(args);
Packit Service a31ea6
    buf[len - 1] = 0; /* be safe ! */
Packit Service a31ea6
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlStrVPrintf:
Packit Service a31ea6
 * @buf:   the result buffer.
Packit Service a31ea6
 * @len:   the result buffer length.
Packit Service a31ea6
 * @msg:   the message with printf formatting.
Packit Service a31ea6
 * @ap:    extra parameters for the message.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Formats @msg and places result into @buf.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of characters written to @buf or -1 if an error occurs.
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
xmlStrVPrintf(xmlChar *buf, int len, const char *msg, va_list ap) {
Packit Service a31ea6
    int ret;
Packit Service a31ea6
Packit Service a31ea6
    if((buf == NULL) || (msg == NULL)) {
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    ret = vsnprintf((char *) buf, len, (const char *) msg, ap);
Packit Service a31ea6
    buf[len - 1] = 0; /* be safe ! */
Packit Service a31ea6
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/************************************************************************
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 *              Generic UTF8 handling routines                          *
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 * From rfc2044: encoding of the Unicode values on UTF-8:               *
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 * UCS-4 range (hex.)           UTF-8 octet sequence (binary)           *
Packit Service a31ea6
 * 0000 0000-0000 007F   0xxxxxxx                                       *
Packit Service a31ea6
 * 0000 0080-0000 07FF   110xxxxx 10xxxxxx                              *
Packit Service a31ea6
 * 0000 0800-0000 FFFF   1110xxxx 10xxxxxx 10xxxxxx                     *
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 * I hope we won't use values > 0xFFFF anytime soon !                   *
Packit Service a31ea6
 *                                                                      *
Packit Service a31ea6
 ************************************************************************/
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Size:
Packit Service a31ea6
 * @utf: pointer to the UTF8 character
Packit Service a31ea6
 *
Packit Service a31ea6
 * calculates the internal size of a UTF8 character
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns the numbers of bytes in the character, -1 on format error
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
xmlUTF8Size(const xmlChar *utf) {
Packit Service a31ea6
    xmlChar mask;
Packit Service a31ea6
    int len;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL)
Packit Service a31ea6
        return -1;
Packit Service a31ea6
    if (*utf < 0x80)
Packit Service a31ea6
        return 1;
Packit Service a31ea6
    /* check valid UTF8 character */
Packit Service a31ea6
    if (!(*utf & 0x40))
Packit Service a31ea6
        return -1;
Packit Service a31ea6
    /* determine number of bytes in char */
Packit Service a31ea6
    len = 2;
Packit Service a31ea6
    for (mask=0x20; mask != 0; mask>>=1) {
Packit Service a31ea6
        if (!(*utf & mask))
Packit Service a31ea6
            return len;
Packit Service a31ea6
        len++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return -1;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Charcmp:
Packit Service a31ea6
 * @utf1: pointer to first UTF8 char
Packit Service a31ea6
 * @utf2: pointer to second UTF8 char
Packit Service a31ea6
 *
Packit Service a31ea6
 * compares the two UCS4 values
Packit Service a31ea6
 *
Packit Service a31ea6
 * returns result of the compare as with xmlStrncmp
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
xmlUTF8Charcmp(const xmlChar *utf1, const xmlChar *utf2) {
Packit Service a31ea6
Packit Service a31ea6
    if (utf1 == NULL ) {
Packit Service a31ea6
        if (utf2 == NULL)
Packit Service a31ea6
            return 0;
Packit Service a31ea6
        return -1;
Packit Service a31ea6
    }
Packit Service a31ea6
    return xmlStrncmp(utf1, utf2, xmlUTF8Size(utf1));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Strlen:
Packit Service a31ea6
 * @utf:  a sequence of UTF-8 encoded bytes
Packit Service a31ea6
 *
Packit Service a31ea6
 * compute the length of an UTF8 string, it doesn't do a full UTF8
Packit Service a31ea6
 * checking of the content of the string.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the number of characters in the string or -1 in case of error
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
xmlUTF8Strlen(const xmlChar *utf) {
Packit Service a31ea6
    int ret = 0;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL)
Packit Service a31ea6
        return(-1);
Packit Service a31ea6
Packit Service a31ea6
    while (*utf != 0) {
Packit Service a31ea6
        if (utf[0] & 0x80) {
Packit Service a31ea6
            if ((utf[1] & 0xc0) != 0x80)
Packit Service a31ea6
                return(-1);
Packit Service a31ea6
            if ((utf[0] & 0xe0) == 0xe0) {
Packit Service a31ea6
                if ((utf[2] & 0xc0) != 0x80)
Packit Service a31ea6
                    return(-1);
Packit Service a31ea6
                if ((utf[0] & 0xf0) == 0xf0) {
Packit Service a31ea6
                    if ((utf[0] & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
Packit Service a31ea6
                        return(-1);
Packit Service a31ea6
                    utf += 4;
Packit Service a31ea6
                } else {
Packit Service a31ea6
                    utf += 3;
Packit Service a31ea6
                }
Packit Service a31ea6
            } else {
Packit Service a31ea6
                utf += 2;
Packit Service a31ea6
            }
Packit Service a31ea6
        } else {
Packit Service a31ea6
            utf++;
Packit Service a31ea6
        }
Packit Service a31ea6
        ret++;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlGetUTF8Char:
Packit Service a31ea6
 * @utf:  a sequence of UTF-8 encoded bytes
Packit Service a31ea6
 * @len:  a pointer to the minimum number of bytes present in
Packit Service a31ea6
 *        the sequence.  This is used to assure the next character
Packit Service a31ea6
 *        is completely contained within the sequence.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Read the first UTF8 character from @utf
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the char value or -1 in case of error, and sets *len to
Packit Service a31ea6
 *        the actual number of bytes consumed (0 in case of error)
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
xmlGetUTF8Char(const unsigned char *utf, int *len) {
Packit Service a31ea6
    unsigned int c;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL)
Packit Service a31ea6
        goto error;
Packit Service a31ea6
    if (len == NULL)
Packit Service a31ea6
        goto error;
Packit Service a31ea6
    if (*len < 1)
Packit Service a31ea6
        goto error;
Packit Service a31ea6
Packit Service a31ea6
    c = utf[0];
Packit Service a31ea6
    if (c & 0x80) {
Packit Service a31ea6
        if (*len < 2)
Packit Service a31ea6
            goto error;
Packit Service a31ea6
        if ((utf[1] & 0xc0) != 0x80)
Packit Service a31ea6
            goto error;
Packit Service a31ea6
        if ((c & 0xe0) == 0xe0) {
Packit Service a31ea6
            if (*len < 3)
Packit Service a31ea6
                goto error;
Packit Service a31ea6
            if ((utf[2] & 0xc0) != 0x80)
Packit Service a31ea6
                goto error;
Packit Service a31ea6
            if ((c & 0xf0) == 0xf0) {
Packit Service a31ea6
                if (*len < 4)
Packit Service a31ea6
                    goto error;
Packit Service a31ea6
                if ((c & 0xf8) != 0xf0 || (utf[3] & 0xc0) != 0x80)
Packit Service a31ea6
                    goto error;
Packit Service a31ea6
                *len = 4;
Packit Service a31ea6
                /* 4-byte code */
Packit Service a31ea6
                c = (utf[0] & 0x7) << 18;
Packit Service a31ea6
                c |= (utf[1] & 0x3f) << 12;
Packit Service a31ea6
                c |= (utf[2] & 0x3f) << 6;
Packit Service a31ea6
                c |= utf[3] & 0x3f;
Packit Service a31ea6
            } else {
Packit Service a31ea6
              /* 3-byte code */
Packit Service a31ea6
                *len = 3;
Packit Service a31ea6
                c = (utf[0] & 0xf) << 12;
Packit Service a31ea6
                c |= (utf[1] & 0x3f) << 6;
Packit Service a31ea6
                c |= utf[2] & 0x3f;
Packit Service a31ea6
            }
Packit Service a31ea6
        } else {
Packit Service a31ea6
          /* 2-byte code */
Packit Service a31ea6
            *len = 2;
Packit Service a31ea6
            c = (utf[0] & 0x1f) << 6;
Packit Service a31ea6
            c |= utf[1] & 0x3f;
Packit Service a31ea6
        }
Packit Service a31ea6
    } else {
Packit Service a31ea6
        /* 1-byte code */
Packit Service a31ea6
        *len = 1;
Packit Service a31ea6
    }
Packit Service a31ea6
    return(c);
Packit Service a31ea6
Packit Service a31ea6
error:
Packit Service a31ea6
    if (len != NULL)
Packit Service a31ea6
	*len = 0;
Packit Service a31ea6
    return(-1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlCheckUTF8:
Packit Service a31ea6
 * @utf: Pointer to putative UTF-8 encoded string.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Checks @utf for being valid UTF-8. @utf is assumed to be
Packit Service a31ea6
 * null-terminated. This function is not super-strict, as it will
Packit Service a31ea6
 * allow longer UTF-8 sequences than necessary. Note that Java is
Packit Service a31ea6
 * capable of producing these sequences if provoked. Also note, this
Packit Service a31ea6
 * routine checks for the 4-byte maximum size, but does not check for
Packit Service a31ea6
 * 0x10ffff maximum value.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Return value: true if @utf is valid.
Packit Service a31ea6
 **/
Packit Service a31ea6
int
Packit Service a31ea6
xmlCheckUTF8(const unsigned char *utf)
Packit Service a31ea6
{
Packit Service a31ea6
    int ix;
Packit Service a31ea6
    unsigned char c;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL)
Packit Service a31ea6
        return(0);
Packit Service a31ea6
    /*
Packit Service a31ea6
     * utf is a string of 1, 2, 3 or 4 bytes.  The valid strings
Packit Service a31ea6
     * are as follows (in "bit format"):
Packit Service a31ea6
     *    0xxxxxxx                                      valid 1-byte
Packit Service a31ea6
     *    110xxxxx 10xxxxxx                             valid 2-byte
Packit Service a31ea6
     *    1110xxxx 10xxxxxx 10xxxxxx                    valid 3-byte
Packit Service a31ea6
     *    11110xxx 10xxxxxx 10xxxxxx 10xxxxxx           valid 4-byte
Packit Service a31ea6
     */
Packit Service a31ea6
    for (ix = 0; (c = utf[ix]);) {      /* string is 0-terminated */
Packit Service a31ea6
        if ((c & 0x80) == 0x00) {	/* 1-byte code, starts with 10 */
Packit Service a31ea6
            ix++;
Packit Service a31ea6
	} else if ((c & 0xe0) == 0xc0) {/* 2-byte code, starts with 110 */
Packit Service a31ea6
	    if ((utf[ix+1] & 0xc0 ) != 0x80)
Packit Service a31ea6
	        return 0;
Packit Service a31ea6
	    ix += 2;
Packit Service a31ea6
	} else if ((c & 0xf0) == 0xe0) {/* 3-byte code, starts with 1110 */
Packit Service a31ea6
	    if (((utf[ix+1] & 0xc0) != 0x80) ||
Packit Service a31ea6
	        ((utf[ix+2] & 0xc0) != 0x80))
Packit Service a31ea6
		    return 0;
Packit Service a31ea6
	    ix += 3;
Packit Service a31ea6
	} else if ((c & 0xf8) == 0xf0) {/* 4-byte code, starts with 11110 */
Packit Service a31ea6
	    if (((utf[ix+1] & 0xc0) != 0x80) ||
Packit Service a31ea6
	        ((utf[ix+2] & 0xc0) != 0x80) ||
Packit Service a31ea6
		((utf[ix+3] & 0xc0) != 0x80))
Packit Service a31ea6
		    return 0;
Packit Service a31ea6
	    ix += 4;
Packit Service a31ea6
	} else				/* unknown encoding */
Packit Service a31ea6
	    return 0;
Packit Service a31ea6
      }
Packit Service a31ea6
      return(1);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Strsize:
Packit Service a31ea6
 * @utf:  a sequence of UTF-8 encoded bytes
Packit Service a31ea6
 * @len:  the number of characters in the array
Packit Service a31ea6
 *
Packit Service a31ea6
 * storage size of an UTF8 string
Packit Service a31ea6
 * the behaviour is not guaranteed if the input string is not UTF-8
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the storage size of
Packit Service a31ea6
 * the first 'len' characters of ARRAY
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
int
Packit Service a31ea6
xmlUTF8Strsize(const xmlChar *utf, int len) {
Packit Service a31ea6
    const xmlChar   *ptr=utf;
Packit Service a31ea6
    xmlChar         ch;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL)
Packit Service a31ea6
        return(0);
Packit Service a31ea6
Packit Service a31ea6
    if (len <= 0)
Packit Service a31ea6
        return(0);
Packit Service a31ea6
Packit Service a31ea6
    while ( len-- > 0) {
Packit Service a31ea6
        if ( !*ptr )
Packit Service a31ea6
            break;
Packit Service a31ea6
        if ( (ch = *ptr++) & 0x80)
Packit Service a31ea6
            while ((ch<<=1) & 0x80 ) {
Packit Service a31ea6
		if (*ptr == 0) break;
Packit Service a31ea6
                ptr++;
Packit Service a31ea6
	    }
Packit Service a31ea6
    }
Packit Service a31ea6
    return (ptr - utf);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Strndup:
Packit Service a31ea6
 * @utf:  the input UTF8 *
Packit Service a31ea6
 * @len:  the len of @utf (in chars)
Packit Service a31ea6
 *
Packit Service a31ea6
 * a strndup for array of UTF8's
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a new UTF8 * or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlUTF8Strndup(const xmlChar *utf, int len) {
Packit Service a31ea6
    xmlChar *ret;
Packit Service a31ea6
    int i;
Packit Service a31ea6
Packit Service a31ea6
    if ((utf == NULL) || (len < 0)) return(NULL);
Packit Service a31ea6
    i = xmlUTF8Strsize(utf, len);
Packit Service a31ea6
    ret = (xmlChar *) xmlMallocAtomic((i + 1) * sizeof(xmlChar));
Packit Service a31ea6
    if (ret == NULL) {
Packit Service a31ea6
        xmlGenericError(xmlGenericErrorContext,
Packit Service a31ea6
                "malloc of %ld byte failed\n",
Packit Service a31ea6
                (len + 1) * (long)sizeof(xmlChar));
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    }
Packit Service a31ea6
    memcpy(ret, utf, i * sizeof(xmlChar));
Packit Service a31ea6
    ret[i] = 0;
Packit Service a31ea6
    return(ret);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Strpos:
Packit Service a31ea6
 * @utf:  the input UTF8 *
Packit Service a31ea6
 * @pos:  the position of the desired UTF8 char (in chars)
Packit Service a31ea6
 *
Packit Service a31ea6
 * a function to provide the equivalent of fetching a
Packit Service a31ea6
 * character from a string array
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a pointer to the UTF8 character or NULL
Packit Service a31ea6
 */
Packit Service a31ea6
const xmlChar *
Packit Service a31ea6
xmlUTF8Strpos(const xmlChar *utf, int pos) {
Packit Service a31ea6
    xmlChar ch;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL) return(NULL);
Packit Service a31ea6
    if (pos < 0)
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    while (pos--) {
Packit Service a31ea6
        if ((ch=*utf++) == 0) return(NULL);
Packit Service a31ea6
        if ( ch & 0x80 ) {
Packit Service a31ea6
            /* if not simple ascii, verify proper format */
Packit Service a31ea6
            if ( (ch & 0xc0) != 0xc0 )
Packit Service a31ea6
                return(NULL);
Packit Service a31ea6
            /* then skip over remaining bytes for this char */
Packit Service a31ea6
            while ( (ch <<= 1) & 0x80 )
Packit Service a31ea6
                if ( (*utf++ & 0xc0) != 0x80 )
Packit Service a31ea6
                    return(NULL);
Packit Service a31ea6
        }
Packit Service a31ea6
    }
Packit Service a31ea6
    return((xmlChar *)utf);
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Strloc:
Packit Service a31ea6
 * @utf:  the input UTF8 *
Packit Service a31ea6
 * @utfchar:  the UTF8 character to be found
Packit Service a31ea6
 *
Packit Service a31ea6
 * a function to provide the relative location of a UTF8 char
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns the relative character position of the desired char
Packit Service a31ea6
 * or -1 if not found
Packit Service a31ea6
 */
Packit Service a31ea6
int
Packit Service a31ea6
xmlUTF8Strloc(const xmlChar *utf, const xmlChar *utfchar) {
Packit Service a31ea6
    int i, size;
Packit Service a31ea6
    xmlChar ch;
Packit Service a31ea6
Packit Service a31ea6
    if (utf==NULL || utfchar==NULL) return -1;
Packit Service a31ea6
    size = xmlUTF8Strsize(utfchar, 1);
Packit Service a31ea6
        for(i=0; (ch=*utf) != 0; i++) {
Packit Service a31ea6
            if (xmlStrncmp(utf, utfchar, size)==0)
Packit Service a31ea6
                return(i);
Packit Service a31ea6
            utf++;
Packit Service a31ea6
            if ( ch & 0x80 ) {
Packit Service a31ea6
                /* if not simple ascii, verify proper format */
Packit Service a31ea6
                if ( (ch & 0xc0) != 0xc0 )
Packit Service a31ea6
                    return(-1);
Packit Service a31ea6
                /* then skip over remaining bytes for this char */
Packit Service a31ea6
                while ( (ch <<= 1) & 0x80 )
Packit Service a31ea6
                    if ( (*utf++ & 0xc0) != 0x80 )
Packit Service a31ea6
                        return(-1);
Packit Service a31ea6
            }
Packit Service a31ea6
        }
Packit Service a31ea6
Packit Service a31ea6
    return(-1);
Packit Service a31ea6
}
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlUTF8Strsub:
Packit Service a31ea6
 * @utf:  a sequence of UTF-8 encoded bytes
Packit Service a31ea6
 * @start: relative pos of first char
Packit Service a31ea6
 * @len:   total number to copy
Packit Service a31ea6
 *
Packit Service a31ea6
 * Create a substring from a given UTF-8 string
Packit Service a31ea6
 * Note:  positions are given in units of UTF-8 chars
Packit Service a31ea6
 *
Packit Service a31ea6
 * Returns a pointer to a newly created string
Packit Service a31ea6
 * or NULL if any problem
Packit Service a31ea6
 */
Packit Service a31ea6
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlUTF8Strsub(const xmlChar *utf, int start, int len) {
Packit Service a31ea6
    int            i;
Packit Service a31ea6
    xmlChar ch;
Packit Service a31ea6
Packit Service a31ea6
    if (utf == NULL) return(NULL);
Packit Service a31ea6
    if (start < 0) return(NULL);
Packit Service a31ea6
    if (len < 0) return(NULL);
Packit Service a31ea6
Packit Service a31ea6
    /*
Packit Service a31ea6
     * Skip over any leading chars
Packit Service a31ea6
     */
Packit Service a31ea6
    for (i = 0;i < start;i++) {
Packit Service a31ea6
        if ((ch=*utf++) == 0) return(NULL);
Packit Service a31ea6
        if ( ch & 0x80 ) {
Packit Service a31ea6
            /* if not simple ascii, verify proper format */
Packit Service a31ea6
            if ( (ch & 0xc0) != 0xc0 )
Packit Service a31ea6
                return(NULL);
Packit Service a31ea6
            /* then skip over remaining bytes for this char */
Packit Service a31ea6
            while ( (ch <<= 1) & 0x80 )
Packit Service a31ea6
                if ( (*utf++ & 0xc0) != 0x80 )
Packit Service a31ea6
                    return(NULL);
Packit Service a31ea6
        }
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    return(xmlUTF8Strndup(utf, len));
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
/**
Packit Service a31ea6
 * xmlEscapeFormatString:
Packit Service a31ea6
 * @msg:  a pointer to the string in which to escape '%' characters.
Packit Service a31ea6
 * Must be a heap-allocated buffer created by libxml2 that may be
Packit Service a31ea6
 * returned, or that may be freed and replaced.
Packit Service a31ea6
 *
Packit Service a31ea6
 * Replaces the string pointed to by 'msg' with an escaped string.
Packit Service a31ea6
 * Returns the same string with all '%' characters escaped.
Packit Service a31ea6
 */
Packit Service a31ea6
xmlChar *
Packit Service a31ea6
xmlEscapeFormatString(xmlChar **msg)
Packit Service a31ea6
{
Packit Service a31ea6
    xmlChar *msgPtr = NULL;
Packit Service a31ea6
    xmlChar *result = NULL;
Packit Service a31ea6
    xmlChar *resultPtr = NULL;
Packit Service a31ea6
    size_t count = 0;
Packit Service a31ea6
    size_t msgLen = 0;
Packit Service a31ea6
    size_t resultLen = 0;
Packit Service a31ea6
Packit Service a31ea6
    if (!msg || !*msg)
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
Packit Service a31ea6
    for (msgPtr = *msg; *msgPtr != '\0'; ++msgPtr) {
Packit Service a31ea6
        ++msgLen;
Packit Service a31ea6
        if (*msgPtr == '%')
Packit Service a31ea6
            ++count;
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    if (count == 0)
Packit Service a31ea6
        return(*msg);
Packit Service a31ea6
Packit Service a31ea6
    resultLen = msgLen + count + 1;
Packit Service a31ea6
    result = (xmlChar *) xmlMallocAtomic(resultLen * sizeof(xmlChar));
Packit Service a31ea6
    if (result == NULL) {
Packit Service a31ea6
        /* Clear *msg to prevent format string vulnerabilities in
Packit Service a31ea6
           out-of-memory situations. */
Packit Service a31ea6
        xmlFree(*msg);
Packit Service a31ea6
        *msg = NULL;
Packit Service a31ea6
        xmlErrMemory(NULL, NULL);
Packit Service a31ea6
        return(NULL);
Packit Service a31ea6
    }
Packit Service a31ea6
Packit Service a31ea6
    for (msgPtr = *msg, resultPtr = result; *msgPtr != '\0'; ++msgPtr, ++resultPtr) {
Packit Service a31ea6
        *resultPtr = *msgPtr;
Packit Service a31ea6
        if (*msgPtr == '%')
Packit Service a31ea6
            *(++resultPtr) = '%';
Packit Service a31ea6
    }
Packit Service a31ea6
    result[resultLen - 1] = '\0';
Packit Service a31ea6
Packit Service a31ea6
    xmlFree(*msg);
Packit Service a31ea6
    *msg = result;
Packit Service a31ea6
Packit Service a31ea6
    return *msg;
Packit Service a31ea6
}
Packit Service a31ea6
Packit Service a31ea6
#define bottom_xmlstring
Packit Service a31ea6
#include "elfgcchack.h"