001: /* Copyright (c) 2001-2005, The HSQL Development Group
002: * All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * Redistributions of source code must retain the above copyright notice, this
008: * list of conditions and the following disclaimer.
009: *
010: * Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * Neither the name of the HSQL Development Group nor the names of its
015: * contributors may be used to endorse or promote products derived from this
016: * software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
020: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
021: * ARE DISCLAIMED. IN NO EVENT SHALL HSQL DEVELOPMENT GROUP, HSQLDB.ORG,
022: * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
025: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
026: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
027: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
028: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030:
031: package org.hsqldb.rowio;
032:
033: import java.io.UnsupportedEncodingException;
034: import java.math.BigDecimal;
035: import java.sql.Date;
036: import java.sql.Time;
037: import java.sql.Timestamp;
038:
039: import org.hsqldb.CachedRow;
040: import org.hsqldb.Trace;
041: import org.hsqldb.Types;
042: import org.hsqldb.lib.StringConverter;
043: import org.hsqldb.persist.TextCache;
044: import org.hsqldb.types.Binary;
045: import org.hsqldb.types.JavaObject;
046:
047: /**
048: * Class for writing the data for a database row in text table format.
049: *
050: * @author sqlbob@users (RMP)
051: * @version 1.8.0
052: * @since 1.7.0
053: */
054: public class RowOutputText extends RowOutputBase {
055:
056: protected String fieldSep;
057: protected String varSep;
058: protected String longvarSep;
059: private boolean fieldSepEnd;
060: private boolean varSepEnd;
061: private boolean longvarSepEnd;
062: private String nextSep = "";
063: private boolean nextSepEnd;
064: protected boolean allQuoted;
065: private String encoding;
066:
067: public RowOutputText(String fieldSep, String varSep,
068: String longvarSep, boolean allQuoted, String encoding) {
069:
070: super ();
071:
072: initTextDatabaseRowOutput(fieldSep, varSep, longvarSep,
073: allQuoted, encoding);
074: }
075:
076: private void initTextDatabaseRowOutput(String fieldSep,
077: String varSep, String longvarSep, boolean allQuoted,
078: String encoding) {
079:
080: //-- Newline indicates that field should match to end of line.
081: if (fieldSep.endsWith("\n")) {
082: fieldSepEnd = true;
083: fieldSep = fieldSep.substring(0, fieldSep.length() - 1);
084: }
085:
086: if (varSep.endsWith("\n")) {
087: varSepEnd = true;
088: varSep = varSep.substring(0, varSep.length() - 1);
089: }
090:
091: if (longvarSep.endsWith("\n")) {
092: longvarSepEnd = true;
093: longvarSep = longvarSep.substring(0,
094: longvarSep.length() - 1);
095: }
096:
097: this .fieldSep = fieldSep;
098: this .varSep = varSep;
099: this .longvarSep = longvarSep;
100: this .allQuoted = allQuoted;
101: this .encoding = encoding;
102: }
103:
104: public void writeEnd() {
105:
106: // terminate at the end of row
107: if (nextSepEnd) {
108: writeBytes(nextSep);
109: }
110:
111: writeBytes(TextCache.NL);
112: }
113:
114: public void writeSize(int size) {
115:
116: // initialise at the start of row
117: nextSep = "";
118: nextSepEnd = false;
119: }
120:
121: public void writeType(int type) {
122:
123: //--do Nothing
124: }
125:
126: public void writeString(String s) {
127:
128: s = checkConvertString(s, fieldSep);
129:
130: // error
131: if (s == null) {
132: return;
133: }
134:
135: // writeBytes(s);
136: byte[] bytes = getBytes(s);
137:
138: write(bytes, 0, bytes.length);
139:
140: nextSep = fieldSep;
141: nextSepEnd = fieldSepEnd;
142: }
143:
144: protected void writeVarString(String s) {
145:
146: s = checkConvertString(s, varSep);
147:
148: if (s == null) {
149: return;
150: }
151:
152: // writeBytes(s);
153: byte[] bytes = getBytes(s);
154:
155: write(bytes, 0, bytes.length);
156:
157: nextSep = varSep;
158: nextSepEnd = varSepEnd;
159: }
160:
161: protected void writeLongVarString(String s) {
162:
163: s = checkConvertString(s, longvarSep);
164:
165: if (s == null) {
166: return;
167: }
168:
169: // writeBytes(s);
170: byte[] bytes = getBytes(s);
171:
172: write(bytes, 0, bytes.length);
173:
174: nextSep = longvarSep;
175: nextSepEnd = longvarSepEnd;
176: }
177:
178: protected String checkConvertString(String s, String sep) {
179:
180: if (s.indexOf('\n') != -1 || s.indexOf('\r') != -1) {
181: throw new IllegalArgumentException(Trace
182: .getMessage(Trace.TEXT_STRING_HAS_NEWLINE));
183: } else if (s.indexOf(sep) != -1) {
184: return null;
185: }
186:
187: return s;
188: }
189:
190: private byte[] getBytes(String s) {
191:
192: byte[] bytes = null;
193:
194: try {
195: bytes = s.getBytes(encoding);
196: } catch (UnsupportedEncodingException e) {
197: bytes = s.getBytes();
198: }
199:
200: return bytes;
201: }
202:
203: protected void writeByteArray(byte[] b) {
204:
205: ensureRoom(b.length * 2);
206: StringConverter.writeHex(this .getBuffer(), count, b);
207:
208: count += b.length * 2;
209: }
210:
211: public void writeShortData(short i) {
212: writeIntData(i);
213: }
214:
215: public void writeIntData(int i) {
216:
217: writeBytes(Integer.toString(i));
218:
219: nextSep = fieldSep;
220: nextSepEnd = fieldSepEnd;
221: }
222:
223: public void writeIntData(int i, int position) {
224: throw Trace.runtimeError(Trace.UNSUPPORTED_INTERNAL_OPERATION,
225: "RowInputText");
226: }
227:
228: public void writeLongData(long i) {
229: throw Trace.runtimeError(Trace.UNSUPPORTED_INTERNAL_OPERATION,
230: "RowInputText");
231: }
232:
233: // fredt@users - comment - methods used for writing each SQL type
234: protected void writeFieldType(int type) {
235:
236: writeBytes(nextSep);
237:
238: switch (type) {
239:
240: case Types.VARCHAR:
241: case Types.VARCHAR_IGNORECASE:
242: nextSep = varSep;
243: nextSepEnd = varSepEnd;
244: break;
245:
246: case Types.LONGVARCHAR:
247: nextSep = longvarSep;
248: nextSepEnd = longvarSepEnd;
249: break;
250:
251: default:
252: nextSep = fieldSep;
253: nextSepEnd = fieldSepEnd;
254: break;
255: }
256: }
257:
258: protected void writeNull(int type) {
259: writeFieldType(type);
260: }
261:
262: protected void writeChar(String s, int t) {
263:
264: switch (t) {
265:
266: case Types.CHAR:
267: writeString(s);
268:
269: return;
270:
271: case Types.VARCHAR:
272: case Types.VARCHAR_IGNORECASE:
273: writeVarString(s);
274:
275: return;
276:
277: case Types.LONGVARCHAR:
278: default:
279: writeLongVarString(s);
280:
281: return;
282: }
283: }
284:
285: protected void writeSmallint(Number o) {
286: writeString(o.toString());
287: }
288:
289: protected void writeInteger(Number o) {
290: writeString(o.toString());
291: }
292:
293: protected void writeBigint(Number o) {
294: writeString(o.toString());
295: }
296:
297: protected void writeReal(Double o, int type) {
298: writeString(o.toString());
299: }
300:
301: protected void writeDecimal(BigDecimal o) {
302: writeString(o.toString());
303: }
304:
305: protected void writeBit(Boolean o) {
306: writeString(o.toString());
307: }
308:
309: protected void writeDate(Date o) {
310: writeString(o.toString());
311: }
312:
313: protected void writeTime(Time o) {
314: writeString(o.toString());
315: }
316:
317: protected void writeTimestamp(Timestamp o) {
318: writeString(o.toString());
319: }
320:
321: protected void writeOther(JavaObject o) {
322:
323: byte[] ba = o.getBytes();
324:
325: writeByteArray(ba);
326: }
327:
328: protected void writeBinary(Binary o, int t) {
329: writeByteArray(o.getBytes());
330: }
331:
332: public int getSize(CachedRow r) {
333:
334: reset();
335:
336: try {
337: writeSize(0);
338: writeData(r.getData(), r.getTable());
339: writeEnd();
340: } catch (Exception e) {
341: reset();
342:
343: // throw (Trace.error(Trace.FILE_IO_ERROR, e.toString()));
344: }
345:
346: int rowsize = size();
347:
348: reset();
349:
350: return rowsize;
351: }
352: }
|