summaryrefslogtreecommitdiff
path: root/src/main/java/com/amazon/carbonado/lob/CharArrayClob.java
diff options
context:
space:
mode:
authorBrian S. O'Neill <bronee@gmail.com>2006-08-30 02:06:57 +0000
committerBrian S. O'Neill <bronee@gmail.com>2006-08-30 02:06:57 +0000
commit21ffac73f08766ea06a289028f7479d04cb0ccff (patch)
tree88e292be0cb4f8813a075f99062baf3a0eaa9763 /src/main/java/com/amazon/carbonado/lob/CharArrayClob.java
parent04b06d8fa2ced539126f74f4d8a19c29b62c5730 (diff)
Add LOB support
Diffstat (limited to 'src/main/java/com/amazon/carbonado/lob/CharArrayClob.java')
-rw-r--r--src/main/java/com/amazon/carbonado/lob/CharArrayClob.java432
1 files changed, 432 insertions, 0 deletions
diff --git a/src/main/java/com/amazon/carbonado/lob/CharArrayClob.java b/src/main/java/com/amazon/carbonado/lob/CharArrayClob.java
new file mode 100644
index 0000000..ed6b5e9
--- /dev/null
+++ b/src/main/java/com/amazon/carbonado/lob/CharArrayClob.java
@@ -0,0 +1,432 @@
+/*
+ * Copyright 2006 Amazon Technologies, Inc. or its affiliates.
+ * Amazon, Amazon.com and Carbonado are trademarks or registered trademarks
+ * of Amazon Technologies, Inc. or its affiliates. All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.amazon.carbonado.lob;
+
+import java.io.IOException;
+import java.io.Reader;
+import java.io.Writer;
+
+import java.util.Arrays;
+
+import com.amazon.carbonado.PersistException;
+
+/**
+ * Implementation of a Clob which is backed by a growable in-memory character
+ * array.
+ *
+ * @author Brian S O'Neill
+ */
+public class CharArrayClob extends AbstractClob {
+
+ private final int mInitialCapacity;
+ private char[] mData;
+ private int mLength;
+
+ /**
+ * Construct a CharArrayClob with the given initial capacity.
+ *
+ * @param capacity initial capacity of internal character array
+ */
+ public CharArrayClob(int capacity) {
+ if (capacity == 0) {
+ throw new IllegalArgumentException();
+ }
+ mInitialCapacity = capacity;
+ mData = new char[capacity];
+ }
+
+ /**
+ * Construct a CharArrayClob initially backed by the given character array. The
+ * character array is not cloned until this CharArrayClob grows or shrinks.
+ *
+ * @param data initial data backing the Clob
+ */
+ public CharArrayClob(char[] data) {
+ if (data.length == 0) {
+ throw new IllegalArgumentException();
+ }
+ mLength = mInitialCapacity = data.length;
+ mData = data;
+ }
+
+ /**
+ * Construct a CharArrayClob initially backed by the given character array. The
+ * character array is not cloned until this CharArrayClob grows or shrinks.
+ *
+ * @param data initial data backing the Clob
+ * @param length initial length of data
+ */
+ public CharArrayClob(char[] data, int length) {
+ if (data.length < length) {
+ throw new IllegalArgumentException();
+ }
+ mInitialCapacity = data.length;
+ mData = data;
+ mLength = length;
+ }
+
+ public Reader openReader() {
+ return new Input(this, 0);
+ }
+
+ public Reader openReader(long pos) {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+ return new Input(this, pos);
+ }
+
+ public Reader openReader(long pos, int bufferSize) {
+ return openReader(pos);
+ }
+
+ public synchronized long getLength() {
+ return mLength;
+ }
+
+ public synchronized String asString() {
+ return new String(mData, 0, mLength);
+ }
+
+ synchronized int read(long pos) {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+
+ if (pos > Integer.MAX_VALUE) {
+ return -1;
+ }
+
+ int ipos = (int) pos;
+ if (ipos >= mLength) {
+ return -1;
+ }
+
+ return mData[ipos];
+ }
+
+ synchronized int read(long pos, char[] chars) {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+ if (chars == null) {
+ throw new IllegalArgumentException("Character array is null");
+ }
+
+ if (pos > Integer.MAX_VALUE) {
+ return -1;
+ }
+
+ int ipos = (int) pos;
+ if (ipos > mLength) { // the use of '>' instead of '>=' is intentional
+ return -1;
+ }
+
+ int length = chars.length;
+ if (ipos + length > mLength) {
+ length = mLength - ipos;
+ }
+
+ System.arraycopy(mData, ipos, chars, 0, length);
+
+ return length;
+ }
+
+ synchronized int read(long pos, char[] chars, int offset, int length) {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+ if (chars == null) {
+ throw new IllegalArgumentException("Character array is null");
+ }
+ if (offset < 0) {
+ throw new IllegalArgumentException("Offset is negative: " + offset);
+ }
+ if (length < 0) {
+ throw new IllegalArgumentException("Length is negative: " + length);
+ }
+
+ if (pos > Integer.MAX_VALUE) {
+ return -1;
+ }
+
+ int ipos = (int) pos;
+ if (ipos > mLength) { // the use of '>' instead of '>=' is intentional
+ return -1;
+ }
+
+ if (ipos + length > mLength) {
+ length = mLength - ipos;
+ }
+
+ try {
+ System.arraycopy(mData, ipos, chars, offset, length);
+ } catch (IndexOutOfBoundsException e) {
+ if (offset >= chars.length && length > 0) {
+ throw new IllegalArgumentException("Offset is too large: " + offset);
+ }
+ throw e;
+ }
+
+ return length;
+ }
+
+ public Writer openWriter() {
+ return new Output(this, 0);
+ }
+
+ public Writer openWriter(long pos) {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+ return new Output(this, pos);
+ }
+
+ public Writer openWriter(long pos, int bufferSize) {
+ return openWriter(pos);
+ }
+
+ public synchronized void setLength(long length) throws PersistException {
+ if (length < 0) {
+ throw new IllegalArgumentException("Length is negative: " + length);
+ }
+ if (length > Integer.MAX_VALUE) {
+ throw new PersistException("Length too long: " + length);
+ }
+ int ilength = (int) length;
+ if (ilength < mLength) {
+ mLength = ilength;
+ if (mData.length > mInitialCapacity) {
+ // Free up some space.
+ mData = new char[mInitialCapacity];
+ }
+ } else if (ilength > mLength) {
+ if (ilength <= mData.length) {
+ Arrays.fill(mData, mLength, ilength, (char) 0);
+ mLength = ilength;
+ } else {
+ int newLength = mData.length * 2;
+ if (newLength < ilength) {
+ newLength = ilength;
+ }
+ char[] newData = new char[newLength];
+ System.arraycopy(mData, 0, newData, 0, mLength);
+ }
+ mLength = ilength;
+ }
+ }
+
+ synchronized void write(long pos, int b) throws IOException {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+
+ if (pos > Integer.MAX_VALUE) {
+ throw new IOException("Position too high: " + pos);
+ }
+
+ int ipos = (int) pos;
+ ensureLengthForWrite(ipos + 1);
+ mData[ipos] = (char) b;
+ }
+
+ synchronized void write(long pos, char[] chars) throws IOException {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+ if (chars == null) {
+ throw new IllegalArgumentException("Character array is null");
+ }
+
+ if (pos > Integer.MAX_VALUE) {
+ throw new IOException("Position too high: " + pos);
+ }
+ if (pos + chars.length > Integer.MAX_VALUE) {
+ throw new IOException("Position plus length too high: " + (pos + chars.length));
+ }
+
+ int ipos = (int) pos;
+ ensureLengthForWrite(ipos + chars.length);
+ System.arraycopy(chars, 0, mData, ipos, chars.length);
+ }
+
+ synchronized void write(long pos, char[] chars, int offset, int length) throws IOException {
+ if (pos < 0) {
+ throw new IllegalArgumentException("Position is negative: " + pos);
+ }
+ if (chars == null) {
+ throw new IllegalArgumentException("Character array is null");
+ }
+ if (offset < 0) {
+ throw new IllegalArgumentException("Offset is negative: " + offset);
+ }
+ if (length < 0) {
+ throw new IllegalArgumentException("Length is negative: " + length);
+ }
+
+ if (pos > Integer.MAX_VALUE) {
+ throw new IOException("Position too high: " + pos);
+ }
+ if (pos + length > Integer.MAX_VALUE) {
+ throw new IOException("Position plus length too high: " + (pos + length));
+ }
+
+ int ipos = (int) pos;
+ ensureLengthForWrite(ipos + length);
+ System.arraycopy(chars, offset, mData, ipos, length);
+ }
+
+ // Caller must be synchronized
+ private void ensureLengthForWrite(int ilength) {
+ if (ilength > mLength) {
+ if (ilength <= mData.length) {
+ mLength = ilength;
+ } else {
+ int newLength = mData.length * 2;
+ if (newLength < ilength) {
+ newLength = ilength;
+ }
+ char[] newData = new char[newLength];
+ System.arraycopy(mData, 0, newData, 0, mLength);
+ mData = newData;
+ }
+ mLength = ilength;
+ }
+ }
+
+ private static class Input extends Reader {
+ private final CharArrayClob mClob;
+ private long mPos;
+ private long mMarkPos;
+
+ Input(CharArrayClob blob, long pos) {
+ mClob = blob;
+ mPos = pos;
+ mMarkPos = pos;
+ }
+
+ @Override
+ public int read() {
+ int b = mClob.read(mPos);
+ if (b >= 0) {
+ mPos++;
+ }
+ return b;
+ }
+
+ @Override
+ public int read(char[] chars) {
+ int length = mClob.read(mPos, chars);
+ if (length > 0) {
+ mPos += length;
+ }
+ return length;
+ }
+
+ @Override
+ public int read(char[] chars, int offset, int length) {
+ length = mClob.read(mPos, chars, offset, length);
+ if (length > 0) {
+ mPos += length;
+ }
+ return length;
+ }
+
+ @Override
+ public long skip(long n) {
+ if (n <= 0) {
+ return 0;
+ }
+
+ long newPos = mPos + n;
+ if (newPos < 0) {
+ newPos = Long.MAX_VALUE;
+ }
+
+ long length = mClob.getLength();
+ if (newPos > length) {
+ newPos = length;
+ }
+
+ n = newPos - mPos;
+ mPos = newPos;
+ return n;
+ }
+
+ @Override
+ public boolean ready() {
+ return (mClob.getLength() - mPos) > 0;
+ }
+
+ @Override
+ public void mark(int readlimit) {
+ mMarkPos = mPos;
+ }
+
+ @Override
+ public void reset() {
+ mPos = mMarkPos;
+ }
+
+ @Override
+ public boolean markSupported() {
+ return true;
+ }
+
+ @Override
+ public void close() {
+ }
+ }
+
+ private static class Output extends Writer {
+ private final CharArrayClob mClob;
+ private long mPos;
+
+ Output(CharArrayClob blob, long pos) {
+ mClob = blob;
+ mPos = pos;
+ }
+
+ @Override
+ public void write(int b) throws IOException {
+ mClob.write(mPos, b);
+ mPos++;
+ }
+
+ @Override
+ public void write(char[] b) throws IOException {
+ mClob.write(mPos, b);
+ mPos += b.length;
+ }
+
+ @Override
+ public void write(char[] b, int offset, int length) throws IOException {
+ mClob.write(mPos, b, offset, length);
+ mPos += length;
+ }
+
+ @Override
+ public void flush() {
+ }
+
+ @Override
+ public void close() {
+ }
+ }
+}