COMMUNITY

Implementing a Leb128 encoder/decoder algorithm in Haxe

I am trying to implement a cross platform Leb128 binary encoder/decoder in Haxe, my current reference is in Golang:

// readVarUint reads an unsigned integer of size n defined in https://webassembly.github.io/spec/core/binary/values.html#binary-int
// readVarUint panics if n>64.
func readVarUint(r io.Reader, n uint) (uint64, error) {
    if n > 64 {
        panic(errors.New("leb128: n must <= 64"))
    }
    p := make([]byte, 1)
    var res uint64
    var shift uint
    for {
        _, err := io.ReadFull(r, p)
        if err != nil {
            return 0, err
        }
        b := uint64(p[0])
        switch {
        case b < 1<<7 && b < 1<<n:
            res += (1 << shift) * b
            return res, nil
        case b >= 1<<7 && n > 7:
            res += (1 << shift) * (b - 1<<7)
            shift += 7
            n -= 7
        default:
            return 0, errors.New("leb128: invalid uint")
        }
    }
}

// readVarint reads a signed integer of size n, defined in https://webassembly.github.io/spec/core/binary/values.html#binary-int
// readVarint panics if n>64.
func readVarint(r io.Reader, n uint) (int64, error) {
	if n > 64 {
		panic(errors.New("leb128: n must <= 64"))
	}
	p := make([]byte, 1)
	var res int64
	var shift uint
	for {
		_, err := io.ReadFull(r, p)
		if err != nil {
			return 0, err
		}
		b := int64(p[0])
		switch {
		case b < 1<<6 && uint64(b) < uint64(1<<(n-1)):
			res += (1 << shift) * b
			return res, nil
		case b >= 1<<6 && b < 1<<7 && uint64(b)+1<<(n-1) >= 1<<7:
			res += (1 << shift) * (b - 1<<7)
			return res, nil
		case b >= 1<<7 && n > 7:
			res += (1 << shift) * (b - 1<<7)
			shift += 7
			n -= 7
		default:
			return 0, errors.New("leb128: invalid int")
		}
	}
}

// AppendUleb128 appends v to b using unsigned LEB128 encoding.
func AppendUleb128(b []byte, v uint64) []byte {
	for {
		c := uint8(v & 0x7f)
		v >>= 7
		if v != 0 {
			c |= 0x80
		}
		b = append(b, c)
		if c&0x80 == 0 {
			break
		}
	}
	return b
}

// AppendSleb128 appends v to b using signed LEB128 encoding.
func AppendSleb128(b []byte, v int64) []byte {
	for {
		c := uint8(v & 0x7f)
		s := uint8(v & 0x40)
		v >>= 7
		if (v != -1 || s == 0) && (v != 0 || s != 0) {
			c |= 0x80
		}
		b = append(b, c)
		if c&0x80 == 0 {
			break
		}
	}
	return b
}

I would appreciate your suggestions.