Updated Buffer and Matcher Classes (#171)
[jpf-core.git] / src / classes / java / nio / ByteBuffer.java
1 /*
2  * Copyright (C) 2014, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The Java Pathfinder core (jpf-core) platform is licensed under the
7  * Apache License, Version 2.0 (the "License"); you may not use this file except
8  * in compliance with the License. You may obtain a copy of the License at
9  * 
10  *        http://www.apache.org/licenses/LICENSE-2.0. 
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and 
16  * limitations under the License.
17  */
18 package java.nio;
19
20 public class ByteBuffer extends Buffer {
21         byte[] array;
22         int offset;
23
24         public static ByteBuffer allocate(int i) {
25                 if (i < 0) {
26                         throw new IllegalArgumentException();
27                 }
28                 ByteBuffer newBuffer = new ByteBuffer(-1, 0, i, i, new byte[i], 0);
29                 return newBuffer;
30         }
31
32         public static ByteBuffer allocateDirect(int capacity) {
33                 return allocate(capacity);
34         }
35
36         ByteBuffer(int mark, int pos, int lim, int cap, byte[] hb, int offset) {
37                 super(mark, pos, lim, cap);
38                 this.array = hb;
39                 this.offset = offset;
40         }
41
42         ByteBuffer(int mark, int pos, int lim, int cap) {
43                 this(mark, pos, lim, cap, null, 0);
44         }
45
46         public ByteBuffer duplicate() {
47                 ByteBuffer copy = new ByteBuffer(-1, 0, capacity, capacity, new byte[capacity], 0);
48                 copy.array = array;
49                 return copy;
50         }
51
52         public ByteBuffer asReadOnlyBuffer() {
53                 return duplicate();
54         }
55
56         public ByteBuffer slice() {
57                 int remaining = limit - position;
58                 ByteBuffer copy = new ByteBuffer(-1, 0, remaining, remaining, new byte[remaining], 0);
59                 copy.array = array;
60                 return copy;
61         }
62
63         public ByteBuffer put(byte b) {
64                 if (position >= limit) {
65                         throw new BufferOverflowException();
66                 }
67                 array[position] = b;
68                 position++;
69                 return this;
70         }
71
72         public ByteBuffer put(int i, byte b) {
73                 if ((i < 0) || (i >= limit)) {
74                         throw new IndexOutOfBoundsException();
75                 }
76                 array[i] = b;
77                 return this;
78         }
79
80         public ByteBuffer put(ByteBuffer src) {
81                 if (src == this) {
82                         throw new IllegalArgumentException();
83                 }
84
85                 int srcRemaining = src.remaining();
86                 if (srcRemaining > remaining()) {
87                         throw new BufferOverflowException();
88                 }
89
90                 System.arraycopy(src.array, src.position(), array, position, srcRemaining);
91
92                 src.position(src.position() + srcRemaining);
93                 position(position + srcRemaining);
94
95                 return this;
96         }
97
98         public ByteBuffer put(byte[] bytes, int offset, int length) {
99                 if ((offset | length | (offset + length) | (bytes.length - (offset + length))) < 0) {
100                         throw new IndexOutOfBoundsException();
101                 }
102
103                 if (length > remaining()) {
104                         throw new BufferOverflowException();
105                 }
106
107                 System.arraycopy(bytes, offset, array, position, length);
108                 position(position + length);
109
110                 return this;
111         }
112
113         public ByteBuffer put(byte[] bytes) {
114                 return put(bytes, 0, bytes.length);
115         }
116
117         public byte get() {
118                 if (position >= limit) {
119                         throw new BufferUnderflowException();
120                 }
121                 position++;
122                 return array[position-1];
123         }
124
125         public byte get(int i) {
126                 if ((i < 0) || (i >= limit)) {
127                         throw new IndexOutOfBoundsException();
128                 }
129                 return array[i];
130         }
131
132         public ByteBuffer get(byte[] bytes) {
133                 return get(bytes, 0, bytes.length);
134         }
135
136         public ByteBuffer get(byte[] bytes, int offset, int length) {
137                 if ((offset | length | (offset + length) | (bytes.length - (offset + length))) < 0) {
138                         throw new IndexOutOfBoundsException();
139                 }
140
141                 if (length > remaining()) {
142                         throw new BufferUnderflowException();
143                 }
144
145                 int end = offset + length;
146                 for (int i = offset; i < end; i++) {
147                         bytes[i] = get();
148                 }
149                 return this;
150         }
151
152         public ByteBuffer order(ByteOrder order) {
153                 return this;
154         }
155
156         /***************************************************************
157          * public char getChar()
158          * @return 16 bit (UTF-16) char of ByteBuffer at this.position 
159          * Caution: 8 or 32 bit character encodings are not supported.
160          */
161         public char getChar() {
162         char res=getChar(this.position);
163         this.position+=2;
164         return res;
165         }
166
167         /***************************************************************
168          * public char getChar(int pos)
169          * @return 16 bit (UTF-16) char of ByteBuffer at int pos 
170          * Caution: 8 or 32 bit character encodings are not supported.
171          */
172         public char getChar(int pos) {
173                 if (limit - pos < 2) {
174                         throw new BufferUnderflowException();
175                 }
176                 int x1 = (array[pos]   & 0xff) << 8;
177                 int x0 = (array[pos+1] & 0xff);
178
179                 return (char) (x1 | x0);
180         }
181
182         /***************************************************************
183          * public ByteBuffer putChar(char c)
184          * @return insert 16 bit (UTF-16) char c at this.position  
185          * Caution: 8 or 32 bit character encodings are not supported.
186          */
187         public ByteBuffer putChar(char c) {
188                 if (limit - position < 2) {
189                         throw new BufferOverflowException();
190                 }
191                 array[position]   = (byte)(c >> 8);
192                 array[position+1] = (byte)(c     );
193                 position += 2;
194
195                 return this;
196         }
197
198         public int getInt() {
199                 if (limit - position < 4) {
200                         throw new BufferUnderflowException();
201                 }
202
203                 int x3 = (array[position  ]       ) << 24;
204                 int x2 = (array[position+1] & 0xff) << 16;
205                 int x1 = (array[position+2] & 0xff) <<  8;
206                 int x0 = (array[position+3] & 0xff);
207                 position += 4;
208
209                 return (x3 | x2 | x1 | x0);
210         }
211
212         public ByteBuffer putInt(int x) {
213                 if (limit - position < 4) {
214                         throw new BufferOverflowException();
215                 }
216
217                 array[position  ] = (byte)(x >> 24);
218                 array[position+1] = (byte)(x >> 16);
219                 array[position+2] = (byte)(x >>  8);
220                 array[position+3] = (byte)(x      );
221                 position += 4;
222
223                 return this;
224         }
225
226         public long getLong() {
227                 if (limit - position < 8) {
228                         throw new BufferUnderflowException();
229                 }
230
231                 long x7 = ((long)(array[position  ]       ) << 56);
232                 long x6 = ((long)(array[position+1] & 0xff) << 48);
233                 long x5 = ((long)(array[position+2] & 0xff) << 40);
234                 long x4 = ((long)(array[position+3] & 0xff) << 32);
235                 long x3 = ((long)(array[position+4] & 0xff) << 24);
236                 long x2 = ((long)(array[position+5] & 0xff) << 16);
237                 long x1 = ((long)(array[position+6] & 0xff) <<  8);
238                 long x0 = (array[position+7] & 0xff      );
239                 position += 8;
240
241                 return (x7 | x6 | x5 | x4 | x3 | x2 | x1 | x0);
242         }
243
244         public ByteBuffer putLong(long x) {
245                 if (limit - position < 8) {
246                         throw new BufferOverflowException();
247                 }
248
249                 array[position  ] = (byte)((x >> 56)       );
250                 array[position+1] = (byte)((x >> 48) & 0xff);
251                 array[position+2] = (byte)((x >> 40) & 0xff);
252                 array[position+3] = (byte)((x >> 32) & 0xff);
253                 array[position+4] = (byte)((x >> 24) & 0xff);
254                 array[position+5] = (byte)((x >> 16) & 0xff);
255                 array[position+6] = (byte)((x >>  8) & 0xff);
256                 array[position+7] = (byte)((x      ) & 0xff);
257                 position += 8;
258
259                 return this;
260         }
261
262         @Override
263         public byte[] array() {
264                 return array;
265         }
266
267         @Override
268         public boolean hasArray() {
269                 return true;
270         }
271
272         public ByteBuffer compact() {
273                 int pos = position();
274                 int lim = limit();
275                 int cap = capacity();
276                 int rem = lim - pos;
277
278                 byte[] newArray = new byte[cap];
279                 System.arraycopy(array, pos, newArray, 0, rem);
280                 array = newArray;
281
282                 position(rem);
283                 limit(cap);
284                 return this;
285         }
286
287         public static ByteBuffer wrap(byte[] outMess) {
288                 ByteBuffer byteBuffer = new ByteBuffer(-1, 0, outMess.length, outMess.length, new byte[outMess.length], 0);
289                 byteBuffer.clear();
290                 System.arraycopy(outMess, 0 , byteBuffer.array, 0, outMess.length);
291                 return byteBuffer;
292         }
293 }