Mixe for Privacy and Anonymity in the Internet
DOM_Output.cpp
Go to the documentation of this file.
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