001: // ========================================================================
002: // Copyright 2001-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014:
015: package org.mortbay.util;
016:
017: import java.io.IOException;
018: import java.io.OutputStream;
019: import java.io.OutputStreamWriter;
020: import java.io.Writer;
021:
022: /* ------------------------------------------------------------ */
023: /** Byte Array ISO 8859 writer.
024: * This class combines the features of a OutputStreamWriter for
025: * ISO8859 encoding with that of a ByteArrayOutputStream. It avoids
026: * many inefficiencies associated with these standard library classes.
027: * It has been optimized for standard ASCII characters.
028: *
029: * @author Greg Wilkins (gregw)
030: */
031: public class ByteArrayISO8859Writer extends Writer {
032: private byte[] _buf;
033: private int _size;
034: private ByteArrayOutputStream2 _bout = null;
035: private OutputStreamWriter _writer = null;
036: private boolean _fixed = false;
037:
038: /* ------------------------------------------------------------ */
039: /** Constructor.
040: */
041: public ByteArrayISO8859Writer() {
042: _buf = new byte[2048];
043: }
044:
045: /* ------------------------------------------------------------ */
046: /** Constructor.
047: * @param capacity Buffer capacity
048: */
049: public ByteArrayISO8859Writer(int capacity) {
050: _buf = new byte[capacity];
051: }
052:
053: /* ------------------------------------------------------------ */
054: public ByteArrayISO8859Writer(byte[] buf) {
055: _buf = buf;
056: _fixed = true;
057: }
058:
059: /* ------------------------------------------------------------ */
060: public Object getLock() {
061: return lock;
062: }
063:
064: /* ------------------------------------------------------------ */
065: public int size() {
066: return _size;
067: }
068:
069: /* ------------------------------------------------------------ */
070: public int capacity() {
071: return _buf.length;
072: }
073:
074: /* ------------------------------------------------------------ */
075: public int spareCapacity() {
076: return _buf.length - _size;
077: }
078:
079: /* ------------------------------------------------------------ */
080: public void setLength(int l) {
081: _size = l;
082: }
083:
084: /* ------------------------------------------------------------ */
085: public byte[] getBuf() {
086: return _buf;
087: }
088:
089: /* ------------------------------------------------------------ */
090: public void writeTo(OutputStream out) throws IOException {
091: out.write(_buf, 0, _size);
092: }
093:
094: /* ------------------------------------------------------------ */
095: public void write(char c) throws IOException {
096: ensureSpareCapacity(1);
097: if (c >= 0 && c <= 0x7f)
098: _buf[_size++] = (byte) c;
099: else {
100: char[] ca = { c };
101: writeEncoded(ca, 0, 1);
102: }
103: }
104:
105: /* ------------------------------------------------------------ */
106: public void write(char[] ca) throws IOException {
107: ensureSpareCapacity(ca.length);
108: for (int i = 0; i < ca.length; i++) {
109: char c = ca[i];
110: if (c >= 0 && c <= 0x7f)
111: _buf[_size++] = (byte) c;
112: else {
113: writeEncoded(ca, i, ca.length - i);
114: break;
115: }
116: }
117: }
118:
119: /* ------------------------------------------------------------ */
120: public void write(char[] ca, int offset, int length)
121: throws IOException {
122: ensureSpareCapacity(length);
123: for (int i = 0; i < length; i++) {
124: char c = ca[offset + i];
125: if (c >= 0 && c <= 0x7f)
126: _buf[_size++] = (byte) c;
127: else {
128: writeEncoded(ca, offset + i, length - i);
129: break;
130: }
131: }
132: }
133:
134: /* ------------------------------------------------------------ */
135: public void write(String s) throws IOException {
136: if (s == null) {
137: write("null", 0, 4);
138: return;
139: }
140:
141: int length = s.length();
142: ensureSpareCapacity(length);
143: for (int i = 0; i < length; i++) {
144: char c = s.charAt(i);
145: if (c >= 0x0 && c <= 0x7f)
146: _buf[_size++] = (byte) c;
147: else {
148: writeEncoded(s.toCharArray(), i, length - i);
149: break;
150: }
151: }
152: }
153:
154: /* ------------------------------------------------------------ */
155: public void write(String s, int offset, int length)
156: throws IOException {
157: ensureSpareCapacity(length);
158: for (int i = 0; i < length; i++) {
159: char c = s.charAt(offset + i);
160: if (c >= 0 && c <= 0x7f)
161: _buf[_size++] = (byte) c;
162: else {
163: writeEncoded(s.toCharArray(), offset + i, length - i);
164: break;
165: }
166: }
167: }
168:
169: /* ------------------------------------------------------------ */
170: private void writeEncoded(char[] ca, int offset, int length)
171: throws IOException {
172: if (_bout == null) {
173: _bout = new ByteArrayOutputStream2(2 * length);
174: _writer = new OutputStreamWriter(_bout,
175: StringUtil.__ISO_8859_1);
176: } else
177: _bout.reset();
178: _writer.write(ca, offset, length);
179: _writer.flush();
180: ensureSpareCapacity(_bout.getCount());
181: System.arraycopy(_bout.getBuf(), 0, _buf, _size, _bout
182: .getCount());
183: _size += _bout.getCount();
184: }
185:
186: /* ------------------------------------------------------------ */
187: public void flush() {
188: }
189:
190: /* ------------------------------------------------------------ */
191: public void resetWriter() {
192: _size = 0;
193: }
194:
195: /* ------------------------------------------------------------ */
196: public void close() {
197: }
198:
199: /* ------------------------------------------------------------ */
200: public void destroy() {
201: _buf = null;
202: }
203:
204: /* ------------------------------------------------------------ */
205: public void ensureSpareCapacity(int n) throws IOException {
206: if (_size + n > _buf.length) {
207: if (_fixed)
208: throw new IOException("Buffer overflow: " + _buf.length);
209: byte[] buf = new byte[(_buf.length + n) * 4 / 3];
210: System.arraycopy(_buf, 0, buf, 0, _size);
211: _buf = buf;
212: }
213: }
214:
215: /* ------------------------------------------------------------ */
216: public byte[] getByteArray() {
217: byte[] data = new byte[_size];
218: System.arraycopy(_buf, 0, data, 0, _size);
219: return data;
220: }
221:
222: }
|