Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <com/sun/star/xml/xpath/XPathObjectType.hpp>
31 : : #include <com/sun/star/xml/dom/XNode.hpp>
32 : : #include <com/sun/star/xml/dom/XText.hpp>
33 : : #include <com/sun/star/xml/dom/XNodeList.hpp>
34 : : #include <com/sun/star/xml/dom/NodeType.hpp>
35 : :
36 : : #include <rtl/ustrbuf.hxx>
37 : : #include <rtl/strbuf.hxx>
38 : : #include <comphelper/processfactory.hxx>
39 : : #include <comphelper/string.hxx>
40 : :
41 : : #include <stdio.h>
42 : :
43 : : #include "serialization_urlencoded.hxx"
44 : :
45 : : using namespace CSS::uno;
46 : : using namespace CSS::io;
47 : : using namespace CSS::xml::xpath;
48 : : using namespace CSS::xml::dom;
49 : :
50 : 0 : CSerializationURLEncoded::CSerializationURLEncoded()
51 : : : m_aFactory(comphelper::getProcessServiceFactory())
52 [ # # ]: 0 : , m_aPipe(Reference< XOutputStream > (m_aFactory->createInstance(
53 [ # # ][ # # ]: 0 : ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.io.Pipe") ) ), UNO_QUERY))
[ # # ][ # # ]
54 : : {
55 : 0 : }
56 : :
57 : :
58 : : /*
59 : : rfc2396
60 : : reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" |
61 : : "$" | ","
62 : : mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"
63 : : unreserved = alphanum | mark
64 : : */
65 : 0 : sal_Bool CSerializationURLEncoded::is_unreserved(sal_Char c)
66 : : {
67 [ # # ]: 0 : if (comphelper::string::isalnumAscii(c))
68 : 0 : return sal_True;
69 [ # # ]: 0 : switch (c) {
70 : : case '-':
71 : : case '_':
72 : : case '.':
73 : : case '!':
74 : : case '~':
75 : : case '*':
76 : : case '\'':
77 : : case '(':
78 : : case ')':
79 : 0 : return sal_True;
80 : : }
81 : 0 : return sal_False;
82 : : }
83 : 0 : void CSerializationURLEncoded::encode_and_append(const ::rtl::OUString& aString, ::rtl::OStringBuffer& aBuffer)
84 : : {
85 [ # # ]: 0 : ::rtl::OString utf8String = OUStringToOString(aString, RTL_TEXTENCODING_UTF8);
86 : 0 : const sal_uInt8 *pString = reinterpret_cast< const sal_uInt8 * >( utf8String.getStr() );
87 : 0 : sal_Char tmpChar[4]; tmpChar[3] = 0;
88 : :
89 [ # # ]: 0 : while( *pString != 0)
90 : : {
91 [ # # ]: 0 : if( *pString < 0x80 )
92 : : {
93 [ # # ][ # # ]: 0 : if ( is_unreserved(*pString) ) {
94 [ # # ]: 0 : aBuffer.append(*pString);
95 [ # # ]: 0 : } else if (*pString == 0x20) {
96 [ # # ]: 0 : aBuffer.append('+');
97 [ # # ][ # # ]: 0 : } else if (*pString == 0x0d && *(pString+1) == 0x0a) {
98 [ # # ]: 0 : aBuffer.append("%0D%0A");
99 : 0 : pString++;
100 [ # # ]: 0 : } else if (*pString == 0x0a) {
101 [ # # ]: 0 : aBuffer.append("%0D%0A");
102 : : } else {
103 : 0 : snprintf(tmpChar, 3, "%%%X", *pString % 0x100);
104 [ # # ]: 0 : aBuffer.append(tmpChar);
105 : : }
106 : : } else {
107 : 0 : snprintf(tmpChar, 3, "%%%X", *pString % 0x100);
108 [ # # ]: 0 : aBuffer.append(tmpChar);
109 [ # # ]: 0 : while (*pString >= 0x80) {
110 : : // continuation...
111 : 0 : pString++;
112 : 0 : snprintf(tmpChar, 3, "%%%X", *pString % 0x100);
113 [ # # ]: 0 : aBuffer.append(tmpChar);
114 : : }
115 : : }
116 : 0 : pString++;
117 : 0 : }
118 : 0 : }
119 : :
120 : 0 : void CSerializationURLEncoded::serialize_node(const Reference< XNode >& aNode)
121 : : {
122 : : // serialize recursive
123 : : // every element node E that has a text child T will be serialized in document order
124 : : // <E1>T1<E2>T2</E2></E1><E3>T3</E3> -> E1=T2&E2=T2&E3=T3 (En := local name)
125 : :
126 : : // this node
127 [ # # ][ # # ]: 0 : Reference< XNodeList > aChildList = aNode->getChildNodes();
128 : 0 : Reference< XNode > aChild;
129 : : // is this an element node?
130 [ # # ][ # # ]: 0 : if (aNode->getNodeType() == NodeType_ELEMENT_NODE)
[ # # ]
131 : : {
132 [ # # ][ # # ]: 0 : ::rtl::OUString aName = aNode->getNodeName();
133 : : // find any text children
134 : 0 : ::rtl::OUStringBuffer aValue;
135 : 0 : Reference< XText > aText;
136 [ # # ][ # # ]: 0 : for(sal_Int32 i=0; i < aChildList->getLength(); i++)
[ # # ]
137 : : {
138 [ # # ][ # # ]: 0 : aChild = aChildList->item(i);
[ # # ]
139 [ # # ][ # # ]: 0 : if (aChild->getNodeType() == NodeType_TEXT_NODE)
[ # # ]
140 : : {
141 [ # # ][ # # ]: 0 : aText = Reference< XText >(aChild, UNO_QUERY);
142 [ # # ][ # # ]: 0 : aValue.append(aText->getData());
[ # # ]
143 : : }
144 : : }
145 : :
146 : : // found anything?
147 [ # # ]: 0 : if (aValue.getLength() > 0)
148 : : {
149 [ # # ]: 0 : ::rtl::OUString aUnencValue = aValue.makeStringAndClear();
150 : 0 : ::rtl::OStringBuffer aEncodedBuffer;
151 [ # # ]: 0 : encode_and_append(aName, aEncodedBuffer);
152 [ # # ]: 0 : aEncodedBuffer.append("=");
153 [ # # ]: 0 : encode_and_append(aUnencValue, aEncodedBuffer);
154 [ # # ]: 0 : aEncodedBuffer.append("&");
155 : 0 : sal_Int8 *pData = (sal_Int8*)aEncodedBuffer.getStr();
156 [ # # ]: 0 : Sequence< sal_Int8 > sData(pData, aEncodedBuffer.getLength());
157 [ # # ][ # # ]: 0 : m_aPipe->writeBytes(sData);
[ # # ]
158 : 0 : }
159 : : }
160 : :
161 : : // element children...
162 [ # # ][ # # ]: 0 : for(sal_Int32 i=0; i < aChildList->getLength(); i++)
[ # # ]
163 : : {
164 [ # # ][ # # ]: 0 : aChild = aChildList->item(i);
[ # # ]
165 : : // if this is an element node, it might be a candidate for serialization
166 [ # # ][ # # ]: 0 : if (aChild.is() && aChild->getNodeType() == NodeType_ELEMENT_NODE)
[ # # ][ # # ]
[ # # ]
167 [ # # ]: 0 : serialize_node(aChild);
168 : 0 : }
169 : 0 : }
170 : :
171 : 0 : void CSerializationURLEncoded::serialize()
172 : : {
173 : :
174 : : // output stream to the pipe buffer
175 [ # # ]: 0 : Reference< XOutputStream > out(m_aPipe, UNO_QUERY);
176 : :
177 [ # # ][ # # ]: 0 : CSS::uno::Reference< CSS::xml::dom::XNode > cur = m_aFragment->getFirstChild();
178 [ # # ]: 0 : while (cur.is())
179 : : {
180 [ # # ]: 0 : serialize_node(cur);
181 [ # # ][ # # ]: 0 : cur = cur->getNextSibling();
[ # # ]
182 : : }
183 [ # # ][ # # ]: 0 : m_aPipe->closeOutput();
184 : 0 : }
185 : :
186 : 0 : Reference< XInputStream > CSerializationURLEncoded::getInputStream()
187 : : {
188 : 0 : return Reference< XInputStream >(m_aPipe, UNO_QUERY);
189 : : }
190 : :
191 : :
192 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|