1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 #ifndef INCLUDED_SUB_SEQUENCE_HXX
25 #define INCLUDED_SUB_SEQUENCE_HXX
26 
27 #include <com/sun/star/uno/Sequence.hxx>
28 
29 #include <boost/shared_ptr.hpp>
30 #include <iostream>
31 #include <stdio.h>
32 #include <ctype.h>
33 #include "exceptions.hxx"
34 #include <WriterFilterDllApi.hxx>
35 #include <resourcemodel/OutputWithDepth.hxx>
36 
37 namespace writerfilter {
38 using namespace ::std;
39 
40 template <class T>
41 class SubSequence;
42 
43 template <typename T>
44 void dumpLine(OutputWithDepth<string> & o, SubSequence<T> & rSeq,
45               sal_uInt32 nOffset, sal_uInt32 nStep);
46 
47 template <class T>
48 class WRITERFILTER_DLLPUBLIC SubSequence
49 {
50     typedef boost::shared_ptr<com::sun::star::uno::Sequence<T> >
51     SequencePointer;
52 
53     SequencePointer mpSequence;
54     sal_uInt32 mnOffset;
55     sal_uInt32 mnCount;
56 
57 public:
58     typedef boost::shared_ptr<SubSequence> Pointer_t;
59 
SubSequence()60     SubSequence() : mpSequence(new ::com::sun::star::uno::Sequence<T>()),
61                     mnOffset(0), mnCount(0)
62     {
63     }
64 
SubSequence(SequencePointer pSequence,sal_uInt32 nOffset_,sal_uInt32 nCount_)65     SubSequence(SequencePointer pSequence, sal_uInt32 nOffset_,
66                 sal_uInt32 nCount_)
67         : mpSequence(pSequence), mnOffset(nOffset_), mnCount(nCount_)
68     {
69     }
70 
SubSequence(SequencePointer pSequence)71     SubSequence(SequencePointer pSequence)
72         : mpSequence(pSequence), mnOffset(0), mnCount(pSequence->getLength())
73     {
74     }
75 
SubSequence(const SubSequence & rSubSequence,sal_uInt32 nOffset_,sal_uInt32 nCount_)76     SubSequence(const SubSequence & rSubSequence, sal_uInt32 nOffset_,
77                 sal_uInt32 nCount_)
78         : mpSequence(rSubSequence.mpSequence),
79           mnOffset(rSubSequence.mnOffset + nOffset_),
80           mnCount(nCount_)
81     {
82     }
83 
SubSequence(const T * pStart,sal_uInt32 nCount_)84     SubSequence(const T * pStart, sal_uInt32 nCount_)
85         : mpSequence(new com::sun::star::uno::Sequence<T>(pStart, nCount_)),
86           mnOffset(0), mnCount(nCount_)
87     {
88     }
89 
SubSequence(sal_Int32 nCount_)90     SubSequence(sal_Int32 nCount_)
91         : mpSequence(new com::sun::star::uno::Sequence<T>(nCount_)), mnOffset(0),
92           mnCount(nCount_)
93     {
94     }
95 
getSequence()96     ::com::sun::star::uno::Sequence<T> & getSequence()
97     {
98         return *mpSequence;
99     }
100 
getSequence() const101     const ::com::sun::star::uno::Sequence<T> & getSequence() const
102     {
103         return *mpSequence;
104     }
105 
reset()106     void reset() {
107         mnOffset = 0;
108         mnCount = mpSequence->getLength();
109     }
110 
getOffset() const111     sal_uInt32 getOffset() const { return mnOffset; }
getCount() const112     sal_uInt32 getCount() const { return mnCount; }
113 
operator [](sal_uInt32 nIndex) const114     const T & operator[] (sal_uInt32 nIndex) const
115     {
116         if (mnOffset + nIndex >=
117             sal::static_int_cast<sal_uInt32>(mpSequence->getLength()))
118             throw ExceptionOutOfBounds("SubSequence::operator[]");
119 
120         return (*mpSequence)[mnOffset + nIndex];
121     }
122 
dump(ostream & o) const123     void dump(ostream & o) const
124     {
125         {
126             char sBuffer[256];
127 
128             snprintf(sBuffer, sizeof(sBuffer),
129                      "<sequence id='%p' offset='%lx' count='%lx'>",
130                      mpSequence.get(), mnOffset, mnCount);
131             o << sBuffer << endl;
132         }
133 
134         sal_uInt32 n = 0;
135         sal_uInt32 nStep = 16;
136 
137         while (n < getCount())
138         {
139             char sBuffer[256];
140 
141             o << "<line>";
142 
143             snprintf(sBuffer, 255, "%08lx: ", n);
144 
145             o << sBuffer;
146 
147             for (sal_uInt32 i = 0; i < nStep; i++)
148             {
149                 if (n + i < getCount())
150                 {
151                     snprintf(sBuffer, 255, "%02x ", operator[](n + i));
152                     o << sBuffer;
153                 }
154                 else
155                     o << "   ";
156 
157                 if (i % 8 == 7)
158                     o << " ";
159             }
160 
161             {
162                 for (sal_uInt32 i = 0; i < nStep; i++)
163                 {
164                     if (n + i < getCount())
165                     {
166                         unsigned char c =
167                             static_cast<unsigned char>(operator[](n + i));
168 
169 						if (c=='&')
170 							o << "&amp;";
171 						else if (c=='<')
172 							o << "&lt;";
173 						else if (c=='>')
174 							o << "&gt;";
175                         else if (c < 128 && isprint(c))
176                             o << c;
177                         else
178                             o << ".";
179                     }
180 
181                 }
182             }
183 
184             o << "</line>" << endl;
185 
186             n += nStep;
187         }
188 
189         o << "</sequence>" << endl;
190     }
191 
dump(OutputWithDepth<string> & o)192     void dump(OutputWithDepth<string> & o)
193     {
194         {
195             char sBuffer[256];
196 
197             snprintf(sBuffer, sizeof(sBuffer),
198                      "<sequence id='%p' offset='%" SAL_PRIxUINT32 "' count='%" SAL_PRIxUINT32 "'>",
199                      mpSequence.get(), mnOffset, mnCount);
200             o.addItem(sBuffer);
201         }
202 
203         sal_uInt32 n = 0;
204         sal_uInt32 nStep = 16;
205 
206         try
207         {
208             sal_uInt32 nCount = getCount();
209             while (n < nCount)
210             {
211                 sal_uInt32 nBytes = nCount - n;
212 
213                 if (nBytes > nStep)
214                     nBytes = nStep;
215 
216                 SubSequence<T> aSeq(*this, n, nBytes);
217                 dumpLine(o, aSeq, n, nStep);
218 
219                 n += nBytes;
220             }
221         }
222         catch (...)
223         {
224             o.addItem("<exception/>");
225         }
226 
227         o.addItem("</sequence>");
228     }
229 
toString() const230     string toString() const
231     {
232         sal_uInt32 n = 0;
233         sal_uInt32 nStep = 16;
234 
235         string sResult;
236 
237         while (n < getCount())
238         {
239             char sBuffer[256];
240 
241             snprintf(sBuffer, 255, "<line>%08" SAL_PRIxUINT32 ": ", n);
242 
243             sResult += sBuffer;
244 
245             for (sal_uInt32 i = 0; i < nStep; i++)
246             {
247                 if (n + i < getCount())
248                 {
249                     snprintf(sBuffer, 255, "%02x ", operator[](n + i));
250                     sResult += sBuffer;
251                 }
252                 else
253                     sResult += "   ";
254 
255                 if (i % 8 == 7)
256                     sResult += " ";
257             }
258 
259             {
260                 for (sal_uInt32 i = 0; i < nStep; i++)
261                 {
262                     if (n + i < getCount())
263                     {
264                         unsigned char c =
265                             static_cast<unsigned char>(operator[](n + i));
266 
267 						if (c=='&')
268 							sResult += "&amp;";
269 						else if (c=='<')
270 							sResult += "&lt;";
271 						else if (c=='>')
272 							sResult += "&gt;";
273                         else if (c < 128 && isprint(c))
274                             sResult += c;
275                         else
276                             sResult += ".";
277                     }
278                 }
279             }
280 
281             sResult += "</line>\n";
282 
283             n += nStep;
284         }
285 
286         return sResult;
287     }
288 };
289 
290 template <typename T>
dumpLine(OutputWithDepth<string> & o,SubSequence<T> & rSeq,sal_uInt32 nOffset,sal_uInt32 nStep)291 void dumpLine(OutputWithDepth<string> & o, SubSequence<T> & rSeq,
292               sal_uInt32 nOffset, sal_uInt32 nStep)
293 {
294     sal_uInt32 nCount = rSeq.getCount();
295     char sBuffer[256];
296 
297     string tmpStr = "<line>";
298 
299     snprintf(sBuffer, 255, "%08" SAL_PRIxUINT32 ": ", nOffset);
300 
301     tmpStr += sBuffer;
302 
303     for (sal_uInt32 i = 0; i < nStep; i++)
304     {
305         if (i < nCount)
306         {
307             snprintf(sBuffer, 255, "%02x ", rSeq[i]);
308             tmpStr += sBuffer;
309         }
310         else
311             tmpStr += "   ";
312 
313         if (i % 8 == 7)
314             tmpStr += " ";
315     }
316 
317     {
318         for (sal_uInt32 i = 0; i < nStep; i++)
319         {
320             if (i < nCount)
321             {
322                 unsigned char c =
323                     static_cast<unsigned char>(rSeq[i]);
324 
325                 if (c=='&')
326                     tmpStr += "&amp;";
327                 else if (c=='<')
328                     tmpStr += "&lt;";
329                 else if (c=='>')
330                     tmpStr += "&gt;";
331                 else if (c < 128 && isprint(c))
332                     tmpStr += c;
333                 else
334                     tmpStr += ".";
335             }
336 
337         }
338     }
339 
340     tmpStr += "</line>";
341 
342     o.addItem(tmpStr);
343 }
344 
345 }
346 
347 #endif // INCLUDED_SUB_SEQUENCE_HXX
348