KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > filesys > util > DataBuffer


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.filesys.util;
18
19 /**
20  * Data Buffer Class
21  * <p>
22  * Dynamic buffer for getting/setting data blocks.
23  */

24 public class DataBuffer
25 {
26
27     // Constants
28

29     private static final int DefaultBufferSize = 256;
30
31     // Data buffer, current position and offset
32

33     private byte[] m_data;
34     private int m_pos;
35     private int m_endpos;
36     private int m_offset;
37
38     /**
39      * Default constructor
40      */

41     public DataBuffer()
42     {
43         m_data = new byte[DefaultBufferSize];
44         m_pos = 0;
45         m_offset = 0;
46     }
47
48     /**
49      * Create a data buffer to write data to
50      *
51      * @param siz int
52      */

53     public DataBuffer(int siz)
54     {
55         m_data = new byte[siz];
56         m_pos = 0;
57         m_offset = 0;
58     }
59
60     /**
61      * Create a data buffer to read data from
62      *
63      * @param buf byte[]
64      * @param off int
65      * @param len int
66      */

67     public DataBuffer(byte[] buf, int off, int len)
68     {
69         m_data = buf;
70         m_offset = off;
71         m_pos = off;
72         m_endpos = off + len;
73     }
74
75     /**
76      * Return the data buffer
77      *
78      * @return byte[]
79      */

80     public final byte[] getBuffer()
81     {
82         return m_data;
83     }
84
85     /**
86      * Return the data length
87      *
88      * @return int
89      */

90     public final int getLength()
91     {
92         if (m_endpos != 0)
93             return m_endpos - m_offset;
94         return m_pos - m_offset;
95     }
96
97     /**
98      * Return the data length in words
99      *
100      * @return int
101      */

102     public final int getLengthInWords()
103     {
104         return getLength() / 2;
105     }
106
107     /**
108      * Return the available data length
109      *
110      * @return int
111      */

112     public final int getAvailableLength()
113     {
114         if (m_endpos == 0)
115             return -1;
116         return m_endpos - m_pos;
117     }
118
119     /**
120      * Return the displacement from the start of the buffer to the current buffer position
121      *
122      * @return int
123      */

124     public final int getDisplacement()
125     {
126         return m_pos - m_offset;
127     }
128
129     /**
130      * Return the buffer base offset
131      *
132      * @return int
133      */

134     public final int getOffset()
135     {
136         return m_offset;
137     }
138
139     /**
140      * Get a byte from the buffer
141      *
142      * @return int
143      */

144     public final int getByte()
145     {
146
147         // Check if there is enough data in the buffer
148

149         if (m_data.length - m_pos < 1)
150             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
151
152         // Unpack the byte value
153

154         int bval = (int) (m_data[m_pos] & 0xFF);
155         m_pos++;
156         return bval;
157     }
158
159     /**
160      * Get a short from the buffer
161      *
162      * @return int
163      */

164     public final int getShort()
165     {
166
167         // Check if there is enough data in the buffer
168

169         if (m_data.length - m_pos < 2)
170             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
171
172         // Unpack the integer value
173

174         int sval = (int) DataPacker.getIntelShort(m_data, m_pos);
175         m_pos += 2;
176         return sval;
177     }
178
179     /**
180      * Get an integer from the buffer
181      *
182      * @return int
183      */

184     public final int getInt()
185     {
186
187         // Check if there is enough data in the buffer
188

189         if (m_data.length - m_pos < 4)
190             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
191
192         // Unpack the integer value
193

194         int ival = DataPacker.getIntelInt(m_data, m_pos);
195         m_pos += 4;
196         return ival;
197     }
198
199     /**
200      * Get a long (64 bit) value from the buffer
201      *
202      * @return long
203      */

204     public final long getLong()
205     {
206
207         // Check if there is enough data in the buffer
208

209         if (m_data.length - m_pos < 8)
210             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
211
212         // Unpack the long value
213

214         long lval = DataPacker.getIntelLong(m_data, m_pos);
215         m_pos += 8;
216         return lval;
217     }
218
219     /**
220      * Get a string from the buffer
221      *
222      * @param uni boolean
223      * @return String
224      */

225     public final String JavaDoc getString(boolean uni)
226     {
227         return getString(255, uni);
228     }
229
230     /**
231      * Get a string from the buffer
232      *
233      * @param maxlen int
234      * @param uni boolean
235      * @return String
236      */

237     public final String JavaDoc getString(int maxlen, boolean uni)
238     {
239
240         // Check for Unicode or ASCII
241

242         String JavaDoc ret = null;
243         int availLen = -1;
244
245         if (uni)
246         {
247
248             // Word align the current buffer position, calculate the available
249
// length
250

251             m_pos = DataPacker.wordAlign(m_pos);
252             availLen = (m_endpos - m_pos) / 2;
253             if (availLen < maxlen)
254                 maxlen = availLen;
255
256             ret = DataPacker.getUnicodeString(m_data, m_pos, maxlen);
257             if (ret != null) {
258                 if ( ret.length() < maxlen)
259                     m_pos += (ret.length() * 2) + 2;
260                 else
261                     m_pos += maxlen * 2;
262             }
263         }
264         else
265         {
266
267             // Calculate the available length
268

269             availLen = m_endpos - m_pos;
270             if (availLen < maxlen)
271                 maxlen = availLen;
272
273             // Unpack the ASCII string
274

275             ret = DataPacker.getString(m_data, m_pos, maxlen);
276             if (ret != null) {
277                 if ( ret.length() < maxlen)
278                     m_pos += ret.length() + 1;
279                 else
280                     m_pos += maxlen;
281             }
282         }
283
284         // Return the string
285

286         return ret;
287     }
288
289     /**
290      * Get a short from the buffer at the specified index
291      *
292      * @param idx int
293      * @return int
294      */

295     public final int getShortAt(int idx)
296     {
297
298         // Check if there is enough data in the buffer
299

300         int pos = m_offset + (idx * 2);
301         if (m_data.length - pos < 2)
302             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
303
304         // Unpack the integer value
305

306         int sval = (int) DataPacker.getIntelShort(m_data, pos) & 0xFFFF;
307         return sval;
308     }
309
310     /**
311      * Get an integer from the buffer at the specified index
312      *
313      * @param idx int
314      * @return int
315      */

316     public final int getIntAt(int idx)
317     {
318
319         // Check if there is enough data in the buffer
320

321         int pos = m_offset + (idx * 2);
322         if (m_data.length - pos < 4)
323             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
324
325         // Unpack the integer value
326

327         int ival = DataPacker.getIntelInt(m_data, pos);
328         return ival;
329     }
330
331     /**
332      * Get a long (64 bit) value from the buffer at the specified index
333      *
334      * @param idx int
335      * @return long
336      */

337     public final long getLongAt(int idx)
338     {
339
340         // Check if there is enough data in the buffer
341

342         int pos = m_offset + (idx * 2);
343         if (m_data.length - pos < 8)
344             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
345
346         // Unpack the long value
347

348         long lval = DataPacker.getIntelLong(m_data, pos);
349         return lval;
350     }
351
352     /**
353      * Skip over a number of bytes
354      *
355      * @param cnt int
356      */

357     public final void skipBytes(int cnt)
358     {
359
360         // Check if there is enough data in the buffer
361

362         if (m_data.length - m_pos < cnt)
363             throw new ArrayIndexOutOfBoundsException JavaDoc("End of data buffer");
364
365         // Skip bytes
366

367         m_pos += cnt;
368     }
369
370     /**
371      * Return the data position
372      *
373      * @return int
374      */

375     public final int getPosition()
376     {
377         return m_pos;
378     }
379
380     /**
381      * Set the read/write buffer position
382      *
383      * @param pos int
384      */

385     public final void setPosition(int pos)
386     {
387         m_pos = pos;
388     }
389
390     /**
391      * Set the end of buffer position, and reset the read position to the beginning of the buffer
392      */

393     public final void setEndOfBuffer()
394     {
395         m_endpos = m_pos;
396         m_pos = m_offset;
397     }
398
399     /**
400      * Set the data length
401      *
402      * @param len int
403      */

404     public final void setLength(int len)
405     {
406         m_pos = m_offset + len;
407     }
408
409     /**
410      * Append a byte value to the buffer
411      *
412      * @param bval int
413      */

414     public final void putByte(int bval)
415     {
416
417         // Check if there is enough space in the buffer
418

419         if (m_data.length - m_pos < 1)
420             extendBuffer();
421
422         // Pack the byte value
423

424         m_data[m_pos++] = (byte) (bval & 0xFF);
425     }
426
427     /**
428      * Append a short value to the buffer
429      *
430      * @param sval int
431      */

432     public final void putShort(int sval)
433     {
434
435         // Check if there is enough space in the buffer
436

437         if (m_data.length - m_pos < 2)
438             extendBuffer();
439
440         // Pack the short value
441

442         DataPacker.putIntelShort(sval, m_data, m_pos);
443         m_pos += 2;
444     }
445
446     /**
447      * Append an integer to the buffer
448      *
449      * @param ival int
450      */

451     public final void putInt(int ival)
452     {
453
454         // Check if there is enough space in the buffer
455

456         if (m_data.length - m_pos < 4)
457             extendBuffer();
458
459         // Pack the integer value
460

461         DataPacker.putIntelInt(ival, m_data, m_pos);
462         m_pos += 4;
463     }
464
465     /**
466      * Append a long to the buffer
467      *
468      * @param lval long
469      */

470     public final void putLong(long lval)
471     {
472
473         // Check if there is enough space in the buffer
474

475         if (m_data.length - m_pos < 8)
476             extendBuffer();
477
478         // Pack the long value
479

480         DataPacker.putIntelLong(lval, m_data, m_pos);
481         m_pos += 8;
482     }
483
484     /**
485      * Append a short value to the buffer at the specified index
486      *
487      * @param idx int
488      * @param sval int
489      */

490     public final void putShortAt(int idx, int sval)
491     {
492
493         // Check if there is enough space in the buffer
494

495         int pos = m_offset + (idx * 2);
496         if (m_data.length - pos < 2)
497             extendBuffer();
498
499         // Pack the short value
500

501         DataPacker.putIntelShort(sval, m_data, pos);
502     }
503
504     /**
505      * Append an integer to the buffer at the specified index
506      *
507      * @param idx int
508      * @param ival int
509      */

510     public final void putIntAt(int idx, int ival)
511     {
512
513         // Check if there is enough space in the buffer
514

515         int pos = m_offset = (idx * 2);
516         if (m_data.length - pos < 4)
517             extendBuffer();
518
519         // Pack the integer value
520

521         DataPacker.putIntelInt(ival, m_data, pos);
522     }
523
524     /**
525      * Append a long to the buffer at the specified index
526      *
527      * @param idx int
528      * @param lval long
529      */

530     public final void putLongAt(int idx, int lval)
531     {
532
533         // Check if there is enough space in the buffer
534

535         int pos = m_offset = (idx * 2);
536         if (m_data.length - pos < 8)
537             extendBuffer();
538
539         // Pack the long value
540

541         DataPacker.putIntelLong(lval, m_data, pos);
542     }
543
544     /**
545      * Append a string to the buffer
546      *
547      * @param str String
548      * @param uni boolean
549      */

550     public final void putString(String JavaDoc str, boolean uni)
551     {
552         putString(str, uni, true);
553     }
554
555     /**
556      * Append a string to the buffer
557      *
558      * @param str String
559      * @param uni boolean
560      * @param nulTerm boolean
561      */

562     public final void putString(String JavaDoc str, boolean uni, boolean nulTerm)
563     {
564
565         // Check for Unicode or ASCII
566

567         if (uni)
568         {
569
570             // Check if there is enough space in the buffer
571

572             int bytLen = str.length() * 2;
573             if (m_data.length - m_pos < bytLen)
574                 extendBuffer(bytLen + 4);
575
576             // Word align the buffer position, pack the Unicode string
577

578             m_pos = DataPacker.wordAlign(m_pos);
579             DataPacker.putUnicodeString(str, m_data, m_pos, nulTerm);
580             m_pos += (str.length() * 2);
581             if (nulTerm)
582                 m_pos += 2;
583         }
584         else
585         {
586
587             // Check if there is enough space in the buffer
588

589             if (m_data.length - m_pos < str.length())
590                 extendBuffer(str.length() + 2);
591
592             // Pack the ASCII string
593

594             DataPacker.putString(str, m_data, m_pos, nulTerm);
595             m_pos += str.length();
596             if (nulTerm)
597                 m_pos++;
598         }
599     }
600
601     /**
602      * Append a fixed length string to the buffer
603      *
604      * @param str String
605      * @param len int
606      */

607     public final void putFixedString(String JavaDoc str, int len)
608     {
609
610         // Check if there is enough space in the buffer
611

612         if (m_data.length - m_pos < str.length())
613             extendBuffer(str.length() + 2);
614
615         // Pack the ASCII string
616

617         DataPacker.putString(str, len, m_data, m_pos);
618         m_pos += len;
619     }
620
621     /**
622      * Append a string to the buffer at the specified buffer position
623      *
624      * @param str String
625      * @param pos int
626      * @param uni boolean
627      * @param nulTerm boolean
628      * @return int
629      */

630     public final int putStringAt(String JavaDoc str, int pos, boolean uni, boolean nulTerm)
631     {
632
633         // Check for Unicode or ASCII
634

635         int retPos = -1;
636
637         if (uni)
638         {
639
640             // Check if there is enough space in the buffer
641

642             int bytLen = str.length() * 2;
643             if (m_data.length - pos < bytLen)
644                 extendBuffer(bytLen + 4);
645
646             // Word align the buffer position, pack the Unicode string
647

648             pos = DataPacker.wordAlign(pos);
649             retPos = DataPacker.putUnicodeString(str, m_data, pos, nulTerm);
650         }
651         else
652         {
653
654             // Check if there is enough space in the buffer
655

656             if (m_data.length - pos < str.length())
657                 extendBuffer(str.length() + 2);
658
659             // Pack the ASCII string
660

661             retPos = DataPacker.putString(str, m_data, pos, nulTerm);
662         }
663
664         // Return the end of string buffer position
665

666         return retPos;
667     }
668
669     /**
670      * Append a fixed length string to the buffer at the specified position
671      *
672      * @param str String
673      * @param len int
674      * @param pos int
675      * @return int
676      */

677     public final int putFixedStringAt(String JavaDoc str, int len, int pos)
678     {
679
680         // Check if there is enough space in the buffer
681

682         if (m_data.length - pos < str.length())
683             extendBuffer(str.length() + 2);
684
685         // Pack the ASCII string
686

687         return DataPacker.putString(str, len, m_data, pos);
688     }
689
690     /**
691      * Append a string pointer to the specified buffer offset
692      *
693      * @param off int
694      */

695     public final void putStringPointer(int off)
696     {
697
698         // Calculate the offset from the start of the data buffer to the string
699
// position
700

701         DataPacker.putIntelInt(off - m_offset, m_data, m_pos);
702         m_pos += 4;
703     }
704
705     /**
706      * Append zero bytes to the buffer
707      *
708      * @param cnt int
709      */

710     public final void putZeros(int cnt)
711     {
712
713         // Check if there is enough space in the buffer
714

715         if (m_data.length - m_pos < cnt)
716             extendBuffer(cnt);
717
718         // Pack the zero bytes
719

720         for (int i = 0; i < cnt; i++)
721             m_data[m_pos++] = 0;
722     }
723
724     /**
725      * Word align the buffer position
726      */

727     public final void wordAlign()
728     {
729         m_pos = DataPacker.wordAlign(m_pos);
730     }
731
732     /**
733      * Longword align the buffer position
734      */

735     public final void longwordAlign()
736     {
737         m_pos = DataPacker.longwordAlign(m_pos);
738     }
739
740     /**
741      * Append a raw data block to the data buffer
742      *
743      * @param buf byte[]
744      * @param off int
745      * @param len int
746      */

747     public final void appendData(byte[] buf, int off, int len)
748     {
749
750         // Check if there is enough space in the buffer
751

752         if (m_data.length - m_pos < len)
753             extendBuffer(len);
754
755         // Copy the data to the buffer and update the current write position
756

757         System.arraycopy(buf, off, m_data, m_pos, len);
758         m_pos += len;
759     }
760
761     /**
762      * Copy all data from the data buffer to the user buffer, and update the read position
763      *
764      * @param buf byte[]
765      * @param off int
766      * @return int
767      */

768     public final int copyData(byte[] buf, int off)
769     {
770         return copyData(buf, off, getLength());
771     }
772
773     /**
774      * Copy data from the data buffer to the user buffer, and update the current read position.
775      *
776      * @param buf byte[]
777      * @param off int
778      * @param cnt int
779      * @return int
780      */

781     public final int copyData(byte[] buf, int off, int cnt)
782     {
783
784         // Check if there is any more data to copy
785

786         if (m_pos == m_endpos)
787             return 0;
788
789         // Calculate the amount of data to copy
790

791         int siz = m_endpos - m_pos;
792         if (siz > cnt)
793             siz = cnt;
794
795         // Copy the data to the user buffer and update the current read position
796

797         System.arraycopy(m_data, m_pos, buf, off, siz);
798         m_pos += siz;
799
800         // Return the amount of data copied
801

802         return siz;
803     }
804
805     /**
806      * Extend the data buffer by the specified amount
807      *
808      * @param ext int
809      */

810     private final void extendBuffer(int ext)
811     {
812
813         // Create a new buffer of the required size
814

815         byte[] newBuf = new byte[m_data.length + ext];
816
817         // Copy the data from the current buffer to the new buffer
818

819         System.arraycopy(m_data, 0, newBuf, 0, m_data.length);
820
821         // Set the new buffer to be the main buffer
822

823         m_data = newBuf;
824     }
825
826     /**
827      * Extend the data buffer, double the currently allocated buffer size
828      */

829     private final void extendBuffer()
830     {
831         extendBuffer(m_data.length * 2);
832     }
833
834     /**
835      * Return the data buffer details as a string
836      *
837      * @return String
838      */

839     public String JavaDoc toString()
840     {
841         StringBuffer JavaDoc str = new StringBuffer JavaDoc();
842
843         str.append("[data=");
844         str.append(m_data);
845         str.append(",");
846         str.append(m_pos);
847         str.append("/");
848         str.append(m_offset);
849         str.append("/");
850         str.append(getLength());
851         str.append("]");
852
853         return str.toString();
854     }
855 }
856
Popular Tags