Skip to content
Permalink
Browse files
Moved PrimitiveMap, OpenWireBinaryReader, OpenWireBinaryWriter, Endia…
…nSupport, MessagePropertyHelper and associated tests from Apache.NMS.ActiveMQ into Apache.NMS. These are generally useful classes that should be shared among the providers instead of forcing all providers to re-implement these highly useful and complex classes.

Renamed OpenWireBinaryWriter to EndianBinaryWriter.
Renamed OpenWireBinaryReader to EndianBinaryReader.
Implemented MapMessage marshaling in Apache.NMS.MSMQ.
  • Loading branch information
Jim Gomes committed Aug 26, 2009
1 parent 55cd8b3 commit 37f0670595d3cb42d67d2f3da6c311f032c4f57b
Show file tree
Hide file tree
Showing 12 changed files with 2,291 additions and 6 deletions.

Large diffs are not rendered by default.

@@ -0,0 +1,295 @@
/*
* 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;

namespace Apache.NMS.Util
{
/// <summary>
/// A BinaryWriter that switches the endian orientation of the write operations so that they
/// are compatible across platforms.
/// </summary>
[CLSCompliant(false)]
public class EndianBinaryWriter : BinaryWriter
{
public const int MAXSTRINGLEN = short.MaxValue;

public EndianBinaryWriter(Stream output)
: base(output)
{
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">A long</param>
public override void Write(long value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">An ushort</param>
public override void Write(ushort value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">An int</param>
public override void Write(int value)
{
int x = EndianSupport.SwitchEndian(value);
base.Write(x);
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="chars">A char[]</param>
/// <param name="index">An int</param>
/// <param name="count">An int</param>
public override void Write(char[] chars, int index, int count)
{
char[] t = new char[count];
for(int i = 0; i < count; i++)
{
t[index + i] = EndianSupport.SwitchEndian(t[index + i]);
}
base.Write(t);
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="chars">A char[]</param>
public override void Write(char[] chars)
{
Write(chars, 0, chars.Length);
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">An uint</param>
public override void Write(uint value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="ch">A char</param>
public override void Write(char ch)
{
base.Write((byte) ((ch >> 8) & 0xFF));
base.Write((byte) (ch & 0xFF));
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">An ulong</param>
public override void Write(ulong value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">A short</param>
public override void Write(short value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

/// <summary>
/// Method Write, writes a string to the output using the WriteString16
/// method.
/// </summary>
/// <param name="text">A string</param>
public override void Write(String text)
{
WriteString16(text);
}

/// <summary>
/// Method WriteString16, writes a string to the output using the Java
/// standard modified UTF-8 encoding with an unsigned short value written first to
/// indicate the length of the encoded data, the short is read as an unsigned
/// value so the max amount of data this method can write is 65535 encoded bytes.
///
/// Unlike the WriteString32 method this method does not encode the length
/// value to -1 if the string is null, this is to match the behaviour of
/// the Java DataOuputStream class's writeUTF method.
///
/// Because modified UTF-8 encding can result in a number of bytes greater that
/// the size of the String this method must first check that the encoding proces
/// will not result in a value that cannot be written becuase it is greater than
/// the max value of an unsigned short.
/// </summary>
/// <param name="text">A string</param>
public void WriteString16(String text)
{
if(text != null)
{
if(text.Length > ushort.MaxValue)
{
throw new IOException(
String.Format(
"Cannot marshall string longer than: {0} characters, supplied string was: " +
"{1} characters", ushort.MaxValue, text.Length));
}

char[] charr = text.ToCharArray();
uint utfLength = CountUtf8Bytes(charr);

if(utfLength > ushort.MaxValue)
{
throw new IOException(
String.Format(
"Cannot marshall an encoded string longer than: {0} bytes, supplied" +
"string requires: {1} characters to encode", ushort.MaxValue, utfLength));
}

byte[] bytearr = new byte[utfLength];
encodeUTF8toBuffer(charr, bytearr);

Write((ushort) utfLength);
Write(bytearr);
}
}

/// <summary>
/// Method WriteString32, writes a string to the output using the Openwire
/// standard modified UTF-8 encoding which an int value written first to
/// indicate the length of the encoded data, the int is read as an signed
/// value so the max amount of data this method can write is 2^31 encoded bytes.
///
/// In the case of a null value being passed this method writes a -1 to the
/// stream to indicate that the string is null.
///
/// Because modified UTF-8 encding can result in a number of bytes greater that
/// the size of the String this method must first check that the encoding proces
/// will not result in a value that cannot be written becuase it is greater than
/// the max value of an int.
/// </summary>
/// <param name="text">A string</param>
public void WriteString32(String text)
{
if(text != null)
{
char[] charr = text.ToCharArray();
uint utfLength = CountUtf8Bytes(charr);

if(utfLength > int.MaxValue)
{
throw new IOException(
String.Format(
"Cannot marshall an encoded string longer than: {0} bytes, supplied" +
"string requires: {1} characters to encode", int.MaxValue, utfLength));
}

byte[] bytearr = new byte[utfLength];
encodeUTF8toBuffer(charr, bytearr);

Write(utfLength);
Write(bytearr);
}
else
{
Write((int) -1);
}
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">A double</param>
public override void Write(float value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

/// <summary>
/// Method Write
/// </summary>
/// <param name="value">A double</param>
public override void Write(double value)
{
base.Write(EndianSupport.SwitchEndian(value));
}

private uint CountUtf8Bytes(char[] chars)
{
uint utfLength = 0;
int c = 0;

for(int i = 0; i < chars.Length; i++)
{
c = chars[i];
if((c >= 0x0001) && (c <= 0x007F))
{
utfLength++;
}
else if(c > 0x07FF)
{
utfLength += 3;
}
else
{
utfLength += 2;
}
}

return utfLength;
}

private void encodeUTF8toBuffer(char[] chars, byte[] buffer)
{
int c = 0;
int count = 0;

for(int i = 0; i < chars.Length; i++)
{
c = chars[i];
if((c >= 0x0001) && (c <= 0x007F))
{
buffer[count++] = (byte) c;
}
else if(c > 0x07FF)
{
buffer[count++] = (byte) (0xE0 | ((c >> 12) & 0x0F));
buffer[count++] = (byte) (0x80 | ((c >> 6) & 0x3F));
buffer[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
}
else
{
buffer[count++] = (byte) (0xC0 | ((c >> 6) & 0x1F));
buffer[count++] = (byte) (0x80 | ((c >> 0) & 0x3F));
}
}
}
}
}

0 comments on commit 37f0670

Please sign in to comment.