Mixe for Privacy and Anonymity in the Internet
DOM_Output.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2000, The JAP-Team
3 All rights reserved.
4 Redistribution and use in source and binary forms, with or without modification,
5 are permitted provided that the following conditions are met:
6 
7  - Redistributions of source code must retain the above copyright notice,
8  this list of conditions and the following disclaimer.
9 
10  - Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation and/or
12  other materials provided with the distribution.
13 
14  - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors
15  may be used to endorse or promote products derived from this software without specific
16  prior written permission.
17 
18 
19 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
20 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS
22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
24 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE
27 */
28 #include "../StdAfx.h"
29 #if !defined ONLY_LOCAL_PROXY || defined INCLUDE_MIDDLE_MIX
30 #include "DOM_Output.hpp"
31 
32 
33 static const XMLCh gEndElement[] = { chOpenAngle, chForwardSlash, chNull };
34 
35 
36 const XMLCh DOM_Output::m_UTF8[6] =
37  {
38  chLatin_U, chLatin_T,chLatin_F, chDash,chDigit_8, chNull
39  };
40 
41 const XMLCh DOM_Output::m_1_0[4] =
42  {
43  chDigit_1,chPeriod,chDigit_0, chNull
44  };
45 
46 const XMLCh DOM_Output::m_XML[41] =
47 {
48  chOpenAngle,chQuestion,chLatin_x,chLatin_m,chLatin_l,chSpace, //<?xml
49  chLatin_v,chLatin_e,chLatin_r,chLatin_s,chLatin_i,chLatin_o,chLatin_n,chEqual, //version=
50  chDoubleQuote,chDigit_1,chPeriod,chDigit_0,chDoubleQuote,chSpace, //"1.0"
51  chLatin_e,chLatin_n,chLatin_c,chLatin_o,chLatin_d,chLatin_i,chLatin_n,chLatin_g,chEqual, //encoding=
52  chDoubleQuote,chLatin_U, chLatin_T,chLatin_F, chDash,chDigit_8, chDoubleQuote, //"UTF-8"
53  chSpace,chQuestion, chCloseAngle, chLF, chNull
54 };
55 
56 
57 /*XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s)
58  {
59  unsigned int lent = s.length();
60 
61  if (lent <= 0)
62  return strm;
63 
64  XMLCh* buf = new XMLCh[lent + 1];
65  XMLString::copyNString(buf, s.rawBuffer(), lent);
66  buf[lent] = 0;
67  strm << buf;
68  delete [] buf;
69  return strm;
70  }
71 */
72 
80 SINT32 DOM_Output::dumpNode(const DOMNode* toWrite,bool bCanonical)
81  {
82  if(toWrite==0)
83  return E_UNKNOWN;
84  // Get the name and value out for convenience
85  const XMLCh* pNodeName = toWrite->getNodeName();
86 
87  switch (toWrite->getNodeType())
88  {
89  case DOMNode::TEXT_NODE:
90  {
91  const XMLCh* pNodeValue = toWrite->getNodeValue();
92  if (pNodeValue == NULL)
93  break;
94  if(!bCanonical)
95  {
96  m_pFormatter->formatBuf(pNodeValue,XMLString::stringLen(pNodeValue),XMLFormatter::CharEscapes);
97  }
98  else //strip whitespaces...
99  {
100  XMLCh* pText=XMLString::replicate(pNodeValue);
101  XMLString::trim(pText);
102  char* tmpStr=XMLString::transcode(pText);
103  m_pFormatter->formatBuf(pText,XMLString::stringLen(pText),XMLFormatter::CharEscapes);
104  XMLString::release(&pText);
105  XMLString::release(&tmpStr);
106  }
107  break;
108  }
109 
110 
111  /* case DOM_Node::PROCESSING_INSTRUCTION_NODE :
112  {
113  *gFormatter << XMLFormatter::NoEscapes << gStartPI << nodeName;
114  if (lent > 0)
115  {
116  *gFormatter << chSpace << nodeValue;
117  }
118  *gFormatter << XMLFormatter::NoEscapes << gEndPI;
119  break;
120  }
121 */
122 
123  case DOMNode::DOCUMENT_NODE :
124  *m_pFormatter<<XMLFormatter::NoEscapes<<m_XML;
125  case DOMNode::DOCUMENT_FRAGMENT_NODE :
126  {
127 
128  DOMNode* pChild = toWrite->getFirstChild();
129  while( pChild != NULL)
130  {
131  dumpNode(pChild,bCanonical);
132  // add linefeed in requested output encoding
133  if(!bCanonical)
134  *m_pFormatter << chLF;
135  pChild = pChild->getNextSibling();
136  }
137  break;
138  }
139 
140 
141  case DOMNode::ELEMENT_NODE :
142  {
143  // The name has to be representable without any escapes
144  *m_pFormatter << XMLFormatter::NoEscapes
145  << chOpenAngle << pNodeName;
146 
147  // Output the element start tag.
148 
149  // Output any attributes on this element in lexicograhpical order
150  DOMNamedNodeMap* pAttributes = toWrite->getAttributes();
151  UINT32 attrCount = pAttributes->getLength();
152  const XMLCh** attr_names=NULL;
153  UINT32* sort_indices=NULL;
154  if(attrCount>0)
155  {
156  attr_names=new const XMLCh*[attrCount];
157  sort_indices=new UINT32[attrCount];
158  for(UINT32 i=0;i<attrCount;i++)
159  {
160  DOMNode* pAttribute = pAttributes->item(i);
161  attr_names[i]=pAttribute->getNodeName();
162  sort_indices[i]=i;
163  }
164  //now sort them
165  if(attrCount>1)
166  {
167  for(UINT32 i=0;i<attrCount;i++)
168  {
169  const XMLCh *akt=attr_names[sort_indices[i]];
170  for(UINT32 j=i+1;j<attrCount;j++)
171  {
172  const XMLCh* tmp=attr_names[sort_indices[j]];
173  if(XMLString::compareString(akt,tmp)>0)
174  {
175  UINT32 t=sort_indices[i];
176  sort_indices[i]=sort_indices[j];
177  sort_indices[j]=t;
178  akt=tmp;
179  }
180  }
181  }
182  }
183  }
184 
185  for (UINT32 i = 0; i < attrCount; i++)
186  {
187  //delete[] attr_names[i];
188  DOMNode* pAttribute = pAttributes->item(sort_indices[i]);
189 
190  //
191  // Again the name has to be completely representable. But the
192  // attribute can have refs and requires the attribute style
193  // escaping.
194  //
195  *m_pFormatter << XMLFormatter::NoEscapes
196  << chSpace << pAttribute->getNodeName()
197  << chEqual << chDoubleQuote
198  << XMLFormatter::AttrEscapes
199  << pAttribute->getNodeValue()
200  << XMLFormatter::NoEscapes
201  << chDoubleQuote;
202  }
203  *m_pFormatter << XMLFormatter::NoEscapes << chCloseAngle;
204 
205  delete[] attr_names;
206  attr_names = NULL;
207  delete[] sort_indices;
208  sort_indices = NULL;
209 
210  //
211  // Test for the presence of children, which includes both
212  // text content and nested elements.
213  //
214  DOMNode* pChild = toWrite->getFirstChild();
215  while( pChild != NULL)
216  {
217  dumpNode(pChild,bCanonical);
218  pChild = pChild->getNextSibling();
219  }
220 
221  *m_pFormatter << XMLFormatter::NoEscapes << gEndElement
222  << pNodeName << chCloseAngle;
223  break;
224  }
225 
226 /*
227  case DOM_Node::ENTITY_REFERENCE_NODE:
228  {
229  DOM_Node child;
230 #if 0
231  for (child = toWrite.getFirstChild();
232  child != 0;
233  child = child.getNextSibling())
234  {
235  dumpNode(child);
236  }
237 #else
238  //
239  // Instead of printing the refernece tree
240  // we'd output the actual text as it appeared in the xml file.
241  // This would be the case when -e option was chosen
242  //
243  m_Formatter << XMLFormatter::NoEscapes << chAmpersand
244  << nodeName << chSemiColon;
245 #endif
246  break;
247  }
248 
249 
250  case DOM_Node::CDATA_SECTION_NODE:
251  {
252  m_Formatter << XMLFormatter::NoEscapes << gStartCDATA
253  << nodeValue << gEndCDATA;
254  break;
255  }
256 
257 
258  case DOM_Node::COMMENT_NODE:
259  {
260  m_Formatter << XMLFormatter::NoEscapes << gStartComment
261  << nodeValue << gEndComment;
262  break;
263  }
264 
265 
266  case DOM_Node::DOCUMENT_TYPE_NODE:
267  {
268  DOM_DocumentType doctype = (DOM_DocumentType &)toWrite;;
269 
270  m_Formatter << XMLFormatter::NoEscapes << gStartDoctype
271  << nodeName;
272 
273  DOMString id = doctype.getPublicId();
274  if (id != 0)
275  {
276  m_Formatter << XMLFormatter::NoEscapes << chSpace << gPublic
277  << id << chDoubleQuote;
278  id = doctype.getSystemId();
279  if (id != 0)
280  {
281  m_Formatter << XMLFormatter::NoEscapes << chSpace
282  << chDoubleQuote << id << chDoubleQuote;
283  }
284  }
285  else
286  {
287  id = doctype.getSystemId();
288  if (id != 0)
289  {
290  m_Formatter << XMLFormatter::NoEscapes << chSpace << gSystem
291  << id << chDoubleQuote;
292  }
293  }
294 
295  id = doctype.getInternalSubset();
296  if (id !=0)
297  m_Formatter << XMLFormatter::NoEscapes << chOpenSquare
298  << id << chCloseSquare;
299 
300  m_Formatter << XMLFormatter::NoEscapes << chCloseAngle;
301  break;
302  }
303 
304 
305  case DOM_Node::ENTITY_NODE:
306  {
307  m_Formatter << XMLFormatter::NoEscapes << gStartEntity
308  << nodeName;
309 
310  DOMString id = ((DOM_Entity &)toWrite).getPublicId();
311  if (id != 0)
312  m_Formatter << XMLFormatter::NoEscapes << gPublic
313  << id << chDoubleQuote;
314 
315  id = ((DOM_Entity &)toWrite).getSystemId();
316  if (id != 0)
317  m_Formatter << XMLFormatter::NoEscapes << gSystem
318  << id << chDoubleQuote;
319 
320  id = ((DOM_Entity &)toWrite).getNotationName();
321  if (id != 0)
322  m_Formatter << XMLFormatter::NoEscapes << gNotation
323  << id << chDoubleQuote;
324 
325  m_Formatter << XMLFormatter::NoEscapes << chCloseAngle << chLF;
326 
327  break;
328  }
329 
330 
331  case DOM_Node::XML_DECL_NODE:
332  {
333  DOMString str;
334 
335  m_Formatter << gXMLDecl1 << ((DOM_XMLDecl &)toWrite).getVersion();
336 
337  m_Formatter << gXMLDecl2 << gEncodingName;
338 
339  str = ((DOM_XMLDecl &)toWrite).getStandalone();
340  if (str != 0)
341  m_Formatter << gXMLDecl3 << str;
342 
343  m_Formatter << gXMLDecl4;
344 
345  break;
346  }
347 
348 */
349  default:
350  return E_UNKNOWN;
351  }
352  return E_SUCCESS;
353 }
354 
355 
356 
357 // ---------------------------------------------------------------------------
358 // ostream << DOMString
359 //
360 // Stream out a DOM string. Doing this requires that we first transcode
361 // to char * form in the default code page for the system
362 // ---------------------------------------------------------------------------
363 /*ostream& operator<< (ostream& target, const DOMString& s)
364 {
365  char *p = s.transcode();
366  target << p;
367  delete [] p;
368  return target;
369 }*/
370 #endif //ONLY_LOCAL_PROXY
signed int SINT32
Definition: basetypedefs.h:132
unsigned int UINT32
Definition: basetypedefs.h:131
static const XMLCh m_UTF8[6]
Definition: DOM_Output.hpp:276
XMLFormatter * m_pFormatter
Definition: DOM_Output.hpp:273
static const XMLCh m_XML[41]
Definition: DOM_Output.hpp:275
static const XMLCh m_1_0[4]
Definition: DOM_Output.hpp:277
SINT32 dumpNode(const DOMNode *toWrite, bool bCanonical)
Dumps a Node of an XML Document.
Definition: DOM_Output.cpp:80
const SINT32 E_SUCCESS
Definition: errorcodes.hpp:2
#define E_UNKNOWN
Definition: errorcodes.hpp:3