1 /* Private header for libxml2 wrapping components
2    Copyright (C) 2009 Free Software Foundation, Inc.
3 
4    Written by:  Richard Frith-Macdonald <rfm@gnu.org>
5    Created: Februrary 2009
6 
7    This file is part of the GNUstep Base Library.
8 
9    This library is free software; you can redistribute it and/or
10    modify it under the terms of the GNU Lesser General Public
11    License as published by the Free Software Foundation; either
12    version 3 of the License, or (at your option) any later version.
13 
14    This library is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17    Lesser General Public License for more details.
18 
19    You should have received a copy of the GNU Lesser General Public
20    License along with this library; if not, write to the Free
21    Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
22    Boston, MA 02110 USA.
23 */
24 
25 #ifndef	_INCLUDED_NSXMLPRIVATE_H
26 #define	_INCLUDED_NSXMLPRIVATE_H
27 
28 #import "common.h"
29 
30 #ifdef	HAVE_LIBXML
31 
32 /* Avoid problems on systems where the xml headers use 'id'
33  */
34 #define	id	GSXMLID
35 
36 /* libxml headers */
37 #include <libxml/tree.h>
38 #include <libxml/entities.h>
39 #include <libxml/parser.h>
40 #include <libxml/parserInternals.h>
41 #include <libxml/HTMLparser.h>
42 #include <libxml/xmlmemory.h>
43 #include <libxml/xmlsave.h>
44 #include <libxml/xpath.h>
45 #include <libxml/xpathInternals.h>
46 
47 #ifdef HAVE_LIBXSLT
48 #include <libxslt/xslt.h>
49 #include <libxslt/xsltInternals.h>
50 #include <libxslt/transform.h>
51 #include <libxslt/xsltutils.h>
52 #endif /* HAVE_LIBXSLT */
53 
54 #undef	id
55 
56 #endif	/* HAVE_LIBXML */
57 
58 #define	EXPOSE_NSXMLDTD_IVARS	1
59 #define	EXPOSE_NSXMLDTDNode_IVARS	1
60 #define	EXPOSE_NSXMLDocument_IVARS	1
61 #define	EXPOSE_NSXMLElement_IVARS	1
62 #define	EXPOSE_NSXMLNode_IVARS	1
63 
64 /*
65  * Macro to cast string to correct type for libxml2
66  */
67 #define	XMLSTRING(X)	((const unsigned char*)[X UTF8String])
68 
XMLStringCopy(NSString * source)69 inline static unsigned char *XMLStringCopy(NSString *source)
70 {
71   char *xmlstr;
72   unsigned int len;
73 
74   len = [source maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding] + 1;
75   if (len == 0)
76     return NULL;
77   xmlstr = malloc(len);
78   [source getCString:xmlstr maxLength:len encoding:NSUTF8StringEncoding];
79   return (unsigned char *)xmlstr;
80 }
81 
82 inline static NSString*
StringFromXMLStringPtr(const unsigned char * bytes)83 StringFromXMLStringPtr(const unsigned char *bytes)
84 {
85   NSString	*str;
86   unsigned int length;
87 
88   if (bytes == NULL)
89     return @"";
90 
91   length = strlen((char *)bytes);
92   str = [[NSString alloc] initWithBytes: bytes
93 				       length: length
94 				     encoding: NSUTF8StringEncoding];
95   return AUTORELEASE(str);
96 }
97 
98 inline static NSString*
StringFromXMLString(const unsigned char * bytes,unsigned length)99 StringFromXMLString(const unsigned char *bytes, unsigned length)
100 {
101   NSString	*str;
102 
103   if (bytes == NULL)
104     return @"";
105 
106   str = [[NSString alloc] initWithBytes: bytes
107 				       length: length
108 				     encoding: NSUTF8StringEncoding];
109   return AUTORELEASE(str);
110 }
111 
112 #if defined(HAVE_LIBXML)
113 
114 #define	GS_XMLNODETYPE \
115 union\
116 {\
117 	xmlDoc *doc;\
118 	xmlDtd *dtd;\
119 	xmlEntity *entity;\
120 	xmlNode *node;\
121 }
122 
123 #else
124 #define GS_XMLNODETYPE void*
125 
126 #endif
127 
128 
129 /* Instance variables for NSXMLNode.  This macro needs to be defined before
130  * the NSXMLNode.h header is imported and before GSInternal.h is imported.
131  *
132  * The 'kind' tells us what sort of node this is.
133  * The 'node' points to the underlying libxml2 node structure.
134  * The 'options' field is a bitmask of options for this node.
135  * The 'objectValue' is the object value set for the node.
136  * The 'subNodes' array is used to retain the objects pointed to by subnodes.
137  *
138  * When we create an Objective-C object for a node we also create objects
139  * for all parents up to the root object. (Reusing existing once as we find
140  * them in the _private points of parent nodes)
141  * This adds the object to the subnode array of the parent object, retaining
142  * the object in this process.
143  * This means a document object will retain all the objects we have created
144  * for its node tree, but we don't have to create all these objects at once.
145  * When we remove an object from its parent we always call the detach method.
146  * Here we unlink the libxml2 node and remove the object from its parent's
147  * subnode array, This will release the object.
148  * When an object gets deallocated it detaches all the subnodes, releasing
149  * them in the process and then it frees the node. That way each object takes
150  * care of freeing its own node, but nodes that don't have objects attached
151  * to them will get freed when their parent object (e.g. the NSXMLDocument)
152  * gets deallocated.
153  * For namespace nodes special rules apply as they don't have a parent pointer.
154  *
155  * URI is probably not needed at all ... I'm not sure
156  */
157 #define GS_NSXMLNode_IVARS \
158   NSUInteger	  kind; \
159   GS_XMLNODETYPE node;  \
160   NSUInteger      options; \
161   id              objectValue; \
162   NSMutableArray *subNodes;
163 
164 
165 /* When using the non-fragile ABI, the instance variables are exposed to the
166  * compiler within the class declaration, so we don't need to incorporate
167  * superclass variables into the subclass declaration.
168  * But with the fragile ABI we need to allocate a single internal structure
169  * containing the private variables for both the subclass and the superclass.
170  */
171 #if	GS_NONFRAGILE
172 #define	SUPERIVARS(X)
173 #else
174 #define	SUPERIVARS(X)	X
175 #endif
176 
177 /* Instance variables for NSXMLDocument with/without the instance
178  * variable 'inherited' from NSXMLNode.
179  * This macro needs to be defined before the NSXMLDocument.h header
180  * is imported and before GSInternal.h is imported.
181  */
182 #define GS_NSXMLDocument_IVARS SUPERIVARS(GS_NSXMLNode_IVARS) \
183   NSString     		*MIMEType; \
184   NSInteger		contentKind; \
185 
186 /* Instance variables for NSXMLDTD with/without the instance
187  * variable 'inherited' from NSXMLNode.
188  * This macro needs to be defined before the NSXMLDTD.h header
189  * is imported and before GSInternal.h is imported.
190  */
191 #define GS_NSXMLDTD_IVARS SUPERIVARS(GS_NSXMLNode_IVARS)
192 
193 /* Instance variables for NSXMLDTDNode with/without the instance
194  * variable 'inherited' from NSXMLNode.
195  * This macro needs to be defined before the NSXMLDTDNode.h header
196  * is imported and before GSInternal.h is imported.
197  */
198 #define GS_NSXMLDTDNode_IVARS SUPERIVARS(GS_NSXMLNode_IVARS) \
199   NSUInteger	DTDKind; \
200 
201 /* Instance variables for NSXMLElement with/without the instance
202  * variable 'inherited' from NSXMLNode.
203  * This macro needs to be defined before the NSXMLElement.h header
204  * is imported and before GSInternal.h is imported.
205  */
206 #define GS_NSXMLElement_IVARS SUPERIVARS(GS_NSXMLNode_IVARS)
207 
208 
209 #import "Foundation/NSArray.h"
210 #import "Foundation/NSData.h"
211 #import "Foundation/NSDebug.h"
212 #import "Foundation/NSDictionary.h"
213 #import "Foundation/NSEnumerator.h"
214 #import "Foundation/NSException.h"
215 #import "Foundation/NSString.h"
216 #import "Foundation/NSURL.h"
217 #import "Foundation/NSXMLNode.h"
218 #import "Foundation/NSXMLDocument.h"
219 #import "Foundation/NSXMLDTDNode.h"
220 #import "Foundation/NSXMLDTD.h"
221 #import "Foundation/NSXMLElement.h"
222 
223 #ifdef	HAVE_LIBXML
224 
225 // Private methods to manage libxml pointers...
226 @interface NSXMLNode (Private)
227 - (void *) _node;
228 - (void) _setNode: (void *)_anode;
229 + (NSXMLNode *) _objectForNode: (xmlNodePtr)node;
230 - (void) _addSubNode: (NSXMLNode *)subNode;
231 - (void) _removeSubNode: (NSXMLNode *)subNode;
232 - (id) _initWithNode: (xmlNodePtr)node kind: (NSXMLNodeKind)kind;
233 - (xmlNodePtr) _childNodeAtIndex: (NSUInteger)index;
234 - (void) _insertChild: (NSXMLNode*)child atIndex: (NSUInteger)index;
235 - (void) _invalidate;
236 @end
237 
238 #endif /* HAVE_LIBXML */
239 
240 #endif
241