'Effi is an efficient file value storage method that works best with small values.
' * Values 250 and under save as one byte
' * Values 502 and under save as two bytes
' * Values 65534 and under save as three bytes
' * Values 16777215 and under save as four bytes
' * Values 2147483648 and under saves as five bytes
' * Negative values write an extra byte
Global maxthrib=(256*256*256)-1
' FILE READING / WRITING
Function WriteEffi(s:TStream,val:Long) 'Writes up to the value of an unsigned integer including negative sign (-2147483648 to 2147483648)
If val<0 Then WriteByte s,255;val=Abs(val) 'CHR 255 = NEGATIVE
If val=<250 Then WriteByte s,val;Return 'CHR<250 = BYTE
If val=<251+251 Then WriteByte s,251;WriteByte s,val-251;Return 'CHR 251 = BYTE+251
If val=<65535 Then WriteByte s,252;WriteShort s,val;Return 'CHR 252 = CONTROL BYTE + UNSIGNED SHORT
If val=<maxthrib Then WriteByte s,253;WriteThrib s,val;Return 'CHR 253 = CONTROL BYTE + UNSIGNED 3-BYTE
WriteByte s,254;WriteUSInt s,val;Return 'CHR 254 = CONTROL BYTE + UNSIGNED INT
End Function
Function ReadEffi:Long(s:TStream) 'Reads up to the value of an unsigned integer including negative sign (-2147483648 to 2147483648)
Local sign=1
Local b=ReadByte(s)
If b=255 Then sign=-1;b=ReadByte(s)
If b=<250 Then Return b*sign
If b=251 Then Return (251+ReadByte(s))*sign
If b=252 Then Return ReadShort(s)*sign
If b=253 Then Return ReadThrib(s)*sign 'unsigned 3-byte value
If b=254 Then Return ReadUSInt(s)*sign 'unsigned integer
End Function
Function WriteThrib(s:TStream,v) 'Unsigned 3-byte value (between a short and an int)
WriteByte s, (v Shr 16) & $ff
WriteByte s, (v Shr 8) & $ff
WriteByte s, v & $ff
End Function
Function ReadThrib(s:TStream) 'Unsigned 3-byte value (between a short and an int)
Local b1=ReadByte(s)
Local b2=ReadByte(s)
Local b3=ReadByte(s)
Return (b1 Shl 16) | (b2 Shl 8) | b3
End Function
Function WriteUSInt(s:TStream,v:Long) 'Unsigned Integer
WriteByte s, (v Shr 24) & $ff
WriteByte s, (v Shr 16) & $ff
WriteByte s, (v Shr 8) & $ff
WriteByte s, v & $ff
End Function
Function ReadUSInt:Long(s:TStream) 'Unsigned Integer
Local b1=ReadByte(s)
Local b2=ReadByte(s)
Local b3=ReadByte(s)
Local b4=ReadByte(s)
Return (b1 Shl 24) | (b2 Shl 16) | (b3 Shl 8) | b4
End Function
' QUICK CONVERSION IF NEEDED (USING STRINGS)
Function Effi$(val:Long)
Local o$
If val<0 Then o=Chr(255);val=Abs(val)
If val=<250 Then o:+Chr(val);Return o
If val=<251+251 Then o:+Chr(251);o:+Chr(val-251);Return o
If val=<65535 Then o:+Chr(252);o:+Chr((val Shr 8) & $ff);o:+Chr(val & $ff);Return o
If val=<maxthrib Then o:+Chr(253);o:+Chr((val Shr 16) & $ff);o:+Chr((val Shr 8) & $ff);o:+Chr(val & $ff);Return o
o:+Chr(254);o:+Chr((val Shr 24) & $ff);o:+Chr((val Shr 16) & $ff);o:+Chr((val Shr 8) & $ff);o:+Chr(val & $ff);Return o
End Function
Function UnEffi:Long(i$)
Local sign=1
Local b=Asc(Mid(i,1,1))
If b=255 Then sign=-1;i=Right(i,Len(i)-1);b=Asc(Mid(i,1,1))
If b=<250 Then Return b*sign
If b=251 Then Return (251+Asc(Mid(i,2,1)))*sign
If b=252 Then Return ( (Asc(Mid(i,2,1)) Shl 8) | Asc(Mid(i,3,1)) )*sign
If b=253 Then Return ( (Asc(Mid(i,2,1)) Shl 16) | (Asc(Mid(i,3,1)) Shl 8) | Asc(Mid(i,4,1)) )*sign
If b=254 Then Return ( (Asc(Mid(i,2,1)) Shl 24) | (Asc(Mid(i,3,1)) Shl 16) | (Asc(Mid(i,4,1)) Shl 8) | Asc(Mid(i,5,1)) )*sign
End Function