1/******************************************************************/
2/* Implementation of XML document processing using PdbXML. */
3/* Author: Olivier Bertrand 2007-2017 */
4/******************************************************************/
5#include "my_global.h"
6#include "global.h"
7#include "plgdbsem.h"
8#include "block.h"
9#include "plgxml.h"
10
11#if !defined(DOMDOC_SUPPORT)
12PXDOC GetDomDoc(PGLOBAL g, char *nsl, char *nsdf,
13 char *enc, PFBLOCK fp)
14 {
15 strcpy(g->Message, MSG(DOM_NOT_SUPP));
16 return NULL;
17 } // end of GetDomDoc
18#endif // !DOMDOC_SUPPORT
19
20#ifndef LIBXML2_SUPPORT
21PXDOC GetLibxmlDoc(PGLOBAL g, char *nsl, char *nsdf,
22 char *enc, PFBLOCK fp)
23 {
24 strcpy(g->Message, "libxml2 not supported");
25 return NULL;
26 } // end of GetLibxmlDoc
27#endif // LIBXML2_SUPPORT
28
29/******************************************************************/
30/* XMLDOCUMENT constructor. */
31/******************************************************************/
32XMLDOCUMENT::XMLDOCUMENT(char *nsl, char *nsdf, char *enc)
33{
34#if defined(ZIP_SUPPORT)
35 zip = NULL;
36#else // !ZIP_SUPPORT
37 zip = false;
38#endif // !ZIP_SUPPORT
39 Namespaces = NULL;
40 Encoding = enc;
41 Nslist = nsl;
42 DefNs = nsdf;
43} // end of XMLDOCUMENT constructor
44
45/******************************************************************/
46/* Initialize zipped file processing. */
47/******************************************************************/
48bool XMLDOCUMENT::InitZip(PGLOBAL g, PCSZ entry)
49{
50#if defined(ZIP_SUPPORT)
51 bool mul = (entry) ? strchr(entry, '*') || strchr(entry, '?') : false;
52 zip = new(g) UNZIPUTL(entry, mul);
53 return zip == NULL;
54#else // !ZIP_SUPPORT
55 sprintf(g->Message, MSG(NO_FEAT_SUPPORT), "ZIP");
56 return true;
57#endif // !ZIP_SUPPORT
58} // end of InitZip
59
60/******************************************************************/
61/* Make the namespace structure list. */
62/******************************************************************/
63char* XMLDOCUMENT::GetMemDoc(PGLOBAL g, char *fn)
64{
65#if defined(ZIP_SUPPORT)
66 return (zip->OpenTable(g, MODE_ANY, fn)) ? NULL : zip->memory;
67#else // !ZIP_SUPPORT
68 return NULL;
69#endif // !ZIP_SUPPORT
70} // end of GetMemDoc
71
72/******************************************************************/
73/* Make the namespace structure list. */
74/******************************************************************/
75bool XMLDOCUMENT::MakeNSlist(PGLOBAL g)
76{
77 char *prefix, *href, *next = Nslist;
78 PNS nsp, *ppns = &Namespaces;
79
80 while (next) {
81 // Skip spaces
82 while ((*next) == ' ')
83 next++;
84
85 if ((*next) == '\0')
86 break;
87
88 // Find prefix
89 prefix = next;
90 next = strchr(next, '=');
91
92 if (next == NULL) {
93 strcpy(g->Message, MSG(BAS_NS_LIST));
94 return true;
95 } // endif next
96
97 *(next++) = '\0';
98
99 // Find href
100 href = next;
101 next = strchr(next, ' ');
102
103 if (next != NULL)
104 *(next++) = '\0';
105
106 // Allocate and link NS structure
107 nsp = (PNS)PlugSubAlloc(g, NULL, sizeof(NS));
108 nsp->Next = NULL;
109 nsp->Prefix = prefix;
110 nsp->Uri = href;
111 *ppns = nsp;
112 ppns = &nsp->Next;
113 } // endwhile next
114
115 return false;
116 } // end of MakeNSlist
117
118/******************************************************************/
119/* Close ZIP file. */
120/******************************************************************/
121void XMLDOCUMENT::CloseZip(void)
122{
123#if defined(ZIP_SUPPORT)
124 if (zip) {
125 zip->close();
126 zip = NULL;
127 } // endif zip
128#endif // ZIP_SUPPORT
129} // end of CloseZip
130
131/******************************************************************/
132/* XMLNODE constructor. */
133/******************************************************************/
134XMLNODE::XMLNODE(PXDOC dp)
135 {
136 Doc = dp;
137 Next = NULL;
138 Children = NULL;
139 Buf = NULL;
140 Len = -1;
141 } // end of XMLNODE constructor
142
143/******************************************************************/
144/* Attach new node at the end of this node children list. */
145/******************************************************************/
146PXNODE XMLNODE::NewChild(PXNODE ncp)
147{
148 PXNODE np, *pnp = &Children;
149
150 for (np = *pnp; np; np = np->Next)
151 pnp = &np->Next;
152
153 *pnp = np;
154 return ncp;
155} // end of NewChild
156
157/******************************************************************/
158/* Delete a node from this node children list. */
159/******************************************************************/
160void XMLNODE::Delete(PXNODE dnp)
161 {
162 PXNODE *pnp = &Children;
163
164 for (PXNODE np = *pnp; np; np = np->Next)
165 if (np == dnp) {
166 *pnp = dnp->Next;
167 break;
168 } else
169 pnp = &np->Next;
170
171 } // end of Delete
172
173/******************************************************************/
174/* Store a string in Buf, enventually reallocating it. */
175/******************************************************************/
176char *XMLNODE::BufAlloc(PGLOBAL g, const char *p, int n)
177 {
178 if (Len < n) {
179 Len = n;
180 Buf = (char*)PlugSubAlloc(g, NULL, n + 1);
181 } // endif Len
182
183 *Buf = '\0';
184 return strncat(Buf, p, n);
185 } // end of BufAlloc
186