EncodingUtils.java
0001 /*
0002  *
0003  * Licensed to the Apache Software Foundation (ASF) under one
0004  * or more contributor license agreements.  See the NOTICE file
0005  * distributed with this work for additional information
0006  * regarding copyright ownership.  The ASF licenses this file
0007  * to you under the Apache License, Version 2.0 (the
0008  * "License"); you may not use this file except in compliance
0009  * with the License.  You may obtain a copy of the License at
0010  *
0011  *   http://www.apache.org/licenses/LICENSE-2.0
0012  *
0013  * Unless required by applicable law or agreed to in writing,
0014  * software distributed under the License is distributed on an
0015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
0016  * KIND, either express or implied.  See the License for the
0017  * specific language governing permissions and limitations
0018  * under the License.
0019  *
0020  */
0021 package org.apache.qpid.framing;
0022 
0023 import org.apache.mina.common.ByteBuffer;
0024 
0025 import org.slf4j.Logger;
0026 import org.slf4j.LoggerFactory;
0027 
0028 import java.nio.charset.Charset;
0029 
0030 public class EncodingUtils
0031 {
0032     private static final Logger _logger = LoggerFactory.getLogger(EncodingUtils.class);
0033 
0034     private static final String STRING_ENCODING = "iso8859-15";
0035 
0036     private static final Charset _charset = Charset.forName("iso8859-15");
0037 
0038     public static final int SIZEOF_UNSIGNED_SHORT = 2;
0039     public static final int SIZEOF_UNSIGNED_INT = 4;
0040     private static final boolean[] ALL_FALSE_ARRAY = new boolean[8];
0041 
0042     public static int encodedShortStringLength(String s)
0043     {
0044         if (s == null)
0045         {
0046             return 1;
0047         }
0048         else
0049         {
0050             return (short) (+ s.length());
0051         }
0052     }
0053 
0054     public static int encodedShortStringLength(short s)
0055     {
0056         if (s == 0)
0057         {
0058             return 1;
0059         }
0060 
0061         int len = 0;
0062         if (s < 0)
0063         {
0064             len = 1;
0065             // sloppy - doesn't work of Integer.MIN_VALUE
0066             s = (short-s;
0067         }
0068 
0069         if (s > 9999)
0070         {
0071             return 5;
0072         }
0073         else if (s > 999)
0074         {
0075             return 4;
0076         }
0077         else if (s > 99)
0078         {
0079             return 3;
0080         }
0081         else if (s > 9)
0082         {
0083             return 2;
0084         }
0085         else
0086         {
0087             return 1;
0088         }
0089 
0090     }
0091 
0092     public static int encodedShortStringLength(int i)
0093     {
0094         if (i == 0)
0095         {
0096             return 1;
0097         }
0098 
0099         int len = 0;
0100         if (i < 0)
0101         {
0102             len = 1;
0103             // sloppy - doesn't work of Integer.MIN_VALUE
0104             i = -i;
0105         }
0106 
0107         // range is now 1 - 2147483647
0108         if (i < Short.MAX_VALUE)
0109         {
0110             return len + encodedShortStringLength((shorti);
0111         }
0112         else if (i > 999999)
0113         {
0114             return len + + encodedShortStringLength((short) (i / 1000000));
0115         }
0116         else // if (i > 99999)
0117         {
0118             return len + + encodedShortStringLength((short) (i / 100000));
0119         }
0120 
0121     }
0122 
0123     public static int encodedShortStringLength(long l)
0124     {
0125         if (l == 0)
0126         {
0127             return 1;
0128         }
0129 
0130         int len = 0;
0131         if (l < 0)
0132         {
0133             len = 1;
0134             // sloppy - doesn't work of Long.MIN_VALUE
0135             l = -l;
0136         }
0137 
0138         if (l < Integer.MAX_VALUE)
0139         {
0140             return len + encodedShortStringLength((intl);
0141         }
0142         else if (l > 9999999999L)
0143         {
0144             return len + 10 + encodedShortStringLength((int) (l / 10000000000L));
0145         }
0146         else
0147         {
0148             return len + + encodedShortStringLength((int) (l / 10L));
0149         }
0150 
0151     }
0152 
0153     public static int encodedShortStringLength(AMQShortString s)
0154     {
0155         if (s == null)
0156         {
0157             return 1;
0158         }
0159         else
0160         {
0161             return (+ s.length());
0162         }
0163     }
0164 
0165     public static int encodedLongStringLength(String s)
0166     {
0167         if (s == null)
0168         {
0169             return 4;
0170         }
0171         else
0172         {
0173             return + s.length();
0174         }
0175     }
0176 
0177     public static int encodedLongStringLength(char[] s)
0178     {
0179         if (s == null)
0180         {
0181             return 4;
0182         }
0183         else
0184         {
0185             return + s.length;
0186         }
0187     }
0188 
0189     public static int encodedLongstrLength(byte[] bytes)
0190     {
0191         if (bytes == null)
0192         {
0193             return 4;
0194         }
0195         else
0196         {
0197             return + bytes.length;
0198         }
0199     }
0200 
0201     public static int encodedFieldTableLength(FieldTable table)
0202     {
0203         if (table == null)
0204         {
0205             // length is encoded as 4 octets
0206             return 4;
0207         }
0208         else
0209         {
0210             // length of the table plus 4 octets for the length
0211             return (inttable.getEncodedSize() 4;
0212         }
0213     }
0214 
0215     public static int encodedContentLength(Content table)
0216     {
0217         // TODO: New Content class required for AMQP 0-9.
0218         return 0;
0219     }
0220 
0221     public static void writeShortStringBytes(ByteBuffer buffer, String s)
0222     {
0223         if (s != null)
0224         {
0225             byte[] encodedString = new byte[s.length()];
0226             char[] cha = s.toCharArray();
0227             for (int i = 0; i < cha.length; i++)
0228             {
0229                 encodedString[i(bytecha[i];
0230             }
0231 
0232             // TODO: check length fits in an unsigned byte
0233             writeUnsignedByte(buffer,  (short)encodedString.length);
0234             buffer.put(encodedString);
0235 
0236 
0237         }
0238         else
0239         {
0240             // really writing out unsigned byte
0241             buffer.put((byte0);
0242         }
0243     }
0244 
0245     public static void writeShortStringBytes(ByteBuffer buffer, AMQShortString s)
0246     {
0247         if (s != null)
0248         {
0249 
0250             s.writeToBuffer(buffer);
0251         }
0252         else
0253         {
0254             // really writing out unsigned byte
0255             buffer.put((byte0);
0256         }
0257     }
0258 
0259     public static void writeLongStringBytes(ByteBuffer buffer, String s)
0260     {
0261         assert (s == null|| (s.length() <= 0xFFFE);
0262         if (s != null)
0263         {
0264             int len = s.length();
0265             writeUnsignedInteger(buffer, s.length());
0266             byte[] encodedString = new byte[len];
0267             char[] cha = s.toCharArray();
0268             for (int i = 0; i < cha.length; i++)
0269             {
0270                 encodedString[i(bytecha[i];
0271             }
0272 
0273             buffer.put(encodedString);
0274         }
0275         else
0276         {
0277             writeUnsignedInteger(buffer, 0);
0278         }
0279     }
0280 
0281     public static void writeLongStringBytes(ByteBuffer buffer, char[] s)
0282     {
0283         assert (s == null|| (s.length <= 0xFFFE);
0284         if (s != null)
0285         {
0286             int len = s.length;
0287             writeUnsignedInteger(buffer, s.length);
0288             byte[] encodedString = new byte[len];
0289             for (int i = 0; i < s.length; i++)
0290             {
0291                 encodedString[i(bytes[i];
0292             }
0293 
0294             buffer.put(encodedString);
0295         }
0296         else
0297         {
0298             writeUnsignedInteger(buffer, 0);
0299         }
0300     }
0301 
0302     public static void writeLongStringBytes(ByteBuffer buffer, byte[] bytes)
0303     {
0304         assert (bytes == null|| (bytes.length <= 0xFFFE);
0305         if (bytes != null)
0306         {
0307             writeUnsignedInteger(buffer, bytes.length);
0308             buffer.put(bytes);
0309         }
0310         else
0311         {
0312             writeUnsignedInteger(buffer, 0);
0313         }
0314     }
0315 
0316     public static void writeUnsignedByte(ByteBuffer buffer, short b)
0317     {
0318         byte bv = (byteb;
0319         buffer.put(bv);
0320     }
0321 
0322     public static void writeUnsignedShort(ByteBuffer buffer, int s)
0323     {
0324         // TODO: Is this comparison safe? Do I need to cast RHS to long?
0325         if (s < Short.MAX_VALUE)
0326         {
0327             buffer.putShort((shorts);
0328         }
0329         else
0330         {
0331             short sv = (shorts;
0332             buffer.put((byte) (0xFF (sv >> 8)));
0333             buffer.put((byte) (0xFF & sv));
0334         }
0335     }
0336 
0337     public static int unsignedIntegerLength()
0338     {
0339         return 4;
0340     }
0341 
0342     public static void writeUnsignedInteger(ByteBuffer buffer, long l)
0343     {
0344         // TODO: Is this comparison safe? Do I need to cast RHS to long?
0345         if (l < Integer.MAX_VALUE)
0346         {
0347             buffer.putInt((intl);
0348         }
0349         else
0350         {
0351             int iv = (intl;
0352 
0353             // FIXME: This *may* go faster if we build this into a local 4-byte array and then
0354             // put the array in a single call.
0355             buffer.put((byte) (0xFF (iv >> 24)));
0356             buffer.put((byte) (0xFF (iv >> 16)));
0357             buffer.put((byte) (0xFF (iv >> 8)));
0358             buffer.put((byte) (0xFF & iv));
0359         }
0360     }
0361 
0362     public static void writeFieldTableBytes(ByteBuffer buffer, FieldTable table)
0363     {
0364         if (table != null)
0365         {
0366             table.writeToBuffer(buffer);
0367         }
0368         else
0369         {
0370             EncodingUtils.writeUnsignedInteger(buffer, 0);
0371         }
0372     }
0373 
0374     public static void writeContentBytes(ByteBuffer buffer, Content content)
0375     {
0376         // TODO: New Content class required for AMQP 0-9.
0377     }
0378 
0379     public static void writeBooleans(ByteBuffer buffer, boolean[] values)
0380     {
0381         byte packedValue = 0;
0382         for (int i = 0; i < values.length; i++)
0383         {
0384             if (values[i])
0385             {
0386                 packedValue = (byte) (packedValue | (<< i));
0387             }
0388         }
0389 
0390         buffer.put(packedValue);
0391     }
0392 
0393     public static void writeBooleans(ByteBuffer buffer, boolean value)
0394     {
0395 
0396         buffer.put(value ? (byte(byte0);
0397     }
0398 
0399     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1)
0400     {
0401         byte packedValue = value0 ? (byte(byte0;
0402 
0403         if (value1)
0404         {
0405             packedValue = (byte) (packedValue | (byte) (<< 1));
0406         }
0407 
0408         buffer.put(packedValue);
0409     }
0410 
0411     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2)
0412     {
0413         byte packedValue = value0 ? (byte(byte0;
0414 
0415         if (value1)
0416         {
0417             packedValue = (byte) (packedValue | (byte) (<< 1));
0418         }
0419 
0420         if (value2)
0421         {
0422             packedValue = (byte) (packedValue | (byte) (<< 2));
0423         }
0424 
0425         buffer.put(packedValue);
0426     }
0427 
0428     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3)
0429     {
0430         byte packedValue = value0 ? (byte(byte0;
0431 
0432         if (value1)
0433         {
0434             packedValue = (byte) (packedValue | (byte) (<< 1));
0435         }
0436 
0437         if (value2)
0438         {
0439             packedValue = (byte) (packedValue | (byte) (<< 2));
0440         }
0441 
0442         if (value3)
0443         {
0444             packedValue = (byte) (packedValue | (byte) (<< 3));
0445         }
0446 
0447         buffer.put(packedValue);
0448     }
0449 
0450     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
0451         boolean value4)
0452     {
0453         byte packedValue = value0 ? (byte(byte0;
0454 
0455         if (value1)
0456         {
0457             packedValue = (byte) (packedValue | (byte) (<< 1));
0458         }
0459 
0460         if (value2)
0461         {
0462             packedValue = (byte) (packedValue | (byte) (<< 2));
0463         }
0464 
0465         if (value3)
0466         {
0467             packedValue = (byte) (packedValue | (byte) (<< 3));
0468         }
0469 
0470         if (value4)
0471         {
0472             packedValue = (byte) (packedValue | (byte) (<< 4));
0473         }
0474 
0475         buffer.put(packedValue);
0476     }
0477 
0478     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
0479         boolean value4, boolean value5)
0480     {
0481         byte packedValue = value0 ? (byte(byte0;
0482 
0483         if (value1)
0484         {
0485             packedValue = (byte) (packedValue | (byte) (<< 1));
0486         }
0487 
0488         if (value2)
0489         {
0490             packedValue = (byte) (packedValue | (byte) (<< 2));
0491         }
0492 
0493         if (value3)
0494         {
0495             packedValue = (byte) (packedValue | (byte) (<< 3));
0496         }
0497 
0498         if (value4)
0499         {
0500             packedValue = (byte) (packedValue | (byte) (<< 4));
0501         }
0502 
0503         if (value5)
0504         {
0505             packedValue = (byte) (packedValue | (byte) (<< 5));
0506         }
0507 
0508         buffer.put(packedValue);
0509     }
0510 
0511     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
0512         boolean value4, boolean value5, boolean value6)
0513     {
0514         byte packedValue = value0 ? (byte(byte0;
0515 
0516         if (value1)
0517         {
0518             packedValue = (byte) (packedValue | (byte) (<< 1));
0519         }
0520 
0521         if (value2)
0522         {
0523             packedValue = (byte) (packedValue | (byte) (<< 2));
0524         }
0525 
0526         if (value3)
0527         {
0528             packedValue = (byte) (packedValue | (byte) (<< 3));
0529         }
0530 
0531         if (value4)
0532         {
0533             packedValue = (byte) (packedValue | (byte) (<< 4));
0534         }
0535 
0536         if (value5)
0537         {
0538             packedValue = (byte) (packedValue | (byte) (<< 5));
0539         }
0540 
0541         if (value6)
0542         {
0543             packedValue = (byte) (packedValue | (byte) (<< 6));
0544         }
0545 
0546         buffer.put(packedValue);
0547     }
0548 
0549     public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1, boolean value2, boolean value3,
0550         boolean value4, boolean value5, boolean value6, boolean value7)
0551     {
0552         byte packedValue = value0 ? (byte(byte0;
0553 
0554         if (value1)
0555         {
0556             packedValue = (byte) (packedValue | (byte) (<< 1));
0557         }
0558 
0559         if (value2)
0560         {
0561             packedValue = (byte) (packedValue | (byte) (<< 2));
0562         }
0563 
0564         if (value3)
0565         {
0566             packedValue = (byte) (packedValue | (byte) (<< 3));
0567         }
0568 
0569         if (value4)
0570         {
0571             packedValue = (byte) (packedValue | (byte) (<< 4));
0572         }
0573 
0574         if (value5)
0575         {
0576             packedValue = (byte) (packedValue | (byte) (<< 5));
0577         }
0578 
0579         if (value6)
0580         {
0581             packedValue = (byte) (packedValue | (byte) (<< 6));
0582         }
0583 
0584         if (value7)
0585         {
0586             packedValue = (byte) (packedValue | (byte) (<< 7));
0587         }
0588 
0589         buffer.put(packedValue);
0590     }
0591 
0592     /**
0593      * This is used for writing longstrs.
0594      *
0595      @param buffer
0596      @param data
0597      */
0598     public static void writeLongstr(ByteBuffer buffer, byte[] data)
0599     {
0600         if (data != null)
0601         {
0602             writeUnsignedInteger(buffer, data.length);
0603             buffer.put(data);
0604         }
0605         else
0606         {
0607             writeUnsignedInteger(buffer, 0);
0608         }
0609     }
0610 
0611     public static void writeTimestamp(ByteBuffer buffer, long timestamp)
0612     {
0613         writeLong(buffer, timestamp);
0614     }
0615 
0616     public static boolean[] readBooleans(ByteBuffer buffer)
0617     {
0618         final byte packedValue = buffer.get();
0619         if (packedValue == 0)
0620         {
0621             return ALL_FALSE_ARRAY;
0622         }
0623 
0624         final boolean[] result = new boolean[8];
0625 
0626         result[0((packedValue & 1!= 0);
0627         result[1((packedValue & (<< 1)) != 0);
0628         result[2((packedValue & (<< 2)) != 0);
0629         result[3((packedValue & (<< 3)) != 0);
0630         if ((packedValue & 0xF0== 0)
0631         {
0632             result[0((packedValue & 1!= 0);
0633         }
0634 
0635         result[4((packedValue & (<< 4)) != 0);
0636         result[5((packedValue & (<< 5)) != 0);
0637         result[6((packedValue & (<< 6)) != 0);
0638         result[7((packedValue & (<< 7)) != 0);
0639 
0640         return result;
0641     }
0642 
0643     public static FieldTable readFieldTable(ByteBuffer bufferthrows AMQFrameDecodingException
0644     {
0645         long length = buffer.getUnsignedInt();
0646         if (length == 0)
0647         {
0648             return null;
0649         }
0650         else
0651         {
0652             return FieldTableFactory.newFieldTable(buffer, length);
0653         }
0654     }
0655 
0656     public static Content readContent(ByteBuffer bufferthrows AMQFrameDecodingException
0657     {
0658         // TODO: New Content class required for AMQP 0-9.
0659         return null;
0660     }
0661 
0662     public static AMQShortString readAMQShortString(ByteBuffer buffer)
0663     {
0664         return AMQShortString.readFromBuffer(buffer);
0665 
0666     }
0667 
0668     public static String readShortString(ByteBuffer buffer)
0669     {
0670         short length = buffer.getUnsigned();
0671         if (length == 0)
0672         {
0673             return null;
0674         }
0675         else
0676         {
0677             // this may seem rather odd to declare two array but testing has shown
0678             // that constructing a string from a byte array is 5 (five) times slower
0679             // than constructing one from a char array.
0680             // this approach here is valid since we know that all the chars are
0681             // ASCII (0-127)
0682             byte[] stringBytes = new byte[length];
0683             buffer.get(stringBytes, 0, length);
0684             char[] stringChars = new char[length];
0685             for (int i = 0; i < stringChars.length; i++)
0686             {
0687                 stringChars[i(charstringBytes[i];
0688             }
0689 
0690             return new String(stringChars);
0691         }
0692     }
0693 
0694     public static String readLongString(ByteBuffer buffer)
0695     {
0696         long length = buffer.getUnsignedInt();
0697         if (length == 0)
0698         {
0699             return "";
0700         }
0701         else
0702         {
0703             // this may seem rather odd to declare two array but testing has shown
0704             // that constructing a string from a byte array is 5 (five) times slower
0705             // than constructing one from a char array.
0706             // this approach here is valid since we know that all the chars are
0707             // ASCII (0-127)
0708             byte[] stringBytes = new byte[(intlength];
0709             buffer.get(stringBytes, 0(intlength);
0710             char[] stringChars = new char[(intlength];
0711             for (int i = 0; i < stringChars.length; i++)
0712             {
0713                 stringChars[i(charstringBytes[i];
0714             }
0715 
0716             return new String(stringChars);
0717         }
0718     }
0719 
0720     public static byte[] readLongstr(ByteBuffer buffer)
0721     {
0722         long length = buffer.getUnsignedInt();
0723         if (length == 0)
0724         {
0725             return null;
0726         }
0727         else
0728         {
0729             byte[] result = new byte[(intlength];
0730             buffer.get(result);
0731 
0732             return result;
0733         }
0734     }
0735 
0736     public static long readTimestamp(ByteBuffer buffer)
0737     {
0738         // Discard msb from AMQ timestamp
0739         // buffer.getUnsignedInt();
0740         return buffer.getLong();
0741     }
0742 
0743     static byte[] hexToByteArray(String id)
0744     {
0745         // Should check param for null, long enough for this check, upper-case and trailing char
0746         String s = (id.charAt(1== 'x'? id.substring(2: id; // strip 0x
0747 
0748         int len = s.length();
0749         int byte_len = len / 2;
0750         byte[] b = new byte[byte_len];
0751 
0752         for (int i = 0; i < byte_len; i++)
0753         {
0754             // fixme: refine these repetitive subscript calcs.
0755             int ch = i * 2;
0756 
0757             byte b1 = Byte.parseByte(s.substring(ch, ch + 1)16);
0758             byte b2 = Byte.parseByte(s.substring(ch + 1, ch + 2)16);
0759 
0760             b[i(byte) ((b1 * 16+ b2);
0761         }
0762 
0763         return (b);
0764     }
0765 
0766     public static char[] convertToHexCharArray(byte[] from)
0767     {
0768         int length = from.length;
0769         char[] result_buff = new char[(length * 22];
0770 
0771         result_buff[0'0';
0772         result_buff[1'x';
0773 
0774         int bite;
0775         int dest = 2;
0776 
0777         for (int i = 0; i < length; i++)
0778         {
0779             bite = from[i];
0780 
0781             if (bite < 0)
0782             {
0783                 bite += 256;
0784             }
0785 
0786             result_buff[dest++= hex_chars[bite >> 4];
0787             result_buff[dest++= hex_chars[bite & 0x0f];
0788         }
0789 
0790         return (result_buff);
0791     }
0792 
0793     public static String convertToHexString(byte[] from)
0794     {
0795         return (new String(convertToHexCharArray(from)));
0796     }
0797 
0798     public static String convertToHexString(ByteBuffer bb)
0799     {
0800         int size = bb.limit();
0801 
0802         byte[] from = new byte[size];
0803 
0804         // Is this not the same.
0805         // bb.get(from, 0, length);
0806         for (int i = 0; i < size; i++)
0807         {
0808             from[i= bb.get(i);
0809         }
0810 
0811         return (new String(convertToHexCharArray(from)));
0812     }
0813 
0814     private static char[] hex_chars = '0''1''2''3''4''5''6''7''8''9''a''b''c''d''e''f' };
0815 
0816     // **** new methods
0817 
0818     // AMQP_BOOLEAN_PROPERTY_PREFIX
0819 
0820     public static void writeBoolean(ByteBuffer buffer, Boolean aBoolean)
0821     {
0822         buffer.put((byte) (aBoolean ? 0));
0823     }
0824 
0825     public static boolean readBoolean(ByteBuffer buffer)
0826     {
0827         byte packedValue = buffer.get();
0828 
0829         return (packedValue == 1);
0830     }
0831 
0832     public static int encodedBooleanLength()
0833     {
0834         return 1;
0835     }
0836 
0837     // AMQP_BYTE_PROPERTY_PREFIX
0838     public static void writeByte(ByteBuffer buffer, Byte aByte)
0839     {
0840         buffer.put(aByte);
0841     }
0842 
0843     public static byte readByte(ByteBuffer buffer)
0844     {
0845         return buffer.get();
0846     }
0847 
0848     public static int encodedByteLength()
0849     {
0850         return 1;
0851     }
0852 
0853     // AMQP_SHORT_PROPERTY_PREFIX
0854     public static void writeShort(ByteBuffer buffer, Short aShort)
0855     {
0856         buffer.putShort(aShort);
0857     }
0858 
0859     public static short readShort(ByteBuffer buffer)
0860     {
0861         return buffer.getShort();
0862     }
0863 
0864     public static int encodedShortLength()
0865     {
0866         return 2;
0867     }
0868 
0869     // INTEGER_PROPERTY_PREFIX
0870     public static void writeInteger(ByteBuffer buffer, Integer aInteger)
0871     {
0872         buffer.putInt(aInteger);
0873     }
0874 
0875     public static int readInteger(ByteBuffer buffer)
0876     {
0877         return buffer.getInt();
0878     }
0879 
0880     public static int encodedIntegerLength()
0881     {
0882         return 4;
0883     }
0884 
0885     // AMQP_LONG_PROPERTY_PREFIX
0886     public static void writeLong(ByteBuffer buffer, Long aLong)
0887     {
0888         buffer.putLong(aLong);
0889     }
0890 
0891     public static long readLong(ByteBuffer buffer)
0892     {
0893         return buffer.getLong();
0894     }
0895 
0896     public static int encodedLongLength()
0897     {
0898         return 8;
0899     }
0900 
0901     // Float_PROPERTY_PREFIX
0902     public static void writeFloat(ByteBuffer buffer, Float aFloat)
0903     {
0904         buffer.putFloat(aFloat);
0905     }
0906 
0907     public static float readFloat(ByteBuffer buffer)
0908     {
0909         return buffer.getFloat();
0910     }
0911 
0912     public static int encodedFloatLength()
0913     {
0914         return 4;
0915     }
0916 
0917     // Double_PROPERTY_PREFIX
0918     public static void writeDouble(ByteBuffer buffer, Double aDouble)
0919     {
0920         buffer.putDouble(aDouble);
0921     }
0922 
0923     public static double readDouble(ByteBuffer buffer)
0924     {
0925         return buffer.getDouble();
0926     }
0927 
0928     public static int encodedDoubleLength()
0929     {
0930         return 8;
0931     }
0932 
0933     public static byte[] readBytes(ByteBuffer buffer)
0934     {
0935         long length = buffer.getUnsignedInt();
0936         if (length == 0)
0937         {
0938             return null;
0939         }
0940         else
0941         {
0942             byte[] dataBytes = new byte[(int)length];
0943             buffer.get(dataBytes, 0(int)length);
0944 
0945             return dataBytes;
0946         }
0947     }
0948 
0949     public static void writeBytes(ByteBuffer buffer, byte[] data)
0950     {
0951         if (data != null)
0952         {
0953             // TODO: check length fits in an unsigned byte
0954             writeUnsignedInteger(buffer,  (long)data.length);
0955             buffer.put(data);
0956         }
0957         else
0958         {                                                    
0959             // really writing out unsigned byte
0960             //buffer.put((byte) 0);
0961             writeUnsignedInteger(buffer, 0L);
0962         }
0963     }
0964 
0965     // CHAR_PROPERTY
0966     public static int encodedCharLength()
0967     {
0968         return encodedByteLength();
0969     }
0970 
0971     public static char readChar(ByteBuffer buffer)
0972     {
0973         // This is valid as we know that the Character is ASCII 0..127
0974         return (charbuffer.get();
0975     }
0976 
0977     public static void writeChar(ByteBuffer buffer, char character)
0978     {
0979         // This is valid as we know that the Character is ASCII 0..127
0980         writeByte(buffer, (bytecharacter);
0981     }
0982 
0983     public static long readLongAsShortString(ByteBuffer buffer)
0984     {
0985         short length = buffer.getUnsigned();
0986         short pos = 0;
0987         if (length == 0)
0988         {
0989             return 0L;
0990         }
0991 
0992         byte digit = buffer.get();
0993         boolean isNegative;
0994         long result = 0;
0995         if (digit == (byte'-')
0996         {
0997             isNegative = true;
0998             pos++;
0999             digit = buffer.get();
1000         }
1001         else
1002         {
1003             isNegative = false;
1004         }
1005 
1006         result = digit - (byte'0';
1007         pos++;
1008 
1009         while (pos < length)
1010         {
1011             pos++;
1012             digit = buffer.get();
1013             result = (result << 3(result << 1);
1014             result += digit - (byte'0';
1015         }
1016 
1017         return result;
1018     }
1019 
1020     public static long readUnsignedInteger(ByteBuffer buffer)
1021     {
1022         long l = 0xFF & buffer.get();
1023         l <<= 8;
1024         l = l | (0xFF & buffer.get());
1025         l <<= 8;
1026         l = l | (0xFF & buffer.get());
1027         l <<= 8;
1028         l = l | (0xFF & buffer.get());
1029 
1030         return l;
1031     }
1032 
1033 }