|
Mixe for Privacy and Anonymity in the Internet
|
00001 /* 00002 Copyright (c) 2000, The JAP-Team 00003 All rights reserved. 00004 Redistribution and use in source and binary forms, with or without modification, 00005 are permitted provided that the following conditions are met: 00006 00007 - Redistributions of source code must retain the above copyright notice, 00008 this list of conditions and the following disclaimer. 00009 00010 - Redistributions in binary form must reproduce the above copyright notice, 00011 this list of conditions and the following disclaimer in the documentation and/or 00012 other materials provided with the distribution. 00013 00014 - Neither the name of the University of Technology Dresden, Germany nor the names of its contributors 00015 may be used to endorse or promote products derived from this software without specific 00016 prior written permission. 00017 00018 00019 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS 00020 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 00021 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS 00022 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00023 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 00024 OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 00025 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 00026 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00027 */ 00028 #include "../StdAfx.h" 00029 #ifndef ONLY_LOCAL_PROXY 00030 #include "DOM_Output.hpp" 00031 00032 00033 static const XMLCh gEndElement[] = { chOpenAngle, chForwardSlash, chNull }; 00034 00035 00036 const XMLCh DOM_Output::m_UTF8[6] = 00037 { 00038 chLatin_U, chLatin_T,chLatin_F, chDash,chDigit_8, chNull 00039 }; 00040 00041 const XMLCh DOM_Output::m_1_0[4] = 00042 { 00043 chDigit_1,chPeriod,chDigit_0, chNull 00044 }; 00045 00046 const XMLCh DOM_Output::m_XML[41] = 00047 { 00048 chOpenAngle,chQuestion,chLatin_x,chLatin_m,chLatin_l,chSpace, //<?xml 00049 chLatin_v,chLatin_e,chLatin_r,chLatin_s,chLatin_i,chLatin_o,chLatin_n,chEqual, //version= 00050 chDoubleQuote,chDigit_1,chPeriod,chDigit_0,chDoubleQuote,chSpace, //"1.0" 00051 chLatin_e,chLatin_n,chLatin_c,chLatin_o,chLatin_d,chLatin_i,chLatin_n,chLatin_g,chEqual, //encoding= 00052 chDoubleQuote,chLatin_U, chLatin_T,chLatin_F, chDash,chDigit_8, chDoubleQuote, //"UTF-8" 00053 chQuestion,chCloseAngle,chCR,chLF,chNull 00054 }; 00055 00056 00057 /*XMLFormatter& operator<< (XMLFormatter& strm, const DOMString& s) 00058 { 00059 unsigned int lent = s.length(); 00060 00061 if (lent <= 0) 00062 return strm; 00063 00064 XMLCh* buf = new XMLCh[lent + 1]; 00065 XMLString::copyNString(buf, s.rawBuffer(), lent); 00066 buf[lent] = 0; 00067 strm << buf; 00068 delete [] buf; 00069 return strm; 00070 } 00071 */ 00072 00080 SINT32 DOM_Output::dumpNode(const DOMNode* toWrite,bool bCanonical) 00081 { 00082 if(toWrite==0) 00083 return E_UNKNOWN; 00084 // Get the name and value out for convenience 00085 const XMLCh* pNodeName = toWrite->getNodeName(); 00086 00087 switch (toWrite->getNodeType()) 00088 { 00089 case DOMNode::TEXT_NODE: 00090 { 00091 const XMLCh* pNodeValue = toWrite->getNodeValue(); 00092 if(!bCanonical) 00093 { 00094 m_pFormatter->formatBuf(pNodeValue,XMLString::stringLen(pNodeValue),XMLFormatter::CharEscapes); 00095 } 00096 else //strip whitespaces... 00097 { 00098 XMLCh* pText=XMLString::replicate(pNodeValue); 00099 XMLString::trim(pText); 00100 char* tmpStr=XMLString::transcode(pText); 00101 m_pFormatter->formatBuf(pText,XMLString::stringLen(pText),XMLFormatter::CharEscapes); 00102 XMLString::release(&pText); 00103 XMLString::release(&tmpStr); 00104 } 00105 break; 00106 } 00107 00108 00109 /* case DOM_Node::PROCESSING_INSTRUCTION_NODE : 00110 { 00111 *gFormatter << XMLFormatter::NoEscapes << gStartPI << nodeName; 00112 if (lent > 0) 00113 { 00114 *gFormatter << chSpace << nodeValue; 00115 } 00116 *gFormatter << XMLFormatter::NoEscapes << gEndPI; 00117 break; 00118 } 00119 */ 00120 00121 case DOMNode::DOCUMENT_NODE : 00122 *m_pFormatter<<XMLFormatter::NoEscapes<<m_XML; 00123 case DOMNode::DOCUMENT_FRAGMENT_NODE : 00124 { 00125 00126 DOMNode* pChild = toWrite->getFirstChild(); 00127 while( pChild != NULL) 00128 { 00129 dumpNode(pChild,bCanonical); 00130 // add linefeed in requested output encoding 00131 if(!bCanonical) 00132 *m_pFormatter << chLF; 00133 pChild = pChild->getNextSibling(); 00134 } 00135 break; 00136 } 00137 00138 00139 case DOMNode::ELEMENT_NODE : 00140 { 00141 // The name has to be representable without any escapes 00142 *m_pFormatter << XMLFormatter::NoEscapes 00143 << chOpenAngle << pNodeName; 00144 00145 // Output the element start tag. 00146 00147 // Output any attributes on this element in lexicograhpical order 00148 DOMNamedNodeMap* pAttributes = toWrite->getAttributes(); 00149 UINT32 attrCount = pAttributes->getLength(); 00150 const XMLCh** attr_names=NULL; 00151 UINT32* sort_indices=NULL; 00152 if(attrCount>0) 00153 { 00154 attr_names=new const XMLCh*[attrCount]; 00155 sort_indices=new UINT32[attrCount]; 00156 for(UINT32 i=0;i<attrCount;i++) 00157 { 00158 DOMNode* pAttribute = pAttributes->item(i); 00159 attr_names[i]=pAttribute->getNodeName(); 00160 sort_indices[i]=i; 00161 } 00162 //now sort them 00163 if(attrCount>1) 00164 { 00165 for(UINT32 i=0;i<attrCount;i++) 00166 { 00167 const XMLCh *akt=attr_names[sort_indices[i]]; 00168 for(UINT32 j=i+1;j<attrCount;j++) 00169 { 00170 const XMLCh* tmp=attr_names[sort_indices[j]]; 00171 if(XMLString::compareString(akt,tmp)>0) 00172 { 00173 UINT32 t=sort_indices[i]; 00174 sort_indices[i]=sort_indices[j]; 00175 sort_indices[j]=t; 00176 akt=tmp; 00177 } 00178 } 00179 } 00180 } 00181 } 00182 00183 for (UINT32 i = 0; i < attrCount; i++) 00184 { 00185 //delete[] attr_names[i]; 00186 DOMNode* pAttribute = pAttributes->item(sort_indices[i]); 00187 00188 // 00189 // Again the name has to be completely representable. But the 00190 // attribute can have refs and requires the attribute style 00191 // escaping. 00192 // 00193 *m_pFormatter << XMLFormatter::NoEscapes 00194 << chSpace << pAttribute->getNodeName() 00195 << chEqual << chDoubleQuote 00196 << XMLFormatter::AttrEscapes 00197 << pAttribute->getNodeValue() 00198 << XMLFormatter::NoEscapes 00199 << chDoubleQuote; 00200 } 00201 *m_pFormatter << XMLFormatter::NoEscapes << chCloseAngle; 00202 00203 delete[] attr_names; 00204 attr_names = NULL; 00205 delete[] sort_indices; 00206 sort_indices = NULL; 00207 00208 // 00209 // Test for the presence of children, which includes both 00210 // text content and nested elements. 00211 // 00212 DOMNode* pChild = toWrite->getFirstChild(); 00213 while( pChild != NULL) 00214 { 00215 dumpNode(pChild,bCanonical); 00216 pChild = pChild->getNextSibling(); 00217 } 00218 00219 *m_pFormatter << XMLFormatter::NoEscapes << gEndElement 00220 << pNodeName << chCloseAngle; 00221 break; 00222 } 00223 00224 /* 00225 case DOM_Node::ENTITY_REFERENCE_NODE: 00226 { 00227 DOM_Node child; 00228 #if 0 00229 for (child = toWrite.getFirstChild(); 00230 child != 0; 00231 child = child.getNextSibling()) 00232 { 00233 dumpNode(child); 00234 } 00235 #else 00236 // 00237 // Instead of printing the refernece tree 00238 // we'd output the actual text as it appeared in the xml file. 00239 // This would be the case when -e option was chosen 00240 // 00241 m_Formatter << XMLFormatter::NoEscapes << chAmpersand 00242 << nodeName << chSemiColon; 00243 #endif 00244 break; 00245 } 00246 00247 00248 case DOM_Node::CDATA_SECTION_NODE: 00249 { 00250 m_Formatter << XMLFormatter::NoEscapes << gStartCDATA 00251 << nodeValue << gEndCDATA; 00252 break; 00253 } 00254 00255 00256 case DOM_Node::COMMENT_NODE: 00257 { 00258 m_Formatter << XMLFormatter::NoEscapes << gStartComment 00259 << nodeValue << gEndComment; 00260 break; 00261 } 00262 00263 00264 case DOM_Node::DOCUMENT_TYPE_NODE: 00265 { 00266 DOM_DocumentType doctype = (DOM_DocumentType &)toWrite;; 00267 00268 m_Formatter << XMLFormatter::NoEscapes << gStartDoctype 00269 << nodeName; 00270 00271 DOMString id = doctype.getPublicId(); 00272 if (id != 0) 00273 { 00274 m_Formatter << XMLFormatter::NoEscapes << chSpace << gPublic 00275 << id << chDoubleQuote; 00276 id = doctype.getSystemId(); 00277 if (id != 0) 00278 { 00279 m_Formatter << XMLFormatter::NoEscapes << chSpace 00280 << chDoubleQuote << id << chDoubleQuote; 00281 } 00282 } 00283 else 00284 { 00285 id = doctype.getSystemId(); 00286 if (id != 0) 00287 { 00288 m_Formatter << XMLFormatter::NoEscapes << chSpace << gSystem 00289 << id << chDoubleQuote; 00290 } 00291 } 00292 00293 id = doctype.getInternalSubset(); 00294 if (id !=0) 00295 m_Formatter << XMLFormatter::NoEscapes << chOpenSquare 00296 << id << chCloseSquare; 00297 00298 m_Formatter << XMLFormatter::NoEscapes << chCloseAngle; 00299 break; 00300 } 00301 00302 00303 case DOM_Node::ENTITY_NODE: 00304 { 00305 m_Formatter << XMLFormatter::NoEscapes << gStartEntity 00306 << nodeName; 00307 00308 DOMString id = ((DOM_Entity &)toWrite).getPublicId(); 00309 if (id != 0) 00310 m_Formatter << XMLFormatter::NoEscapes << gPublic 00311 << id << chDoubleQuote; 00312 00313 id = ((DOM_Entity &)toWrite).getSystemId(); 00314 if (id != 0) 00315 m_Formatter << XMLFormatter::NoEscapes << gSystem 00316 << id << chDoubleQuote; 00317 00318 id = ((DOM_Entity &)toWrite).getNotationName(); 00319 if (id != 0) 00320 m_Formatter << XMLFormatter::NoEscapes << gNotation 00321 << id << chDoubleQuote; 00322 00323 m_Formatter << XMLFormatter::NoEscapes << chCloseAngle << chLF; 00324 00325 break; 00326 } 00327 00328 00329 case DOM_Node::XML_DECL_NODE: 00330 { 00331 DOMString str; 00332 00333 m_Formatter << gXMLDecl1 << ((DOM_XMLDecl &)toWrite).getVersion(); 00334 00335 m_Formatter << gXMLDecl2 << gEncodingName; 00336 00337 str = ((DOM_XMLDecl &)toWrite).getStandalone(); 00338 if (str != 0) 00339 m_Formatter << gXMLDecl3 << str; 00340 00341 m_Formatter << gXMLDecl4; 00342 00343 break; 00344 } 00345 00346 */ 00347 default: 00348 return E_UNKNOWN; 00349 } 00350 return E_SUCCESS; 00351 } 00352 00353 00354 00355 // --------------------------------------------------------------------------- 00356 // ostream << DOMString 00357 // 00358 // Stream out a DOM string. Doing this requires that we first transcode 00359 // to char * form in the default code page for the system 00360 // --------------------------------------------------------------------------- 00361 /*ostream& operator<< (ostream& target, const DOMString& s) 00362 { 00363 char *p = s.transcode(); 00364 target << p; 00365 delete [] p; 00366 return target; 00367 }*/ 00368 #endif //ONLY_LOCAL_PROXY
1.7.6.1