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
50 {
51 m_writer.writeNumericCharacterReference(value);
52 }
53
54 private:
55
56 ThisType& m_writer;
57 };
58
60 {
61 public:
62
64 m_writer(writer)
65 {
66 }
67
68 void
70 {
71 m_writer.throwUnrepresentableCharacterException(
72 value,
73 m_writer.getMemoryManager());
74 }
75
76 private:
77
78 ThisType& m_writer;
79 };
80
81 friend class WriteCharRef;
83
85
88 MemoryManager& theMemoryManager) :
90 writer,
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);
114 assert(length(m_newlineString) == m_newlineStringLength);
115
116 write(
117 m_newlineString,
118 m_newlineStringLength);
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,
129 size_type length,
130 bool& outsideCDATA)
131 {
132 assert(chars != 0 && length > 0 && start < length);
133
134 const XalanDOMChar theChar = chars[start];
135
137
138 size_type result = start;
139
140 if (isUTF16HighSurrogate(theChar) == true)
141 {
142 if (start + 1 >= length)
143 {
144 throwInvalidUTF16SurrogateException(
145 theChar,
146 0,
147 getMemoryManager());
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,
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,
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,
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,
252 {
253 for(size_type i = 0; i < theLength; ++i)
254 {
255 write(theChars[i]);
256 }
257 }
258
259 void
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
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,
298 size_type length)
299 {
300
301 return write(chars, start, length, m_charRefFunctor);
302 }
303
304 void
306 const XalanDOMChar* theChars,
308 {
309 for(size_type i = 0; i < theLength; ++i)
310 {
311 const XalanDOMChar ch = theChars[i];
312
313 if (isUTF16HighSurrogate(ch) == true)
314 {
315 if (i + 1 >= theLength)
316 {
317 throwInvalidUTF16SurrogateException(ch, 0, getMemoryManager());
318 }
319 else
320 {
321 XalanUnicodeChar value = decodeUTF16SurrogatePair(ch, theChars[i+1], getMemoryManager());
322
323 if (this->m_isPresentable(value))
324 {
325 write(value);
326 }
327 else
328 {
329 this->writeNumberedEntityReference(value);
330 }
331
332 ++i;
333 }
334 }
335 else
336 {
337 write(static_cast<XalanUnicodeChar>(ch));
338 }
339 }
340 }
341
342 void
344 {
345 write(theChars, XalanDOMString::length(theChars));
346 }
347
348 void
350 {
351 m_writer.flush();
352 }
353
354 void
356 {
357 m_writer.write(m_buffer, 0, m_bufferPosition - m_buffer);
358
359 m_bufferPosition = m_buffer;
360 m_bufferRemaining = kBufferSize;
361 }
362
363private:
364
365 /**
366 * Writes a representable code point
367 *
368 * @param chars Array of the characters for transcoding
369 *
370 * @param start Place int the array the transcoding should start
371 *
372 * @param length The length of the array
373 *
374 * @param failureHandler The functor handles the non-representable characters
375 *
376 * @return Place int the array of the next character
377 */
378
379 template <class TranscodingFailureFunctor>
381 write(
382 const XalanDOMChar chars[],
383 size_type start,
384 size_type length,
386 {
387 assert(chars != 0 && length > 0);
388 assert(start <= length);
389
390 size_type result = start;
391
392 const XalanDOMChar ch = chars[start];
393
394 XalanUnicodeChar value = ch;
395
396 if (isUTF16HighSurrogate(ch) == true)
397 {
398 if (start + 1 >= length)
399 {
400 throwInvalidUTF16SurrogateException(
401 ch,
402 0,
403 getMemoryManager());
404 }
405 else
406 {
407 value = decodeUTF16SurrogatePair(ch, chars[start+1], getMemoryManager());
408
409 ++result;
410 }
411 }
412
413 if(m_predicate(value))
414 {
415 write(value);
416 }
417 else
418 {
419 failureHandler(value);
420 }
421
422 return result;
423 }
424
425 /**
426 * Writes a representable code point
427 *
428 * @param theChar UTF-32 code point . For passing it to the Xerces
429 * transcoder, we convert it back to UTF-16
430 */
431 void
432 write(XalanUnicodeChar theChar)
433 {
434 // encode back UTF-32 into UTF-16
435
436 if (theChar > 0xFFFF)
437 {
438 if (m_bufferRemaining < 2)
439 {
440 flushBuffer();
441 }
442
443 *m_bufferPosition = static_cast<XalanDOMChar>((theChar >> 10) + 0xD7C0);
444
445 ++m_bufferPosition;
446
447 *m_bufferPosition = static_cast<XalanDOMChar>((theChar & 0x03FF) + 0xDC00);
448
449 ++m_bufferPosition;
450
451 m_bufferRemaining = m_bufferRemaining - size_type(2);
452 }
453 else
454 {
455 if (m_bufferRemaining == 0)
456 {
457 flushBuffer();
458 }
459
460 *m_bufferPosition = XalanDOMChar(theChar);
461
462 ++m_bufferPosition;
463 --m_bufferRemaining;
464 }
465 }
466
467 void
468 writeNumericCharacterReference(XalanUnicodeChar theChar)
469 {
470 const XalanDOMString& theString =
471 formatNumericCharacterReference(theChar);
472
473 const XalanDOMString::size_type theLength =
474 theString.length();
475
476 if (m_bufferRemaining < theLength)
477 {
478 flushBuffer();
479 }
480
481 using std::copy;
482
483 assert(theString.size() <= m_bufferRemaining);
484
485 m_bufferPosition =
486 copy(
487 theString.begin(),
488 theString.end(),
489 m_bufferPosition);
490
491 m_bufferRemaining -= theLength;
492 }
493
494 enum
495 {
496 // The size of the buffer. The minimum for this
497 // is the length of the longest numeric character
498 // reference that can be written.
499 kBufferSize = 512u
500 };
501
502
503 // Data members...
504 XalanDOMChar m_buffer[kBufferSize];
505
506 XalanDOMChar* m_bufferPosition;
507
508 size_type m_bufferRemaining;
509
510 const Predicate m_predicate;
511
512 const ConstantsType m_constants;
513
514 const WriteCharRef m_charRefFunctor;
515
516 const ThrowTranscodingException m_exceptionFunctor;
517};
518
519
520
521}
522
523
524
525#endif // XALANUNICODESUBSETWRITER_HEADER_GUARD_1357924680
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
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 writeSafe(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