/*
*
* 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.Collections.Generic;
using System.Diagnostics;
using System.Text;
using org.apache.qpid.transport.util;
namespace org.apache.qpid.transport.codec
{
///
/// AbstractDecoder
///
public abstract class AbstractDecoder : IDecoder
{
private readonly Dictionary str8cache = new Dictionary();
protected abstract byte DoGet();
protected abstract void DoGet(byte[] bytes);
public abstract bool HasRemaining();
protected byte Get()
{
return DoGet();
}
protected void Get(byte[] bytes)
{
DoGet(bytes);
}
protected Binary Get(int size)
{
byte[] bytes = new byte[size];
Get(bytes);
return new Binary(bytes);
}
protected short Uget()
{
return (short) (0xFF & Get());
}
public virtual short ReadUint8()
{
return Uget();
}
public abstract int ReadUint16();
public abstract long ReadUint32();
public int ReadSequenceNo()
{
return (int) ReadUint32();
}
public virtual long ReadUint64()
{
long l = 0;
for (int i = 0; i < 8; i++)
{
l |= ((long) (0xFF & Get())) << (56 - i*8);
}
return l;
}
public abstract short ReadInt8();
public abstract int ReadInt16();
public abstract long ReadInt32() ;
public abstract long ReadInt64();
public abstract float ReadFloat() ;
public abstract double ReadDouble() ;
public long ReadDatetime()
{
return ReadUint64();
}
private static String Decode(byte[] bytes, int offset, int length, Encoding encoding)
{
return encoding.GetString(bytes, offset, length);
}
private static String Decode(byte[] bytes, Encoding encoding)
{
return Decode(bytes, 0, bytes.Length, encoding);
}
public String ReadStr8()
{
short size = ReadUint8();
Binary bin = Get(size);
String str;
if (! str8cache.TryGetValue(bin, out str))
{
str = Decode(bin.Array(), bin.Offset(), bin.Size(), Encoding.UTF8);
str8cache.Add(bin, str);
}
return str;
}
public String ReadStr16()
{
int size = ReadUint16();
byte[] bytes = new byte[size];
Get(bytes);
return Decode(bytes, Encoding.UTF8);
}
public byte[] ReadVbin8()
{
int size = ReadUint8();
byte[] bytes = new byte[size];
Get(bytes);
return bytes;
}
public byte[] ReadVbin16()
{
int size = ReadUint16();
byte[] bytes = new byte[size];
Get(bytes);
return bytes;
}
public byte[] ReadVbin32()
{
int size = (int) ReadUint32();
byte[] bytes = new byte[size];
Get(bytes);
return bytes;
}
public RangeSet ReadSequenceSet()
{
int count = ReadUint16()/8;
if (count == 0)
{
return null;
}
RangeSet ranges = new RangeSet();
for (int i = 0; i < count; i++)
{
ranges.Add(ReadSequenceNo(), ReadSequenceNo());
}
return ranges;
}
public RangeSet ReadByteRanges()
{
throw new Exception("not implemented");
}
public UUID ReadUuid()
{
long msb = ReadUint64();
long lsb = ReadUint64();
return new UUID(msb, lsb);
}
public String ReadContent()
{
throw new Exception("Deprecated");
}
public Struct ReadStruct(int type)
{
Struct st = Struct.Create(type);
int width = st.GetSizeWidth();
if (width > 0)
{
long size = ReadSize(width);
if (size == 0)
{
return null;
}
}
if (type > 0)
{
int code = ReadUint16();
Debug.Assert(code == type);
}
st.Read(this);
return st;
}
public Struct ReadStruct32()
{
long size = ReadUint32();
if (size == 0)
{
return null;
}
int type = ReadUint16();
Struct result = Struct.Create(type);
result.Read(this);
return result;
}
public Dictionary ReadMap()
{
long size = ReadUint32();
if (size == 0)
{
return null;
}
long count = ReadUint32();
Dictionary result = new Dictionary();
for (int i = 0; i < count; i++)
{
String key = ReadStr8();
byte code = Get();
QpidType t = GetType(code);
Object value = Read(t);
result.Add(key, value);
}
return result;
}
public List