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) (1 + s.length());
0051 }
0052 }
0053
0054 public static int encodedShortStringLength(short s)
0055 {
0056 if (s == 0)
0057 {
0058 return 1 + 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 1 + 5;
0072 }
0073 else if (s > 999)
0074 {
0075 return 1 + 4;
0076 }
0077 else if (s > 99)
0078 {
0079 return 1 + 3;
0080 }
0081 else if (s > 9)
0082 {
0083 return 1 + 2;
0084 }
0085 else
0086 {
0087 return 1 + 1;
0088 }
0089
0090 }
0091
0092 public static int encodedShortStringLength(int i)
0093 {
0094 if (i == 0)
0095 {
0096 return 1 + 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((short) i);
0111 }
0112 else if (i > 999999)
0113 {
0114 return len + 6 + encodedShortStringLength((short) (i / 1000000));
0115 }
0116 else // if (i > 99999)
0117 {
0118 return len + 5 + encodedShortStringLength((short) (i / 100000));
0119 }
0120
0121 }
0122
0123 public static int encodedShortStringLength(long l)
0124 {
0125 if (l == 0)
0126 {
0127 return 1 + 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((int) l);
0141 }
0142 else if (l > 9999999999L)
0143 {
0144 return len + 10 + encodedShortStringLength((int) (l / 10000000000L));
0145 }
0146 else
0147 {
0148 return len + 1 + 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 (1 + 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 4 + 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 4 + 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 4 + 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 (int) table.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] = (byte) cha[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((byte) 0);
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((byte) 0);
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] = (byte) cha[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] = (byte) s[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 = (byte) b;
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((short) s);
0328 }
0329 else
0330 {
0331 short sv = (short) s;
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((int) l);
0348 }
0349 else
0350 {
0351 int iv = (int) l;
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 | (1 << 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) 1 : (byte) 0);
0397 }
0398
0399 public static void writeBooleans(ByteBuffer buffer, boolean value0, boolean value1)
0400 {
0401 byte packedValue = value0 ? (byte) 1 : (byte) 0;
0402
0403 if (value1)
0404 {
0405 packedValue = (byte) (packedValue | (byte) (1 << 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) 1 : (byte) 0;
0414
0415 if (value1)
0416 {
0417 packedValue = (byte) (packedValue | (byte) (1 << 1));
0418 }
0419
0420 if (value2)
0421 {
0422 packedValue = (byte) (packedValue | (byte) (1 << 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) 1 : (byte) 0;
0431
0432 if (value1)
0433 {
0434 packedValue = (byte) (packedValue | (byte) (1 << 1));
0435 }
0436
0437 if (value2)
0438 {
0439 packedValue = (byte) (packedValue | (byte) (1 << 2));
0440 }
0441
0442 if (value3)
0443 {
0444 packedValue = (byte) (packedValue | (byte) (1 << 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) 1 : (byte) 0;
0454
0455 if (value1)
0456 {
0457 packedValue = (byte) (packedValue | (byte) (1 << 1));
0458 }
0459
0460 if (value2)
0461 {
0462 packedValue = (byte) (packedValue | (byte) (1 << 2));
0463 }
0464
0465 if (value3)
0466 {
0467 packedValue = (byte) (packedValue | (byte) (1 << 3));
0468 }
0469
0470 if (value4)
0471 {
0472 packedValue = (byte) (packedValue | (byte) (1 << 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) 1 : (byte) 0;
0482
0483 if (value1)
0484 {
0485 packedValue = (byte) (packedValue | (byte) (1 << 1));
0486 }
0487
0488 if (value2)
0489 {
0490 packedValue = (byte) (packedValue | (byte) (1 << 2));
0491 }
0492
0493 if (value3)
0494 {
0495 packedValue = (byte) (packedValue | (byte) (1 << 3));
0496 }
0497
0498 if (value4)
0499 {
0500 packedValue = (byte) (packedValue | (byte) (1 << 4));
0501 }
0502
0503 if (value5)
0504 {
0505 packedValue = (byte) (packedValue | (byte) (1 << 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) 1 : (byte) 0;
0515
0516 if (value1)
0517 {
0518 packedValue = (byte) (packedValue | (byte) (1 << 1));
0519 }
0520
0521 if (value2)
0522 {
0523 packedValue = (byte) (packedValue | (byte) (1 << 2));
0524 }
0525
0526 if (value3)
0527 {
0528 packedValue = (byte) (packedValue | (byte) (1 << 3));
0529 }
0530
0531 if (value4)
0532 {
0533 packedValue = (byte) (packedValue | (byte) (1 << 4));
0534 }
0535
0536 if (value5)
0537 {
0538 packedValue = (byte) (packedValue | (byte) (1 << 5));
0539 }
0540
0541 if (value6)
0542 {
0543 packedValue = (byte) (packedValue | (byte) (1 << 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) 1 : (byte) 0;
0553
0554 if (value1)
0555 {
0556 packedValue = (byte) (packedValue | (byte) (1 << 1));
0557 }
0558
0559 if (value2)
0560 {
0561 packedValue = (byte) (packedValue | (byte) (1 << 2));
0562 }
0563
0564 if (value3)
0565 {
0566 packedValue = (byte) (packedValue | (byte) (1 << 3));
0567 }
0568
0569 if (value4)
0570 {
0571 packedValue = (byte) (packedValue | (byte) (1 << 4));
0572 }
0573
0574 if (value5)
0575 {
0576 packedValue = (byte) (packedValue | (byte) (1 << 5));
0577 }
0578
0579 if (value6)
0580 {
0581 packedValue = (byte) (packedValue | (byte) (1 << 6));
0582 }
0583
0584 if (value7)
0585 {
0586 packedValue = (byte) (packedValue | (byte) (1 << 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 << 1)) != 0);
0628 result[2] = ((packedValue & (1 << 2)) != 0);
0629 result[3] = ((packedValue & (1 << 3)) != 0);
0630 if ((packedValue & 0xF0) == 0)
0631 {
0632 result[0] = ((packedValue & 1) != 0);
0633 }
0634
0635 result[4] = ((packedValue & (1 << 4)) != 0);
0636 result[5] = ((packedValue & (1 << 5)) != 0);
0637 result[6] = ((packedValue & (1 << 6)) != 0);
0638 result[7] = ((packedValue & (1 << 7)) != 0);
0639
0640 return result;
0641 }
0642
0643 public static FieldTable readFieldTable(ByteBuffer buffer) throws 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 buffer) throws 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] = (char) stringBytes[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[(int) length];
0709 buffer.get(stringBytes, 0, (int) length);
0710 char[] stringChars = new char[(int) length];
0711 for (int i = 0; i < stringChars.length; i++)
0712 {
0713 stringChars[i] = (char) stringBytes[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[(int) length];
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 * 2) + 2];
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 ? 1 : 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 (char) buffer.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, (byte) character);
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 }
|