typedef base128uint ReadUintBase128();
typedef struct
{
uint8 flags;
uint32 tag;
base128uint origLength;
base128uint transformLength;
} tableDirectoryEntry <optimize=false>;
uint32 ReadUIntBase128()
{
local uint32 accum = 0;
local uint16 i = 0;
for (i = 0; i < 5; i++) {
local uint8 data_byte = ReadByte();
// No leading 0's
if (i == 0 && data_byte == 0x80) return 0;
// If any of top 7 bits are set then << 7 would overflow
if (accum & 0xFE000000) return 0;
accum = (accum << 7) | (data_byte & 0x7F);
// Spin until most significant bit of data byte is false
if ((data_byte & 0x80) == 0) {
return accum;
}
}
// UIntBase128 sequence exceeds 5 bytes
return 0;
}
The above code will, of course, not run but I hope it’s complete enough to illustrate what I am trying to accomplish. Is there any way for struct members to be the result of a calculation without using local?
For a variable sized array it would be easiest to define base123uint as a struct, then use one function to figure out how many bytes are in the array and another function to convert the datatype to a string. For example:
typedef struct {
uint8 data[ CalculateUIntBase128Size() ];
} base128uint <read=ReadUIntBase128>;
typedef struct
{
uint8 flags;
uint32 tag;
base128uint origLength;
base128uint transformLength;
} tableDirectoryEntry <optimize=false>;
uint32 CalculateUIntBase128Size()
{
local int64 pos = FTell();
local int32 i;
local uint8 data_byte;
for( i = 0; i < 5; i++ )
{
data_byte = ReadUByte( pos+i );
if ((data_byte & 0x80) == 0)
{
i = i + 1;
break;
}
}
return i;
}
string ReadUIntBase128( base128uint &num )
{
local uint32 accum = 0;
local uint16 i = 0;
local uint32 count = sizeof(num.data);
local uint8 data_byte;
for (i = 0; i < count; i++) {
data_byte = num.data[i];
// No leading 0's
if (i == 0 && data_byte == 0x80) return "0";
// If any of top 7 bits are set then << 7 would overflow
if (accum & 0xFE000000) return "ERROR";
accum = (accum << 7) | (data_byte & 0x7F);
// Spin until most significant bit of data byte is false
if ((data_byte & 0x80) == 0) {
return Str( "%u", accum );
}
}
// UIntBase128 sequence exceeds 5 bytes
return "OVERFLOW";
}
We weren’t sure how the logic in the ‘CalculateUIntBase128Size’ function should work and you would have to fix that up. Let us know if you have any questions on this. Cheers!