1. /*
  2. * The Apache Software License, Version 1.1
  3. *
  4. *
  5. * Copyright (c) 1999 The Apache Software Foundation. All rights
  6. * reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright
  13. * notice, this list of conditions and the following disclaimer.
  14. *
  15. * 2. Redistributions in binary form must reproduce the above copyright
  16. * notice, this list of conditions and the following disclaimer in
  17. * the documentation and/or other materials provided with the
  18. * distribution.
  19. *
  20. * 3. The end-user documentation included with the redistribution,
  21. * if any, must include the following acknowledgment:
  22. * "This product includes software developed by the
  23. * Apache Software Foundation (http://www.apache.org/)."
  24. * Alternately, this acknowledgment may appear in the software itself,
  25. * if and wherever such third-party acknowledgments normally appear.
  26. *
  27. * 4. The names "Xalan" and "Apache Software Foundation" must
  28. * not be used to endorse or promote products derived from this
  29. * software without prior written permission. For written
  30. * permission, please contact apache@apache.org.
  31. *
  32. * 5. Products derived from this software may not be called "Apache",
  33. * nor may "Apache" appear in their name, without prior written
  34. * permission of the Apache Software Foundation.
  35. *
  36. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  37. * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  38. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  39. * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  40. * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  41. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  42. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  43. * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  44. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  45. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  46. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  47. * SUCH DAMAGE.
  48. * ====================================================================
  49. *
  50. * This software consists of voluntary contributions made by many
  51. * individuals on behalf of the Apache Software Foundation and was
  52. * originally based on software copyright (c) 1999, Lotus
  53. * Development Corporation., http://www.lotus.com. For more
  54. * information on the Apache Software Foundation, please see
  55. * <http://www.apache.org/>.
  56. */
  57. package org.apache.xalan.serialize;
  58. import java.io.*;
  59. /**
  60. * This class writes ASCII to a byte stream as quickly as possible. For the
  61. * moment it does not do buffering, though I reserve the right to do some
  62. * buffering down the line if I can prove that it will be faster even if the
  63. * output stream is buffered.
  64. */
  65. public class WriterToUTF8 extends Writer
  66. {
  67. /** The byte stream to write to. */
  68. private final OutputStream m_os;
  69. /**
  70. * Create an unbuffered UTF-8 writer.
  71. *
  72. *
  73. * @param os The byte stream to write to.
  74. *
  75. * @throws UnsupportedEncodingException
  76. */
  77. public WriterToUTF8(OutputStream os) throws UnsupportedEncodingException
  78. {
  79. m_os = os;
  80. }
  81. /**
  82. * Write a single character. The character to be written is contained in
  83. * the 16 low-order bits of the given integer value; the 16 high-order bits
  84. * are ignored.
  85. *
  86. * <p> Subclasses that intend to support efficient single-character output
  87. * should override this method.
  88. *
  89. * @param c int specifying a character to be written.
  90. * @exception IOException If an I/O error occurs
  91. */
  92. public void write(final int c) throws IOException
  93. {
  94. if (c < 0x80)
  95. m_os.write(c);
  96. else if (c < 0x800)
  97. {
  98. m_os.write(0xc0 + (c >> 6));
  99. m_os.write(0x80 + (c & 0x3f));
  100. }
  101. else
  102. {
  103. m_os.write(0xe0 + (c >> 12));
  104. m_os.write(0x80 + ((c >> 6) & 0x3f));
  105. m_os.write(0x80 + (c & 0x3f));
  106. }
  107. }
  108. /**
  109. * Write a portion of an array of characters.
  110. *
  111. * @param chars Array of characters
  112. * @param start Offset from which to start writing characters
  113. * @param length Number of characters to write
  114. *
  115. * @exception IOException If an I/O error occurs
  116. *
  117. * @throws java.io.IOException
  118. */
  119. public void write(final char chars[], final int start, final int length)
  120. throws java.io.IOException
  121. {
  122. final OutputStream os = m_os;
  123. int n = length+start;
  124. for (int i = start; i < n; i++)
  125. {
  126. final char c = chars[i];
  127. if (c < 0x80)
  128. os.write(c);
  129. else if (c < 0x800)
  130. {
  131. os.write(0xc0 + (c >> 6));
  132. os.write(0x80 + (c & 0x3f));
  133. }
  134. else
  135. {
  136. os.write(0xe0 + (c >> 12));
  137. os.write(0x80 + ((c >> 6) & 0x3f));
  138. os.write(0x80 + (c & 0x3f));
  139. }
  140. }
  141. }
  142. /**
  143. * Write a string.
  144. *
  145. * @param s String to be written
  146. *
  147. * @exception IOException If an I/O error occurs
  148. */
  149. public void write(final String s) throws IOException
  150. {
  151. final int n = s.length();
  152. final OutputStream os = m_os;
  153. for (int i = 0; i < n; i++)
  154. {
  155. final char c = s.charAt(i);
  156. if (c < 0x80)
  157. os.write(c);
  158. else if (c < 0x800)
  159. {
  160. os.write(0xc0 + (c >> 6));
  161. os.write(0x80 + (c & 0x3f));
  162. }
  163. else
  164. {
  165. os.write(0xe0 + (c >> 12));
  166. os.write(0x80 + ((c >> 6) & 0x3f));
  167. os.write(0x80 + (c & 0x3f));
  168. }
  169. }
  170. }
  171. /**
  172. * Flush the stream. If the stream has saved any characters from the
  173. * various write() methods in a buffer, write them immediately to their
  174. * intended destination. Then, if that destination is another character or
  175. * byte stream, flush it. Thus one flush() invocation will flush all the
  176. * buffers in a chain of Writers and OutputStreams.
  177. *
  178. * @exception IOException If an I/O error occurs
  179. *
  180. * @throws java.io.IOException
  181. */
  182. public void flush() throws java.io.IOException
  183. {
  184. m_os.flush();
  185. }
  186. /**
  187. * Close the stream, flushing it first. Once a stream has been closed,
  188. * further write() or flush() invocations will cause an IOException to be
  189. * thrown. Closing a previously-closed stream, however, has no effect.
  190. *
  191. * @exception IOException If an I/O error occurs
  192. *
  193. * @throws java.io.IOException
  194. */
  195. public void close() throws java.io.IOException
  196. {
  197. m_os.close();
  198. }
  199. /**
  200. * Get the output stream where the events will be serialized to.
  201. *
  202. * @return reference to the result stream, or null of only a writer was
  203. * set.
  204. */
  205. public OutputStream getOutputStream()
  206. {
  207. return m_os;
  208. }
  209. }