Once I get that upgrade to 36-hour days, I will tackle that. – Mychaeel

Legacy:CompactIndex

From Unreal Wiki, The Unreal Engine Documentation Site
Jump to: navigation, search

CompactIndex is a special integer data type used very often in the Unreal Engine. It is used to reduce the size of a integer. However in the worst case scenario it takes up one extra byte (5bytes instead of 4), but this isn't often the case. CompactIndex is for example used to store the length of a string.

A CompactIndex tries to use as less bytes as possible to store the integer's (32bit) value.

The bytes[edit]

1st Byte[edit]

The MSB (Most Significant Bit) flags if the string is in UTF-16 encoding instead of normal ASCII. Thus the MSB only has a meaning when used for string length.

MSB-1 defines if there's another byte following this byte that should be included with the CompactIndex.

The other 6 bits are used for the value. Therefor the maximum value in the first byte is (2^6)-1 = 63

2nd to 4th Byte[edit]

The MSB defines if there's another byte following this byte that should be included with the CompactIndex.

The rest is used for the value. (2^7)-1 = 127

5th Byte[edit]

The whole byte is used for the value. However, because the first 4 bytes already consume 27 of the 32 bits only 5 bits are used in this byte.

Integer to CompactIndex[edit]

B1 = 1st byte of the CompactIndex; B2 = 2nd byte of the CompactIndex; etc.

//TODO
final function IntToIndex( int Integer, out byte data[255], out byte ptr )
{
	local int val;
 
	val = abs(Integer);
	if( val != Integer )
		data[ptr] = 0x80; // B1 sign bit
 
	data[ptr] += val & 0x3f; // B1 data, 6 bits
	val = val >> 6;
	if( val != 0 )
	{
		data[ptr] += 0x40; // B1 continue bit
		data[++ptr] = val & 0x7f; // B2 data, 7 bits
		val = val >> 7;
		if( val != 0 )
		{
			data[ptr] += 0x80; // B2 continue bit
			data[++ptr] = val & 0x7f; // B3 data, 7 bits
			val = val >> 7;
			if( val != 0 )
			{
				data[ptr] += 0x80; // B3 continue bit
				data[++ptr] = val & 0x7f; // B4 data, 7 bits
				val = val >> 7;
				if( val != 0 )
				{
					data[ptr] += 0x80; // B4 continue bit
					data[++ptr] = val & 0x1f; // B5 data, 5 bits
				}
			}
		}
	}
}

CompactIndex to Integer[edit]

B1 = 1st byte of the CompactIndex; B2 = 2nd byte of the CompactIndex; etc.

Integer = B1 & 0x3F;
if (B1 & 0x40) // got a 2nd byte
{
  Integer += (B2 & 0x3F) << 6;
  if (B2 & 0x80) // got a 3rd byte
  {
    Integer += (B3 & 0x3F) << 13;
    if (B3 & 0x80) // got a 4th byte
    {
      Integer += (B4 & 0x3F) << 20;
      if (B4 & 0x80) // got a 5th byte
      {
        Integer += (B5 & 0x3F) << 27;
      }
    }
  }
}

Example:

final function int IndexToInt( byte data[255], optional byte ptr )
{
	local byte B1,B2,B3,B4,B5;
	local int Integer;
 
	B1 = data[ptr++];
	Integer = B1 & 0x3f;
	if((B1 & 0x40)!=0)
	{
		B2 = data[ptr++];
		Integer += (B2 & 0x7f) << 6;
		if((B2 & 0x80)!=0)
		{
			B3 = data[ptr++];
			Integer += (B3 & 0x7f) << 13;
			if((B3 & 0x80)!=0)
			{
				B4 = data[ptr++];
				Integer += (B4 & 0x7f) << 20;
				if((B4 & 0x80)!=0)
				{
					B5 = data[ptr++];
					Integer += B5 << 27;
				}
			}
		}
	}
 
	if((B1 & 0x80)!=0) 
		Integer = -Integer;
 
	return Integer;
}

El Muerte: need this description when I'm going to port by UE2 query specification to the wiki