Xalan-C++ API Reference 1.12.0
XalanOtherEncodingWriter.hpp
Go to the documentation of this file.
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18#if !defined(XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680)
19#define XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680
20
21
23
24
25
26namespace XALAN_CPP_NAMESPACE {
27
28
29
30
31template <class Predicate,
32 class ConstantsType>
34{
35public:
36
38
40 {
41 public:
42
44 m_writer(writer)
45 {
46 }
47
48 void
49 operator()(XalanUnicodeChar value) const
50 {
51 m_writer.writeNumericCharacterReference(value);
52 }
53
54 private:
55
57 };
58
60 {
61 public:
62
64 m_writer(writer)
65 {
66 }
67
68 void
69 operator()(XalanUnicodeChar value) const
70 {
71 m_writer.throwUnrepresentableCharacterException(
72 value,
73 m_writer.getMemoryManager());
74 }
75
76 private:
77
79 };
80
81 friend class WriteCharRef;
83
84 typedef XalanDOMChar value_type;
85
87 Writer& writer,
88 MemoryManager& theMemoryManager) :
90 writer,
91 theMemoryManager),
92 m_buffer(),
93 m_bufferPosition(m_buffer),
94 m_bufferRemaining(kBufferSize),
95 m_predicate(writer.getStream()),
96 m_constants(),
97 m_charRefFunctor(*this),
98 m_exceptionFunctor(*this)
99 {
100 }
101
102 virtual
106
107 /**
108 * Output a line break.
109 */
110 void
112 {
113 assert(m_newlineString != 0);
115
116 write(
119 }
120
121 /**
122 * Writes CDATA chars , if not presentable, fixes it
123 * with addition CDATA sections
124 */
127 const XalanDOMChar chars[],
128 size_type start,
130 bool& outsideCDATA)
131 {
132 assert(chars != 0 && length > 0 && start < length);
133
134 const XalanDOMChar theChar = chars[start];
135
136 XalanUnicodeChar value = theChar;
137
138 size_type result = start;
139
140 if (isUTF16HighSurrogate(theChar) == true)
141 {
142 if (start + 1 >= length)
143 {
145 theChar,
146 0,
148 }
149 else
150 {
151 value = decodeUTF16SurrogatePair(theChar, chars[start+1], getMemoryManager());
152
153 ++result;
154 }
155 }
156
157 if(m_predicate(value))
158 {
159 if (outsideCDATA == false)
160 {
161 // We have a representable char in the normal state,
162 // so just print it.
163 write(value);
164 }
165 else
166 {
167 // The previous character was a not representable.
168 // Open the CDATA section again, print the character,
169 // then change the flag.
170 write(
171 m_constants.s_cdataOpenString,
172 m_constants.s_cdataOpenStringLength);
173
174 write(value);
175
176 outsideCDATA = false;
177 }
178 }
179 else
180 {
181 if(outsideCDATA == false)
182 {
183 // we have a non-representable char in the normal state -
184 // close the CDATA section and print the value
185 write(
186 m_constants.s_cdataCloseString,
187 m_constants.s_cdataCloseStringLength);
188
189 writeNumericCharacterReference(value);
190
191 outsideCDATA = true;
192 }
193 else
194 {
195 writeNumericCharacterReference(value);
196 }
197 }
198
199 return result;
200 }
201
202 /**
203 * Writes name characters. If a character is not representable,
204 * an exception is thrown.
205 */
206 void
208 const XalanDOMChar* data,
209 size_type theLength)
210 {
211 for( size_type i = 0; i < theLength; ++i)
212 {
213 i = write(data, i , theLength, m_exceptionFunctor);
214 }
215 }
216
217 /**
218 * Writes PI characters. If a character is not representable,
219 * an exception is thrown.
220 */
221 void
223 const XalanDOMChar* data,
224 size_type theLength)
225 {
226 for( size_type i = 0; i < theLength; )
227 {
228 i = write(data, i , theLength, m_exceptionFunctor);
229 }
230 }
231
232 /**
233 * Writes comment characters. If a character is not representable,
234 * or must be written as a character reference for compatibility with
235 * XML 1.1, an exception is thrown.
236 */
237 void
239 const XalanDOMChar* data,
240 size_type theLength)
241 {
242 for( size_type i = 0; i < theLength; )
243 {
244 i = write(data, i , theLength, m_exceptionFunctor);
245 }
246 }
247
248 void
250 const XalanDOMChar* theChars,
251 size_type theLength)
252 {
253 for(size_type i = 0; i < theLength; ++i)
254 {
255 write(theChars[i]);
256 }
257 }
258
259 void
260 write(const XalanDOMString& theChars)
261 {
262 write(theChars.c_str(), theChars.length());
263 }
264
265 /**
266 * Writes writes a UTF-16 code unit that isn't
267 * part of the surrogate pair
268 */
269 void
270 write(XalanDOMChar theChar)
271 {
272 assert(
273 isUTF16HighSurrogate(theChar) == false &&
274 isUTF16LowSurrogate(theChar) == false);
275
276 if (m_bufferRemaining == 0)
277 {
278 flushBuffer();
279 }
280
281 if(m_predicate(theChar))
282 {
283 *m_bufferPosition = theChar;
284
285 ++m_bufferPosition;
286 --m_bufferRemaining;
287 }
288 else
289 {
290 writeNumericCharacterReference(theChar);
291 }
292 }
293
296 const XalanDOMChar chars[],
297 size_type start,
299 {
300
301 return write(chars, start, length, m_charRefFunctor);
302 }
303
304 void
305 write(const XalanDOMChar* theChars)
306 {
307 write(theChars, XalanDOMString::length(theChars));
308 }
309
310 void
312 {
313 m_writer.flush();
314 }
315
316 void
318 {
319 m_writer.write(m_buffer, 0, m_bufferPosition - m_buffer);
320
321 m_bufferPosition = m_buffer;
322 m_bufferRemaining = kBufferSize;
323 }
324
325private:
326
327 /**
328 * Writes a representable code point
329 *
330 * @param chars Array of the characters for transcoding
331 *
332 * @param start Place int the array the transcoding should start
333 *
334 * @param length The length of the array
335 *
336 * @param failureHandler The functor handles the non-representable characters
337 *
338 * @return Place int the array of the next character
339 */
340
341 template <class TranscodingFailureFunctor>
343 write(
344 const XalanDOMChar chars[],
345 size_type start,
347 TranscodingFailureFunctor& failureHandler)
348 {
349 assert(chars != 0 && length > 0);
350 assert(start <= length);
351
352 size_type result = start;
353
354 const XalanDOMChar ch = chars[start];
355
356 XalanUnicodeChar value = ch;
357
358 if (isUTF16HighSurrogate(ch) == true)
359 {
360 if (start + 1 >= length)
361 {
362 throwInvalidUTF16SurrogateException(
363 ch,
364 0,
365 getMemoryManager());
366 }
367 else
368 {
369 value = decodeUTF16SurrogatePair(ch, chars[start+1], getMemoryManager());
370
371 ++result;
372 }
373 }
374
375 if(m_predicate(value))
376 {
377 write(value);
378 }
379 else
380 {
381 failureHandler(value);
382 }
383
384 return result;
385 }
386
387 /**
388 * Writes a representable code point
389 *
390 * @param theChar UTF-32 code point . For passing it to the Xerces
391 * transcoder, we convert it back to UTF-16
392 */
393 void
394 write(XalanUnicodeChar theChar)
395 {
396 // encode back UTF-32 into UTF-16
397
398 if (theChar > 0xFFFF)
399 {
400 if (m_bufferRemaining < 2)
401 {
402 flushBuffer();
403 }
404
405 *m_bufferPosition = static_cast<XalanDOMChar>((theChar >> 10) + 0xD7C0);
406
407 ++m_bufferPosition;
408
409 *m_bufferPosition = static_cast<XalanDOMChar>((theChar & 0x03FF) + 0xDC00);
410
411 ++m_bufferPosition;
412
413 m_bufferRemaining = m_bufferRemaining - size_type(2);
414 }
415 else
416 {
417 if (m_bufferRemaining == 0)
418 {
419 flushBuffer();
420 }
421
422 *m_bufferPosition = XalanDOMChar(theChar);
423
424 ++m_bufferPosition;
425 --m_bufferRemaining;
426 }
427 }
428
429 void
430 writeNumericCharacterReference(XalanUnicodeChar theChar)
431 {
432 const XalanDOMString& theString =
433 formatNumericCharacterReference(theChar);
434
435 const XalanDOMString::size_type theLength =
436 theString.length();
437
438 if (m_bufferRemaining < theLength)
439 {
440 flushBuffer();
441 }
442
443 using std::copy;
444
445 assert(theString.size() <= m_bufferRemaining);
446
447 m_bufferPosition =
448 copy(
449 theString.begin(),
450 theString.end(),
451 m_bufferPosition);
452
453 m_bufferRemaining -= theLength;
454 }
455
456 enum
457 {
458 // The size of the buffer. The minimum for this
459 // is the length of the longest numeric character
460 // reference that can be written.
461 kBufferSize = 512u
462 };
463
464
465 // Data members...
466 XalanDOMChar m_buffer[kBufferSize];
467
468 XalanDOMChar* m_bufferPosition;
469
470 size_type m_bufferRemaining;
471
472 const Predicate m_predicate;
473
474 const ConstantsType m_constants;
475
476 const WriteCharRef m_charRefFunctor;
477
478 const ThrowTranscodingException m_exceptionFunctor;
479};
480
481
482
483}
484
485
486
487#endif // XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680
const XalanDOMChar * c_str() const
size_type length() const
static void throwInvalidUTF16SurrogateException(XalanDOMChar ch, XalanDOMChar next, MemoryManager &theManager)
static bool isUTF16HighSurrogate(XalanDOMChar theChar)
XalanFormatterWriter(Writer &theWriter, MemoryManager &theMemoryManager)
static XalanUnicodeChar decodeUTF16SurrogatePair(XalanDOMChar theHighSurrogate, XalanDOMChar theLowSurrogate, MemoryManager &theManager)
size_type m_newlineStringLength
The length of the the string of characters that represents the newline.
static bool isUTF16LowSurrogate(XalanDOMChar theChar)
FormatterListener::size_type size_type
const XalanDOMChar * m_newlineString
The string of characters that represents the newline.
void writeNameChar(const XalanDOMChar *data, size_type theLength)
Writes name characters.
void writeCommentChars(const XalanDOMChar *data, size_type theLength)
Writes comment characters.
void writePIChars(const XalanDOMChar *data, size_type theLength)
Writes PI characters.
size_type writeCDATAChar(const XalanDOMChar chars[], size_type start, size_type length, bool &outsideCDATA)
Writes CDATA chars , if not presentable, fixes it with addition CDATA sections.
size_type write(const XalanDOMChar chars[], size_type start, size_type length)
void write(const XalanDOMString &theChars)
XalanOtherEncodingWriter< Predicate, ConstantsType > ThisType
void write(const XalanDOMChar *theChars, size_type theLength)
void write(const XalanDOMChar *theChars)
XalanOtherEncodingWriter(Writer &writer, MemoryManager &theMemoryManager)
void write(XalanDOMChar theChar)
Writes writes a UTF-16 code unit that isn't part of the surrogate pair.
XalanDOMString::size_type length(const XalanDOMString &theString)
Get the length of a XalanDOMString.
size_t size_type
Definition XalanMap.hpp:46