001: /*
002:
003: Derby - Class org.apache.derby.iapi.util.ByteArray
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.iapi.util;
023:
024: import java.io.ObjectOutput;
025: import java.io.ObjectInput;
026: import java.io.IOException;
027:
028: /**
029: ByteArray wraps java byte arrays (byte[]) to allow
030: byte arrays to be used as keys in hashtables.
031:
032: This is required because the equals function on
033: byte[] directly uses reference equality.
034: <P>
035: This class also allows the trio of array, offset and length
036: to be carried around as a single object.
037: */
038: public final class ByteArray {
039:
040: private byte[] array;
041: private int offset;
042: private int length;
043:
044: /**
045: Create an instance of this class that wraps ths given array.
046: This class does not make a copy of the array, it just saves
047: the reference.
048: */
049: public ByteArray(byte[] array, int offset, int length) {
050: this .array = array;
051: this .offset = offset;
052: this .length = length;
053: }
054:
055: public ByteArray(byte[] array) {
056: this (array, 0, array.length);
057: }
058:
059: public ByteArray() {
060: }
061:
062: public void setBytes(byte[] array) {
063: this .array = array;
064: offset = 0;
065: length = array.length;
066: }
067:
068: public void setBytes(byte[] array, int length) {
069: this .array = array;
070: this .offset = 0;
071: this .length = length;
072: }
073:
074: public void setBytes(byte[] array, int offset, int length) {
075: this .array = array;
076: this .offset = offset;
077: this .length = length;
078: }
079:
080: /**
081: Value equality for byte arrays.
082: */
083: public boolean equals(Object other) {
084: if (other instanceof ByteArray) {
085: ByteArray ob = (ByteArray) other;
086: return ByteArray.equals(array, offset, length, ob.array,
087: ob.offset, ob.length);
088: }
089: return false;
090: }
091:
092: /**
093: */
094: public int hashCode() {
095:
096: byte[] larray = array;
097:
098: int hash = length;
099: for (int i = 0; i < length; i++) {
100: hash += larray[i + offset];
101: }
102: return hash;
103: }
104:
105: public final byte[] getArray() {
106: return array;
107: }
108:
109: public final int getOffset() {
110: return offset;
111: }
112:
113: public final int getLength() {
114: return length;
115: }
116:
117: public final void setLength(int newLength) {
118: length = newLength;
119: }
120:
121: /**
122: * Read this object from a stream of stored objects.
123: *
124: * @param in read this.
125: *
126: * @exception IOException thrown on error
127: */
128: public void readExternal(ObjectInput in) throws IOException {
129: int len = length = in.readInt();
130: offset = 0;
131: array = new byte[len];
132:
133: in.readFully(array, 0, len);
134: }
135:
136: /**
137: * Write the byte array out w/o compression
138: *
139: * @param out write bytes here.
140: *
141: * @exception IOException thrown on error
142: */
143: public void writeExternal(ObjectOutput out) throws IOException {
144: out.writeInt(length);
145: out.write(array, offset, length);
146: }
147:
148: /**
149: Compare two byte arrays using value equality.
150: Two byte arrays are equal if their length is
151: identical and their contents are identical.
152: */
153: private static boolean equals(byte[] a, int aOffset, int aLength,
154: byte[] b, int bOffset, int bLength) {
155:
156: if (aLength != bLength)
157: return false;
158:
159: for (int i = 0; i < aLength; i++) {
160: if (a[i + aOffset] != b[i + bOffset])
161: return false;
162: }
163: return true;
164: }
165: }
|