1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 2; tab-width: 2 -*- */
2 /* gdome-xml-xmldtdutil.c
3  *
4  * Copyright (C) 2001 Paolo Casarini <paolo@casarini.org>
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 /* NOTE
22 
23  This file contains some functions that work directly on the gnome-xml
24  tree structure. We use it to make a right implementation of DocumentType
25  interface at gdome2 layer: gnome-xml make difference between internal and
26  external entities and notations.
27  Theese functions are to joining notations and entities in a single hash holded
28  by the Gdome_xml_DocumentType struct.
29  With this functions we also create a wrapper on gnome-xml xmlNotation structs
30  trasforming them in gdome_xmlNotation structs.
31 */
32 
33 #include <string.h>
34 #include "gdome.h"
35 #include <libxml/tree.h>
36 #include <libxml/parser.h>
37 #include <libxml/xmlmemory.h>
38 #include <libxml/xmlerror.h>
39 #include <libxml/hash.h>
40 #include "gdome-xml-xmldtdutil.h"
41 
42 
43 typedef struct _hashIterator hashIterator;
44 struct _hashIterator {
45 	xmlDoc *doc;
46 	xmlHashTable *ht;
47 };
48 
49 /* Hash Scanner function for gdome_xmlNotationsHashCreate*/
50 void
notationsHashScanner(void * payload,void * data,xmlChar * name)51 notationsHashScanner (void *payload, void *data, xmlChar *name) {
52 	hashIterator *priv = (hashIterator *)data;
53 	xmlNotation *orig_not = (xmlNotation *)payload;
54   gdome_xmlNotation *new_not = NULL;
55 
56   new_not = (gdome_xmlNotation *) xmlMalloc(sizeof(gdome_xmlNotation));
57 	if (new_not == NULL) {
58 		xmlGenericError(xmlGenericErrorContext,
59 										"gdome_createGdomeNotationsHash : malloc failed\n");
60 		return;
61 	}
62 	memset(new_not, 0 , sizeof(gdome_xmlNotation));
63 
64   /* Initialize gdome_xmlNotation struct */
65 	new_not->type = XML_NOTATION_NODE;
66   new_not->name = orig_not->name;
67 	new_not->doc = priv->doc;
68 	new_not->PublicID = orig_not->PublicID;
69 	new_not->SystemID = orig_not->SystemID;
70   new_not->orig = orig_not;
71 
72   /* add the new struct to the new hash */
73   xmlHashAddEntry (priv->ht, new_not->name, new_not);
74 }
75 
76 /* Hash Scanner function for gdome_xmlEntitiesHashCreate*/
77 void
entitiesHashScanner(void * payload,void * data,xmlChar * name)78 entitiesHashScanner (void *payload, void *data, xmlChar *name) {
79 	hashIterator *priv = (hashIterator *)data;
80 	xmlEntity *orig_not = (xmlEntity *)payload;
81 
82   /* add the struct to the new hash */
83   xmlHashAddEntry (priv->ht, name, orig_not);
84 }
85 
86 /* Clean up a gdome_xmlNotation record */
notationDeallocator(gdome_xmlNotation * not)87 void notationDeallocator(gdome_xmlNotation *not) {
88 	if (not == NULL) return;
89 
90   /*
91 	if (not->name != NULL)
92 		xmlFree((char *) not->name);
93 	if (not->PublicID != NULL)
94 		xmlFree((char *) not->PublicID);
95 	if (not->SystemID != NULL)
96 		xmlFree((char *) not->SystemID);
97   xmlFree(not);
98   */
99   g_free (not);
100 }
101 
102 /**
103  * gdome_xmlNotationsHashCreate:
104  * @doc:  Document that own notations
105  *
106  * Create a gdome notations hash joining external and internal notations hash
107  * of the Document specified.
108  * Returns: a gdome notations hash.
109  */
110 xmlHashTable *
gdome_xmlNotationsHashCreate(xmlDoc * doc)111 gdome_xmlNotationsHashCreate (xmlDoc *doc) {
112 	xmlHashTable *ret = NULL;
113   hashIterator iter;
114 
115 	if (doc == NULL)
116 		return NULL;
117 
118 	if ((doc->extSubset != NULL && doc->extSubset->notations != NULL) ||
119 			(doc->intSubset != NULL && doc->intSubset->notations != NULL)) {
120 		ret = xmlHashCreate(0);
121 		iter.doc = doc;
122 		iter.ht = ret;
123 	}
124 
125 	if (doc->extSubset != NULL && doc->extSubset->notations != NULL)
126 		xmlHashScan(doc->extSubset->notations, notationsHashScanner, &iter);
127 	if (doc->intSubset != NULL && doc->intSubset->notations != NULL)
128 		xmlHashScan(doc->intSubset->notations, notationsHashScanner, &iter);
129 
130 	return ret;
131 }
132 
133 /**
134  * gdome_xmlNotationsHashFree:
135  * @ht:  HashTable to free
136  *
137  * Free the Notations HashTable specified.
138  */
139 void
gdome_xmlNotationsHashFree(xmlHashTable * ht)140 gdome_xmlNotationsHashFree (xmlHashTable *ht) {
141   xmlHashFree (ht, (xmlHashDeallocator) notationDeallocator);
142 }
143 
144 /**
145  * gdome_xmlEntitiesHashCreate:
146  * @doc:  Document that own notations
147  *
148  * Create a gdome entities hash joining external and internal entities hash
149  * of the Document specified.
150  * Returns: a gdome entities hash.
151  */
152 xmlHashTable *
gdome_xmlEntitiesHashCreate(xmlDoc * doc)153 gdome_xmlEntitiesHashCreate (xmlDoc *doc) {
154 	xmlHashTable *ret = NULL;
155   hashIterator iter;
156 
157 	if (doc == NULL)
158 		return NULL;
159 
160 	if ((doc->extSubset != NULL && doc->extSubset->entities != NULL) ||
161 			(doc->intSubset != NULL && doc->intSubset->entities != NULL)) {
162 		ret = xmlHashCreate(0);
163 		iter.doc = doc;
164 		iter.ht = ret;
165 	}
166 
167 	if (doc->extSubset != NULL && doc->extSubset->entities != NULL)
168 		xmlHashScan(doc->extSubset->entities, entitiesHashScanner, &iter);
169 	if (doc->intSubset != NULL && doc->intSubset->entities != NULL)
170 		xmlHashScan(doc->intSubset->entities, entitiesHashScanner, &iter);
171 
172 	return ret;
173 }
174 
175 /**
176  * gdome_xmlEntitiesHashFree:
177  * @ht:  HashTable to free
178  *
179  * Free the Entities HashTable specified.
180  */
181 void
gdome_xmlEntitiesHashFree(xmlHashTable * ht)182 gdome_xmlEntitiesHashFree (xmlHashTable *ht) {
183   xmlHashFree (ht, NULL);
184 }
185