evert/improve last changes

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@34925 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Richard Frith-MacDonald 2012-03-12 18:13:27 +00:00
parent f3da6a5455
commit 84ce4ee4e3
5 changed files with 127 additions and 315 deletions

View file

@ -1,3 +1,11 @@
2012-03-11 Richard Frith-Macdonald & Fred Kiefer
* Source/NSXMLNamespace.m:
* Source/GNUmakefile:
* Source/NSXMLPrivate.h:
* Source/NSXMLNode.m:
Revert most of my last change in favour of Fred's changes.
2012-03-11 Richard Frith-Macdonald <rfm@gnu.org>
* Source/NSXMLNamespace.m: New class for namespaces

View file

@ -286,7 +286,6 @@ NSXMLDocument.m \
NSXMLDTD.m \
NSXMLDTDNode.m \
NSXMLElement.m \
NSXMLNamespace.m \
NSXMLNode.m \
NSXMLParser.m \
NSZone.m \

View file

@ -1,280 +0,0 @@
/* Implementation for NSXMLNamespace for GNUStep
Copyright (C) 2008 Free Software Foundation, Inc.
Written by: Richard Frith-Macdonald <rfm@gnu.org>
Created: September 2008
This file is part of the GNUstep Base Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02111 USA.
*/
#import "common.h"
#define GSInternal NSXMLNamespaceInternal
#define GS_XMLNODETYPE xmlNs
#import "NSXMLPrivate.h"
@interface NSXMLNamespace : NSXMLNode
{
@public GS_NSXMLNamespace_IVARS
/* The pointer to private additional data used to avoid breaking ABI
* when we don't have the non-fragile ABI available is inherited from
* NSXMLNode. See Source/GSInternal.h for details.
*/
}
@end
#import "GSInternal.h"
GS_PRIVATE_INTERNAL(NSXMLNamespace)
#if defined(HAVE_LIBXML)
static void
clearPrivatePointers(xmlNodePtr aNode)
{
if (!aNode)
return;
aNode->_private = NULL;
clearPrivatePointers(aNode->children);
clearPrivatePointers(aNode->next);
if (aNode->type == XML_ELEMENT_NODE)
clearPrivatePointers((xmlNodePtr)(aNode->properties));
// FIXME: Handle more node types
}
@implementation NSXMLNamespace
- (NSString*) canonicalXMLStringPreservingComments: (BOOL)comments
{
return [self notImplemented: _cmd]; // FIXME ... generate from libxml
}
- (NSXMLNode*) childAtIndex: (NSUInteger)index
{
return nil;
}
- (NSUInteger) childCount
{
return 0;
}
- (NSArray*) children
{
return nil;
}
- (id) copyWithZone: (NSZone*)zone
{
NSXMLNamespace *c = [[self class] allocWithZone: zone];
// FIXME
GSIVar(c, options) = internal->options;
if (nil != internal->objectValue)
{
/*
Only copy the objectValue when externally set.
The problem here are nodes created by parsing XML.
There the stringValue may be set, but the objectValue isn't.
This should rather be solved by creating a suitable objectValue,
when the node gets instantiated.
*/
[c setObjectValue: internal->objectValue];
}
[c setURI: [self URI]];
// [c setName: [self name]];
// [c setStringValue: [self stringValue]];
return c;
}
- (NSString*) description
{
return [NSString stringWithFormat:@"<%@ %@ %d>%@\n",
NSStringFromClass([self class]),
[self name], [self kind], [self XMLString]];
}
- (void) dealloc
{
if (GS_EXISTS_INTERNAL)
{
xmlNs *old = internal->node;
// FIXME
if (old)
{
old->_private = NULL;
xmlFreeNs(old);
}
GS_DESTROY_INTERNAL(NSXMLNode);
}
[super dealloc];
}
- (void) detach
{
xmlNsPtr ns = internal->node;
if (ns)
{
// FIXME
}
}
- (NSUInteger) hash
{
return [[self name] hash];
}
- (NSUInteger) index
{
return 0;
}
- (id) init
{
return [self initWithKind: NSXMLNamespaceKind];
}
- (NSUInteger) level
{
return 0;
}
- (NSString*) localName
{
return [[self class] localNameForName: [self name]];
}
- (NSString*) name
{
return nil;
}
- (NSXMLNode*) nextNode
{
return nil;
}
- (NSXMLNode*) nextSibling
{
return nil;
}
- (id) objectValue
{
return nil;
}
- (NSXMLNode*) parent
{
return nil;
}
- (NSString*) prefix
{
return StringFromXMLStringPtr(internal->node->prefix);
}
- (NSXMLNode*) previousNode
{
return nil;
}
- (NSXMLNode*) previousSibling
{
return nil;
}
- (NSXMLDocument*) rootDocument
{
return nil;
}
- (NSString*) stringValue
{
return StringFromXMLStringPtr(internal->node->href);
}
- (void) setObjectValue: (id)value
{
return;
}
- (void) setName: (NSString *)name
{
return;
}
- (void) setStringValue: (NSString*)string
{
[self setStringValue: string resolvingEntities: NO];
}
- (void) setStringValue: (NSString*)string resolvingEntities: (BOOL)resolve
{
return;
}
- (void) setURI: (NSString*)URI
{
//xmlNodeSetBase(internal->node, XMLSTRING(URI));
}
- (NSString*) URI
{
return StringFromXMLStringPtr(internal->node->href);
}
- (NSString*) XMLString
{
return [self XMLStringWithOptions: NSXMLNodeOptionsNone];
}
- (NSString*) XMLStringWithOptions: (NSUInteger)options
{
return nil;
}
- (NSString*) XPath
{
return nil;
}
- (NSArray*) nodesForXPath: (NSString*)anxpath error: (NSError**)error
{
return nil;
}
- (NSArray*) objectsForXQuery: (NSString*)xquery
constants: (NSDictionary*)constants
error: (NSError**)error
{
return nil;
}
- (NSArray*) objectsForXQuery: (NSString*)xquery error: (NSError**)error
{
return nil;
}
@end
#endif

View file

@ -33,7 +33,8 @@ GS_PRIVATE_INTERNAL(NSXMLNode)
#if defined(HAVE_LIBXML)
@class NSXMLNamespace;
@interface NSXMLNamespaceNode : NSXMLNode
@end
static int
countAttributes(xmlNodePtr node)
@ -210,6 +211,22 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
return NO;
}
/* FIXME ... the libxml2 data structure representing a namespace has a
* completely different layout from that of almost all other nodes, so
* the generix NSXMLNode code won't work and we need to override every
* method we use!
*/
@implementation NSXMLNamespaceNode
- (NSUInteger) level
{
return 0;
}
- (NSXMLNode*) parent
{
return nil;
}
@end
@implementation NSXMLNode (Private)
- (void *) _node
{
@ -219,11 +236,18 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
- (void) _setNode: (void *)_anode
{
DESTROY(internal->subNodes);
if (_anode)
{
((xmlNodePtr)_anode)->_private = self;
}
internal->node = _anode;
if (internal->node != NULL)
{
if (internal->node->type == XML_NAMESPACE_DECL)
{
((xmlNsPtr)(internal->node))->_private = self;
}
else
{
internal->node->_private = self;
}
}
}
+ (NSXMLNode *) _objectForNode: (xmlNodePtr)node
@ -232,12 +256,21 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
if (node)
{
result = node->_private;
if (node->type == XML_NAMESPACE_DECL)
{
result = ((xmlNs *)node)->_private;
}
else
{
result = node->_private;
}
if (result == nil)
{
Class cls;
NSXMLNodeKind kind;
xmlElementType type = node->type;
xmlDoc *docNode;
NSXMLDocument *doc = nil;
switch (type)
{
@ -301,12 +334,18 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
return nil;
break;
}
if ((node->doc != NULL) && ((xmlNodePtr)(node->doc) != node))
if (node->type == XML_NAMESPACE_DECL)
{
NSXMLDocument *doc;
doc = (NSXMLDocument*)[self
_objectForNode: (xmlNodePtr)node->doc];
docNode = NULL;
}
else
{
docNode = node->doc;
}
if ((docNode != NULL) && ((xmlNodePtr)docNode != node))
{
doc = (NSXMLDocument*)[self _objectForNode: (xmlNodePtr)docNode];
if (doc != nil)
{
cls = [[doc class] replacementClassForClass: cls];
@ -315,10 +354,17 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
result = [[cls alloc] _initWithNode: node kind: kind];
AUTORELEASE(result);
if (node->parent)
if (node->type == XML_NAMESPACE_DECL)
{
NSXMLNode *parent = [self _objectForNode: node->parent];
[parent _addSubNode: result];
[doc _addSubNode: result];
}
else
{
if (node->parent)
{
NSXMLNode *parent = [self _objectForNode: node->parent];
[parent _addSubNode: result];
}
}
}
}
@ -365,8 +411,12 @@ isEqualTree(xmlNodePtr nodeA, xmlNodePtr nodeB)
{
NSUInteger count = 0;
xmlNodePtr node = internal->node;
xmlNodePtr children = node->children;
xmlNodePtr children;
if (node->type == XML_NAMESPACE_DECL)
return NULL;
children = node->children;
if (!children)
return NULL; // the Cocoa docs say it returns nil if there are no children
@ -473,11 +523,23 @@ clearPrivatePointers(xmlNodePtr aNode)
{
if (!aNode)
return;
if (aNode->type == XML_NAMESPACE_DECL)
{
xmlNsPtr ns = (xmlNsPtr)aNode;
ns->_private = NULL;
clearPrivatePointers((xmlNodePtr)ns->next);
return;
}
aNode->_private = NULL;
clearPrivatePointers(aNode->children);
clearPrivatePointers(aNode->next);
if (aNode->type == XML_ELEMENT_NODE)
clearPrivatePointers((xmlNodePtr)(aNode->properties));
{
clearPrivatePointers((xmlNodePtr)(aNode->properties));
}
// FIXME: Handle more node types
}
@ -829,7 +891,8 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
- (NSString*) canonicalXMLStringPreservingComments: (BOOL)comments
{
return [self notImplemented: _cmd]; // FIXME ... generate from libxml
// FIXME ... generate from libxml
return [self notImplemented: _cmd];
}
- (NSXMLNode*) childAtIndex: (NSUInteger)index
@ -849,6 +912,11 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
return 0;
}
if (node->type == XML_NAMESPACE_DECL)
{
return 0;
}
for (children = node->children; children; children = children->next)
{
count++;
@ -870,7 +938,9 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
xmlNodePtr children = NULL;
xmlNodePtr node = internal->node;
if ((node == NULL) || (node->children == NULL))
if ((node == NULL) ||
(node->type == XML_NAMESPACE_DECL) ||
(node->children == NULL))
{
return nil;
}
@ -938,14 +1008,25 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
[internal->objectValue release];
[internal->subNodes release];
if (node)
node->_private = NULL;
if (node && node->parent == NULL)
{
if (node->type == XML_DOCUMENT_NODE)
xmlFreeDoc((xmlDocPtr)node);
else
xmlFreeNode(node); // the top level node frees the entire tree
}
{
if (internal->node->type == XML_NAMESPACE_DECL)
{
((xmlNsPtr)internal->node)->_private = NULL;
xmlFreeNode(node);
}
else
{
node->_private = NULL;
if (node->parent == NULL)
{
// the top level node frees the entire tree
if (node->type == XML_DOCUMENT_NODE)
xmlFreeDoc((xmlDocPtr)node);
else
xmlFreeNode(node);
}
}
}
GS_DESTROY_INTERNAL(NSXMLNode);
}
[super dealloc];
@ -980,6 +1061,12 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
xmlNodePtr node = internal->node;
int count = 0;
if (internal->node->type == XML_NAMESPACE_DECL)
{
// FIXME: Could try to go to document an loop over the namespaces
return 0;
}
while ((node = node->prev))
{
count++; // count our earlier sibling nodes
@ -1031,7 +1118,7 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
break;
case NSXMLNamespaceKind:
theSubclass = [NSXMLNamespace class];
theSubclass = [NSXMLNamespaceNode class];
break;
case NSXMLAttributeKind:
@ -1148,6 +1235,11 @@ execute_xpath(NSXMLNode *xmlNode, NSString *xpath_exp, NSString *nmspaces)
return 0;
}
if (internal->node->type == XML_NAMESPACE_DECL)
{
return 0;
}
tmp = internal->node->parent;
while (tmp != NULL)
{

View file

@ -146,13 +146,6 @@ StringFromXMLString(const unsigned char *bytes, unsigned length)
*/
#define GS_NSXMLElement_IVARS SUPERIVARS(GS_NSXMLNode_IVARS)
/* Instance variables for NSXMLNamespace with/without the instance
* variable 'inherited' from NSXMLNode.
* This macro needs to be defined before the NSXMLNamespace interface
* is declared and before GSInternal.h is imported.
*/
#define GS_NSXMLNamespace_IVARS SUPERIVARS(GS_NSXMLNode_IVARS)
#import "Foundation/NSArray.h"
#import "Foundation/NSData.h"