1 /*******************************************************************************
\r
2 * Copyright (c) 2007, 2010 Association for Decentralized Information Management
\r
3 * in Industry THTH ry.
\r
4 * All rights reserved. This program and the accompanying materials
\r
5 * are made available under the terms of the Eclipse Public License v1.0
\r
6 * which accompanies this distribution, and is available at
\r
7 * http://www.eclipse.org/legal/epl-v10.html
\r
10 * VTT Technical Research Centre of Finland - initial API and implementation
\r
11 *******************************************************************************/
\r
12 package org.simantics.db.server.protocol;
\r
14 import java.io.PrintStream;
\r
15 import java.io.UnsupportedEncodingException;
\r
16 import java.nio.ByteBuffer;
\r
17 import java.nio.ByteOrder;
\r
18 import java.nio.CharBuffer;
\r
19 import java.nio.charset.CharacterCodingException;
\r
20 import java.nio.charset.Charset;
\r
21 import java.nio.charset.CharsetDecoder;
\r
22 import java.nio.charset.CodingErrorAction;
\r
24 public class DataBuffer {
\r
25 private static final Charset UTF8 = Charset.forName("UTF-8");
\r
26 private boolean DEBUG = false;
\r
27 private ByteBuffer buffer = null;
\r
28 enum Allocation { JavaAllocation, DirectAllocation }
\r
29 DataBuffer(Allocation a) {
\r
31 case JavaAllocation:
\r
32 buffer = ByteBuffer.allocate(20);
\r
34 case DirectAllocation:
\r
35 buffer = ByteBuffer.allocate(20);
\r
39 DataBuffer(byte[] bytes, int size) {
\r
40 buffer = ByteBuffer.allocate(size);
\r
41 buffer.put(bytes, 0, size);
\r
44 DataBuffer(byte[] bytes) {
\r
45 buffer = ByteBuffer.wrap(bytes);
\r
48 public DataBuffer(ByteBuffer byteBuffer) {
\r
49 buffer = byteBuffer.duplicate();
\r
50 buffer.order(byteBuffer.order());
\r
52 public DataBuffer(ByteBuffer byteBuffer, int dummy) {
\r
53 buffer = byteBuffer;
\r
55 public ByteBuffer getByteBuffer() {
\r
58 private void checkCapacity(int a) {
\r
59 if (buffer.capacity() - buffer.position() >= a)
\r
61 ByteBuffer t = buffer;
\r
62 int capacity = t.capacity();
\r
63 int position = t.position();
\r
64 int newCapacity = capacity + Math.max(capacity/2, a);
\r
65 buffer = ByteBuffer.allocate(newCapacity);
\r
68 buffer.position(position);
\r
69 buffer.order(t.order());
\r
71 public void clear() {
\r
74 public void order(ByteOrder byteOrder) {
\r
75 buffer.order(byteOrder);
\r
77 public void mark() {
\r
80 public void position(int position) {
\r
81 buffer.position(position);
\r
83 public byte[] getBytes() {
\r
84 byte[] t = new byte[buffer.position()];
\r
89 public short get(short a) {
\r
90 return buffer.getShort();
\r
92 public int get(int a) {
\r
93 return buffer.getInt();
\r
95 public void put(int a) {
\r
99 public int[] get(int[] a) {
\r
100 int size = buffer.getInt();
\r
101 int[] t = new int[size];
\r
102 buffer.asIntBuffer().get(t);
\r
103 buffer.position(buffer.position() + size * 4);
\r
106 public void put(int[] a) {
\r
109 checkCapacity(4 + 4*a.length);
\r
110 this.put(a.length);
\r
111 for (int i=0; i<a.length; ++i)
\r
112 buffer.putInt(a[i]);
\r
114 public long[] get(long[] a) {
\r
115 int size = buffer.getInt();
\r
116 long[] t = new long[size];
\r
117 buffer.asLongBuffer().get(t, 0, size);
\r
118 buffer.position(buffer.position() + 8 * size);
\r
121 public void put(long[] a) {
\r
122 checkCapacity(4 + 8*a.length);
\r
123 this.put(a.length);
\r
124 for (int i=0; i<a.length; ++i)
\r
125 buffer.putLong(a[i]);
\r
127 public boolean get(boolean a) {
\r
128 byte b = buffer.get();
\r
131 public void put(boolean a) {
\r
133 byte b = a ? (byte)0xff : (byte)0;
\r
136 public byte get(byte a) {
\r
137 return buffer.get();
\r
139 public void put(byte a) {
\r
143 public byte[] get(byte[] a) {
\r
144 int size = buffer.getInt();
\r
145 byte[] t = new byte[size];
\r
146 buffer.get(t, 0, size);
\r
149 public void put(byte[] a) {
\r
150 checkCapacity(4 + a.length);
\r
151 this.put(a.length);
\r
154 public ByteBuffer get(ByteBuffer a) {
\r
155 int size = buffer.getInt();
\r
156 byte[] t = new byte[size];
\r
157 buffer.get(t, 0, size);
\r
161 public void put(ByteBuffer a) {
\r
162 byte[] t = a.array();
\r
163 checkCapacity(4 + t.length);
\r
164 this.put(t.length);
\r
167 public static void printChars(PrintStream out, ByteBuffer buf, int pos) {
\r
168 out.print("[" + buf.limit() + "]");
\r
169 for(int i=pos;i<buf.limit();++i) {
\r
170 int val = (int)buf.get(i);
\r
173 char c = (char)val;
\r
174 if(c >= 32 && c < 128)
\r
177 out.print('\u00A4');
\r
179 out.print("(" + val + ")");
\r
183 public String get(String a) {
\r
186 CharsetDecoder decoder = UTF8.newDecoder();
\r
187 ByteBuffer bbuf = ByteBuffer.wrap(t);
\r
191 cbuf = decoder.decode(bbuf);
\r
192 s = cbuf.toString();
\r
193 } catch (CharacterCodingException e) {
\r
196 printChars(System.err, bbuf, 0);
\r
200 .onMalformedInput(CodingErrorAction.REPLACE)
\r
201 .onUnmappableCharacter(CodingErrorAction.REPLACE)
\r
203 s = cbuf.toString();
\r
204 } catch (CharacterCodingException e1) {
\r
205 throw new Error("not possible", e1);
\r
210 public void put(String a) {
\r
212 put(a.getBytes(UTF8.name()));
\r
213 } catch (UnsupportedEncodingException e) {
\r
214 throw new Error("UnsupportedEncoding: " + UTF8.name());
\r
217 public long get(long a) {
\r
218 return buffer.getLong();
\r
220 public void put(long a) {
\r
224 public float get(float f) {
\r
225 return buffer.getFloat();
\r
227 public void put(float a) {
\r
229 buffer.putFloat(a);
\r
231 public double get(double f) {
\r
232 return buffer.getDouble();
\r
234 public void put(double a) {
\r
236 buffer.putDouble(a);
\r
238 public String[] get(String[] a) {
\r
239 int size = buffer.getInt();
\r
240 String[] t = new String[size];
\r
241 for (int i=0; i<size; ++i)
\r
242 t[i] = this.get(t[i]);
\r
245 public void put(String[] a) {
\r
247 this.put(a.length);
\r
248 for (int i=0; i<a.length; ++i)
\r