Skip to content

Instantly share code, notes, and snippets.

@Vincenz099
Created March 17, 2019 12:19
Show Gist options
  • Select an option

  • Save Vincenz099/7526e187defee21cc1965805532bb9de to your computer and use it in GitHub Desktop.

Select an option

Save Vincenz099/7526e187defee21cc1965805532bb9de to your computer and use it in GitHub Desktop.
string compression
[MethodImpl(256)]
public BitBuffer AddString(string value) {
Debug.Assert(value != null, "String is null");
Debug.Assert(value.Length <= stringLengthMax, "String too long, raise the stringLengthMax value or split the string.");
int length = value.Length;
if (length > stringLengthMax)
length = stringLengthMax;
if (length * 17 + 10 > (totalNumBits - bitsWriten)) // possible overflow
{
if(Utils.GetStringBitSize(value, length) > (totalNumBits - bitsWriten))
throw new ArgumentOutOfRangeException("String would not fit in bitstream.");
}
uint codePage = 0; // Ascii
for (int i = 0; i < length; i++) {
var val = value[i];
if (val > 127) {
codePage = 1; // Latin1
if (val > 255) {
codePage = 2; // LatinExtended
if (val > 511) {
codePage = 3; // UTF-16
break;
}
}
}
}
Add(2, codePage);
Add(stringLengthBits, (uint)length);
if (codePage == 0)
for (int i = 0; i < length; i++){
Add(bitsASCII, value[i]);
}
else if (codePage == 1)
for (int i = 0; i < length; i++){
Add(bitsLATIN1, value[i]);
}
else if (codePage == 2)
for (int i = 0; i < length; i++) {
Add(bitsLATINEXT, value[i]);
}
else if (codePage == 3)
for (int i = 0; i < length; i++){
if (value[i] > 127){
Add(1, 1);
Add(bitsUTF16, value[i]);
}
else{
Add(1, 0);
Add(bitsASCII, value[i]);
}
}
return this;
}
private StringBuilder builder = new StringBuilder(stringLengthMax);
[MethodImpl(256)]
public string ReadString() {
builder.Length = 0;
uint codePage = Read(2);
uint length = Read(stringLengthBits);
if (codePage == 0)
for (int i = 0; i < length; i++) {
builder.Append((char)Read(bitsASCII));
}
else if (codePage == 1)
for (int i = 0; i < length; i++) {
builder.Append((char)Read(bitsLATIN1));
}
else if (codePage == 2)
for (int i = 0; i < length; i++) {
builder.Append((char)Read(bitsLATINEXT));
}
else if (codePage == 3)
for (int i = 0; i < length; i++) {
var needs16 = Read(1);
if (needs16 == 1)
builder.Append((char)Read(bitsUTF16));
else
builder.Append((char)Read(bitsASCII));
}
return builder.ToString();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment