1 /*******************************************************************************.
2 * Copyright (c) 2011-2012 Ericsson, Ecole Polytechnique de Montreal and others
4 * All rights reserved. This program and the accompanying materials are made
5 * available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
9 * Contributors: Matthew Khouzam - Initial Design and implementation
10 * Contributors: Francis Giraldeau - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.ctf
.core
.event
.io
;
15 import java
.nio
.BufferOverflowException
;
16 import java
.nio
.ByteBuffer
;
17 import java
.nio
.ByteOrder
;
20 * <b><u>BitBuffer</u></b>
22 * TODO Implement me. Please.
24 public class BitBuffer
{
26 // ------------------------------------------------------------------------
28 // ------------------------------------------------------------------------
30 /* default bit width */
31 public static final int BIT_CHAR
= 8;
32 public static final int BIT_SHORT
= 16;
33 public static final int BIT_INT
= 32;
34 public static final int BIT_FLOAT
= 32;
35 public static final int BIT_LONG
= 64;
37 // ------------------------------------------------------------------------
39 // ------------------------------------------------------------------------
41 private ByteBuffer buf
;
43 private ByteOrder byteOrder
;
45 // ------------------------------------------------------------------------
47 // ------------------------------------------------------------------------
50 this(null, ByteOrder
.BIG_ENDIAN
);
53 public BitBuffer(ByteBuffer buf
) {
54 this(buf
, ByteOrder
.BIG_ENDIAN
);
57 public BitBuffer(ByteBuffer buf
, ByteOrder order
) {
63 // ------------------------------------------------------------------------
64 // 'Get' operations on buffer
65 // ------------------------------------------------------------------------
68 * Relative <i>get</i> method for reading 32-bit integer.
70 * Reads next four bytes from the current bit position according to current
73 * @return The int value read from the buffer
76 int val
= getInt(BIT_INT
, true);
82 * Relative <i>get</i> method for reading integer of <i>length</i> bits.
84 * Reads <i>length</i> bits starting at the current position. The result is
85 * signed extended if <i>signed</i> is true. The current position is
86 * increased of <i>length</i> bits.
89 * The length in bits of this integer
91 * The sign extended flag
92 * @return The int value read from the buffer
94 public int getInt(int length
, boolean signed
) {
96 if (!canRead(pos
, length
)) {
97 throw new BufferOverflowException();
102 if (byteOrder
== ByteOrder
.LITTLE_ENDIAN
) {
103 val
= getIntLE(pos
, length
, signed
);
105 val
= getIntBE(pos
, length
, signed
);
112 * Absolute <i>get</i> method for reading integer of <i>length</i> bits.
114 * Reads <i>length</i> bits starting from position <i>index</i>. The result
115 * is signed extended if <i>signed</i> is true. The current position is
116 * increased of <i>length</i> bits.
119 * The start index in bits
121 * The length in bits to read
123 * The sign extended flag
124 * @return The int value read from the buffer
126 public int getInt(int index
, int length
, boolean signed
) {
127 if (!canRead(index
, length
)) {
128 throw new BufferOverflowException();
133 if (byteOrder
== ByteOrder
.LITTLE_ENDIAN
) {
134 return getIntLE(index
, length
, signed
);
136 return getIntBE(index
, length
, signed
);
139 private int getIntBE(int index
, int length
, boolean signed
) {
140 assert ((length
> 0) && (length
<= BIT_INT
));
141 int end
= index
+ length
;
142 int startByte
= index
/ BIT_CHAR
;
143 int endByte
= (end
+ (BIT_CHAR
- 1)) / BIT_CHAR
;
144 int currByte
, lshift
, cshift
, mask
, cmask
, cache
;
147 currByte
= startByte
;
148 cache
= buf
.get(currByte
) & 0xFF;
149 boolean isNeg
= (cache
& (1 << (BIT_CHAR
- (index
% BIT_CHAR
) - 1))) != 0;
150 if (signed
&& isNeg
) {
153 if (startByte
== (endByte
- 1)) {
154 cmask
= cache
>>> ((BIT_CHAR
- (end
% BIT_CHAR
)) % BIT_CHAR
);
155 if (((length
) % BIT_CHAR
) > 0) {
156 mask
= ~
((~
0) << length
);
163 cshift
= index
% BIT_CHAR
;
165 mask
= ~
((~
0) << (BIT_CHAR
- cshift
));
166 cmask
= cache
& mask
;
167 lshift
= BIT_CHAR
- cshift
;
173 for (; currByte
< (endByte
- 1); currByte
++) {
175 value
|= buf
.get(currByte
) & 0xFF;
177 lshift
= end
% BIT_CHAR
;
179 mask
= ~
((~
0) << lshift
);
180 cmask
= buf
.get(currByte
) & 0xFF;
181 cmask
>>>= BIT_CHAR
- lshift
;
187 value
|= buf
.get(currByte
) & 0xFF;
192 private int getIntLE(int index
, int length
, boolean signed
) {
193 assert ((length
> 0) && (length
<= BIT_INT
));
194 int end
= index
+ length
;
195 int startByte
= index
/ BIT_CHAR
;
196 int endByte
= (end
+ (BIT_CHAR
- 1)) / BIT_CHAR
;
197 int currByte
, lshift
, cshift
, mask
, cmask
, cache
, mod
;
200 currByte
= endByte
- 1;
201 cache
= buf
.get(currByte
) & 0xFF;
202 mod
= end
% BIT_CHAR
;
203 lshift
= (mod
> 0) ? mod
: BIT_CHAR
;
204 boolean isNeg
= (cache
& (1 << (lshift
- 1))) != 0;
205 if (signed
&& isNeg
) {
208 if (startByte
== (endByte
- 1)) {
209 cmask
= cache
>>> (index
% BIT_CHAR
);
210 if (((length
) % BIT_CHAR
) > 0) {
211 mask
= ~
((~
0) << length
);
218 cshift
= end
% BIT_CHAR
;
220 mask
= ~
((~
0) << cshift
);
221 cmask
= cache
& mask
;
227 for (; currByte
>= (startByte
+ 1); currByte
--) {
229 value
|= buf
.get(currByte
) & 0xFF;
231 lshift
= index
% BIT_CHAR
;
233 mask
= ~
((~
0) << (BIT_CHAR
- lshift
));
234 cmask
= buf
.get(currByte
) & 0xFF;
237 value
<<= (BIT_CHAR
- lshift
);
241 value
|= buf
.get(currByte
) & 0xFF;
246 // ------------------------------------------------------------------------
247 // 'Put' operations on buffer
248 // ------------------------------------------------------------------------
251 * Relative <i>put</i> method to write signed 32-bit integer.
253 * Write four bytes starting from current bit position in the buffer
254 * according to the current byte order. The current position is increased of
255 * <i>length</i> bits.
258 * The int value to write
260 public void putInt(int value
) {
261 putInt(BIT_INT
, value
);
265 * Relative <i>put</i> method to write <i>length</i> bits integer.
267 * Writes <i>length</i> lower-order bits from the provided <i>value</i>,
268 * starting from current bit position in the buffer. Sequential bytes are
269 * written according to the current byte order. The sign bit is carried to
270 * the MSB if signed is true. The sign bit is included in <i>length</i>. The
271 * current position is increased of <i>length</i>.
274 * The number of bits to write
278 public void putInt(int length
, int value
) {
279 putInt(this.pos
, length
, value
);
283 * Absolute <i>put</i> method to write <i>length</i> bits integer.
285 * Writes <i>length</i> lower-order bits from the provided <i>value</i>,
286 * starting from <i>index</i> position in the buffer. Sequential bytes are
287 * written according to the current byte order. The sign bit is carried to
288 * the MSB if signed is true. The sign bit is included in <i>length</i>. The
289 * current position is increased of <i>length</i>.
292 * The start position to write the value
296 * The number of bits to write
298 public void putInt(int index
, int length
, int value
) {
299 if (!canRead(index
, length
)) {
300 throw new BufferOverflowException();
305 if (byteOrder
== ByteOrder
.LITTLE_ENDIAN
) {
306 putIntLE(index
, length
, value
);
308 putIntBE(index
, length
, value
);
312 private void putIntBE(int index
, int length
, int value
) {
313 assert ((length
> 0) && (length
<= BIT_INT
));
314 int end
= index
+ length
;
315 int startByte
= index
/ BIT_CHAR
;
316 int endByte
= (end
+ (BIT_CHAR
- 1)) / BIT_CHAR
;
317 int currByte
, lshift
, cshift
, mask
, cmask
;
318 int correctedValue
= value
;
321 * mask v high bits. Works for unsigned and two complement signed
322 * numbers which value do not overflow on length bits.
325 if (length
< BIT_INT
) {
326 correctedValue
&= ~
(~
0 << length
);
330 if (startByte
== (endByte
- 1)) {
331 lshift
= (BIT_CHAR
- (end
% BIT_CHAR
)) % BIT_CHAR
;
332 mask
= ~
((~
0) << lshift
);
333 if ((index
% BIT_CHAR
) > 0) {
334 mask
|= (~
(0)) << (BIT_CHAR
- (index
% BIT_CHAR
));
336 cmask
= correctedValue
<< lshift
;
338 * low bits are cleared because of lshift and high bits are already
342 int b
= buf
.get(startByte
) & 0xFF;
343 buf
.put(startByte
, (byte) ((b
& mask
) | cmask
));
347 /* head byte contains MSB */
348 currByte
= endByte
- 1;
349 cshift
= end
% BIT_CHAR
;
351 lshift
= BIT_CHAR
- cshift
;
352 mask
= ~
((~
0) << lshift
);
353 cmask
= correctedValue
<< lshift
;
355 int b
= buf
.get(currByte
) & 0xFF;
356 buf
.put(currByte
, (byte) ((b
& mask
) | cmask
));
357 correctedValue
>>>= cshift
;
363 for (; currByte
>= (startByte
+ 1); currByte
--) {
364 buf
.put(currByte
, (byte) correctedValue
);
365 correctedValue
>>>= BIT_CHAR
;
367 /* end byte contains LSB */
368 if ((index
% BIT_CHAR
) > 0) {
369 mask
= (~
0) << (BIT_CHAR
- (index
% BIT_CHAR
));
370 cmask
= correctedValue
& ~mask
;
371 int b
= buf
.get(currByte
) & 0xFF;
372 buf
.put(currByte
, (byte) ((b
& mask
) | cmask
));
374 buf
.put(currByte
, (byte) correctedValue
);
378 private void putIntLE(int index
, int length
, int value
) {
379 assert ((length
> 0) && (length
<= BIT_INT
));
380 int end
= index
+ length
;
381 int startByte
= index
/ BIT_CHAR
;
382 int endByte
= (end
+ (BIT_CHAR
- 1)) / BIT_CHAR
;
383 int currByte
, lshift
, cshift
, mask
, cmask
;
384 int correctedValue
= value
;
387 * mask v high bits. Works for unsigned and two complement signed
388 * numbers which value do not overflow on length bits.
391 if (length
< BIT_INT
) {
392 correctedValue
&= ~
(~
0 << length
);
396 if (startByte
== (endByte
- 1)) {
397 lshift
= index
% BIT_CHAR
;
398 mask
= ~
((~
0) << lshift
);
399 if ((end
% BIT_CHAR
) > 0) {
400 mask
|= (~
(0)) << (end
% BIT_CHAR
);
402 cmask
= correctedValue
<< lshift
;
404 * low bits are cleared because of lshift and high bits are already
408 int b
= buf
.get(startByte
) & 0xFF;
409 buf
.put(startByte
, (byte) ((b
& mask
) | cmask
));
414 currByte
= startByte
;
415 cshift
= index
% BIT_CHAR
;
417 mask
= ~
((~
0) << cshift
);
418 cmask
= correctedValue
<< cshift
;
420 int b
= buf
.get(currByte
) & 0xFF;
421 buf
.put(currByte
, (byte) ((b
& mask
) | cmask
));
422 correctedValue
>>>= BIT_CHAR
- cshift
;
423 // index += BIT_CHAR - cshift;
428 for (; currByte
< (endByte
- 1); currByte
++) {
429 buf
.put(currByte
, (byte) correctedValue
);
430 correctedValue
>>>= BIT_CHAR
;
433 if ((end
% BIT_CHAR
) > 0) {
434 mask
= (~
0) << (end
% BIT_CHAR
);
435 cmask
= correctedValue
& ~mask
;
436 int b
= buf
.get(currByte
) & 0xFF;
437 buf
.put(currByte
, (byte) ((b
& mask
) | cmask
));
439 buf
.put(currByte
, (byte) correctedValue
);
443 // ------------------------------------------------------------------------
444 // Buffer attributes handling
445 // ------------------------------------------------------------------------
447 public boolean canRead(int length
) {
448 return canRead(pos
, length
);
451 public boolean canRead(int index
, int length
) {
456 if ((index
+ length
) > (buf
.capacity() * BIT_CHAR
)) {
462 public void order(ByteOrder order
) {
463 this.byteOrder
= order
;
469 public ByteOrder
order() {
473 public void position(int newPosition
) {
474 this.pos
= newPosition
;
477 public int position() {
481 public void setByteBuffer(ByteBuffer buf
) {
484 this.buf
.order(byteOrder
);
489 public ByteBuffer
getByteBuffer() {
493 public void setByteOrder(ByteOrder byteOrder
) {
494 this.byteOrder
= byteOrder
;
497 public ByteOrder
getByteOrder() {
501 public void clear() {
This page took 0.058751 seconds and 5 git commands to generate.