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 
26 namespace XALAN_CPP_NAMESPACE {
27 
28 
29 
30 
31 template <class Predicate,
32  class ConstantsType>
34 {
35 public:
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 
56  ThisType& m_writer;
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 
78  ThisType& m_writer;
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
104  {
105  }
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  */
125  size_type
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  {
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,
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 
294  size_type
296  const XalanDOMChar chars[],
297  size_type start,
299  {
300 
301  return write(chars, start, length, m_charRefFunctor);
302  }
303 
304  void
306  const XalanDOMChar* theChars,
307  size_type theLength)
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
343  write(const XalanDOMChar* theChars)
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 
363 private:
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>
380  size_type
381  write(
382  const XalanDOMChar chars[],
383  size_type start,
385  TranscodingFailureFunctor& failureHandler)
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
xalanc::XalanOtherEncodingWriter::ThrowTranscodingException
Definition: XalanOtherEncodingWriter.hpp:59
XALAN_CPP_NAMESPACE
#define XALAN_CPP_NAMESPACE
Xalan-C++ namespace, including major and minor version.
Definition: XalanVersion.hpp:76
xalanc::XalanOtherEncodingWriter::ThisType
XalanOtherEncodingWriter< Predicate, ConstantsType > ThisType
Definition: XalanOtherEncodingWriter.hpp:37
xalanc::XalanOtherEncodingWriter::write
void write(const XalanDOMString &theChars)
Definition: XalanOtherEncodingWriter.hpp:260
xalanc::XalanOtherEncodingWriter::flushWriter
void flushWriter()
Definition: XalanOtherEncodingWriter.hpp:349
xalanc::XalanOtherEncodingWriter::WriteCharRef
Definition: XalanOtherEncodingWriter.hpp:39
xalanc::XalanOtherEncodingWriter::~XalanOtherEncodingWriter
virtual ~XalanOtherEncodingWriter()
Definition: XalanOtherEncodingWriter.hpp:103
xalanc::XalanOtherEncodingWriter::flushBuffer
void flushBuffer()
Definition: XalanOtherEncodingWriter.hpp:355
xalanc::size_type
size_t size_type
Definition: XalanMap.hpp:46
xalanc::XalanOtherEncodingWriter::writeNameChar
void writeNameChar(const XalanDOMChar *data, size_type theLength)
Writes name characters.
Definition: XalanOtherEncodingWriter.hpp:207
xalanc::XalanOtherEncodingWriter::write
void write(const XalanDOMChar *theChars)
Definition: XalanOtherEncodingWriter.hpp:343
xalanc::XalanOtherEncodingWriter::WriteCharRef::WriteCharRef
WriteCharRef(ThisType &writer)
Definition: XalanOtherEncodingWriter.hpp:43
xalanc::XalanOtherEncodingWriter::writePIChars
void writePIChars(const XalanDOMChar *data, size_type theLength)
Writes PI characters.
Definition: XalanOtherEncodingWriter.hpp:222
xalanc::XalanOtherEncodingWriter::value_type
XalanDOMChar value_type
Definition: XalanOtherEncodingWriter.hpp:84
xalanc::XalanDOMString::length
size_type length() const
Definition: XalanDOMString.hpp:209
xalanc::XalanFormatterWriter::size_type
FormatterListener::size_type size_type
Definition: XalanFormatterWriter.hpp:48
xalanc::XalanOtherEncodingWriter::write
size_type write(const XalanDOMChar chars[], size_type start, size_type length)
Definition: XalanOtherEncodingWriter.hpp:295
xalanc::XalanOtherEncodingWriter::XalanOtherEncodingWriter
XalanOtherEncodingWriter(Writer &writer, MemoryManager &theMemoryManager)
Definition: XalanOtherEncodingWriter.hpp:86
xalanc::length
XalanDOMString::size_type length(const XalanDOMString &theString)
Get the length of a XalanDOMString.
Definition: DOMStringHelper.hpp:235
xalanc::XalanOtherEncodingWriter::WriteCharRef::operator()
void operator()(XalanUnicodeChar value) const
Definition: XalanOtherEncodingWriter.hpp:49
XalanFormatterWriter.hpp
xalanc::XalanOtherEncodingWriter::writeSafe
void writeSafe(const XalanDOMChar *theChars, size_type theLength)
Definition: XalanOtherEncodingWriter.hpp:305
xalanc::XalanOtherEncodingWriter::outputNewline
void outputNewline()
Output a line break.
Definition: XalanOtherEncodingWriter.hpp:111
xalanc::XalanOtherEncodingWriter::writeCommentChars
void writeCommentChars(const XalanDOMChar *data, size_type theLength)
Writes comment characters.
Definition: XalanOtherEncodingWriter.hpp:238
xalanc::XalanFormatterWriter
Definition: XalanFormatterWriter.hpp:44
xalanc::XalanOtherEncodingWriter::writeCDATAChar
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.
Definition: XalanOtherEncodingWriter.hpp:126
xalanc::XalanOtherEncodingWriter::ThrowTranscodingException::operator()
void operator()(XalanUnicodeChar value) const
Definition: XalanOtherEncodingWriter.hpp:69
xalanc::XalanDOMString::c_str
const XalanDOMChar * c_str() const
Definition: XalanDOMString.hpp:344
xalanc::XalanOtherEncodingWriter::write
void write(const XalanDOMChar *theChars, size_type theLength)
Definition: XalanOtherEncodingWriter.hpp:249
xalanc::XalanOtherEncodingWriter
Definition: XalanOtherEncodingWriter.hpp:33
xalanc::XalanOtherEncodingWriter::ThrowTranscodingException::ThrowTranscodingException
ThrowTranscodingException(ThisType &writer)
Definition: XalanOtherEncodingWriter.hpp:63
xalanc::XalanDOMString
Definition: XalanDOMString.hpp:45
xalanc::Writer
Definition: Writer.hpp:44
xalanc::XalanOtherEncodingWriter::write
void write(XalanDOMChar theChar)
Writes writes a UTF-16 code unit that isn't part of the surrogate pair.
Definition: XalanOtherEncodingWriter.hpp:270