[xml] Patch for base64Binary datatype.
- From: Anthony Carrico <acarrico memebeam org>
- To: libxml <xml gnome org>
- Subject: [xml] Patch for base64Binary datatype.
- Date: Wed, 27 Aug 2003 00:23:42 -0400
This is my first time playing with the libxml2 codebase, so I hope I
didn't violate any rules or overlook something obvious. Here is a
patch to support base64Binary datatypes:
$ cvs diff -u xmlschemastypes.c
Index: xmlschemastypes.c
===================================================================
RCS file: /cvs/gnome/gnome-xml/xmlschemastypes.c,v
retrieving revision 1.43
diff -u -r1.43 xmlschemastypes.c
--- xmlschemastypes.c 8 Aug 2003 14:00:27 -0000 1.43
+++ xmlschemastypes.c 27 Aug 2003 04:13:35 -0000
@@ -83,7 +83,8 @@
XML_SCHEMAS_USHORT,
XML_SCHEMAS_BYTE,
XML_SCHEMAS_UBYTE,
- XML_SCHEMAS_HEXBINARY
+ XML_SCHEMAS_HEXBINARY,
+ XML_SCHEMAS_BASE64BINARY
} xmlSchemaValType;
static unsigned long powten[10] = {
@@ -141,6 +142,13 @@
unsigned int total;
};
+typedef struct _xmlSchemaValBase64 xmlSchemaValBase64;
+typedef xmlSchemaValBase64 *xmlSchemaValBase64Ptr;
+struct _xmlSchemaValBase64 {
+ xmlChar *str;
+ unsigned int total;
+};
+
struct _xmlSchemaVal {
xmlSchemaValType type;
union {
@@ -149,6 +157,7 @@
xmlSchemaValDuration dur;
xmlSchemaValQName qname;
xmlSchemaValHex hex;
+ xmlSchemaValBase64 base64;
float f;
double d;
int b;
@@ -179,6 +188,7 @@
static xmlSchemaTypePtr xmlSchemaTypeBooleanDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeDoubleDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeHexBinaryDef = NULL;
+static xmlSchemaTypePtr xmlSchemaTypeBase64BinaryDef = NULL;
static xmlSchemaTypePtr xmlSchemaTypeAnyURIDef = NULL;
/*
@@ -290,6 +300,8 @@
XML_SCHEMAS_ANYURI);
xmlSchemaTypeHexBinaryDef = xmlSchemaInitBasicType("hexBinary",
XML_SCHEMAS_HEXBINARY);
+ xmlSchemaTypeBase64BinaryDef
+ = xmlSchemaInitBasicType("base64Binary", XML_SCHEMAS_BASE64BINARY);
/*
* derived datatypes
@@ -425,6 +437,10 @@
if (value->value.hex.str != NULL)
xmlFree(value->value.hex.str);
break;
+ case XML_SCHEMAS_BASE64BINARY:
+ if (value->value.base64.str != NULL)
+ xmlFree(value->value.base64.str);
+ break;
default:
break;
}
@@ -795,6 +811,25 @@
return 0;
}
+/**
+ * _xmlSchemaBase64Decode:
+ * @ch: a character
+ *
+ * Converts a base64 encoded character to its base 64 value.
+ *
+ * Returns 0-63 (value), 64 (pad), or -1 (not recognized)
+ */
+static int
+_xmlSchemaBase64Decode (const xmlChar ch) {
+ if (('A' <= ch) && (ch <= 'Z')) return ch - 'A';
+ if (('a' <= ch) && (ch <= 'z')) return ch - 'a' + 26;
+ if (('0' <= ch) && (ch <= '9')) return ch - '0' + 52;
+ if ('+' == ch) return 62;
+ if ('/' == ch) return 63;
+ if ('=' == ch) return 64;
+ return -1;
+}
+
/****************************************************************
* *
* XML Schema Dates/Times Datatypes Handling *
@@ -1976,6 +2011,127 @@
}
goto return0;
}
+ case XML_SCHEMAS_BASE64BINARY: {
+ /* ISSUE:
+
+ Ignore all stray characters? (yes, currently)
+ Worry about long lines? (no, currently)
+
+ rfc2045.txt:
+
+ "The encoded output stream must be represented in lines of
+ no more than 76 characters each. All line breaks or other
+ characters not found in Table 1 must be ignored by decoding
+ software. In base64 data, characters other than those in
+ Table 1, line breaks, and other white space probably
+ indicate a transmission error, about which a warning
+ message or even a message rejection might be appropriate
+ under some circumstances." */
+ const xmlChar *cur=value;
+ xmlChar *base;
+ int total, i=0, pad=0;
+
+ if (cur == NULL)
+ goto return1;
+
+ for (; *cur; ++cur) {
+ int val=_xmlSchemaBase64Decode (*cur);
+ if (val<0)
+ ;
+ else if (val<64)
+ i++;
+ else
+ break;
+ }
+ for (; *cur; ++cur) {
+ int val=_xmlSchemaBase64Decode (*cur);
+ if (val<0)
+ ;
+ else if (val<64)
+ goto return1;
+ if (val==64)
+ pad++;
+ }
+
+ /* rfc2045.txt: "Special processing is performed if fewer than
+ 24 bits are available at the end of the data being encoded.
+ A full encoding quantum is always completed at the end of a
+ body. When fewer than 24 input bits are available in an
+ input group, zero bits are added (on the right) to form an
+ integral number of 6-bit groups. Padding at the end of the
+ data is performed using the "=" character. Since all
+ base64 input is an integral number of octets, only the
+ following cases can arise: (1) the final quantum of
+ encoding input is an integral multiple of 24 bits; here,
+ the final unit of encoded output will be an integral
+ multiple of 4 characters with no "=" padding, (2) the final
+ quantum of encoding input is exactly 8 bits; here, the
+ final unit of encoded output will be two characters
+ followed by two "=" padding characters, or (3) the final
+ quantum of encoding input is exactly 16 bits; here, the
+ final unit of encoded output will be three characters
+ followed by one "=" padding character." */
+
+ total = 3*(i/4);
+ if (pad==0) {
+ if (i%4!=0)
+ goto return1;
+ }
+ else if (pad==1) {
+ int val;
+ if (i%4!=3)
+ goto return1;
+ for (val=_xmlSchemaBase64Decode(*cur);
+ (val<0) || (val>63);
+ val=_xmlSchemaBase64Decode(*cur))
+ --cur;
+ /* 16bits in 24bits means 2 pad bits: nnnnnn nnmmmm mmmm00 */
+ /* 00111100 -> 0x3c */
+ if (val & ~0x3c)
+ goto return1;
+ total+=2;
+ }
+ else if (pad==2) {
+ int val;
+ if (i%4!=2)
+ goto return1;
+ for (val=_xmlSchemaBase64Decode(*cur);
+ (val<0) || (val>63);
+ val=_xmlSchemaBase64Decode(*cur))
+ --cur;
+ /* 8bits in 12bits means 4 pad bits: nnnnnn nn0000 */
+ /* 00110000 -> 0x30 */
+ if (val & ~0x30)
+ goto return1;
+ total+=1;
+ }
+ else
+ goto return1;
+
+ if (val != NULL) {
+ v = xmlSchemaNewValue(XML_SCHEMAS_BASE64BINARY);
+ if (v == NULL)
+ goto error;
+ base = (xmlChar *) xmlMallocAtomic((i + pad +1) * sizeof(xmlChar));
+ if (base == NULL) {
+ xmlGenericError(xmlGenericErrorContext,
+ "malloc of %ld byte failed\n",
+ (i + pad + 1) * (long)sizeof(xmlChar));
+ xmlFree(v);
+ goto return1;
+ }
+ v->value.base64.str = base;
+ for (cur=value; *cur; ++cur)
+ if (_xmlSchemaBase64Decode(*cur) >= 0) {
+ *base=*cur;
+ ++base;
+ }
+ *base=0;
+ v->value.base64.total = total;
+ *val = v;
+ }
+ goto return0;
+ }
case XML_SCHEMAS_INTEGER:
case XML_SCHEMAS_PINTEGER:
case XML_SCHEMAS_NPINTEGER:
@@ -3138,6 +3294,21 @@
return(-1);
}
return (-2);
+ case XML_SCHEMAS_BASE64BINARY:
+ if (y->type == XML_SCHEMAS_BASE64BINARY) {
+ if (x->value.base64.total == y->value.base64.total) {
+ int ret = xmlStrcmp(x->value.base64.str, y->value.base64.str);
+ if (ret > 0)
+ return(1);
+ else if (ret == 0)
+ return(0);
+ }
+ else if (x->value.base64.total > y->value.base64.total)
+ return(1);
+ else
+ return(-1);
+ }
+ return (-2);
case XML_SCHEMAS_STRING:
case XML_SCHEMAS_IDREFS:
case XML_SCHEMAS_ENTITIES:
@@ -3284,7 +3455,9 @@
}
if ((val != NULL) && (val->type == XML_SCHEMAS_HEXBINARY))
len = val->value.hex.total;
- else {
+ else if ((val != NULL) && (val->type == XML_SCHEMAS_BASE64BINARY))
+ len = val->value.base64.total;
+ else {
switch (base->flags) {
case XML_SCHEMAS_IDREF:
case XML_SCHEMAS_NORMSTRING:
--
Anthony Carrico
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]