--- /dev/null
+/*******************************************************************************\r
+ * Copyright (c) 2007, 2010 Association for Decentralized Information Management\r
+ * in Industry THTH ry.\r
+ * All rights reserved. This program and the accompanying materials\r
+ * are made available under the terms of the Eclipse Public License v1.0\r
+ * which accompanies this distribution, and is available at\r
+ * http://www.eclipse.org/legal/epl-v10.html\r
+ *\r
+ * Contributors:\r
+ * VTT Technical Research Centre of Finland - initial API and implementation\r
+ *******************************************************************************/\r
+package org.simantics.db.server.protocol;\r
+\r
+import java.io.PrintStream;\r
+import java.io.UnsupportedEncodingException;\r
+import java.nio.ByteBuffer;\r
+import java.nio.ByteOrder;\r
+import java.nio.CharBuffer;\r
+import java.nio.charset.CharacterCodingException;\r
+import java.nio.charset.Charset;\r
+import java.nio.charset.CharsetDecoder;\r
+import java.nio.charset.CodingErrorAction;\r
+\r
+public class DataBuffer {\r
+ private static final Charset UTF8 = Charset.forName("UTF-8");\r
+ private boolean DEBUG = false;\r
+ private ByteBuffer buffer = null;\r
+ enum Allocation { JavaAllocation, DirectAllocation }\r
+ DataBuffer(Allocation a) {\r
+ switch (a) {\r
+ case JavaAllocation:\r
+ buffer = ByteBuffer.allocate(20);\r
+ break;\r
+ case DirectAllocation:\r
+ buffer = ByteBuffer.allocate(20);\r
+ break;\r
+ }\r
+ }\r
+ DataBuffer(byte[] bytes, int size) {\r
+ buffer = ByteBuffer.allocate(size);\r
+ buffer.put(bytes, 0, size);\r
+ buffer.rewind();\r
+ }\r
+ DataBuffer(byte[] bytes) {\r
+ buffer = ByteBuffer.wrap(bytes);\r
+ buffer.rewind();\r
+ }\r
+ public DataBuffer(ByteBuffer byteBuffer) {\r
+ buffer = byteBuffer.duplicate();\r
+ buffer.order(byteBuffer.order());\r
+ }\r
+ public DataBuffer(ByteBuffer byteBuffer, int dummy) {\r
+ buffer = byteBuffer;\r
+ }\r
+ public ByteBuffer getByteBuffer() {\r
+ return buffer;\r
+ }\r
+ private void checkCapacity(int a) {\r
+ if (buffer.capacity() - buffer.position() >= a)\r
+ return;\r
+ ByteBuffer t = buffer;\r
+ int capacity = t.capacity();\r
+ int position = t.position();\r
+ int newCapacity = capacity + Math.max(capacity/2, a);\r
+ buffer = ByteBuffer.allocate(newCapacity);\r
+ t.clear();\r
+ buffer.put(t);\r
+ buffer.position(position);\r
+ buffer.order(t.order());\r
+ }\r
+ public void clear() {\r
+ buffer.clear();\r
+ }\r
+ public void order(ByteOrder byteOrder) {\r
+ buffer.order(byteOrder);\r
+ }\r
+ public void mark() {\r
+ buffer.mark();\r
+ }\r
+ public void position(int position) {\r
+ buffer.position(position);\r
+ }\r
+ public byte[] getBytes() {\r
+ byte[] t = new byte[buffer.position()];\r
+ buffer.clear();\r
+ buffer.get(t);\r
+ return t;\r
+ }\r
+ public short get(short a) {\r
+ return buffer.getShort();\r
+ }\r
+ public int get(int a) {\r
+ return buffer.getInt();\r
+ }\r
+ public void put(int a) {\r
+ checkCapacity(4);\r
+ buffer.putInt(a);\r
+ }\r
+ public int[] get(int[] a) {\r
+ int size = buffer.getInt();\r
+ int[] t = new int[size];\r
+ buffer.asIntBuffer().get(t);\r
+ buffer.position(buffer.position() + size * 4);\r
+ return t;\r
+ }\r
+ public void put(int[] a) {\r
+ if (null == a)\r
+ a = new int[0];\r
+ checkCapacity(4 + 4*a.length);\r
+ this.put(a.length);\r
+ for (int i=0; i<a.length; ++i)\r
+ buffer.putInt(a[i]);\r
+ }\r
+ public long[] get(long[] a) {\r
+ int size = buffer.getInt();\r
+ long[] t = new long[size];\r
+ buffer.asLongBuffer().get(t, 0, size);\r
+ buffer.position(buffer.position() + 8 * size);\r
+ return t;\r
+ }\r
+ public void put(long[] a) {\r
+ checkCapacity(4 + 8*a.length);\r
+ this.put(a.length);\r
+ for (int i=0; i<a.length; ++i)\r
+ buffer.putLong(a[i]);\r
+ }\r
+ public boolean get(boolean a) {\r
+ byte b = buffer.get();\r
+ return !(0 == b);\r
+ }\r
+ public void put(boolean a) {\r
+ checkCapacity(1);\r
+ byte b = a ? (byte)0xff : (byte)0;\r
+ buffer.put(b);\r
+ }\r
+ public byte get(byte a) {\r
+ return buffer.get();\r
+ }\r
+ public void put(byte a) {\r
+ checkCapacity(1);\r
+ buffer.put(a);\r
+ }\r
+ public byte[] get(byte[] a) {\r
+ int size = buffer.getInt();\r
+ byte[] t = new byte[size];\r
+ buffer.get(t, 0, size);\r
+ return t;\r
+ }\r
+ public void put(byte[] a) {\r
+ checkCapacity(4 + a.length);\r
+ this.put(a.length);\r
+ buffer.put(a);\r
+ }\r
+ public ByteBuffer get(ByteBuffer a) {\r
+ int size = buffer.getInt();\r
+ byte[] t = new byte[size];\r
+ buffer.get(t, 0, size);\r
+ a.put(t);\r
+ return a;\r
+ }\r
+ public void put(ByteBuffer a) {\r
+ byte[] t = a.array();\r
+ checkCapacity(4 + t.length);\r
+ this.put(t.length);\r
+ buffer.put(t);\r
+ }\r
+ public static void printChars(PrintStream out, ByteBuffer buf, int pos) {\r
+ out.print("[" + buf.limit() + "]");\r
+ for(int i=pos;i<buf.limit();++i) {\r
+ int val = (int)buf.get(i);\r
+ if(val < 0)\r
+ val += 256;\r
+ char c = (char)val;\r
+ if(c >= 32 && c < 128)\r
+ out.print(c);\r
+ else if(c==0)\r
+ out.print('\u00A4');\r
+ else\r
+ out.print("(" + val + ")");\r
+ }\r
+ out.println();\r
+ }\r
+ public String get(String a) {\r
+ byte[] t = null;\r
+ t = this.get(t);\r
+ CharsetDecoder decoder = UTF8.newDecoder();\r
+ ByteBuffer bbuf = ByteBuffer.wrap(t);\r
+ CharBuffer cbuf;\r
+ String s = null;\r
+ try {\r
+ cbuf = decoder.decode(bbuf);\r
+ s = cbuf.toString();\r
+ } catch (CharacterCodingException e) {\r
+ bbuf.rewind();\r
+ if (DEBUG)\r
+ printChars(System.err, bbuf, 0);\r
+ try {\r
+ cbuf = UTF8\r
+ .newDecoder()\r
+ .onMalformedInput(CodingErrorAction.REPLACE)\r
+ .onUnmappableCharacter(CodingErrorAction.REPLACE)\r
+ .decode(bbuf);\r
+ s = cbuf.toString();\r
+ } catch (CharacterCodingException e1) {\r
+ throw new Error("not possible", e1);\r
+ }\r
+ }\r
+ return s;\r
+ }\r
+ public void put(String a) {\r
+ try {\r
+ put(a.getBytes(UTF8.name()));\r
+ } catch (UnsupportedEncodingException e) {\r
+ throw new Error("UnsupportedEncoding: " + UTF8.name());\r
+ }\r
+ }\r
+ public long get(long a) {\r
+ return buffer.getLong();\r
+ }\r
+ public void put(long a) {\r
+ checkCapacity(8);\r
+ buffer.putLong(a);\r
+ }\r
+ public float get(float f) {\r
+ return buffer.getFloat();\r
+ }\r
+ public void put(float a) {\r
+ checkCapacity(4);\r
+ buffer.putFloat(a);\r
+ }\r
+ public double get(double f) {\r
+ return buffer.getDouble();\r
+ }\r
+ public void put(double a) {\r
+ checkCapacity(8);\r
+ buffer.putDouble(a);\r
+ }\r
+ public String[] get(String[] a) {\r
+ int size = buffer.getInt();\r
+ String[] t = new String[size];\r
+ for (int i=0; i<size; ++i)\r
+ t[i] = this.get(t[i]);\r
+ return t;\r
+ }\r
+ public void put(String[] a) {\r
+ checkCapacity(4);\r
+ this.put(a.length);\r
+ for (int i=0; i<a.length; ++i)\r
+ this.put(a[i]);\r
+ }\r
+}\r