1 /* 2 * Copyright (c) 2014, 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 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 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 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 26 package jdk.internal.jimage; 27 28 import java.nio.ByteBuffer; 29 import java.nio.ByteOrder; 30 import java.util.Arrays; 31 32 class ImageStream { 33 private ByteBuffer buffer; 34 35 ImageStream() { 36 this(1024, ByteOrder.nativeOrder()); 37 } 38 39 ImageStream(int size) { 40 this(size, ByteOrder.nativeOrder()); 41 } 42 43 ImageStream(byte[] bytes) { 44 this(bytes, ByteOrder.nativeOrder()); 45 } 46 47 ImageStream(ByteOrder byteOrder) { 48 this(1024, byteOrder); 49 } 50 51 ImageStream(int size, ByteOrder byteOrder) { 52 buffer = ByteBuffer.allocate(size); 53 buffer.order(byteOrder); 54 } 55 56 ImageStream(byte[] bytes, ByteOrder byteOrder) { 57 buffer = ByteBuffer.wrap(bytes); 58 buffer.order(byteOrder); 59 } 60 61 ImageStream(ByteBuffer buffer) { 62 this.buffer = buffer; 63 } 64 65 ImageStream align(int alignment) { 66 int padding = (getSize() - 1) & ((1 << alignment) - 1); 67 68 for (int i = 0; i < padding; i++) { 69 put((byte)0); 70 } 71 72 return this; 73 } 74 75 private void ensure(int needs) { 76 assert 0 <= needs : "Negative needs"; 77 78 if (needs > buffer.remaining()) { 79 byte[] bytes = buffer.array(); 80 ByteOrder byteOrder = buffer.order(); 81 int position = buffer.position(); 82 int newSize = needs <= bytes.length ? bytes.length << 1 : position + needs; 83 buffer = ByteBuffer.allocate(newSize); 84 buffer.order(byteOrder); 85 buffer.put(bytes, 0, position); 86 } 87 } 88 89 boolean hasByte() { 90 return buffer.remaining() != 0; 91 } 92 93 boolean hasBytes(int needs) { 94 return needs <= buffer.remaining(); 95 } 96 97 void skip(int n) { 98 assert 0 <= n : "Negative offset"; 99 buffer.position(buffer.position() + n); 100 } 101 102 int get() { 103 return buffer.get() & 0xFF; 104 } 105 106 void get(byte bytes[], int offset, int size) { 107 buffer.get(bytes, offset, size); 108 } 109 110 int getShort() { 111 return buffer.getShort(); 112 } 113 114 int getInt() { 115 return buffer.getInt(); 116 } 117 118 long getLong() { 119 return buffer.getLong(); 120 } 121 122 ImageStream put(byte byt) { 123 ensure(1); 124 buffer.put(byt); 125 126 return this; 127 } 128 129 ImageStream put(int byt) { 130 return put((byte)byt); 131 } 132 133 ImageStream put(byte bytes[], int offset, int size) { 134 ensure(size); 135 buffer.put(bytes, offset, size); 136 137 return this; 138 } 139 140 ImageStream put(ImageStream stream) { 141 put(stream.buffer.array(), 0, stream.buffer.position()); 142 143 return this; 144 } 145 146 ImageStream putShort(short value) { 147 ensure(2); 148 buffer.putShort(value); 149 150 return this; 151 } 152 153 ImageStream putShort(int value) { 154 return putShort((short)value); 155 } 156 157 ImageStream putInt(int value) { 158 ensure(4); 159 buffer.putInt(value); 160 161 return this; 162 } 163 164 ImageStream putLong(long value) { 165 ensure(8); 166 buffer.putLong(value); 167 168 return this; 169 } 170 171 ByteBuffer getBuffer() { 172 return buffer; 173 } 174 175 int getPosition() { 176 return buffer.position(); 177 } 178 179 int getSize() { 180 return buffer.position(); 181 } 182 183 byte[] getBytes() { 184 return buffer.array(); 185 } 186 187 void setPosition(int offset) { 188 buffer.position(offset); 189 } 190 191 byte[] toArray() { 192 return Arrays.copyOf(buffer.array(), buffer.position()); 193 } 194 }