001: //kelondrobyteArray.java
002: // (C) 2007 by Michael Peter Christen; mc@anomic.de, Frankfurt a. M., Germany
003: // first published 30.03.2007 on http://yacy.net
004: //
005: // This is a part of YaCy, a peer-to-peer based web search engine
006: //
007: // $LastChangedDate: 2006-04-02 22:40:07 +0200 (So, 02 Apr 2006) $
008: // $LastChangedRevision: 1986 $
009: // $LastChangedBy: orbiter $
010: //
011: // LICENSE
012: //
013: // This program is free software; you can redistribute it and/or modify
014: // it under the terms of the GNU General Public License as published by
015: // the Free Software Foundation; either version 2 of the License, or
016: // (at your option) any later version.
017: //
018: // This program is distributed in the hope that it will be useful,
019: // but WITHOUT ANY WARRANTY; without even the implied warranty of
020: // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
021: // GNU General Public License for more details.
022: //
023: // You should have received a copy of the GNU General Public License
024: // along with this program; if not, write to the Free Software
025: // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
026:
027: package de.anomic.kelondro;
028:
029: import java.io.IOException;
030: import java.io.UnsupportedEncodingException;
031:
032: // this class is a experimental replacement of byte[]. It should be used
033: // if frequent System.arraycopy usage is common for byte[] data types
034: // when replaced by this class, all copies share the same byte[] but can
035: // access a different part of the byte array
036:
037: public class kelondroByteArray {
038:
039: private byte[] buffer;
040: private int offset;
041: private int length;
042:
043: public kelondroByteArray(int initLength) {
044: this .buffer = new byte[initLength];
045: this .length = 0;
046: this .offset = 0;
047: }
048:
049: public kelondroByteArray(byte[] bb) {
050: this .buffer = bb;
051: this .length = bb.length;
052: this .offset = 0;
053: }
054:
055: public kelondroByteArray(byte[] bb, int offset, int length) {
056: this .buffer = bb;
057: this .length = length;
058: this .offset = offset;
059: }
060:
061: public kelondroByteArray(kelondroByteArray ba, int offset,
062: int length) {
063: this .buffer = ba.buffer;
064: this .length = length;
065: this .offset = ba.offset + offset;
066: }
067:
068: public void ensureSize(int needed) {
069: if (buffer.length - offset >= needed)
070: return;
071: byte[] newbuffer = new byte[needed];
072: System.arraycopy(buffer, offset, newbuffer, 0, length);
073: buffer = newbuffer;
074: offset = 0;
075: newbuffer = null;
076: }
077:
078: public void trim(int needed) {
079: if (buffer.length - offset < needed)
080: return;
081: if (buffer.length - offset == length)
082: return;
083: byte[] newbuffer = new byte[needed];
084: System.arraycopy(buffer, offset, newbuffer, 0, length);
085: buffer = newbuffer;
086: offset = 0;
087: newbuffer = null;
088: }
089:
090: public final void removeShift(int pos, int dist, int upBound) {
091: assert (pos + dist >= 0) : "pos = " + pos + ", dist = " + dist;
092: assert (pos >= 0) : "pos = " + pos;
093: assert (this .offset + upBound <= buffer.length) : "upBound = "
094: + upBound + ", buffer.length = " + buffer.length;
095: assert (this .offset + upBound - dist <= buffer.length) : "dist = "
096: + dist
097: + ", upBound = "
098: + upBound
099: + ", buffer.length = " + buffer.length;
100: System.arraycopy(buffer, this .offset + pos + dist, buffer,
101: this .offset + pos, upBound - pos - dist);
102: }
103:
104: public final void swap(int i, int j, int size) {
105: if (this .offset + this .length + size <= buffer.length) {
106: // there is space in the chunkcache that we can use as buffer
107: System.arraycopy(buffer, this .offset + size * i, buffer,
108: buffer.length - size, size);
109: System.arraycopy(buffer, this .offset + size * j, buffer,
110: this .offset + size * i, size);
111: System.arraycopy(buffer, buffer.length - size, buffer,
112: this .offset + size * j, size);
113: } else {
114: // allocate a chunk to use as buffer
115: byte[] a = new byte[size];
116: System
117: .arraycopy(buffer, this .offset + size * i, a, 0,
118: size);
119: System.arraycopy(buffer, this .offset + size * j, buffer,
120: this .offset + size * i, size);
121: System
122: .arraycopy(a, 0, buffer, this .offset + size * j,
123: size);
124: }
125: }
126:
127: public void clear() {
128: length = 0;
129: offset = 0;
130: }
131:
132: public int length() {
133: return length;
134: }
135:
136: public byte[] asBytes() {
137: byte[] tmp = new byte[length];
138: System.arraycopy(buffer, offset, tmp, 0, length);
139: return tmp;
140: }
141:
142: public byte readByte(int pos) {
143: return buffer[this .offset + pos];
144: }
145:
146: public long readLongB64e(int pos, int length) {
147: return kelondroBase64Order.enhancedCoder.decodeLong(buffer,
148: this .offset + pos, length);
149: }
150:
151: public long readLongB256(int pos, int length) {
152: return kelondroNaturalOrder.decodeLong(buffer, this .offset
153: + pos, length);
154: }
155:
156: public byte[] readBytes(int from_pos, int length) {
157: byte[] buf = new byte[length];
158: System
159: .arraycopy(buffer, this .offset + from_pos, buf, 0,
160: length);
161: return buf;
162: }
163:
164: public String readString(int from_pos, int length) {
165: return new String(buffer, this .offset + from_pos, length);
166: }
167:
168: public String readString(int from_pos, int length, String encoding) {
169: try {
170: return new String(buffer, this .offset + from_pos, length,
171: encoding);
172: } catch (UnsupportedEncodingException e) {
173: return "";
174: }
175: }
176:
177: public void readToRA(int from_pos, kelondroRA to_file, int len)
178: throws IOException {
179: to_file.write(this .buffer, from_pos, len);
180: }
181:
182: public void write(int to_position, byte b) {
183: buffer[this .offset + to_position] = b;
184: }
185:
186: public void write(int to_position, byte[] from_array,
187: int from_offset, int from_length) {
188: System.arraycopy(from_array, from_offset, this .buffer,
189: this .offset + to_position, from_length);
190: }
191:
192: public void write(int to_position, kelondroByteArray from_array) {
193: System.arraycopy(from_array.buffer, from_array.offset,
194: this .buffer, this .offset + to_position,
195: from_array.length);
196: }
197:
198: public void write(int to_position, kelondroByteArray from_array,
199: int from_offset, int from_length) {
200: System.arraycopy(from_array.buffer, from_array.offset
201: + from_offset, this .buffer, this .offset + to_position,
202: from_length);
203: }
204:
205: public int write(int to_position, kelondroRA from_file, int len)
206: throws IOException {
207: if (len == 0)
208: return 0;
209: return from_file.read(this .buffer, to_position, len);
210: }
211:
212: public static boolean equals(byte[] buffer, byte[] pattern) {
213: return equals(buffer, 0, pattern);
214: }
215:
216: public static boolean equals(byte[] buffer, int offset,
217: byte[] pattern) {
218: // compares two byte arrays: true, if pattern appears completely at offset position
219: if (buffer.length < offset + pattern.length)
220: return false;
221: for (int i = 0; i < pattern.length; i++)
222: if (buffer[offset + i] != pattern[i])
223: return false;
224: return true;
225: }
226:
227: public void reset() {
228: this .length = 0;
229: this .offset = 0;
230: }
231:
232: public int compareTo(kelondroByteArray b, kelondroByteOrder order) {
233: return order.compare(this .buffer, this .offset, this .length,
234: b.buffer, b.offset, b.length);
235: }
236:
237: public int compareTo(int aoffset, int alength, kelondroByteArray b,
238: int boffset, int blength, kelondroByteOrder order) {
239: return order.compare(this.buffer, this.offset + aoffset,
240: alength, b.buffer, b.offset + boffset, blength);
241: }
242: }
|