001: /**
002: * com.mckoi.database.global.ByteLongObject 24 Sep 2000
003: *
004: * Mckoi SQL Database ( http://www.mckoi.com/database )
005: * Copyright (C) 2000, 2001, 2002 Diehl and Associates, Inc.
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License
009: * Version 2 as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License Version 2 for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * Version 2 along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: * Change Log:
021: *
022: *
023: */package com.mckoi.database.global;
024:
025: import java.io.IOException;
026: import java.io.InputStream;
027:
028: /**
029: * A byte array that can be transferred between the client and server. This
030: * is used for transferring BLOB data to/from the database engine.
031: *
032: * @author Tobias Downer
033: */
034:
035: public class ByteLongObject implements java.io.Serializable,
036: BlobAccessor {
037:
038: static final long serialVersionUID = -6843780673892019530L;
039:
040: /**
041: * The binary data.
042: */
043: private byte[] data;
044:
045: /**
046: * Constructor.
047: */
048: public ByteLongObject(byte[] from, int offset, int length) {
049: data = new byte[(int) length];
050: System.arraycopy(from, (int) offset, data, 0, (int) length);
051: }
052:
053: public ByteLongObject(byte[] from) {
054: this (from, 0, from.length);
055: }
056:
057: public ByteLongObject(InputStream in, int length)
058: throws IOException {
059: data = new byte[length];
060: int i = 0;
061: while (i < length) {
062: int read = in.read(data, i, length - i);
063: if (read == -1) {
064: throw new IOException("Premature end of stream.");
065: }
066: i += read;
067: }
068: }
069:
070: /**
071: * Returns the size of the data in this object.
072: */
073: public int length() {
074: return data.length;
075: }
076:
077: /**
078: * Returns the byte at offset 'n' into the binary object.
079: */
080: public byte getByte(int n) {
081: return data[n];
082: }
083:
084: /**
085: * Returns the internal byte[] of this binary object. Care needs to be
086: * taken when handling this object because altering the contents will
087: * change this object.
088: */
089: public byte[] getByteArray() {
090: return data;
091: }
092:
093: /**
094: * Returns an InputStream that allows us to read the entire byte long object.
095: */
096: public InputStream getInputStream() {
097: return new BLOBInputStream();
098: }
099:
100: public String toString() {
101: StringBuffer buf = new StringBuffer();
102: if (data == null) {
103: buf.append("[ BLOB (NULL) ]");
104: } else {
105: buf.append("[ BLOB size=");
106: buf.append(data.length);
107: buf.append(" ]");
108: }
109: return new String(buf);
110: }
111:
112: /**
113: * Inner class that encapsulates the byte long object in an input stream.
114: */
115: private class BLOBInputStream extends InputStream {
116:
117: private int index;
118:
119: public BLOBInputStream() {
120: index = 0;
121: }
122:
123: public int read() throws IOException {
124: if (index >= length()) {
125: return -1;
126: }
127: int b = ((int) getByte(index)) & 0x0FF;
128: ++index;
129: return b;
130: }
131:
132: public int read(byte[] buf, int off, int len)
133: throws IOException {
134: // As per the InputStream specification.
135: if (len == 0) {
136: return 0;
137: }
138:
139: int size = length();
140: int to_read = Math.min(len, size - index);
141:
142: if (to_read <= 0) {
143: // Nothing can be read
144: return -1;
145: }
146:
147: System.arraycopy(data, index, buf, off, to_read);
148: index += to_read;
149:
150: return to_read;
151: }
152:
153: }
154:
155: }
|