diff options
Diffstat (limited to 'qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs')
-rw-r--r-- | qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs | 353 |
1 files changed, 353 insertions, 0 deletions
diff --git a/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs b/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs new file mode 100644 index 0000000000..fb3efb1b0f --- /dev/null +++ b/qpid/dotnet/Qpid.Client/Client/Message/QpidBytesMessage.cs @@ -0,0 +1,353 @@ +/* + * + * 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.IO; +using System.Runtime.Serialization; +using System.Text; +using Apache.Qpid.Framing; +using Apache.Qpid.Messaging; +using Apache.Qpid.Buffer; + +namespace Apache.Qpid.Client.Message +{ + [Serializable] + class MessageEOFException : QpidException + { + public MessageEOFException(string message) : base(message) + { + } + + protected MessageEOFException(SerializationInfo info, StreamingContext ctxt) + : base(info, ctxt) + { + } + } + + public class QpidBytesMessage : AbstractQmsMessage, IBytesMessage + { + private const int DEFAULT_BUFFER_INITIAL_SIZE = 1024; + + public QpidBytesMessage() : this(null) + { + } + + /// <summary> + /// Construct a bytes message with existing data. + /// </summary> + /// <param name="data">if data is not null, the message is immediately in read only mode. if data is null, it is in + /// write-only mode</param> + QpidBytesMessage(ByteBuffer data) : base(data) + { + // superclass constructor has instantiated a content header at this point + if (data == null) + { + _data = ByteBuffer.Allocate(DEFAULT_BUFFER_INITIAL_SIZE); + _data.IsAutoExpand = true; + } + } + + internal QpidBytesMessage(long messageNbr, ContentHeaderBody contentHeader, ByteBuffer data) + // TODO: this casting is ugly. Need to review whole ContentHeaderBody idea + : base(messageNbr, (BasicContentHeaderProperties)contentHeader.Properties, data) + { + } + + public override void ClearBodyImpl() + { + _data.Clear(); + } + + public override string ToBodyString() + { + CheckReadable(); + try + { + return GetText(); + } + catch (IOException e) + { + throw new QpidException(e.ToString()); + } + } + + private String GetText() + { + // this will use the default platform encoding + if (_data == null) + { + return null; + } + int pos = _data.Position; + _data.Rewind(); + // one byte left is for the end of frame marker + if (_data.Remaining == 0) + { + // this is really redundant since pos must be zero + _data.Position = pos; + return null; + } + else + { + byte[] data = new byte[_data.Remaining]; + _data.GetBytes(data); + return Encoding.UTF8.GetString(data); + } + } + + public long BodyLength + { + get + { + CheckReadable(); + return _data.Limit; + } + } + + private void CheckWritable() + { + if (_readableMessage) + { + throw new MessageNotWriteableException("You need to call clearBody() to make the message writable"); + } + } + + public bool ReadBoolean() + { + CheckReadable(); + CheckAvailable(1); + return _data.GetByte() != 0; + } + + public byte ReadByte() + { + CheckReadable(); + CheckAvailable(1); + return _data.GetByte(); + } + + public short ReadSignedByte() + { + CheckReadable(); + CheckAvailable(1); + return _data.GetSByte(); + } + + public short ReadShort() + { + CheckReadable(); + CheckAvailable(2); + return _data.GetInt16(); + } + + public char ReadChar() + { + CheckReadable(); + CheckAvailable(2); + return _data.GetChar(); + } + + public int ReadInt() + { + CheckReadable(); + CheckAvailable(4); + return _data.GetInt32(); + } + + public long ReadLong() + { + CheckReadable(); + CheckAvailable(8); + return _data.GetInt64(); + } + + public float ReadFloat() + { + CheckReadable(); + CheckAvailable(4); + return _data.GetFloat(); + } + + public double ReadDouble() + { + CheckReadable(); + CheckAvailable(8); + return _data.GetDouble(); + } + + public string ReadUTF() + { + CheckReadable(); + // we check only for one byte since theoretically the string could be only a + // single byte when using UTF-8 encoding + CheckAvailable(1); + try + { + byte[] data = new byte[_data.Remaining]; + _data.GetBytes(data); + return Encoding.UTF8.GetString(data); + } + catch (IOException e) + { + throw new QpidException(e.ToString(), e); + } + } + + public int ReadBytes(byte[] bytes) + { + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + CheckReadable(); + int count = (_data.Remaining >= bytes.Length ? bytes.Length : _data.Remaining); + if (count == 0) + { + return -1; + } + else + { + _data.GetBytes(bytes, 0, count); + return count; + } + } + + public int ReadBytes(byte[] bytes, int maxLength) + { + if (bytes == null) + { + throw new ArgumentNullException("bytes"); + } + if (maxLength > bytes.Length) + { + throw new ArgumentOutOfRangeException("maxLength must be >= 0"); + } + CheckReadable(); + int count = (_data.Remaining >= maxLength ? maxLength : _data.Remaining); + if (count == 0) + { + return -1; + } + else + { + _data.GetBytes(bytes, 0, count); + return count; + } + } + + public void WriteBoolean(bool b) + { + CheckWritable(); + _data.Put(b ? (byte)1 : (byte)0); + } + + public void WriteByte(byte b) + { + CheckWritable(); + _data.Put(b); + } + + public void WriteShort(short i) + { + CheckWritable(); + _data.Put(i); + } + + public void WriteChar(char c) + { + CheckWritable(); + _data.Put(c); + } + + public void WriteSignedByte(short value) + { + CheckWritable(); + _data.Put(value); + } + + public void WriteDouble(double value) + { + CheckWritable(); + _data.Put(value); + } + + public void WriteFloat(float value) + { + CheckWritable(); + _data.Put(value); + } + + public void WriteInt(int value) + { + CheckWritable(); + _data.Put(value); + } + + public void WriteLong(long value) + { + CheckWritable(); + _data.Put(value); + } + + public void WriteUTF(string value) + { + CheckWritable(); + byte[] encodedData = Encoding.UTF8.GetBytes(value); + _data.Put(encodedData); + } + + public void WriteBytes(byte[] bytes) + { + CheckWritable(); + _data.Put(bytes); + } + + public void WriteBytes(byte[] bytes, int offset, int length) + { + CheckWritable(); + _data.Put(bytes, offset, length); + } + + protected override void Reset() + { + base.Reset(); + _data.Flip(); + } + + void IBytesMessage.Reset() + { + Reset(); + } + + /** + * Check that there is at least a certain number of bytes available to read + * + * @param len the number of bytes + * @throws MessageEOFException if there are less than len bytes available to read + */ + private void CheckAvailable(int len) + { + if (_data.Remaining < len) + { + throw new MessageEOFException("Unable to read " + len + " bytes"); + } + } + } +} |