public virtual int decode(byte[] source, int sourceOffset)
{
int offset = sourceOffset;
int code = source[offset++] & 0xff;
int l;
int count;
switch (code)
{
case edsNull:
type = edsTypeNull;
break;
case edsTrue:
type = edsTypeBoolean;
@bool = true;
break;
case edsFalse:
type = edsTypeBoolean;
@bool = false;
break;
case edsIntMinus10:
case edsIntMinus9:
case edsIntMinus8:
case edsIntMinus7:
case edsIntMinus6:
case edsIntMinus5:
case edsIntMinus4:
case edsIntMinus3:
case edsIntMinus2:
case edsIntMinus1:
case edsInt0:
case edsInt1:
case edsInt2:
case edsInt3:
case edsInt4:
case edsInt5:
case edsInt6:
case edsInt7:
case edsInt8:
case edsInt9:
case edsInt10:
case edsInt11:
case edsInt12:
case edsInt13:
case edsInt14:
case edsInt15:
case edsInt16:
case edsInt17:
case edsInt18:
case edsInt19:
case edsInt20:
case edsInt21:
case edsInt22:
case edsInt23:
case edsInt24:
case edsInt25:
case edsInt26:
case edsInt27:
case edsInt28:
case edsInt29:
case edsInt30:
case edsInt31:
integer32 = code - edsInt0;
scale = 0;
type = edsTypeInt32;
break;
case edsIntLen1:
type = edsTypeInt32;
scale = 0;
integer32 = (sbyte)source[offset++];
break;
case edsIntLen2:
type = edsTypeInt32;
scale = 0;
integer32 = ((sbyte)source[offset] << 8) | (source[offset + 1] & 0xff);
offset += 2;
break;
case edsIntLen3:
type = edsTypeInt32;
scale = 0;
integer32 = ((sbyte)source[offset]) << 16 | (source[offset + 1] & 0xff) << 8 | (source[offset + 2] & 0xff);
offset += 3;
break;
case edsIntLen4:
type = edsTypeInt32;
scale = 0;
integer32 = ((sbyte)source[offset]) << 24 | (source[offset + 1] & 0xff) << 16 | (source[offset + 2] & 0xff) << 8 | (source[offset + 3] & 0xff);
offset += 4;
break;
case edsIntLen5:
case edsIntLen6:
case edsIntLen7:
case edsIntLen8:
l = code - edsIntLen1;
integer64 = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
scale = 0;
type = edsTypeInt64;
break;
case edsScaledLen0:
scale = (sbyte)source[offset++];
integer64 = 0;
type = edsTypeScaled;
break;
case edsScaledLen1:
case edsScaledLen2:
case edsScaledLen3:
case edsScaledLen4:
case edsScaledLen5:
case edsScaledLen6:
case edsScaledLen7:
case edsScaledLen8:
scale = (sbyte)source[offset++];
l = code - edsScaledLen1;
integer64 = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
type = edsTypeScaled;
break;
case edsUtf8Len0:
case edsUtf8Len1:
case edsUtf8Len2:
case edsUtf8Len3:
case edsUtf8Len4:
case edsUtf8Len5:
case edsUtf8Len6:
case edsUtf8Len7:
case edsUtf8Len8:
case edsUtf8Len9:
case edsUtf8Len10:
case edsUtf8Len11:
case edsUtf8Len12:
case edsUtf8Len13:
case edsUtf8Len14:
case edsUtf8Len15:
case edsUtf8Len16:
case edsUtf8Len17:
case edsUtf8Len18:
case edsUtf8Len19:
case edsUtf8Len20:
case edsUtf8Len21:
case edsUtf8Len22:
case edsUtf8Len23:
case edsUtf8Len24:
case edsUtf8Len25:
case edsUtf8Len26:
case edsUtf8Len27:
case edsUtf8Len28:
case edsUtf8Len29:
case edsUtf8Len30:
case edsUtf8Len31:
case edsUtf8Len32:
case edsUtf8Len33:
case edsUtf8Len34:
case edsUtf8Len35:
case edsUtf8Len36:
case edsUtf8Len37:
case edsUtf8Len38:
case edsUtf8Len39:
l = code - edsUtf8Len0;
@string = getString(source, offset, l);
offset += l;
type = edsTypeUtf8;
break;
case edsUtf8Count1:
case edsUtf8Count2:
case edsUtf8Count3:
case edsUtf8Count4:
count = code - edsUtf8Count1;
int length = source[offset++] & 0xff;
for (int n = 0; n < count; ++n)
{
length = length << 8 | (source[offset++] & 0xff);
}
@string = getString(source, offset, length);
offset += length;
type = edsTypeUtf8;
break;
case edsOpaqueLen0:
case edsOpaqueLen1:
case edsOpaqueLen2:
case edsOpaqueLen3:
case edsOpaqueLen4:
case edsOpaqueLen5:
case edsOpaqueLen6:
case edsOpaqueLen7:
case edsOpaqueLen8:
case edsOpaqueLen9:
case edsOpaqueLen10:
case edsOpaqueLen11:
case edsOpaqueLen12:
case edsOpaqueLen13:
case edsOpaqueLen14:
case edsOpaqueLen15:
case edsOpaqueLen16:
case edsOpaqueLen17:
case edsOpaqueLen18:
case edsOpaqueLen19:
case edsOpaqueLen20:
case edsOpaqueLen21:
case edsOpaqueLen22:
case edsOpaqueLen23:
case edsOpaqueLen24:
case edsOpaqueLen25:
case edsOpaqueLen26:
case edsOpaqueLen27:
case edsOpaqueLen28:
case edsOpaqueLen29:
case edsOpaqueLen30:
case edsOpaqueLen31:
case edsOpaqueLen32:
case edsOpaqueLen33:
case edsOpaqueLen34:
case edsOpaqueLen35:
case edsOpaqueLen36:
case edsOpaqueLen37:
case edsOpaqueLen38:
case edsOpaqueLen39:
l = code - edsOpaqueLen0;
bytes = new byte[l];
Array.Copy(source, offset, bytes, 0, l);
offset += l;
type = edsTypeOpaque;
break;
case edsOpaqueCount1:
case edsOpaqueCount2:
case edsOpaqueCount3:
case edsOpaqueCount4:
count = code - edsOpaqueCount1 + 1;
l = source[offset++] & 0xff;
for (int n = 1; n < count; ++n)
{
l = l << 8 | (source[offset++] & 0xff);
}
bytes = new byte[l];
Array.Copy(source, offset, bytes, 0, l);
offset += l;
type = edsTypeOpaque;
break;
case edsDoubleLen0:
case edsDoubleLen1:
case edsDoubleLen2:
case edsDoubleLen3:
case edsDoubleLen4:
case edsDoubleLen5:
case edsDoubleLen6:
case edsDoubleLen7:
case edsDoubleLen8:
count = code - edsDoubleLen0;
long lvalue = 0;
for (int n = 0; n < count; ++n)
{
lvalue = (lvalue << 8) | (source[offset++] & 0xff);
}
lvalue <<= (8 - count) * 8;
dbl = BitConverter.Int64BitsToDouble(lvalue);
type = edsTypeDouble;
break;
case edsTimeLen0:
integer64 = 0;
scale = 0;
type = edsTypeTime;
break;
case edsTimeLen1:
case edsTimeLen2:
case edsTimeLen3:
case edsTimeLen4:
l = code - edsTimeLen1;
integer64 = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
scale = 0;
type = edsTypeTime;
break;
case edsMilliSecLen0:
integer64 = 0;
scale = 0;
type = edsTypeMilliseconds;
break;
case edsMilliSecLen1:
case edsMilliSecLen2:
case edsMilliSecLen3:
case edsMilliSecLen4:
case edsMilliSecLen5:
case edsMilliSecLen6:
case edsMilliSecLen7:
case edsMilliSecLen8:
l = code - edsMilliSecLen1;
integer64 = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
scale = 0;
type = edsTypeMilliseconds;
break;
case edsNanoSecLen0:
integer64 = 0;
scale = 0;
type = edsTypeNanoseconds;
break;
case edsNanoSecLen1:
case edsNanoSecLen2:
case edsNanoSecLen3:
case edsNanoSecLen4:
case edsNanoSecLen5:
case edsNanoSecLen6:
case edsNanoSecLen7:
case edsNanoSecLen8:
l = code - edsNanoSecLen1;
integer64 = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
scale = 0;
type = edsTypeNanoseconds;
break;
//
// 09/2012 Added support for new scaled date/times encoding. These replace the old encoding
// edsTimeLen, edsMilliSecLen and edsNanoSecLen.
//
case edsScaledTimeLen1:
case edsScaledTimeLen2:
case edsScaledTimeLen3:
case edsScaledTimeLen4:
case edsScaledTimeLen5:
case edsScaledTimeLen6:
case edsScaledTimeLen7:
case edsScaledTimeLen8:
scale = (sbyte)source[offset++];
l = code - edsScaledTimeLen1 + 1;
integer64 = (sbyte)source[offset++];
for (int n = 1; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
type = edsTypeScaledTime;
break;
case edsScaledDateLen1:
case edsScaledDateLen2:
case edsScaledDateLen3:
case edsScaledDateLen4:
case edsScaledDateLen5:
case edsScaledDateLen6:
case edsScaledDateLen7:
case edsScaledDateLen8:
scale = (sbyte)source[offset++];
l = code - edsScaledDateLen1 + 1;
integer64 = (sbyte)source[offset++];
for (int n = 1; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
type = edsTypeScaledDate;
break;
case edsScaledTimestampLen1:
case edsScaledTimestampLen2:
case edsScaledTimestampLen3:
case edsScaledTimestampLen4:
case edsScaledTimestampLen5:
case edsScaledTimestampLen6:
case edsScaledTimestampLen7:
case edsScaledTimestampLen8:
scale = (sbyte)source[offset++];
l = code - edsScaledTimestampLen1 + 1;
integer64 = (sbyte)source[offset++];
for (int n = 1; n < l; ++n)
{
integer64 = (integer64 << 8) | (source[offset++] & 0xff);
}
type = edsTypeScaledTimestamp;
break;
case edsClobLen0:
blobId = 0;
type = edsTypeClob;
break;
case edsClobLen1:
case edsClobLen2:
case edsClobLen3:
case edsClobLen4:
l = code - edsClobLen1;
blobId = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
blobId = (blobId << 8) | (source[offset++] & 0xff);
}
type = edsTypeClob;
break;
case edsBlobLen0:
blobId = 0;
type = edsTypeBlob;
break;
case edsBlobLen1:
case edsBlobLen2:
case edsBlobLen3:
case edsBlobLen4:
l = code - edsBlobLen1;
blobId = (sbyte)source[offset++];
for (int n = 0; n < l; ++n)
{
blobId = (blobId << 8) | (source[offset++] & 0xff);
}
type = edsTypeBlob;
break;
case edsScaledCount1:
{
// For some reason C++ EncodedStream expects the encoded
// length to be length+1.
length = (source[offset++] & 0xff) - 1;
scale = (sbyte)source[offset++];
type = edsTypeBigInt;
bytes = new byte[length];
Array.Copy(source, offset, bytes, 0, length);
offset += length;
int sign = ((bytes[0] & 0x80) > 0) ? -1 : 1;
if (sign == -1)
{
bytes[0] &= 0x7f;
}
BigInteger bi = new BigInteger(bytes);
bigDecimal = Decimal.Parse(bi.ToString());
}
break;
case edsScaledCount2:
{
// For some reason C++ EncodedStream expects the encoded
// length to be length+1.
scale = (sbyte)source[offset++];
sbyte sign = (sbyte)source[offset++];
length = (source[offset++] & 0xff); // in bytes
type = edsTypeBigInt;
bytes = new byte[length];
Array.Copy(source, offset, bytes, 0, length);
offset += length;
if (sign == -1)
bytes[0] &= 0x7f;
else
sign = 1;
BigInteger bi = new BigInteger(bytes);
if (sign == -1)
bi = -bi;
bigDecimal = ScaleDecimal(Decimal.Parse(bi.ToString()), scale);
}
break;
case edsUUID:
{
byte[] buff = new byte[16];
for (int n = 0; n < 16; ++n)
{
buff[n] = (byte)(source[offset++] & 0xff);
}
uuid = new Guid(buff);
type = edsTypeUUID;
}
break;
default:
type = edsTypeUnknown;
break;
}
priorCode = code;
return offset;
}