Preliminary XML support

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@7470 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2000-09-11 11:59:33 +00:00
parent 1dfa3c2749
commit 34edef037c
13 changed files with 1803 additions and 17 deletions

View file

@ -95,8 +95,6 @@ preface.m \
mframe.m \
objc-gnu2next.m
GNU_EXTRAS_MFILES = \
GNU_CFILES = \
md5.c \
numbers.c \
@ -138,8 +136,6 @@ o_map_cbs.h \
objc-gnu2next.h \
preface.h
GNU_EXTRAS_HFILES = \
# GNUStep source files
BASE_MFILES = \
@ -226,6 +222,10 @@ objc-load.m \
NSURL.m \
NSURLHandle.m
ifeq ($(HAVE_LIBXML),1)
BASE_MFILES += GSXML.m
endif
NSVALUE_MFILES = \
NSValue0.m NSValue1.m NSValue2.m NSValue3.m \
NSValue4.m
@ -319,6 +319,10 @@ Foundation/objc-load.h \
Foundation/NSURL.h \
Foundation/NSURLHandle.h
ifeq ($(HAVE_LIBXML),1)
BASE_HEADERS += Foundation/GSXML.h
endif
UNICODE_HEADERS = \
unicode/caseconv.h \
unicode/cop.h \

1280
Source/GSXML.m Normal file

File diff suppressed because it is too large Load diff

View file

@ -39,7 +39,7 @@
#
# Additional flags to pass to the preprocessor
ADDITIONAL_CPPFLAGS = $(DEFS) -Wall
ADDITIONAL_CPPFLAGS = $(DEFS) -DHAVE_LIBXML=$(HAVE_LIBXML) -Wall
# Additional flags to pass to the Objective-C compiler
ADDITIONAL_OBJCFLAGS =

View file

@ -718,7 +718,7 @@ static IMP msInitImp; /* designated initialiser for mutable */
if (plInit == 0)
setupPl([NSGCString class]);
result = parsePlItem(&data);
result = parsePl(&data);
if (result == nil && data.err != nil)
{

View file

@ -402,7 +402,7 @@
if (plInit == 0)
setupPl([NSGString class]);
result = parsePlItem(&data);
result = parsePl(&data);
if (result == nil && data.err != nil)
{

View file

@ -2665,7 +2665,7 @@ handle_printf_atsign (FILE *stream,
if (plInit == 0)
setupPl([NSGString class]);
result = parsePlItem(&data);
result = parsePl(&data);
if (result == nil && data.err != nil)
{

View file

@ -21,6 +21,107 @@
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA.
*/
#if HAVE_LIBXML
#include <Foundation/GSXML.h>
static char base64[]
= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static void
decodeBase64Unit(const char* ptr, unsigned char *out)
{
out[0] = (ptr[0] << 2) | ((ptr[1] & 0x30) >> 4);
out[1] = ((ptr[1] & 0x0F) << 4) | ((ptr[2] & 0x3C) >> 2);
out[2] = ((ptr[2] & 0x03) << 6) | (ptr[3] & 0x3F);
out[3] = 0;
}
static NSData*
decodeBase64(const char *source)
{
int length = strlen(source);
char *sourceBuffer = objc_malloc(length+1);
NSMutableData *data = [NSMutableData dataWithCapacity:0];
int i, j;
unsigned char tmp[4];
strcpy(sourceBuffer, source);
j = 0;
for (i = 0; i < length; i++)
{
if (!isspace(source[i]))
{
sourceBuffer[j++] = source[i];
}
}
sourceBuffer[j] = '\0';
length = strlen(sourceBuffer);
while (length > 0 && sourceBuffer[length-1] == '=')
{
sourceBuffer[--length] = '\0';
}
for (i = 0; i < length; i += 4)
{
decodeBase64Unit(&sourceBuffer[i], tmp);
[data appendBytes: tmp length: strlen(tmp)];
}
objc_free(sourceBuffer);
return data;
}
static char*
encodeBase64(NSData *source)
{
int length = [source length];
int enclen = length / 3;
int remlen = length - 3 * enclen;
int destlen = 4 * ((length - 1) / 3) + 5;
unsigned char *sourceBuffer = malloc(length);
unsigned char *destBuffer = malloc(destlen);
int sourceIndex = 0, destIndex = 0;
[source getBytes:sourceBuffer];
destBuffer[destlen - 1] = '\0';
for (sourceIndex = 0; sourceIndex < length - 2; sourceIndex += 3, destIndex += 4)
{
destBuffer[destIndex] = base64[sourceBuffer[sourceIndex] >> 2];
destBuffer[destIndex + 1] = base64[((sourceBuffer[sourceIndex] << 4) | (sourceBuffer[sourceIndex + 1] >> 4)) & 0x3f];
destBuffer[destIndex + 2] = base64[((sourceBuffer[sourceIndex + 1] << 2) | (sourceBuffer[sourceIndex + 2] >> 6)) & 0x3f];
destBuffer[destIndex + 3] = base64[sourceBuffer[sourceIndex + 2] & 0x3f];
}
if (remlen == 1)
{
destBuffer[destIndex] = base64[sourceBuffer[sourceIndex] >> 2];
destBuffer[destIndex + 1] = (sourceBuffer[sourceIndex] << 4) & 0x30;
destBuffer[destIndex + 1] = base64[destBuffer[destIndex + 1]];
destBuffer[destIndex + 2] = '=';
destBuffer[destIndex + 3] = '=';
}
else if (remlen == 2)
{
destBuffer[destIndex] = base64[sourceBuffer[sourceIndex] >> 2];
destBuffer[destIndex + 1] = (sourceBuffer[sourceIndex] << 4) & 0x30;
destBuffer[destIndex + 1] |= sourceBuffer[sourceIndex + 1] >> 4;
destBuffer[destIndex + 1] = base64[destBuffer[destIndex + 1]];
destBuffer[destIndex + 2] = (sourceBuffer[sourceIndex + 1] << 2) & 0x3c;
destBuffer[destIndex + 2] = base64[destBuffer[destIndex + 2]];
destBuffer[destIndex + 3] = '=';
}
free(sourceBuffer);
return destBuffer;
}
#endif
/*
* Cache some commonly used character sets along with methods to
* check membership.
@ -555,6 +656,142 @@ static id parsePlItem(pldata* pld)
}
}
#if HAVE_LIBXML
static GSXMLNode*
elementNode(GSXMLNode* node)
{
while (node != nil)
{
if ([node type] == XML_ELEMENT_NODE)
{
break;
}
node = [node next];
}
return node;
}
static id
nodeToObject(GSXMLNode* node)
{
NSString *name;
NSString *content;
GSXMLNode *children;
node = elementNode(node);
if (node == nil)
{
return nil;
}
name = [node name];
children = elementNode([node children]);
content = [children content];
if ([name isEqualToString: @"string"])
{
return content;
}
else if ([name isEqualToString: @"key"])
{
return content;
}
else if ([name isEqualToString: @"true"])
{
return [NSNumber numberWithBool: YES];
}
else if ([name isEqualToString: @"false"])
{
return [NSNumber numberWithBool: NO];
}
else if ([name isEqualToString: @"integer"])
{
return [NSNumber numberWithInt: [content intValue]];
}
else if ([name isEqualToString: @"real"])
{
return [NSNumber numberWithDouble: [content doubleValue]];
}
else if ([name isEqualToString: @"date"])
{
return [NSCalendarDate dateWithString: content
calendarFormat: @"%Y-%m-%d %H:%M:%S"];
}
else if ([name isEqualToString: @"data"])
{
return decodeBase64([content cString]);
}
// container class
else if ([name isEqualToString: @"array"])
{
NSMutableArray *container = [NSMutableArray array];
while (children != nil)
{
[container addObject: nodeToObject(children)];
children = elementNode([children next]);
}
return container;
}
else if ([name isEqualToString: @"dict"])
{
NSMutableDictionary *container = [NSMutableDictionary dictionary];
while (children != nil)
{
NSString *key = nodeToObject(children);
children = elementNode([children next]);
[container setObject: nodeToObject(children) forKey: key];
children = elementNode([children next]);
}
return container;
}
else
{
return nil;
}
}
#endif
static id parsePl(pldata* pld)
{
#if HAVE_LIBXML
while (pld->pos < pld->end && isspace(pld->ptr[pld->pos]))
{
pld->pos++;
}
/*
* A string beginning with a '<?' must be an XML file
*/
if (pld->pos + 1 < pld->end && pld->ptr[pld->pos] == '<'
&& pld->ptr[pld->pos+1] == '?')
{
NSData *data;
GSXMLParser *parser;
data = [NSData dataWithBytes: pld->ptr length: pld->end];
NSLog(@"Parsing '%*s'", pld->end, pld->ptr);
parser = [GSXMLParser parser: data];
if ([parser parse] == YES)
{
if (![[[[parser doc] root] name] isEqualToString: @"plist"])
{
NSLog(@"not a property list - because name node is %@",
[[[parser doc] root] name]);
return nil;
}
return nodeToObject([[[parser doc] root] children]);
}
else
{
NSLog(@"not a property list - failed to parse as XML");
return nil;
}
}
#endif
return parsePlItem(pld);
}
static id parseSfItem(pldata* pld)
{
NSMutableDictionary *dict;