1 28 29 package org.jibx.runtime.impl; 30 31 import java.io.IOException ; 32 import java.io.OutputStream ; 33 import java.io.UnsupportedEncodingException ; 34 35 45 46 public abstract class StreamWriterBase extends XMLWriterBase 47 { 48 51 protected static final byte[] QUOT_ENTITY = 52 { 53 (byte)'&', (byte)'q', (byte)'u', (byte)'o', (byte)'t', (byte)';' 54 }; 55 protected static final byte[] AMP_ENTITY = 56 { 57 (byte)'&', (byte)'a', (byte)'m', (byte)'p', (byte)';' 58 }; 59 protected static final byte[] GT_ENTITY = 60 { 61 (byte)'&', (byte)'g', (byte)'t', (byte)';' 62 }; 63 protected static final byte[] LT_ENTITY = 64 { 65 (byte)'&', (byte)'l', (byte)'t', (byte)';' 66 }; 67 protected static final byte[] LT_CDATASTART = 68 { 69 (byte)'<', (byte)'!', (byte)'[', (byte)'C', (byte)'D', (byte)'A', 70 (byte)'T', (byte)'A', (byte)'[' 71 }; 72 protected static final byte[] LT_CDATAEND = 73 { 74 (byte)']', (byte)']', (byte)'>' 75 }; 76 77 78 private static final int INITIAL_BUFFER_SIZE = 2048; 79 80 81 private final String m_encodingName; 82 83 84 private OutputStream m_stream; 85 86 87 protected byte[] m_buffer; 88 89 90 protected int m_fillOffset; 91 92 93 protected byte[][] m_prefixBytes; 94 95 96 protected byte[][][] m_extensionBytes; 97 98 99 private boolean m_indent; 100 101 102 private int m_indentBase; 103 104 105 private int m_indentPerLevel; 106 107 108 private byte[] m_indentSequence; 109 110 119 120 public StreamWriterBase(String enc, String [] uris) { 121 super(uris); 122 m_encodingName = enc; 123 m_prefixBytes = new byte[uris.length][]; 124 m_buffer = new byte[INITIAL_BUFFER_SIZE]; 125 } 126 127 134 135 public void setOutput(OutputStream outs) { 136 try { 137 close(); 138 } catch (IOException e) { } 139 m_stream = outs; 140 reset(); 141 } 142 143 154 155 public void setIndentSpaces(int count, String newline, char indent) { 156 if (count >= 0) { 157 try { 158 if (newline == null) { 159 newline = "\n"; 160 } 161 m_indent = true; 162 byte[] base = newline.getBytes(m_encodingName); 163 m_indentBase = base.length; 164 byte[] per = new String (new char[] 165 { indent }).getBytes(m_encodingName); 166 m_indentPerLevel = count * per.length; 167 int length = m_indentBase + m_indentPerLevel * 10; 168 m_indentSequence = new byte[length]; 169 for (int i = 0; i < length; i++) { 170 if (i < newline.length()) { 171 m_indentSequence[i] = base[i]; 172 } else { 173 int index = (i - m_indentBase) % per.length; 174 m_indentSequence[i] = per[index]; 175 } 176 } 177 } catch (UnsupportedEncodingException e) { 178 throw new RuntimeException 179 ("Encoding " + m_encodingName + " not recognized by JVM"); 180 } 181 } else { 182 m_indent = false; 183 } 184 } 185 186 194 195 protected void makeSpace(int length) throws IOException { 196 if (m_fillOffset + length > m_buffer.length) { 197 m_stream.write(m_buffer, 0, m_fillOffset); 198 m_fillOffset = 0; 199 if (length > m_buffer.length) { 200 m_buffer = new byte[Math.max(length, m_buffer.length*2)]; 201 } 202 } 203 } 204 205 210 211 protected void undefineNamespace(int index) { 212 if (index < m_prefixBytes.length) { 213 m_prefixBytes[index] = null; 214 } else if (m_extensionBytes != null) { 215 index -= m_prefixes.length; 216 for (int i = 0; i < m_extensionBytes.length; i++) { 217 int length = m_extensionBytes[i].length; 218 if (index < length) { 219 m_extensionBytes[i][index] = null; 220 break; 221 } else { 222 index -= length; 223 } 224 } 225 } else { 226 throw new IllegalArgumentException ("Index out of range"); 227 } 228 } 229 230 237 238 protected void writePrefix(int index) throws IOException { 239 try { 240 byte[] bytes = null; 241 if (index < m_prefixBytes.length) { 242 bytes = m_prefixBytes[index]; 243 } else if (m_extensionBytes != null) { 244 index -= m_prefixes.length; 245 for (int i = 0; i < m_extensionBytes.length; i++) { 246 int length = m_extensionBytes[i].length; 247 if (index < length) { 248 bytes = m_extensionBytes[i][index]; 249 break; 250 } else { 251 index -= length; 252 } 253 } 254 } 255 makeSpace(bytes.length); 256 System.arraycopy(bytes, 0, m_buffer, m_fillOffset, bytes.length); 257 m_fillOffset += bytes.length; 258 } catch (NullPointerException ex) { 259 throw new IOException ("Namespace URI has not been declared."); 260 } 261 } 262 263 270 271 protected int writeEntity(byte[] bytes, int offset) { 272 System.arraycopy(bytes, 0, m_buffer, offset, bytes.length); 273 return offset + bytes.length; 274 } 275 276 281 282 public void pushExtensionNamespaces(String [] uris) { 283 super.pushExtensionNamespaces(uris); 284 byte[][] items = new byte[uris.length][]; 285 if (m_extensionBytes == null) { 286 m_extensionBytes = new byte[][][] { items }; 287 } else { 288 int length = m_extensionBytes.length; 289 byte[][][] grow = new byte[length+1][][]; 290 System.arraycopy(m_extensionBytes, 0, grow, 0, length); 291 grow[length] = items; 292 m_extensionBytes = grow; 293 } 294 } 295 296 300 301 public void popExtensionNamespaces() { 302 super.popExtensionNamespaces(); 303 int length = m_extensionBytes.length; 304 if (length == 1) { 305 m_extensionBytes = null; 306 } else { 307 byte[][][] shrink = new byte[length-1][][]; 308 System.arraycopy(m_extensionBytes, 0, shrink, 0, length-1); 309 m_extensionBytes = shrink; 310 } 311 } 312 313 323 324 public void indent() throws IOException { 325 if (m_indent) { 326 int length = m_indentBase + m_nestingDepth * m_indentPerLevel; 327 if (length > m_indentSequence.length) { 328 int use = Math.max(length, 329 m_indentSequence.length*2 - m_indentBase); 330 byte[] grow = new byte[use]; 331 System.arraycopy(m_indentSequence, 0, grow, 0, 332 m_indentSequence.length); 333 for (int i = m_indentSequence.length; i < use; i++) { 334 grow[i] = grow[m_indentBase]; 335 } 336 m_indentSequence = grow; 337 } 338 makeSpace(length); 339 System.arraycopy(m_indentSequence, 0, m_buffer, m_fillOffset, 340 length); 341 m_fillOffset += length; 342 } 343 } 344 345 351 352 public void close() throws IOException { 353 if (m_stream != null) { 354 indent(); 355 m_stream.write(m_buffer, 0, m_fillOffset); 356 m_fillOffset = 0; 357 m_stream.flush(); 358 m_stream.close(); 359 m_stream = null; 360 } 361 } 362 363 368 369 public void reset() { 370 super.reset(); 371 m_fillOffset = 0; 372 } 373 } | Popular Tags |