/* * * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ using System; using System.Text; using Qpid.Buffer; namespace Qpid.Framing { public class EncodingUtils { private static readonly Encoding DEFAULT_ENCODER = Encoding.ASCII; // SHORT STRING public static ushort EncodedShortStringLength(string s) { if ( s == null ) { return 1; } else { return (ushort)(1 + s.Length); } } public static void WriteShortStringBytes(ByteBuffer buffer, string s) { if ( s != null ) { //try //{ //final byte[] encodedString = s.getBytes(STRING_ENCODING); byte[] encodedString; lock ( DEFAULT_ENCODER ) { encodedString = DEFAULT_ENCODER.GetBytes(s); } // TODO: check length fits in an unsigned byte buffer.put((byte)encodedString.Length); buffer.put(encodedString); } else { // really writing out unsigned byte buffer.put((byte)0); } } // ASCII STRINGS public static uint EncodedAsciiStringLength(string s) { // TODO: move this to 2-byte length once the proposed encodings // have been approved. Also, validate length! if ( s == null ) return 4; else return (uint) (4 + s.Length); } public static string ReadAsciiString(ByteBuffer buffer) { return ReadLongString(buffer, DEFAULT_ENCODER); } public static void WriteAsciiString(ByteBuffer buffer, string s) { WriteLongStringBytes(buffer, s, DEFAULT_ENCODER); } // LONG STRING public static uint EncodedLongStringLength(string s) { return EncodedLongStringLength(s, DEFAULT_ENCODER); } public static uint EncodedLongStringLength(string s, Encoding encoding) { if ( s == null ) { return 4; } else { return (uint)(4 + encoding.GetByteCount(s)); } } public static string ReadLongString(ByteBuffer buffer) { return ReadLongString(buffer, DEFAULT_ENCODER); } public static string ReadLongString(ByteBuffer buffer, Encoding encoding) { uint length = buffer.getUnsignedInt(); if ( length == 0 ) { return null; } else { byte[] data = new byte[length]; buffer.get(data); lock ( encoding ) { return encoding.GetString(data); } } } public static void WriteLongStringBytes(ByteBuffer buffer, string s) { WriteLongStringBytes(buffer, s, DEFAULT_ENCODER); } public static void WriteLongStringBytes(ByteBuffer buffer, string s, Encoding encoding) { if ( !(s == null || s.Length <= 0xFFFE) ) { throw new ArgumentException("String too long"); } if ( s != null ) { lock ( encoding ) { byte[] encodedString = null; encodedString = encoding.GetBytes(s); buffer.put((uint)encodedString.Length); buffer.put(encodedString); } } else { buffer.put((uint)0); } } // BINARY public static uint EncodedLongstrLength(byte[] bytes) { if ( bytes == null ) { return 4; } else { return (uint)(4 + bytes.Length); } } public static byte[] ReadLongstr(ByteBuffer buffer) { uint length = buffer.getUnsignedInt(); if ( length == 0 ) { return null; } else { byte[] result = new byte[length]; buffer.get(result); return result; } } public static void WriteLongstr(ByteBuffer buffer, byte[] data) { if ( data != null ) { buffer.put((uint)data.Length); buffer.put(data); } else { buffer.put((uint)0); } } // BOOLEANS public static bool[] ReadBooleans(ByteBuffer buffer) { byte packedValue = buffer.get(); bool[] result = new bool[8]; for ( int i = 0; i < 8; i++ ) { result[i] = ((packedValue & (1 << i)) != 0); } return result; } public static void WriteBooleans(ByteBuffer buffer, bool[] values) { byte packedValue = 0; for ( int i = 0; i < values.Length; i++ ) { if ( values[i] ) { packedValue = (byte)(packedValue | (1 << i)); } } buffer.put(packedValue); } // FIELD TABLES public static uint EncodedFieldTableLength(FieldTable table) { if ( table == null ) { // size is encoded as 4 octets return 4; } else { // size of the table plus 4 octets for the size return table.EncodedSize + 4; } } /// /// Reads the field table using the data in the specified buffer /// /// The buffer to read from. /// a populated field table /// if the buffer does not contain a decodable field table public static FieldTable ReadFieldTable(ByteBuffer buffer) { uint length = buffer.GetUnsignedInt(); if ( length == 0 ) { return null; } else { return new FieldTable(buffer, length); } } public static void WriteFieldTableBytes(ByteBuffer buffer, FieldTable table) { if ( table != null ) { table.WriteToBuffer(buffer); } else { buffer.put((uint)0); } } /// /// Read a short string from the buffer /// /// The buffer to read from. /// a string /// if the buffer does not contain a decodable short string public static string ReadShortString(ByteBuffer buffer) { byte length = buffer.get(); if ( length == 0 ) { return null; } else { byte[] data = new byte[length]; buffer.get(data); lock ( DEFAULT_ENCODER ) { return DEFAULT_ENCODER.GetString(data); } } } // BOOLEAN public static uint EncodedBooleanLength() { return 1; } public static bool ReadBoolean(ByteBuffer buffer) { byte packedValue = buffer.get(); return (packedValue == 1); } public static void WriteBoolean(ByteBuffer buffer, bool value) { buffer.put((byte)(value ? 1 : 0)); } // CHAR public static uint EncodedCharLength() { return EncodedByteLength(); } public static char ReadChar(ByteBuffer buffer) { return (char)buffer.get(); } public static void WriteChar(ByteBuffer buffer, char value) { buffer.put((byte)value); } // BYTE public static uint EncodedByteLength() { return 1; } public static byte ReadByte(ByteBuffer buffer) { return buffer.get(); } public static void WriteByte(ByteBuffer buffer, byte value) { buffer.put(value); } // SBYTE public static uint EncodedSByteLength() { return 1; } public static sbyte ReadSByte(ByteBuffer buffer) { return (sbyte)buffer.get(); } public static void WriteSByte(ByteBuffer buffer, sbyte value) { buffer.put((byte)value); } // INT16 public static uint EncodedShortLength() { return 2; } public static short ReadShort(ByteBuffer buffer) { return buffer.getShort(); } public static void WriteShort(ByteBuffer buffer, short value) { buffer.putShort(value); } // UINT16 public static uint EncodedUnsignedShortLength() { return 2; } public static ushort ReadUnsignedShort(ByteBuffer buffer) { return buffer.GetUnsignedShort(); } public static void WriteUnsignedShort(ByteBuffer buffer, ushort value) { buffer.put(value); } // INT32 public static uint EncodedIntegerLength() { return 4; } public static int ReadInteger(ByteBuffer buffer) { return buffer.getInt(); } public static void WriteInteger(ByteBuffer buffer, int value) { buffer.putInt(value); } // UINT32 public static uint UnsignedIntegerLength() { return 4; } public static void WriteUnsignedInteger(ByteBuffer buffer, uint value) { buffer.put(value); } public static uint ReadUnsignedInteger(ByteBuffer buffer) { return buffer.getUnsignedInt(); } // INT64 public static uint EncodedUnsignedLongLength() { return 8; } public static ulong ReadUnsignedLong(ByteBuffer buffer) { return buffer.GetUnsignedLong(); } public static void WriteUnsignedLong(ByteBuffer buffer, ulong value) { buffer.put(value); } // UINT64 public static uint EncodedLongLength() { return 8; } public static long ReadLong(ByteBuffer buffer) { return buffer.getLong(); } public static void WriteLong(ByteBuffer buffer, long value) { buffer.putLong(value); } // FLOAT public static uint EncodedFloatLength() { return 4; } public static void WriteFloat(ByteBuffer buffer, float value) { buffer.putFloat(value); } public static float ReadFloat(ByteBuffer buffer) { return buffer.getFloat(); } // DOUBLE public static uint EncodedDoubleLength() { return 8; } public static void WriteDouble(ByteBuffer buffer, double value) { buffer.putDouble(value); } public static double ReadDouble(ByteBuffer buffer) { return buffer.getDouble(); } } }