diff --git a/ChangeLog b/ChangeLog index 97cabd8e8..2db85b8f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,9 +8,16 @@ tolerate URLs where the network part is missing and the '//' left out. * Source/GSXML.m: Reorganized init methods in line with Manuels ideas but with naming consistent with other classes. + Correct methods for setting parser behavior for the object concerned + rather than default behavior for all parsers. + Support NSURL parsing. * Source/propList.h: Update for change in GSXMLParser API. * Documentation/gsdoc/GSXMLParser.gsdoc: update for new initialisation methods. + * Source/NSArray.m: Put code in place to generate XML proplists + * Source/NSDictionary.m: Put code in place to generate XML proplists + * Source/GSCompatibility.m: Put code in place to generate XML proplists + but disable it until working entity replacement is done. 2000-09-21 Adam Fedor diff --git a/Documentation/gsdoc/GSXMLParser.gsdoc b/Documentation/gsdoc/GSXMLParser.gsdoc index 5217bca28..5c7890ee1 100644 --- a/Documentation/gsdoc/GSXMLParser.gsdoc +++ b/Documentation/gsdoc/GSXMLParser.gsdoc @@ -182,7 +182,7 @@

The source for the parsing process is not specified - so - parsing must be done incfrementally by feeding data to the + parsing must be done incrementally by feeding data to the parser.

@@ -236,9 +236,8 @@

Sets the input source for the parser to be the specified data - object (which must contain a nul terminated XML document), - so parsing of the entire document will be performed rather than - incremental parsing. + object (which must contain an XML document), so parsing of the + entire document will be performed rather than incremental parsing.

@@ -254,7 +253,8 @@ doc -

Return GSXMLDocument object. +

+ Return GSXMLDocument object.

@@ -264,7 +264,7 @@

Parse source. Return YES if parsed, otherwise NO. - This method should be called once to parse the entiore document. + This method should be called once to parse the entire document.

GSXMLParser *p = [GSXMLParser parserWithContentsOfFile:@"macos.xml"]; @@ -292,8 +292,8 @@ block of data from the same document. After the whole of the document has been parsed, the method should be called with an empty or nil data object to indicate end of parsing. - Once this has been done, the method may be used again to - parse a new document. + On this final call, the return value indicates whether the + document was valid or not.

GSXMLParser *p = [GSXMLParser parserWithSAXHandler: nil source: nil]; @@ -307,7 +307,7 @@ } // Do something with document parsed - [p parse: nil]; // Ready to parse another document. + [p parse: nil]; // Completed parsing of document.
@@ -318,7 +318,7 @@ yesno

- Set and return the previous value for default entity support. + Set and return the previous value for entity support. Initially the parser always keeps entity references instead of substituting entity values in the output.

@@ -330,8 +330,7 @@ yesno

- Set and return the previous value for default blanks - text nodes support. + Set and return the previous value for blank text nodes support. ignorableWhitespace() are only generated when running the parser in validating mode and when the current element doesn't allow CDATA or mixed content. diff --git a/Documentation/gsdoc/GSXMLParser.html b/Documentation/gsdoc/GSXMLParser.html index 3f018fae1..b62d5681b 100644 --- a/Documentation/gsdoc/GSXMLParser.html +++ b/Documentation/gsdoc/GSXMLParser.html @@ -226,7 +226,7 @@ Creation of a new Parser by calling

The source for the parsing process is not specified - so - parsing must be done incfrementally by feeding data to the + parsing must be done incrementally by feeding data to the parser.

@@ -280,9 +280,8 @@ Creation of a new Parser by calling

Sets the input source for the parser to be the specified data - object (which must contain a nul terminated XML document), - so parsing of the entire document will be performed rather than - incremental parsing. + object (which must contain an XML document), so parsing of the + entire document will be performed rather than incremental parsing.

@@ -300,7 +299,8 @@ Return pointer to xmlParserCtxt structure. - (GSXMLDocument*) doc;

-Return GSXMLDocument object. + + Return GSXMLDocument object.

@@ -311,7 +311,7 @@ Return GSXMLDocument object.

Parse source. Return YES if parsed, otherwise NO. - This method should be called once to parse the entiore document. + This method should be called once to parse the entire document.

example @@ -343,8 +343,8 @@ Return GSXMLDocument object. block of data from the same document. After the whole of the document has been parsed, the method should be called with an empty or nil data object to indicate end of parsing. - Once this has been done, the method may be used again to - parse a new document. + On this final call, the return value indicates whether the + document was valid or not.

example @@ -361,7 +361,7 @@ Return GSXMLDocument object. } // Do something with document parsed - [p parse: nil]; // Ready to parse another document. + [p parse: nil]; // Completed parsing of document. @@ -373,7 +373,7 @@ Return GSXMLDocument object.

- Set and return the previous value for default entity support. + Set and return the previous value for entity support. Initially the parser always keeps entity references instead of substituting entity values in the output.

@@ -385,8 +385,7 @@ Return GSXMLDocument object.

- Set and return the previous value for default blanks - text nodes support. + Set and return the previous value for blank text nodes support. ignorableWhitespace() are only generated when running the parser in validating mode and when the current element doesn't allow CDATA or mixed content. diff --git a/Documentation/gsdoc/NSURL.html b/Documentation/gsdoc/NSURL.html index 84e9e6142..59dbd7fd6 100644 --- a/Documentation/gsdoc/NSURL.html +++ b/Documentation/gsdoc/NSURL.html @@ -51,16 +51,20 @@

URLWithString:

+ (id) URLWithString: (NSString*)URLString;
+ Initializes with a string as specified in RFCs 1738 and 1808

URLWithString:relativeToURL:

+ (id) URLWithString: (NSString*)URLString relativeToURL: (NSURL*)baseURL;
+ Initializes relative to a base URL, with a string as + specified in RFCs 1738 and 1808

fileURLWithPath:

+ (id) fileURLWithPath: (NSString*)path;
+ Initializes as a file schem URL with the specified path.

Instances Methods

diff --git a/Documentation/gsdoc/NSURLHandle.html b/Documentation/gsdoc/NSURLHandle.html index dc2244b6f..0634c1d44 100644 --- a/Documentation/gsdoc/NSURLHandle.html +++ b/Documentation/gsdoc/NSURLHandle.html @@ -52,21 +52,27 @@

URLHandleClassForURL:

+ (Class) URLHandleClassForURL: (NSURL*)anURL;
+ Returns the most recently registered NSURLHandle subclass that + responds to canInitWithURL: with YES

cachedHandleForURL:

+ (NSURLHandle*) cachedHandleForURL: (NSURL*)anURL;
+ Returns a previously created object that handles the specified + URL (if any exists).

canInitWithURL:

+ (BOOL) canInitWithURL: (NSURL*)anURL;
+ Implemented by subclasses to say which URLs they can handle.

registerURLHandleClass:

+ (void) registerURLHandleClass: (Class)anURLHandleSubclass;
+ Used to register a subclass as being available to handle URLs.

Instances Methods

diff --git a/Source/GSCompatibility.m b/Source/GSCompatibility.m index 832fdeadb..725840634 100644 --- a/Source/GSCompatibility.m +++ b/Source/GSCompatibility.m @@ -109,6 +109,8 @@ BOOL GSMacOSXCompatibleGeometry() BOOL GSMacOSXCompatiblePropertyLists() { +/* HACK until xml propertylists fully working */ +return NO; if (setupDone == NO) compatibilitySetup(); return MacOSXCompatiblePropertyLists; @@ -178,9 +180,30 @@ XMLString(NSString* obj) return obj; } +static NSString *indentStrings[] = { + @"", + @" ", + @"\t", + @"\t ", + @"\t\t", + @"\t\t ", + @"\t\t\t", + @"\t\t\t ", + @"\t\t\t\t", + @"\t\t\t\t ", + @"\t\t\t\t\t", + @"\t\t\t\t\t ", + @"\t\t\t\t\t\t" +}; + static void -XMLPlObject(NSMutableString *dest, id obj) +XMLPlObject(NSMutableString *dest, id obj, NSDictionary *loc, unsigned lev) { + if (lev >= sizeof(indentStrings) / sizeof(*indentStrings)) + lev = sizeof(indentStrings) / sizeof(*indentStrings) - 1; + + [dest appendString: indentStrings[lev]]; + if ([obj isKindOfClass: [NSString class]]) { [dest appendString: @""]; @@ -233,14 +256,19 @@ XMLPlObject(NSMutableString *dest, id obj) e = [obj objectEnumerator]; while ((obj = [e nextObject])) { - XMLPlObject(dest, obj); + XMLPlObject(dest, obj, loc, lev + 1); } + [dest appendString: indentStrings[lev]]; [dest appendString: @"\n"]; } else if ([obj isKindOfClass: [NSDictionary class]]) { NSEnumerator *e; id key; + unsigned nxt = lev + 1; + + if (lev >= sizeof(indentStrings) / sizeof(*indentStrings)) + lev = sizeof(indentStrings) / sizeof(*indentStrings) - 1; [dest appendString: @"\n"]; e = [obj keyEnumerator]; @@ -249,11 +277,13 @@ XMLPlObject(NSMutableString *dest, id obj) id val; val = [obj objectForKey: key]; + [dest appendString: indentStrings[nxt]]; [dest appendString: @""]; [dest appendString: XMLString(key)]; [dest appendString: @"\n"]; - XMLPlObject(dest, val); + XMLPlObject(dest, val, loc, nxt); } + [dest appendString: indentStrings[lev]]; [dest appendString: @"\n"]; } else @@ -265,3 +295,18 @@ XMLPlObject(NSMutableString *dest, id obj) } } +NSString* +GSXMLPlMake(id obj, NSDictionary *loc, unsigned lev) +{ + NSMutableString *dest; + + dest = [NSMutableString stringWithCString: + "\n\n" + "\n"]; + + XMLPlObject(dest, obj, loc, 0); + [dest appendString: @""]; + return dest; +} + diff --git a/Source/GSXML.m b/Source/GSXML.m index aa8b423da..8537303bb 100644 --- a/Source/GSXML.m +++ b/Source/GSXML.m @@ -32,6 +32,8 @@ #include #include +#include +#include #include #include #include @@ -937,10 +939,14 @@ static NSString *endMarker = @"At end of incremental parse"; RELEASE(self); return nil; } - self = [self init]; - if (self != nil) + saxHandler = RETAIN(handler); + [saxHandler parser: self]; + lib = (void*)xmlCreatePushParserCtxt([saxHandler lib], saxHandler, 0, 0, ""); + if (lib == NULL) { - saxHandler = RETAIN(handler); + NSLog(@"Failed to create libxml parser context"); + RELEASE(self); + return nil; } return self; } @@ -1013,29 +1019,28 @@ static NSString *endMarker = @"At end of incremental parse"; if ([src isKindOfClass: [NSData class]]) { - lib = (void*)xmlCreateMemoryParserCtxt((void*)[src bytes], - [src length]-1); - if (lib == NULL) - { - NSLog(@"out of memory"); - return NO; - } } else if ([src isKindOfClass: NSString_class]) { - NSFileManager *mgr = [NSFileManager defaultManager]; + NSData *data = [NSData dataWithContentsOfFile: src]; - if ([mgr isReadableFileAtPath: src] == NO) + if (data == nil) { NSLog(@"File to parse (%@) is not readable", src); return NO; } - lib = (void*)xmlCreateFileParserCtxt([src cString]); - if (lib == NULL) - { - NSLog(@"out of memory"); + ASSIGN(src, data); + } + else if ([src isKindOfClass: [NSURL class]]) + { + NSData *data = [src resourceDataUsingCache: YES]; + + if (data == nil) + { + NSLog(@"URL to parse (%@) is not readable", src); return NO; - } + } + ASSIGN(src, data); } else { @@ -1043,18 +1048,10 @@ static NSString *endMarker = @"At end of incremental parse"; return NO; } - if (saxHandler != nil) - { - NSAssert([saxHandler parser] == nil, NSGenericException); - free(((xmlParserCtxtPtr)lib)->sax); - ((xmlParserCtxtPtr)lib)->sax = [saxHandler lib]; - ((xmlParserCtxtPtr)lib)->userData = saxHandler; - [saxHandler parser: self]; - } - tmp = RETAIN(src); ASSIGN(src, endMarker); - xmlParseDocument(lib); + xmlParseChunk(lib, [tmp bytes], [tmp length], 0); + xmlParseChunk(lib, 0, 0, 0); RELEASE(tmp); if (((xmlParserCtxtPtr)lib)->wellFormed) @@ -1065,17 +1062,11 @@ static NSString *endMarker = @"At end of incremental parse"; - (BOOL) parse: (NSData*)data { - /* - * Permit start of new parse after completed one. - */ if (src == endMarker) { - xmlFreeDoc(((xmlParserCtxtPtr)lib)->myDoc); - xmlClearParserCtxt(lib); - lib = NULL; - src = nil; + NSLog(@"GSXMLParser -parse: called on object that is fully parsed"); + return NO; } - if (src != nil) { NSLog(@"XMLParser -parse: called for parser not initialised with nil"); @@ -1104,21 +1095,7 @@ static NSString *endMarker = @"At end of incremental parse"; } else { - if (lib == NULL) - { - NSAssert([saxHandler parser] == nil, NSGenericException); - [saxHandler parser: self]; - lib = (void*)xmlCreatePushParserCtxt([saxHandler lib], saxHandler, - [data bytes], [data length], "incremental"); - if (lib == NULL) - { - return NO; - } - } - else - { - xmlParseChunk(lib, [data bytes], [data length], 0); - } + xmlParseChunk(lib, [data bytes], [data length], 0); return YES; } } @@ -1143,17 +1120,26 @@ static NSString *endMarker = @"At end of incremental parse"; - (BOOL) substituteEntities: (BOOL)yesno { - return xmlSubstituteEntitiesDefault(yesno); + BOOL result = ((xmlParserCtxtPtr)lib)->replaceEntities ? YES : NO; + + ((xmlParserCtxtPtr)lib)->replaceEntities = (yesno == YES) ? 1 : 0; + return result; } - (BOOL) keepBlanks: (BOOL)yesno { - return xmlKeepBlanksDefault(yesno); + BOOL result = ((xmlParserCtxtPtr)lib)->keepBlanks ? YES : NO; + + ((xmlParserCtxtPtr)lib)->keepBlanks = (yesno == YES) ? 1 : 0; + return result; } - (BOOL) doValidityChecking: (BOOL)yesno { - return !(xmlDoValidityCheckingDefaultValue = yesno); + BOOL result = ((xmlParserCtxtPtr)lib)->validate ? YES : NO; + + ((xmlParserCtxtPtr)lib)->validate = (yesno == YES) ? 1 : 0; + return result; } - (BOOL) getWarnings: (BOOL)yesno @@ -1161,7 +1147,6 @@ static NSString *endMarker = @"At end of incremental parse"; return !(xmlGetWarningsDefaultValue = yesno); } - - (void) setExternalEntityLoader: (void*)function { xmlSetExternalEntityLoader((xmlExternalEntityLoader)function); diff --git a/Source/NSArray.m b/Source/NSArray.m index 7d9485827..cd9d9fcf6 100644 --- a/Source/NSArray.m +++ b/Source/NSArray.m @@ -656,14 +656,25 @@ static SEL rlSel = @selector(removeLastObject); - (NSString*) descriptionWithLocale: (NSDictionary*)locale indent: (unsigned int)level { - NSMutableString *result; + extern BOOL GSMacOSXCompatiblePropertyLists(); - result = [[NSGMutableCString alloc] initWithCapacity: 20*[self count]]; - result = AUTORELEASE(result); - [self descriptionWithLocale: locale - indent: level - to: (id)result]; - return result; + if (GSMacOSXCompatiblePropertyLists() == YES) + { + extern NSString *GSXMLPlMake(id obj, NSDictionary *loc, unsigned lev); + + return GSXMLPlMake(self, locale, level); + } + else + { + NSMutableString *result; + + result = [[NSGMutableCString alloc] initWithCapacity: 20*[self count]]; + result = AUTORELEASE(result); + [self descriptionWithLocale: locale + indent: level + to: (id)result]; + return result; + } } static NSString *indentStrings[] = { diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index aee1bf371..57a93948d 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -627,14 +627,25 @@ compareIt(id o1, id o2, void* context) - (NSString*) descriptionWithLocale: (NSDictionary*)locale indent: (unsigned int)level { - NSMutableString *result; + extern BOOL GSMacOSXCompatiblePropertyLists(); - result = AUTORELEASE([[NSGMutableCString alloc] initWithCapacity: - 20*[self count]]); - [self descriptionWithLocale: locale - indent: level - to: (id)result]; - return result; + if (GSMacOSXCompatiblePropertyLists() == YES) + { + extern NSString *GSXMLPlMake(id obj, NSDictionary *loc, unsigned lev); + + return GSXMLPlMake(self, locale, level); + } + else + { + NSMutableString *result; + + result = AUTORELEASE([[NSGMutableCString alloc] initWithCapacity: + 20*[self count]]); + [self descriptionWithLocale: locale + indent: level + to: (id)result]; + return result; + } } static NSString *indentStrings[] = { diff --git a/Source/propList.h b/Source/propList.h index 0289bff2c..f99f7298f 100644 --- a/Source/propList.h +++ b/Source/propList.h @@ -725,12 +725,12 @@ static id parsePl(pldata* pld) { NSData *data; GSXMLParser *parser; - char *buf = NSZoneMalloc(NSDefaultMallocZone(), pld->end+1); + char *buf = NSZoneMalloc(NSDefaultMallocZone(), pld->end); memcpy(buf, pld->ptr, pld->end); - buf[pld->end] = '\0'; - data = [NSData dataWithBytesNoCopy: buf length: pld->end+1]; + data = [NSData dataWithBytesNoCopy: buf length: pld->end]; parser = [GSXMLParser parserWithData: data]; + [parser substituteEntities: NO]; if ([parser parse] == YES) { if (![[[[parser doc] root] name] isEqualToString: @"plist"]) diff --git a/Testing/basic.m b/Testing/basic.m index 1b955d7cb..65d9b8773 100644 --- a/Testing/basic.m +++ b/Testing/basic.m @@ -23,6 +23,8 @@ int main (int argc, char **argv) NSData *data = [url resourceDataUsingCache: YES]; NSLog(@"%@", data); + url = [NSURL fileURLWithPath: @"/tmp/z"]; + [url setResourceData: data]; NSLog(@"%@", _(Testing)); NSLog(@"%@", $(@"Testing"));