001: /*
002:
003: Derby - Class org.apache.derby.impl.jdbc.BinaryToRawStream
004:
005: Licensed to the Apache Software Foundation (ASF) under one or more
006: contributor license agreements. See the NOTICE file distributed with
007: this work for additional information regarding copyright ownership.
008: The ASF licenses this file to you under the Apache License, Version 2.0
009: (the "License"); you may not use this file except in compliance with
010: the License. You may obtain a copy of the License at
011:
012: http://www.apache.org/licenses/LICENSE-2.0
013:
014: Unless required by applicable law or agreed to in writing, software
015: distributed under the License is distributed on an "AS IS" BASIS,
016: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: See the License for the specific language governing permissions and
018: limitations under the License.
019:
020: */
021:
022: package org.apache.derby.impl.jdbc;
023:
024: import org.apache.derby.iapi.services.sanity.SanityManager;
025:
026: import java.io.InputStream;
027: import java.io.IOException;
028: import java.io.EOFException;
029:
030: /**
031: Converts a stream containing the Cloudscape stored binary form
032: to one that just contains the application's data.
033: Simply read and save the length information.
034: */
035: final class BinaryToRawStream extends java.io.FilterInputStream {
036: /**
037: * Length of the value represented by this stream.
038: * Set to -1 if the length is unknown.
039: */
040: private int length;
041:
042: // used by caller to insure that parent can not be GC'd until this
043: // stream is no longer being used.
044: private Object parent;
045:
046: BinaryToRawStream(InputStream in, Object parent) throws IOException {
047: super (in);
048:
049: this .parent = parent;
050:
051: int bl = in.read();
052: if (bl == -1)
053: throw new java.io.EOFException();
054:
055: if ((bl & 0x80) != 0) {
056: if (bl == 0xC0) {
057: int v1 = in.read();
058: int v2 = in.read();
059: int v3 = in.read();
060: int v4 = in.read();
061:
062: if (v1 == -1 || v2 == -1 || v3 == -1 || v4 == -1)
063: throw new java.io.EOFException();
064: length = (((v1 & 0xff) << 24) | ((v2 & 0xff) << 16)
065: | ((v3 & 0xff) << 8) | (v4 & 0xff));
066:
067: } else if (bl == 0xA0) {
068: // read an unsigned short
069: int v1 = in.read();
070: int v2 = in.read();
071: if (v1 == -1 || v2 == -1)
072: throw new java.io.EOFException();
073: length = (((v1 & 0xff) << 8) + (v2 & 0xff));
074:
075: } else {
076: length = bl & 0x1F;
077: }
078: } else {
079: // old length in bits
080: int v2 = in.read();
081: int v3 = in.read();
082: int v4 = in.read();
083: if (v2 == -1 || v3 == -1 || v4 == -1)
084: throw new java.io.EOFException();
085: int lenInBits = (((bl & 0xff) << 24) | ((v2 & 0xff) << 16)
086: | ((v3 & 0xff) << 8) | (v4 & 0xff));
087:
088: length = lenInBits / 8;
089: if ((lenInBits % 8) != 0)
090: length++;
091:
092: // Signifies unknown length
093: if (length == 0)
094: length = -1;
095: }
096: }
097:
098: /**
099: * Return the length of the value in thie stream in bytes.
100: * If the value is unknown then -1 is returned.
101: */
102: int getLength() {
103: return length;
104: }
105: }
|