Attached is the EncodedStream class from AmorphousDB as an example of what
I've been talking about.  The module has types that Firebird doesn't need
and is certainly missing types that Firebird needs, but it demonstrates
what I've been talking about.  Please note that it has not been licensed as
open source, so it should not be used verbatim.  Anyone is free, of course,
to use the technique.  Also note that it hasn't been QAed for production
use, though it is thought to work.

On Mon, Mar 2, 2015 at 8:35 PM, Slavomir Skopalik <skopa...@elektlabs.cz>
wrote:

> Hi all,
> after discusion with Jim, I was created frist draft of proposal for
> value encoding.
>
> Pros: efectivity for numerical values including date and time
> Cons: poor for strings (can be worst then current), can be solved by
> apply RLE (not current) over final result.
>
> It is designed as simple (there is space for improovement, but general
> value distribution function should be know)
> and easy to implement.
> It is use data from record format to skip length storage where is posible.
>
> Control byte= code:3bits + Value:5bits
>
> Code    Value    Meaning
> =====        =======
> 0
>      0    NULL
>      1    Float Nan
>      2-31    Unused
> 1
>      0    Fixed Binary (length comes from record format)
>      1-31    Unused
> 2        Int5    - (-16~15) from value
> 3        Int13    +1byte
> 4        Int21    +2bytes
> 5        Int29    +3bytes
> 6        Int37    +4bytes
> 7        Int45    +5bytes
>
> DataType in format structure:
>
> INT         - stored by absolute value, fixed binary for INT greater
> than 2^45
> VARCHAR        - int (length) + bytes[lenght]
> CHAR        - VARCHAR + fill space
> DATE        - Value-'1.1.2016' stored as int (nuber of days)
> TIME        - Time - '12:00:00' PM (noon) and stored as INT (what is
> requested precision?)
> TIMESTAMP    - as DATE followed by TIME
> FLOAT        - integer value stored as integer, else Fixed binary (4)
> DOUBLE PRECISION    - integer value stored as integer, else Fixed binary
> (8)
> DECIMAL        - Stored as INT
> BLOBID        - stored as integer
>
>
> Record format:
> uint32    tr_id
> uint8    format
> <data>
>
>
> Any comments?
>
> Slavek
>
> --
> Ing. Slavomir Skopalik
> Executive Head
> Elekt Labs s.r.o.
> Collection and evaluation of data from machines and laboratories
> by means of system MASA (http://www.elektlabs.cz/m2demo)
> -----------------------------------------------------------------
> Address:
> Elekt Labs s.r.o.
> Chaloupky 158
> 783 72 Velky Tynec
> Czech Republic
> ---------------------------------------------------------------
> Mobile: +420 724 207 851
> icq:199 118 333
> skype:skopaliks
> e-mail:skopa...@elektlabs.cz
> http://www.elektlabs.cz
>
>
>
>
> ------------------------------------------------------------------------------
> Dive into the World of Parallel Programming The Go Parallel Website,
> sponsored
> by Intel and developed in partnership with Slashdot Media, is your hub for
> all
> things parallel software development, from weekly thought leadership blogs
> to
> news, videos, case studies, tutorials and more. Take a look and join the
> conversation now. http://goparallel.sourceforge.net/
> Firebird-Devel mailing list, web interface at
> https://lists.sourceforge.net/lists/listinfo/firebird-devel
>
// Copyright (c) 2014 by James A. Starkey.  All rights reserved.

#include <memory.h>
#include <string.h>
#include "Common.h"
#include "EncodedStream.h"
#include "ServerException.h"


EncodedStream::EncodedStream(void)
{
	readPtr = readEnd = NULL;
}


EncodedStream::EncodedStream(Stream* stream) : Stream(stream)
{
	readPtr = readEnd = NULL;
}

EncodedStream::EncodedStream(int length, const char* bytes, bool copyFlag) : Stream(length, bytes, copyFlag)
{
	readPtr = readEnd = NULL;
}


EncodedStream::~EncodedStream(void)
{
}


void EncodedStream::decode(void)
{
	code = getByte();
		
	switch (code)
		{
		case codeNull:
			type = typeNull;
			break;

		case codeEnd:
			type = typeEnd;
			break;

		case codeBoolean0:
		case codeBoolean1:
			type = typeBoolean;
			boolean = code == codeBoolean1;
			break;
				
		case codeClass0:
		case codeClass1:
		case codeClass2:
		case codeClass3:
		case codeClass4:
		case codeClass5:
		case codeClass6:
		case codeClass7:
		case codeClass8:
		case codeClass9:
		case codeClass10:
		case codeClass11:
		case codeClass12:
		case codeClass13:
		case codeClass14:
		case codeClass15:
		case codeClass16:
			type = typeClassId;
			number = code - codeClass0;
			break;

		case codeClassCount1:
		case codeClassCount2:
		case codeClassCount3:
		case codeClassCount4:
			decodeUnimplemented(code);

		case codeIntMinus10:
		case codeIntMinus9:
		case codeIntMinus8:
		case codeIntMinus7:
		case codeIntMinus6:
		case codeIntMinus5:
		case codeIntMinus4:
		case codeIntMinus3:
		case codeIntMinus2:
		case codeIntMinus1:
		case codeInt0:
		case codeInt1:
		case codeInt2:
		case codeInt3:
		case codeInt4:
		case codeInt5:
		case codeInt6:
		case codeInt7:
		case codeInt8:
		case codeInt9:
		case codeInt10:
		case codeInt11:
		case codeInt12:
		case codeInt13:
		case codeInt14:
		case codeInt15:
		case codeInt16:
		case codeInt17:
		case codeInt18:
		case codeInt19:
		case codeInt20:
		case codeInt21:
		case codeInt22:
		case codeInt23:
		case codeInt24:
		case codeInt25:
		case codeInt26:
		case codeInt27:
		case codeInt28:
		case codeInt29:
		case codeInt30:
		case codeInt31:
		case codeInt32:
			type = typeInt;
			scale = 0;
			number = code - codeInt0;
			break;
			
		case codeIntLen1:
		case codeIntLen2:
		case codeIntLen3:
		case codeIntLen4:
			type = typeInt;
			scale = 0;
			number = decodeInteger(code - codeIntLen1 + 1);
			break;

		case codeIntLen5:
		case codeIntLen6:
		case codeIntLen7:
		case codeIntLen8:
			type = typeLong;
			scale = 0;
			number = decodeInteger(code - codeIntLen1 + 1);
			break;

		case codeScaledIntLen1:
		case codeScaledIntLen2:
		case codeScaledIntLen3:
		case codeScaledIntLen4:
		case codeScaledIntLen5:
		case codeScaledIntLen6:
		case codeScaledIntLen7:
		case codeScaledIntLen8:
			type = typeLong;
			scale = (int) getByte();
			number = decodeInteger(code - codeScaledIntLen1 + 1);
			break;

		case codeUtf8Len0:
			type = typeString;
			string = NULL;
			break;

		case codeUtf8Len1:
		case codeUtf8Len2:
		case codeUtf8Len3:
		case codeUtf8Len4:
		case codeUtf8Len5:
		case codeUtf8Len6:
		case codeUtf8Len7:
		case codeUtf8Len8:
		case codeUtf8Len9:
		case codeUtf8Len10:
		case codeUtf8Len11:
		case codeUtf8Len12:
		case codeUtf8Len13:
		case codeUtf8Len14:
		case codeUtf8Len15:
		case codeUtf8Len16:
		case codeUtf8Len17:
		case codeUtf8Len18:
		case codeUtf8Len19:
		case codeUtf8Len20:
		case codeUtf8Len21:
		case codeUtf8Len22:
		case codeUtf8Len23:
		case codeUtf8Len24:
		case codeUtf8Len25:
		case codeUtf8Len26:
		case codeUtf8Len27:
		case codeUtf8Len28:
		case codeUtf8Len29:
		case codeUtf8Len30:
		case codeUtf8Len31:
		case codeUtf8Len32:
			{
			type = typeString;
			int length = code - codeUtf8Len0;
			char *bytes = string.getStringBuffer(length);
			readData(length, bytes);
			string.releaseStringBuffer();
				
			return;
			}

		case codeUtf8Count1:
		case codeUtf8Count2:
		case codeUtf8Count3:
		case codeUtf8Count4:
			{
			type = typeString;
			int length = (int) decodeInteger(code - codeUtf8Count1 + 1);
			char *bytes = string.getStringBuffer(length);
			readData(length, bytes);
			string.releaseStringBuffer();
				
			return;
			}

		case codeDateLen0:
		case codeDateLen1:
		case codeDateLen2:
		case codeDateLen3:
		case codeDateLen4:
		case codeDateLen5:
		case codeDateLen6:
		case codeDateLen7:
		case codeDateLen8:
			type = typeDate;
			date.date = decodeInteger(code - codeDateLen0);

			return;

		case codeTimestampLen0:
		case codeTimestampLen1:
		case codeTimestampLen2:
		case codeTimestampLen3:
		case codeTimestampLen4:
		case codeTimestampLen5:
		case codeTimestampLen6:
		case codeTimestampLen7:
		case codeTimestampLen8:
			type = typeTimestamp;
			number = decodeInteger(code - codeTimestampLen0);
			scale = ((signed char) getByte()) * 30;

			return;

		case codeDouble0:
		case codeDouble1:
		case codeDouble2:
		case codeDouble3:
		case codeDouble4:
		case codeDouble5:
		case codeDouble6:
		case codeDouble7:
		case codeDouble8:
			{
			union
				{
				double	dbl;
				UCHAR	bytes[8];
				} stuff;

			type = typeDouble;
			int count = code - codeDouble0;
			stuff.dbl = 0;

			for (int n = 0; n < count; ++n)
				stuff.bytes[7 - n] = getByte();

			dbl = stuff.dbl;
			
			return;
			}

		case codeOpaqueLen0:
		case codeOpaqueLen1:
		case codeOpaqueLen2:
		case codeOpaqueLen3:
		case codeOpaqueLen4:
		case codeOpaqueLen5:
		case codeOpaqueLen6:
		case codeOpaqueLen7:
		case codeOpaqueLen8:
		case codeOpaqueLen9:
		case codeOpaqueLen10:
		case codeOpaqueLen11:
		case codeOpaqueLen12:
		case codeOpaqueLen13:
		case codeOpaqueLen14:
		case codeOpaqueLen15:
		case codeOpaqueLen16:
			{
			type = typeOpaque;
			int length = code - codeOpaqueLen0;
			char *bytes = string.getStringBuffer(length);
			readData(length, bytes);
			string.releaseStringBuffer();
				
			return;
			}

		case codeOpaqueCount1:
		case codeOpaqueCount2:
		case codeOpaqueCount3:
		case codeOpaqueCount4:
			{
			type = typeOpaque;
			int length = (int) decodeInteger(code - codeOpaqueCount1 + 1);
			char *bytes = string.getStringBuffer(length);
			readData(length, bytes);
			string.releaseStringBuffer();
				
			return;
			}

		case codeUuid:
			type = typeUUId;
			uuid.data.d.data1 = (uint32_t) decodeInteger(sizeof(uuid.data.d.data1));
			uuid.data.d.data2 = (uint16_t) decodeInteger(sizeof(uuid.data.d.data2));
			uuid.data.d.data3 = (uint16_t) decodeInteger(sizeof(uuid.data.d.data3));
			uuid.data.d.data4 = (uint16_t) decodeInteger(sizeof(uuid.data.d.data4));

			for (int n = 0; n < sizeof(uuid.data.d.data5); ++n)
				uuid.data.d.data5[n] = getByte();

			break;
			
		default:
			decodeUnimplemented(code);
		}
}


void EncodedStream::decodeUnimplemented(int code)
{
	throw ServerException("decode byte code %d not implemented", code);
}

void EncodedStream::encodeUnimplemented(const char* type)
{
	throw ServerException("encode %s not implemented", type);
}

void EncodedStream::encodeNull()
{
	putByte(codeNull);
}
	
 void EncodedStream::encodeEnd()
{
	putByte(codeEnd);
}
	
 void EncodedStream::encodeBoolean(bool value)
{
	putByte((char) (codeBoolean0 + ((value) ? 1 : 0)));
}

void EncodedStream::encodeInt(int value)
{
	encodeInt64(value);
}

void EncodedStream::encodeInt64(int64_t value)
{
	if (value >= (codeIntMinus10 - codeInt0) && value < (codeIntLen1 - codeInt0))
		{
		putByte((char) (codeInt0 + value));
			
		return;
		}

    int count = byteCount(value);
    putByte(codeIntLen1 + count - 1);
    putNumber(count, value);
}


void EncodedStream::encodeScaledInt(int scale, int64_t value)
{
	if (scale == 0 || value == 0)
		encodeInt64(value);
	else
		{
		int count = byteCount(value);
		putByte(codeScaledIntLen1 + count - 1);
		putByte(scale);
		putNumber(count, value);
		}
}

int EncodedStream::byteCount(int64_t n)
{
	if (n == 0)
		return 0;
		
	if (n > 0)
		{
		if (n < (1L << 7))
			return 1;
			
		if (n < (1L << 15))
			return 2;
			
		if (n < (1L << 23))
			return 3;
			
		if (n < (1L << 31))
			return 4;
			
		if (n < (1LL << 39))
			return 5;
			
		if (n < (1LL << 47))
			return 6;
			
		if (n < (1LL << 55))
			return 7;
			
		return 8;
		}
		
	if (n >= -(1L << 7))
		return 1;
		
	if (n >= -(1L << 15))
		return 2;
		
	if (n >= -(1L << 23))
		return 3;
		
	if (n >= -(1L << 31))
		return 4;
		
	if (n >= -(1LL << 39))
		return 5;
		
	if (n >= -(1LL << 47))
		return 6;
		
	if (n >= -(1LL << 55))
		return 7;
		
	return 8;
}


void EncodedStream::putNumber(int count, int64_t value)
{
    for (int shift = (count - 1) * 8; shift >= 0; shift -= 8)
        putByte((char) (value >> shift));
}


void EncodedStream::encodeString(String string)
{
	encodeString((int) string.getLength(), string);
}


void EncodedStream::encodeString(const char* string)
{
	encodeString((int) strlen(string), string);
}

void EncodedStream::encodeString(int length, const char* string)
{
	if (length < codeUtf8Count1 - codeUtf8Len0)
		putByte((char) (codeUtf8Len0 + length));
	else
		{
		int count = byteCount(length);
		putByte((char) (codeUtf8Count1 + count - 1));
		putNumber(count, length);
		}
			
	putBytes(length, string);
}


void EncodedStream::encodeOpaque(int length, const UCHAR* data)
{
	if (length < codeOpaqueCount1 - codeOpaqueLen0)
		putByte((char) (codeOpaqueLen0 + length));
	else
		{
		int count = byteCount(length);
		putByte((char) (codeOpaqueCount1 + count - 1));
		putNumber(count, length);
		}
			
	putBytes(length, (const char*) data);
}

int EncodedStream::getInt32(void)
{
	decode();

	if (type == typeNull)
		return 0;

	if (type != typeInt)
		decodeError("int");

	if (scale)
		decodeError("unexpected scale");

	return (int) number;
}


int64_t EncodedStream::getInt64(void)
{
	decode();

	if (type == typeNull)
		return 0;

	if (type != typeInt && type != typeLong)
		decodeError("int64");

	if (scale)
		decodeError("unexpected scale");

	return number;
}


void EncodedStream::decodeError(const char* expectedType)
{
	throw ServerException("Decode error, expected \"%s\"",expectedType);
}


int64_t EncodedStream::decodeInteger(int count)
{
	int64_t number = (signed char) getByte();

	for (int n = 1; n < count; ++n)
		number = (number << 8) | getByte();

	return number;
}


void EncodedStream::encodeUUId(UUId* uuid)
{
	putByte(codeUuid);
	putNumber(sizeof(uuid->data.d.data1), uuid->data.d.data1);
	putNumber(sizeof(uuid->data.d.data2), uuid->data.d.data2);
	putNumber(sizeof(uuid->data.d.data3), uuid->data.d.data3);
	putNumber(sizeof(uuid->data.d.data4), uuid->data.d.data4);

	for (int n = 0; n < sizeof(uuid->data.d.data5); ++n)
		putByte(uuid->data.d.data5[n]);
}


UUId EncodedStream::getUUId(void)
{
	decode();

	if (type != typeUUId)
		decodeError("UUID");

	return uuid;
}


void EncodedStream::readData(void)
{
	if (!totalLength)
		dataOverrun();

	if ( !(readSegment = (readSegment) ? readSegment->next : segments) )
		dataOverrun();

	readPtr = (UCHAR*) readSegment->data;
	readEnd = readPtr + readSegment->bytesUsed;
}


void EncodedStream::readData(int length, void* buffer)
{
	UCHAR *p = (UCHAR*) buffer;

	for (int len = length; len;)
		{
		int l = (int) MIN(readEnd - readPtr, len);

		if (l)
			{
			memcpy(p, readPtr, l);
			readPtr += l;
			len -= l;
			p += l;
			}
		else
			readData();
		}
		
}

String EncodedStream::getEncodedString(void)
{
	decode();

	if (type != typeString)
		decodeError("String");

	return string;
}


String EncodedStream::getOpaque(void)
{
	decode();

	if (type != typeOpaque)
		decodeError("Opaque");

	return string;
}


int64_t EncodedStream::getScaledInt(int* scale)
{
	decode();

	if (type == typeNull)
		{
		*scale = 0;

		return 0;
		}

	if (type != typeInt)
		decodeError("int");

	*scale = this->scale;

	return number;
}


bool EncodedStream::getBoolean(void)
{
	decode();

	if (type != typeBoolean)
		decodeError("Boolean");

	return boolean;
}

// This, of course, has endian problems

void EncodedStream::encodeDouble(double value)
{
	union
		{
		double	dbl;
		UCHAR	bytes[8];
		} stuff;

	stuff.dbl = value;
	int zeroBytes = 0;

	while (zeroBytes < 8 && stuff.bytes[zeroBytes] == 0)
		++zeroBytes;

	putByte(codeDouble0 + 8 - zeroBytes);

	for (int n = 8; n > zeroBytes;)
		putByte(stuff.bytes[--n]);
}


double EncodedStream::getDouble(void)
{
	decode();

	if (type != typeDouble)
		decodeError("double");

	return dbl;
}


void EncodedStream::encodeDate(Date value)
{
	int count = byteCount(value.date);
    putByte(codeDateLen0 + count);
    putNumber(count, value.date);
}


Date EncodedStream::getDate(void)
{
	decode();

	if (type != typeDate)
		decodeError("date");

	return date;
}


Timestamp EncodedStream::getTimestamp(void)
{
	decode();

	if (type != typeTimestamp)
		decodeError("timestamp");

	return Timestamp(number, scale);
}


void EncodedStream::encodeTimestamp(Timestamp value)
{
	int count = byteCount(value.timestamp);
    putByte(codeTimestampLen0 + count);
    putNumber(count, value.timestamp);
	putByte(value.tzOffset / 30);
}



void EncodedStream::setEncodedStream(EncodedStream* stream)
{
	setStream(stream);
	readPtr = stream->readPtr;
	readEnd = stream->readEnd;
}
// Copyright (c) 2014 by James A. Starkey.  All rights reserved.


#pragma once

#include "Stream.h"
#include "StringClass.h"
#include "UUId.h"
#include "Date.h"
#include "Timestamp.h"

static const int typeNull				= 1;
static const int typeEnd				= 2;
static const int typeBoolean			= 3;
static const int typeClassId			= 4;
static const int typeAttributeId		= 5;
static const int typeObjectId			= 6;
static const int typeList				= 7;
static const int typeInt				= 8;
static const int typeLong				= 9;
static const int typeDouble				= 10;
static const int typeDate				= 11;
static const int typeString				= 12;
static const int typeOpaque				= 13;
static const int typeUUId				= 14;
static const int typeTimestamp			= 15;
	

static const int codeNull               = 1;
static const int codeEnd                = 2;
static const int codeBoolean0           = 3;
static const int codeBoolean1           = 4;
static const int codeClass0             = 5;
static const int codeClass1             = 6;
static const int codeClass2             = 7;
static const int codeClass3             = 8;
static const int codeClass4             = 9;
static const int codeClass5             = 10;
static const int codeClass6             = 11;
static const int codeClass7             = 12;
static const int codeClass8             = 13;
static const int codeClass9             = 14;
static const int codeClass10            = 15;
static const int codeClass11            = 16;
static const int codeClass12            = 17;
static const int codeClass13            = 18;
static const int codeClass14            = 19;
static const int codeClass15            = 20;
static const int codeClass16            = 21;
static const int codeClassCount1        = 22;
static const int codeClassCount2        = 23;
static const int codeClassCount3        = 24;
static const int codeClassCount4        = 25;
static const int codeIntMinus10         = 26;
static const int codeIntMinus9          = 27;
static const int codeIntMinus8          = 28;
static const int codeIntMinus7          = 29;
static const int codeIntMinus6          = 30;
static const int codeIntMinus5          = 31;
static const int codeIntMinus4          = 32;
static const int codeIntMinus3          = 33;
static const int codeIntMinus2          = 34;
static const int codeIntMinus1          = 35;
static const int codeInt0               = 36;
static const int codeInt1               = 37;
static const int codeInt2               = 38;
static const int codeInt3               = 39;
static const int codeInt4               = 40;
static const int codeInt5               = 41;
static const int codeInt6               = 42;
static const int codeInt7               = 43;
static const int codeInt8               = 44;
static const int codeInt9               = 45;
static const int codeInt10              = 46;
static const int codeInt11              = 47;
static const int codeInt12              = 48;
static const int codeInt13              = 49;
static const int codeInt14              = 50;
static const int codeInt15              = 51;
static const int codeInt16              = 52;
static const int codeInt17              = 53;
static const int codeInt18              = 54;
static const int codeInt19              = 55;
static const int codeInt20              = 56;
static const int codeInt21              = 57;
static const int codeInt22              = 58;
static const int codeInt23              = 59;
static const int codeInt24              = 60;
static const int codeInt25              = 61;
static const int codeInt26              = 62;
static const int codeInt27              = 63;
static const int codeInt28              = 64;
static const int codeInt29              = 65;
static const int codeInt30              = 66;
static const int codeInt31              = 67;
static const int codeInt32              = 68;
static const int codeIntLen1            = 69;
static const int codeIntLen2            = 70;
static const int codeIntLen3            = 71;
static const int codeIntLen4            = 72;
static const int codeIntLen5            = 73;
static const int codeIntLen6            = 74;
static const int codeIntLen7            = 75;
static const int codeIntLen8            = 76;
static const int codeScaledIntLen1      = 77;
static const int codeScaledIntLen2      = 78;
static const int codeScaledIntLen3      = 79;
static const int codeScaledIntLen4      = 80;
static const int codeScaledIntLen5      = 81;
static const int codeScaledIntLen6      = 82;
static const int codeScaledIntLen7      = 83;
static const int codeScaledIntLen8      = 84;
static const int codeUtf8Len0           = 85;
static const int codeUtf8Len1           = 86;
static const int codeUtf8Len2           = 87;
static const int codeUtf8Len3           = 88;
static const int codeUtf8Len4           = 89;
static const int codeUtf8Len5           = 90;
static const int codeUtf8Len6           = 91;
static const int codeUtf8Len7           = 92;
static const int codeUtf8Len8           = 93;
static const int codeUtf8Len9           = 94;
static const int codeUtf8Len10          = 95;
static const int codeUtf8Len11          = 96;
static const int codeUtf8Len12          = 97;
static const int codeUtf8Len13          = 98;
static const int codeUtf8Len14          = 99;
static const int codeUtf8Len15          = 100;
static const int codeUtf8Len16          = 101;
static const int codeUtf8Len17          = 102;
static const int codeUtf8Len18          = 103;
static const int codeUtf8Len19          = 104;
static const int codeUtf8Len20          = 105;
static const int codeUtf8Len21          = 106;
static const int codeUtf8Len22          = 107;
static const int codeUtf8Len23          = 108;
static const int codeUtf8Len24          = 109;
static const int codeUtf8Len25          = 110;
static const int codeUtf8Len26          = 111;
static const int codeUtf8Len27          = 112;
static const int codeUtf8Len28          = 113;
static const int codeUtf8Len29          = 114;
static const int codeUtf8Len30          = 115;
static const int codeUtf8Len31          = 116;
static const int codeUtf8Len32          = 117;
static const int codeUtf8Count1         = 118;
static const int codeUtf8Count2         = 119;
static const int codeUtf8Count3         = 120;
static const int codeUtf8Count4         = 121;
static const int codeDateLen0         = 122;
static const int codeDateLen1         = 123;
static const int codeDateLen2         = 124;
static const int codeDateLen3         = 125;
static const int codeDateLen4         = 126;
static const int codeDateLen5         = 127;
static const int codeDateLen6         = 128;
static const int codeDateLen7         = 129;
static const int codeDateLen8         = 130;
static const int codeDouble0            = 131;
static const int codeDouble1            = 132;
static const int codeDouble2            = 133;
static const int codeDouble3            = 134;
static const int codeDouble4            = 135;
static const int codeDouble5            = 136;
static const int codeDouble6            = 137;
static const int codeDouble7            = 138;
static const int codeDouble8            = 139;
static const int codeOpaqueLen0         = 140;
static const int codeOpaqueLen1         = 141;
static const int codeOpaqueLen2         = 142;
static const int codeOpaqueLen3         = 143;
static const int codeOpaqueLen4         = 144;
static const int codeOpaqueLen5         = 145;
static const int codeOpaqueLen6         = 146;
static const int codeOpaqueLen7         = 147;
static const int codeOpaqueLen8         = 148;
static const int codeOpaqueLen9         = 149;
static const int codeOpaqueLen10        = 150;
static const int codeOpaqueLen11        = 151;
static const int codeOpaqueLen12        = 152;
static const int codeOpaqueLen13        = 153;
static const int codeOpaqueLen14        = 154;
static const int codeOpaqueLen15        = 155;
static const int codeOpaqueLen16        = 156;
static const int codeOpaqueCount1       = 157;
static const int codeOpaqueCount2       = 158;
static const int codeOpaqueCount3       = 159;
static const int codeOpaqueCount4       = 160;
static const int codeUuid               = 161;
static const int codeTimestampLen0      = 162;
static const int codeTimestampLen1      = 163;
static const int codeTimestampLen2      = 164;
static const int codeTimestampLen3      = 165;
static const int codeTimestampLen4      = 166;
static const int codeTimestampLen5      = 167;
static const int codeTimestampLen6      = 168;
static const int codeTimestampLen7      = 169;
static const int codeTimestampLen8      = 170;
	
	

class EncodedStream : public Stream
{
public:
	EncodedStream(void);
	EncodedStream(int length, const char* bytes, bool copyFlag);
	EncodedStream(Stream* stream);
	~EncodedStream(void);

	void		decode(void);
	int			byteCount(int64_t n);
	void		putNumber(int count, int64_t number);
	void		decodeError(const char* expectedType);
	int64_t		decodeInteger(int count);
	void		setEncodedStream(EncodedStream* stream);

	void		encodeNull();
	void		encodeEnd();
	void		encodeBoolean(bool value);
	void		encodeInt(int value);
	void		encodeInt64(int64_t value);
	void		encodeString(String value);
	void		encodeString(const char* string);
	void		encodeString(int length, const char* string);
	void		encodeUUId(UUId* uuid);
	void		encodeOpaque(int length, const UCHAR* data);
	void		encodeScaledInt(int scale, int64_t number);
	void		encodeDate(Date value);
	void		encodeTimestamp(Timestamp timestamp);
	void		encodeDouble(double value);

	int			getInt32(void);
	int64_t		getInt64(void);
	UUId		getUUId(void);
	String		getOpaque(void);
	String		getEncodedString(void);				// getString conflicts with Stream::getString
	int64_t		getScaledInt(int* scale);
	bool		getBoolean(void);
	double		getDouble(void);
	Date		getDate(void);
	Timestamp	getTimestamp(void);

	virtual void	readData(void);
	virtual void	readData(int length, void* buffer);
	virtual void	decodeUnimplemented(int code);
	virtual void	encodeUnimplemented(const char *text);

	inline UCHAR getByte()
		{
		for (;;)
			if (readPtr < readEnd)
				return *readPtr++;
			else
				readData();
		}

	int 		type;
	int64_t		number;
	String		string;
	bool		boolean;
	int			code;
	int			scale;
	UUId		uuid;
	double		dbl;
	Date		date;
	const UCHAR	*readPtr;
	const UCHAR	*readEnd;
};

------------------------------------------------------------------------------
Dive into the World of Parallel Programming The Go Parallel Website, sponsored
by Intel and developed in partnership with Slashdot Media, is your hub for all
things parallel software development, from weekly thought leadership blogs to
news, videos, case studies, tutorials and more. Take a look and join the 
conversation now. http://goparallel.sourceforge.net/
Firebird-Devel mailing list, web interface at 
https://lists.sourceforge.net/lists/listinfo/firebird-devel

Reply via email to