comparison truffle/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/VariableLengthIntBuffer.java @ 21951:9c8c0937da41

Moving all sources into truffle subdirectory
author Jaroslav Tulach <jaroslav.tulach@oracle.com>
date Wed, 17 Jun 2015 10:58:08 +0200
parents graal/com.oracle.truffle.api/src/com/oracle/truffle/api/nodes/serial/VariableLengthIntBuffer.java@96c1d057a5ed
children dc83cc1f94f2
comparison
equal deleted inserted replaced
21950:2a5011c7e641 21951:9c8c0937da41
1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25 package com.oracle.truffle.api.nodes.serial;
26
27 import java.nio.*;
28
29 /**
30 * Experimental API. May change without notice. Simple variable length unsigned int buffer backed by
31 * a byte buffer.
32 */
33 public class VariableLengthIntBuffer {
34
35 public static final int NULL = -1;
36
37 private ByteBuffer buffer;
38
39 public VariableLengthIntBuffer(ByteBuffer buffer) {
40 this.buffer = buffer;
41 }
42
43 public VariableLengthIntBuffer(byte[] array) {
44 buffer = ByteBuffer.wrap(array);
45 }
46
47 /**
48 * Returns the backing byte buffer.
49 */
50 public ByteBuffer getBuffer() {
51 return buffer;
52 }
53
54 public byte[] getBytes() {
55 int pos = buffer.position();
56 byte[] bytes = new byte[buffer.position()];
57 buffer.rewind();
58 buffer.get(bytes);
59 buffer.position(pos);
60 return bytes;
61 }
62
63 public int get() {
64 byte peekByte = buffer.get(buffer.position());
65 if ((peekByte & 0x80) == 0) {
66 // single byte encoding with prefix 0 (range 127)
67 return buffer.get(); // no bit to be masked
68 } else {
69 if (peekByte == (byte) 0xFF) {
70 buffer.get(); // skip one byte
71 return NULL;
72 }
73 int result = buffer.getInt() & 0x7FFF_FFFF; // first bit masked out
74 assert (result & 0x4000_0000) == 0;
75 return result;
76 }
77 }
78
79 public void put(int i) {
80 ensureCapacity();
81 if (i == NULL) {
82 buffer.put((byte) 0xFF);
83 } else if ((i & 0xFFFF_FF80) == 0) { // 7 bits data
84 buffer.put((byte) i);
85 } else if ((i & 0xC000_0000) == 0) { // 32 bits data
86 buffer.putInt(i | 0x8000_0000); // append leading 1
87 } else {
88 throw new IllegalArgumentException("Integer out of encodeable " + i);
89 }
90 }
91
92 private void ensureCapacity() {
93 if (buffer.position() + 4 > buffer.capacity()) {
94 ByteBuffer newBuffer = ByteBuffer.allocate(buffer.capacity() * 2);
95
96 int pos = buffer.position();
97 buffer.rewind();
98 newBuffer.put(buffer);
99 newBuffer.position(pos);
100
101 buffer = newBuffer;
102 }
103 }
104
105 public boolean hasRemaining() {
106 return buffer.hasRemaining();
107 }
108
109 }