📄 xmlschemastypes.c
字号:
* @value: a value
*
* Replaces 0xd, 0x9 and 0xa with a space.
*
* Returns the new string or NULL if no change was required.
*/
xmlChar *
xmlSchemaWhiteSpaceReplace(const xmlChar *value) {
const xmlChar *cur = value;
xmlChar *ret = NULL, *mcur;
if (value == NULL)
return(NULL);
while ((*cur != 0) &&
(((*cur) != 0xd) && ((*cur) != 0x9) && ((*cur) != 0xa))) {
cur++;
}
if (*cur == 0)
return (NULL);
ret = xmlStrdup(value);
/* TODO FIXME: I guess gcc will bark at this. */
mcur = (xmlChar *) (ret + (cur - value));
do {
if ( ((*mcur) == 0xd) || ((*mcur) == 0x9) || ((*mcur) == 0xa) )
*mcur = ' ';
mcur++;
} while (*mcur != 0);
return(ret);
}
/**
* xmlSchemaCollapseString:
* @value: a value
*
* Removes and normalize white spaces in the string
*
* Returns the new string or NULL if no change was required.
*/
xmlChar *
xmlSchemaCollapseString(const xmlChar *value) {
const xmlChar *start = value, *end, *f;
xmlChar *g;
int col = 0;
if (value == NULL) return(NULL);
while ((*start != 0) && (IS_BLANK_CH(*start))) start++;
end = start;
while (*end != 0) {
if ((*end == ' ') && (IS_BLANK_CH(end[1]))) {
col = end - start;
break;
} else if ((*end == 0xa) || (*end == 0x9) || (*end == 0xd)) {
col = end - start;
break;
}
end++;
}
if (col == 0) {
f = end;
end--;
while ((end > start) && (IS_BLANK_CH(*end))) end--;
end++;
if ((start == value) && (f == end)) return(NULL);
return(xmlStrndup(start, end - start));
}
start = xmlStrdup(start);
if (start == NULL) return(NULL);
g = (xmlChar *) (start + col);
end = g;
while (*end != 0) {
if (IS_BLANK_CH(*end)) {
end++;
while (IS_BLANK_CH(*end)) end++;
if (*end != 0)
*g++ = ' ';
} else
*g++ = *end++;
}
*g = 0;
return((xmlChar *) start);
}
/**
* xmlSchemaValAtomicListNode:
* @type: the predefined atomic type for a token in the list
* @value: the list value to check
* @ret: the return computed value
* @node: the node containing the value
*
* Check that a value conforms to the lexical space of the predefined
* list type. if true a value is computed and returned in @ret.
*
* Returns the number of items if this validates, a negative error code
* number otherwise
*/
static int
xmlSchemaValAtomicListNode(xmlSchemaTypePtr type, const xmlChar *value,
xmlSchemaValPtr *ret, xmlNodePtr node) {
xmlChar *val, *cur, *endval;
int nb_values = 0;
int tmp = 0;
if (value == NULL) {
return(-1);
}
val = xmlStrdup(value);
if (val == NULL) {
return(-1);
}
if (ret != NULL) {
*ret = NULL;
}
cur = val;
/*
* Split the list
*/
while (IS_BLANK_CH(*cur)) *cur++ = 0;
while (*cur != 0) {
if (IS_BLANK_CH(*cur)) {
*cur = 0;
cur++;
while (IS_BLANK_CH(*cur)) *cur++ = 0;
} else {
nb_values++;
cur++;
while ((*cur != 0) && (!IS_BLANK_CH(*cur))) cur++;
}
}
if (nb_values == 0) {
xmlFree(val);
return(nb_values);
}
endval = cur;
cur = val;
while ((*cur == 0) && (cur != endval)) cur++;
while (cur != endval) {
tmp = xmlSchemaValPredefTypeNode(type, cur, NULL, node);
if (tmp != 0)
break;
while (*cur != 0) cur++;
while ((*cur == 0) && (cur != endval)) cur++;
}
/* TODO what return value ? c.f. bug #158628
if (ret != NULL) {
TODO
} */
xmlFree(val);
if (tmp == 0)
return(nb_values);
return(-1);
}
/**
* xmlSchemaParseUInt:
* @str: pointer to the string R/W
* @llo: pointer to the low result
* @lmi: pointer to the mid result
* @lhi: pointer to the high result
*
* Parse an unsigned long into 3 fields.
*
* Returns the number of significant digits in the number or
* -1 if overflow of the capacity
*/
static int
xmlSchemaParseUInt(const xmlChar **str, unsigned long *llo,
unsigned long *lmi, unsigned long *lhi) {
unsigned long lo = 0, mi = 0, hi = 0;
const xmlChar *tmp, *cur = *str;
int ret = 0, i = 0;
while (*cur == '0') { /* ignore leading zeroes */
cur++;
}
tmp = cur;
while ((*tmp != 0) && (*tmp >= '0') && (*tmp <= '9')) {
i++;tmp++;ret++;
}
if (i > 24) {
*str = tmp;
return(-1);
}
while (i > 16) {
hi = hi * 10 + (*cur++ - '0');
i--;
}
while (i > 8) {
mi = mi * 10 + (*cur++ - '0');
i--;
}
while (i > 0) {
lo = lo * 10 + (*cur++ - '0');
i--;
}
*str = cur;
*llo = lo;
*lmi = mi;
*lhi = hi;
return(ret);
}
/**
* xmlSchemaValAtomicType:
* @type: the predefined type
* @value: the value to check
* @val: the return computed value
* @node: the node containing the value
* flags: flags to control the vlidation
*
* Check that a value conforms to the lexical space of the atomic type.
* if true a value is computed and returned in @val.
* This checks the value space for list types as well (IDREFS, NMTOKENS).
*
* Returns 0 if this validates, a positive error code number otherwise
* and -1 in case of internal or API error.
*/
static int
xmlSchemaValAtomicType(xmlSchemaTypePtr type, const xmlChar * value,
xmlSchemaValPtr * val, xmlNodePtr node, int flags,
xmlSchemaWhitespaceValueType ws,
int normOnTheFly, int applyNorm, int createStringValue)
{
xmlSchemaValPtr v;
xmlChar *norm = NULL;
int ret = 0;
if (xmlSchemaTypesInitialized == 0)
xmlSchemaInitTypes();
if (type == NULL)
return (-1);
/*
* validating a non existant text node is similar to validating
* an empty one.
*/
if (value == NULL)
value = BAD_CAST "";
if (val != NULL)
*val = NULL;
if ((flags == 0) && (value != NULL)) {
if ((type->builtInType != XML_SCHEMAS_STRING) &&
(type->builtInType != XML_SCHEMAS_ANYTYPE) &&
(type->builtInType != XML_SCHEMAS_ANYSIMPLETYPE)) {
if (type->builtInType == XML_SCHEMAS_NORMSTRING)
norm = xmlSchemaWhiteSpaceReplace(value);
else
norm = xmlSchemaCollapseString(value);
if (norm != NULL)
value = norm;
}
}
switch (type->builtInType) {
case XML_SCHEMAS_UNKNOWN:
goto error;
case XML_SCHEMAS_ANYTYPE:
case XML_SCHEMAS_ANYSIMPLETYPE:
if ((createStringValue) && (val != NULL)) {
v = xmlSchemaNewValue(XML_SCHEMAS_ANYSIMPLETYPE);
if (v != NULL) {
v->value.str = xmlStrdup(value);
*val = v;
} else {
goto error;
}
}
goto return0;
case XML_SCHEMAS_STRING:
if (! normOnTheFly) {
const xmlChar *cur = value;
if (ws == XML_SCHEMA_WHITESPACE_REPLACE) {
while (*cur != 0) {
if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
goto return1;
} else {
cur++;
}
}
} else if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE) {
while (*cur != 0) {
if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
goto return1;
} else if IS_WSP_SPACE_CH(*cur) {
cur++;
if IS_WSP_SPACE_CH(*cur)
goto return1;
} else {
cur++;
}
}
}
}
if (createStringValue && (val != NULL)) {
if (applyNorm) {
if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
norm = xmlSchemaCollapseString(value);
else if (ws == XML_SCHEMA_WHITESPACE_REPLACE)
norm = xmlSchemaWhiteSpaceReplace(value);
if (norm != NULL)
value = norm;
}
v = xmlSchemaNewValue(XML_SCHEMAS_STRING);
if (v != NULL) {
v->value.str = xmlStrdup(value);
*val = v;
} else {
goto error;
}
}
goto return0;
case XML_SCHEMAS_NORMSTRING:{
if (normOnTheFly) {
if (applyNorm) {
if (ws == XML_SCHEMA_WHITESPACE_COLLAPSE)
norm = xmlSchemaCollapseString(value);
else
norm = xmlSchemaWhiteSpaceReplace(value);
if (norm != NULL)
value = norm;
}
} else {
const xmlChar *cur = value;
while (*cur != 0) {
if ((*cur == 0xd) || (*cur == 0xa) || (*cur == 0x9)) {
goto return1;
} else {
cur++;
}
}
}
if (val != NULL) {
v = xmlSchemaNewValue(XML_SCHEMAS_NORMSTRING);
if (v != NULL) {
v->value.str = xmlStrdup(value);
*val = v;
} else {
goto error;
}
}
goto return0;
}
case XML_SCHEMAS_DECIMAL:{
const xmlChar *cur = value;
unsigned int len, neg = 0;
xmlChar cval[25];
xmlChar *cptr = cval;
int dec = -1;
if (cur == NULL)
goto return1;
if (normOnTheFly)
while IS_WSP_BLANK_CH(*cur) cur++;
/* First we handle an optional sign */
if (*cur == '+')
cur++;
else if (*cur == '-') {
neg = 1;
cur++;
}
/*
* Next we "pre-parse" the number, in preparation for calling
* the common routine xmlSchemaParseUInt. We get rid of any
* leading zeroes (because we have reserved only 25 chars),
* and note the position of any decimal point.
*/
len = 0;
/*
* Skip leading zeroes.
*/
while (*cur == '0')
cur++;
if (*cur != 0) {
while (len < 24) {
if ((*cur >= '0') && (*cur <= '9')) {
*cptr++ = *cur++;
len++;
} else if (*cur == '.') {
if (dec != -1)
goto return1; /* multiple decimal points */
cur++;
if ((*cur == 0) && (cur -1 == value))
goto return1;
dec = len;
while ((len < 24) && (*cur >= '0') &&
(*cur <= '9')) {
*cptr++ = *cur++;
len++;
}
break;
} else
break;
}
}
if (normOnTheFly)
while IS_WSP_BLANK_CH(*cur) cur++;
if (*cur != 0)
goto return1; /* error if any extraneous chars */
if (val != NULL) {
v = xmlSchemaNewValue(XML_SCHEMAS_DECIMAL);
if (v != NULL) {
/*
* If a mixed decimal, get rid of trailing zeroes
*/
if (dec != -1) {
while ((len > dec) && (cptr > cval) &&
(*(cptr-1) == '0')) {
cptr--;
len--;
}
}
*cptr = 0; /* Terminate our (preparsed) string */
cptr = cval;
/*
* Now evaluate the significant digits of the number
*/
if (*cptr != 0)
xmlSchemaParseUInt((const xmlChar **)&cptr,
&v->value.decimal.lo,
&v->value.decimal.mi,
&v->value.decimal.hi);
/*
* Set the total digits to 1 if a zero value.
*/
if (len == 0)
len++;
v->value.decimal.sign = neg;
if (dec == -1) {
v->value.decimal.frac = 0;
v->value.decimal.total = len;
} else {
v->value.decimal.frac = len - dec;
v->value.decimal.total = len;
}
*val =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -