KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > caucho > util > ByteBuffer


1 /*
2  * Copyright (c) 1998-2006 Caucho Technology -- all rights reserved
3  *
4  * This file is part of Resin(R) Open Source
5  *
6  * Each copy or derived work must preserve the copyright notice and this
7  * notice unmodified.
8  *
9  * Resin Open Source is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * Resin Open Source is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
17  * of NON-INFRINGEMENT. See the GNU General Public License for more
18  * details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Resin Open Source; if not, write to the
22  * Free SoftwareFoundation, Inc.
23  * 59 Temple Place, Suite 330
24  * Boston, MA 02111-1307 USA
25  *
26  * @author Scott Ferguson
27  */

28
29 package com.caucho.util;
30
31 import com.caucho.vfs.ReadStream;
32 import com.caucho.vfs.VfsStream;
33
34 import java.io.IOException JavaDoc;
35 import java.io.InputStream JavaDoc;
36 import java.io.OutputStream JavaDoc;
37 import java.io.UnsupportedEncodingException JavaDoc;
38
39 /**
40  * A variable-length byte buffer, similar to a character buffer.
41  *
42  * <p>The byte buffer is unsynchronized.
43  */

44 public final class ByteBuffer {
45   private byte []_buffer;
46   private int _capacity;
47   private int _length;
48
49   public ByteBuffer(int minimumCapacity)
50   {
51     _capacity = 32;
52     if (minimumCapacity > 0x1000) {
53       _capacity = (minimumCapacity + 0xfff) & ~0xfff;
54     } else {
55       while (_capacity < minimumCapacity) {
56     _capacity += _capacity;
57       }
58     }
59
60     _buffer = new byte[minimumCapacity];
61     _length = 0;
62   }
63
64   public ByteBuffer()
65   {
66     _buffer = new byte[32];
67     _capacity = _buffer.length;
68     _length = 0;
69   }
70
71   /**
72    * Returns the actual capacity of the buffer, i.e. how many bytes it
73    * can hold.
74    */

75   public int capacity()
76   {
77     return _capacity;
78   }
79
80   public int hashCode()
81   {
82     int hash = 17;
83     for (int i = _length - 1; i >= 0; i--) {
84       hash = 65537 * hash + _buffer[i];
85     }
86
87     return hash;
88   }
89
90   /**
91    * Ensure the buffer can hold at least 'minimumCapacity' bytes.
92    */

93   public void ensureCapacity(int minimumCapacity)
94   {
95     if (minimumCapacity <= _capacity)
96       return;
97
98     if (minimumCapacity > 0x1000) {
99       _capacity = (minimumCapacity + 0xfff) & ~0xfff;
100     } else {
101       while (_capacity < minimumCapacity) {
102     _capacity += _capacity;
103       }
104     }
105
106     byte []bytes = new byte[_capacity];
107
108     System.arraycopy(_buffer, 0, bytes, 0, _length);
109
110     _buffer = bytes;
111   }
112
113   /**
114    * Returns the buffer length
115    */

116   public int length()
117   {
118     return _length;
119   }
120
121   public int size()
122   {
123     return _length;
124   }
125   /**
126    * Returns the buffer length
127    */

128   public int getLength()
129   {
130     return _length;
131   }
132
133   /**
134    * Set the buffer.
135    */

136   public void setLength(int len)
137   {
138     if (len < 0)
139       throw new RuntimeException JavaDoc("illegal argument");
140     else if (len > _capacity)
141       ensureCapacity(len);
142
143     _length = len;
144   }
145
146   public void clear()
147   {
148     _length = 0;
149   }
150   
151   /**
152    * Returns the byte array for the buffer.
153    */

154   public byte []getBuffer() { return _buffer; }
155
156   /**
157    * Add a byte to the buffer.
158    */

159   public void append(int b)
160   {
161     if (_length + 1 > _capacity)
162       ensureCapacity(_length + 1);
163
164     _buffer[_length++] = (byte) b;
165   }
166
167   /**
168    * Inserts a byte array
169    */

170   public void add(int i, byte []buffer, int offset, int length)
171   {
172     if (_length + length > _capacity)
173       ensureCapacity(_length + length);
174
175     System.arraycopy(_buffer, i, _buffer, i + length, _length - i);
176     System.arraycopy(buffer, offset, _buffer, i, length);
177
178     _length += length;
179   }
180
181   public void add(byte []buffer, int offset, int length)
182   {
183     if (_capacity < _length + length)
184       ensureCapacity(_length + length);
185
186     System.arraycopy(buffer, offset, _buffer, _length, length);
187
188     _length += length;
189   }
190
191   /**
192    * Inserts a byte array
193    */

194   public void add(int i, int data)
195   {
196     if (_length + 1 > _capacity)
197       ensureCapacity(_length + 1);
198
199     System.arraycopy(_buffer, i, _buffer, i + 1, _length - i);
200     _buffer[i] = (byte) data;
201
202     _length += 1;
203   }
204
205   public void add(int data)
206   {
207     if (_capacity < _length + 1)
208       ensureCapacity(_length + 1);
209
210     _buffer[_length++] = (byte) data;
211   }
212
213   public void set(int i, byte []buffer, int offset, int length)
214   {
215     System.arraycopy(buffer, offset, _buffer, i, length);
216   }
217
218   public void set(int i, int data)
219   {
220     _buffer[i] = (byte) data;
221   }
222
223   public void insert(int i, byte []buffer, int offset, int length)
224   {
225     if (_length + length > _capacity)
226       ensureCapacity(_length + length);
227
228     System.arraycopy(_buffer, i, _buffer, i + length, _length - i);
229     System.arraycopy(_buffer, offset, _buffer, i, length);
230
231     _length += length;
232   }
233
234   /**
235    * Inserts a byte array
236    */

237   public void replace(int i, byte []buffer, int offset, int length)
238   {
239     System.arraycopy(buffer, offset, _buffer, i, length);
240   }
241
242   /**
243    * Inserts a byte array
244    */

245   public void append(byte []buffer, int offset, int length)
246   {
247     if (_length + length >= _capacity)
248       ensureCapacity(_length + length);
249
250     System.arraycopy(buffer, offset, _buffer, _length, length);
251
252     _length += length;
253   }
254
255   public void addByte(int v)
256   {
257     add(v);
258   }
259
260   /**
261    * Inserts a short into the buffer
262    */

263   public void replaceShort(int i, int s)
264   {
265     _buffer[i] = (byte) (s >> 8);
266     _buffer[i + 1] = (byte) (s);
267   }
268
269   /**
270    * Appends a short (little endian) in the buffer
271    */

272   public void appendShort(int s)
273   {
274     if (_length + 2 > _capacity)
275       ensureCapacity(_length + 2);
276
277     replaceShort(_length, s);
278
279     _length += 2;
280   }
281
282   public void addShort(int s)
283   {
284     if (_length + 2 > _capacity)
285       ensureCapacity(_length + 2);
286
287     _buffer[_length++] = (byte) (s >> 8);
288     _buffer[_length++] = (byte) s;
289   }
290
291   public void addShort(int i, int s)
292   {
293     add(i, (byte) (s >> 8));
294     add(i + 1, (byte) (s));
295   }
296
297   public void setShort(int i, int s)
298   {
299     _buffer[i] = (byte) (s >> 8);
300     _buffer[i + 1] = (byte) (s);
301   }
302
303   /**
304    * Inserts a int (little endian) into the buffer
305    */

306   public void replaceInt(int i, int v)
307   {
308     _buffer[i] = (byte) (v >> 24);
309     _buffer[i + 1] = (byte) (v >> 16);
310     _buffer[i + 2] = (byte) (v >> 8);
311     _buffer[i + 3] = (byte) (v);
312   }
313
314   /**
315    * Appends an int (little endian) in the buffer
316    */

317   public void appendInt(int s)
318   {
319     if (_length + 4 > _capacity)
320       ensureCapacity(_length + 4);
321
322     _buffer[_length++] = (byte) (s >> 24);
323     _buffer[_length++] = (byte) (s >> 16);
324     _buffer[_length++] = (byte) (s >> 8);
325     _buffer[_length++] = (byte) s;
326   }
327
328   public void addInt(int s)
329   {
330     if (_capacity < _length + 4)
331       ensureCapacity(_length + 4);
332
333     _buffer[_length++] = (byte) (s >> 24);
334     _buffer[_length++] = (byte) (s >> 16);
335     _buffer[_length++] = (byte) (s >> 8);
336     _buffer[_length++] = (byte) s;
337   }
338
339   public void addInt(int i, int s)
340   {
341     add(i + 0, (byte) (s >> 24));
342     add(i + 1, (byte) (s >> 16));
343     add(i + 2, (byte) (s >> 8));
344     add(i + 3, (byte) (s));
345   }
346
347   public void setInt(int i, int v)
348   {
349     _buffer[i] = (byte) (v >> 24);
350     _buffer[i + 1] = (byte) (v >> 16);
351     _buffer[i + 2] = (byte) (v >> 8);
352     _buffer[i + 3] = (byte) (v);
353   }
354
355   public void addLong(long v)
356   {
357     if (_length + 8 > _capacity)
358       ensureCapacity(_length + 8);
359
360     _buffer[_length++] = (byte) (v >> 56L);
361     _buffer[_length++] = (byte) (v >> 48L);
362     _buffer[_length++] = (byte) (v >> 40L);
363     _buffer[_length++] = (byte) (v >> 32L);
364     
365     _buffer[_length++] = (byte) (v >> 24L);
366     _buffer[_length++] = (byte) (v >> 16L);
367     _buffer[_length++] = (byte) (v >> 8L);
368     _buffer[_length++] = (byte) v;
369   }
370
371   public void addFloat(float v)
372   {
373     if (_length + 4 > _capacity)
374       ensureCapacity(_length + 4);
375
376     int bits = Float.floatToIntBits(v);
377
378     _buffer[_length++] = (byte) (bits >> 24);
379     _buffer[_length++] = (byte) (bits >> 16);
380     _buffer[_length++] = (byte) (bits >> 8);
381     _buffer[_length++] = (byte) bits;
382   }
383
384   public void addDouble(double v)
385   {
386     if (_length + 8 > _capacity)
387       ensureCapacity(_length + 8);
388
389     long bits = Double.doubleToLongBits(v);
390
391     _buffer[_length++] = (byte) (bits >> 56);
392     _buffer[_length++] = (byte) (bits >> 48);
393     _buffer[_length++] = (byte) (bits >> 40);
394     _buffer[_length++] = (byte) (bits >> 32);
395     _buffer[_length++] = (byte) (bits >> 24);
396     _buffer[_length++] = (byte) (bits >> 16);
397     _buffer[_length++] = (byte) (bits >> 8);
398     _buffer[_length++] = (byte) bits;
399   }
400
401   public void addString(String JavaDoc s)
402   {
403     int len = s.length();
404     if (len + _length > _capacity)
405       ensureCapacity(_length + len);
406
407     for (int i = 0; i < len; i++)
408       _buffer[_length++] = (byte) s.charAt(i);
409   }
410
411   /**
412    * Adds a string with a specified encoding.
413    */

414   public void addString(String JavaDoc s, String JavaDoc encoding)
415   {
416     if (encoding == null || encoding.equals("ISO-8859-1")) {
417       addString(s);
418       return;
419     }
420
421     // XXX: special case for utf-8?
422

423     byte []bytes = null;
424
425     try {
426       bytes = s.getBytes(encoding);
427     } catch (UnsupportedEncodingException JavaDoc e) {
428       addString(s);
429       return;
430     }
431     
432     int len = bytes.length;
433     if (len + _length > _capacity)
434       ensureCapacity(_length + len);
435
436     for (int i = 0; i < len; i++)
437       _buffer[_length++] = bytes[i];
438   }
439
440   public void add(String JavaDoc s)
441   {
442     int len = s.length();
443     if (len + _length > _capacity)
444       ensureCapacity(_length + len);
445
446     for (int i = 0; i < len; i++)
447       _buffer[_length++] = (byte) s.charAt(i);
448   }
449
450   public void add(char []s, int offset, int len)
451   {
452     if (len + _length > _capacity)
453       ensureCapacity(_length + len);
454
455     for (int i = 0; i < len; i++)
456       _buffer[_length++] = (byte) s[offset + i];
457   }
458
459   public void add(CharBuffer cb)
460   {
461     int len = cb.length();
462     
463     if (len + _length > _capacity)
464       ensureCapacity(_length + len);
465
466     char []s = cb.getBuffer();
467
468     for (int i = 0; i < len; i++)
469       _buffer[_length++] = (byte) s[i];
470   }
471
472   public void remove(int begin, int length)
473   {
474     System.arraycopy(_buffer, begin + length, _buffer, begin,
475              _capacity - length - begin);
476
477     _length -= length;
478   }
479
480   /**
481    * Appends an int (little endian) in the buffer
482    */

483   public void append(String JavaDoc string)
484   {
485     for (int i = 0; i < string.length(); i++)
486       append(string.charAt(i));
487   }
488
489   /**
490    * Returns the byte at the specified offset.
491    */

492   public byte byteAt(int i)
493   {
494     if (i < 0 || i > _length)
495       throw new RuntimeException JavaDoc();
496
497     return _buffer[i];
498   }
499   /**
500    * Returns the byte at the specified offset.
501    */

502   public void setByteAt(int i, int b)
503   {
504     _buffer[i] = (byte) b;
505   }
506
507   public byte get(int i)
508   {
509     if (i < 0 || i >= _length)
510       throw new RuntimeException JavaDoc("out of bounds: " + i + " len: " + _length);
511
512     return _buffer[i];
513   }
514
515   public short getShort(int i)
516   {
517     if (i < 0 || i + 1 >= _length)
518       throw new RuntimeException JavaDoc("out of bounds: " + i + " len: " + _length);
519
520     return (short) (((_buffer[i] & 0xff) << 8) +
521             (_buffer[i + 1] & 0xff));
522   }
523
524   public int getInt(int i)
525   {
526     if (i < 0 || i + 3 >= _length)
527       throw new RuntimeException JavaDoc("out of bounds: " + i + " len: " + _length);
528
529     return (((_buffer[i + 0] & 0xff) << 24) +
530         ((_buffer[i + 1] & 0xff) << 16) +
531         ((_buffer[i + 2] & 0xff) << 8) +
532         ((_buffer[i + 3] & 0xff)));
533   }
534
535   public void print(int i)
536   {
537     if (_length + 16 >= _capacity)
538       ensureCapacity(_length + 16);
539
540     if (i < 0) {
541       _buffer[_length++] = (byte) '-';
542       i = -i;
543     } else if (i == 0) {
544       _buffer[_length++] = (byte) '0';
545       return;
546     }
547
548     int start = _length;
549     while (i > 0) {
550       _buffer[_length++] = (byte) ((i % 10) + '0');
551       i /= 10;
552     }
553
554     for (int j = (_length - start) / 2; j > 0; j--) {
555       byte temp = _buffer[_length - j];
556       _buffer[_length - j] = _buffer[start + j - 1];
557       _buffer[start + j - 1] = temp;
558     }
559   }
560
561   /**
562    * Clones the buffer
563    */

564   public Object JavaDoc clone()
565   {
566     ByteBuffer newBuffer = new ByteBuffer(_length);
567
568     System.arraycopy(_buffer, 0, newBuffer._buffer, 0, _length);
569
570     return newBuffer;
571   }
572
573   public boolean equals(Object JavaDoc b)
574   {
575     if (! (b instanceof ByteBuffer))
576       return false;
577
578     ByteBuffer bb = (ByteBuffer) b;
579     if (bb._length != _length)
580       return false;
581
582     for (int i = _length - 1; i >= 0; i--)
583       if (bb._buffer[i] != _buffer[i])
584     return false;
585
586     return true;
587   }
588
589   public InputStream JavaDoc createInputStream()
590   {
591     return new BBInputStream(this);
592   }
593
594   public OutputStream JavaDoc createOutputStream()
595   {
596     return new BBOutputStream(this);
597   }
598   
599   public ReadStream createReadStream()
600   {
601     return VfsStream.openRead(new BBInputStream(this));
602   }
603
604   /**
605    * Returns the bytes
606    */

607   public byte []getByteArray()
608   {
609     byte []bytes = new byte[_length];
610
611     System.arraycopy(_buffer, 0, bytes, 0, _length);
612
613     return bytes;
614   }
615   
616
617   /**
618    * String representation of the buffer.
619    */

620   public String JavaDoc toString()
621   {
622     return new String JavaDoc(_buffer, 0, _length);
623   }
624
625   public String JavaDoc toString(String JavaDoc encoding)
626   {
627     try {
628       return new String JavaDoc(_buffer, 0, _length, encoding);
629     } catch (Exception JavaDoc e) {
630       return new String JavaDoc(_buffer, 0, _length);
631     }
632   }
633
634   static class BBInputStream extends InputStream JavaDoc {
635     ByteBuffer _buf;
636     int _index;
637
638     public int available()
639     {
640       return _buf._length - _index;
641     }
642     
643     public int read() throws IOException JavaDoc
644     {
645       if (_index >= _buf._length)
646     return -1;
647       else
648     return _buf._buffer[_index++] & 0xff;
649     }
650
651     BBInputStream(ByteBuffer buf)
652     {
653       _buf = buf;
654     }
655   }
656
657   static class BBOutputStream extends OutputStream JavaDoc {
658     ByteBuffer _buf;
659
660     public void write(int ch) throws IOException JavaDoc
661     {
662       _buf.append(ch);
663     }
664
665     BBOutputStream(ByteBuffer buf)
666     {
667       _buf = buf;
668     }
669   }
670 }
671
672
673
Popular Tags