1

I'm trying to implement LEB128 to write a custom Minecraft Server implemention. I'm doing so by following Wikipedia article about LEB128 and port example Javascript code given to C. https://en.wikipedia.org/wiki/LEB128

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
int leb128(const char* in) {
    int result = 0;
    int shift_counter = 0;
    size_t s = strlen(in);
    int data = atoi(in);
    for(unsigned char i = 0; i < s; i++) {
        const char byte = ((unsigned char*)&data)[i];
        result |= (byte & 0x7f) << i * 7;
        shift_counter += 7;
        if(!(byte & 0x80))  break;
        if((shift_counter < 32 && (byte & 0x40)) != 0) return result |= (~0 << shift_counter);
        
    }
    return result;

}

/* this actually prints bytes makes the int but lazily named it because I renamed every function i took from my og project to avoid revealing the name */
void printInt(int a) {
    int* e = &a;
    puts("\n");
    for(unsigned i = 0; i < sizeof(int); i++) {
        printf(" %d ", ((unsigned char*)e)[i]);
    }

}

int main(void) {
   printInt(leb128("-1"));
   printInt(leb128("255"));
   printInt(leb128("25565"));

   return 0;
}

problem is that I do not receive data in given example table located at https://wiki.vg/Protocol

screenshot from wiki.vg

Input Expected Output
-1 255 255 255 15 255 255 255 255
255 255 1 255 255 255 255
25565 221 199 1 221 255 255 255

What could be I'm doing wrong?

  • 1
    The linked wiki page says: *"Starting with an N-bit two's complement representation, where N is a multiple of 7, the number is broken into groups as for the unsigned encoding"*, but the posted code passes a *string* with a decimal representation of a number and converts it into an `int` "storing" the bytes. – Bob__ Jan 24 '23 at 09:15
  • im trying to port this: https://en.wikipedia.org/wiki/LEB128 since wiki.vg says that LEB128 and minecraft's format is exactly same except Minecraft has a maximum 5 byte limit while LEB128 is 10 so there isn't too much difference. I tried to code it myself but mine had weird bugs so I tried porting existing code from Wikipedia, sadly it was written in js so I tried to port it into C. – user21053170 Jan 24 '23 at 09:20
  • project is sake of learning, I'm spending time to try to figure out how it works but first I would need to build it then study it, it doesn't feel same when you read someone elses code. – user21053170 Jan 24 '23 at 09:55
  • I'm going to update the code in a few minutes (remove project name from functions and check for bugs), i now use ints still getting invalid value – user21053170 Jan 24 '23 at 10:12
  • The number conversion techniques you are using are problematic. for example using `size_t s = strlen(in);` to get string length of `"-1"` means that you will only convert two iterations , ( `for(unsigned char i = 0; i < s; i++)` ) of a value stored in memory with at least 32 bits. It may help to review a method that illustrates [how to convert a `byte` to its binary representation](https://stackoverflow.com/a/18904441/645128). You can then pad and split the resultant string, per leb128, and use eg `strtol()` for conversions beyond that. (look for `const char *byte_to_binary64(__int64 x)` – ryyker Jan 24 '23 at 15:57

0 Answers0