package base64vlq

import 

const encodeStd = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"

const (
	vlqBaseShift       = 5
	vlqBase            = 1 << vlqBaseShift
	vlqBaseMask        = vlqBase - 1
	vlqSignBit         = 1
	vlqContinuationBit = vlqBase
)

var decodeMap [256]byte

func init() {
	for  := 0;  < len(encodeStd); ++ {
		decodeMap[encodeStd[]] = byte()
	}
}

func toVLQSigned( int32) int32 {
	if  < 0 {
		return -<<1 + 1
	}
	return  << 1
}

func fromVLQSigned( int32) int32 {
	 := &vlqSignBit != 0
	 >>= 1
	if  {
		return -
	}
	return 
}

type Encoder struct {
	w io.ByteWriter
}

func ( io.ByteWriter) *Encoder {
	return &Encoder{
		w: ,
	}
}

func ( Encoder) ( int32) error {
	 = toVLQSigned()
	for  := int32(vlqContinuationBit); &vlqContinuationBit != 0; {
		 =  & vlqBaseMask
		 >>= vlqBaseShift
		if  > 0 {
			 |= vlqContinuationBit
		}

		 := .w.WriteByte(encodeStd[])
		if  != nil {
			return 
		}
	}
	return nil
}

type Decoder struct {
	r io.ByteReader
}

func ( io.ByteReader) Decoder {
	return Decoder{
		r: ,
	}
}

func ( Decoder) () ( int32,  error) {
	 := uint(0)
	for  := true; ; {
		,  := .r.ReadByte()
		if  != nil {
			return 0, 
		}

		 = decodeMap[]
		 = &vlqContinuationBit != 0
		 += int32(&vlqBaseMask) << 
		 += vlqBaseShift
	}
	return fromVLQSigned(), nil
}