github.com/sagernet/sing@v0.4.0-beta.19.0.20240518125136-f67a0988a636/common/rw/varint.go (about)

     1  package rw
     2  
     3  import (
     4  	"encoding/binary"
     5  	"io"
     6  
     7  	"github.com/sagernet/sing/common"
     8  )
     9  
    10  type stubByteReader struct {
    11  	io.Reader
    12  }
    13  
    14  func (r stubByteReader) ReadByte() (byte, error) {
    15  	return ReadByte(r.Reader)
    16  }
    17  
    18  func ToByteReader(reader io.Reader) io.ByteReader {
    19  	if byteReader, ok := reader.(io.ByteReader); ok {
    20  		return byteReader
    21  	}
    22  	return &stubByteReader{reader}
    23  }
    24  
    25  func ReadUVariant(reader io.Reader) (uint64, error) {
    26  	return binary.ReadUvarint(ToByteReader(reader))
    27  }
    28  
    29  func UVariantLen(x uint64) int {
    30  	switch {
    31  	case x < 1<<(7*1):
    32  		return 1
    33  	case x < 1<<(7*2):
    34  		return 2
    35  	case x < 1<<(7*3):
    36  		return 3
    37  	case x < 1<<(7*4):
    38  		return 4
    39  	case x < 1<<(7*5):
    40  		return 5
    41  	case x < 1<<(7*6):
    42  		return 6
    43  	case x < 1<<(7*7):
    44  		return 7
    45  	case x < 1<<(7*8):
    46  		return 8
    47  	case x < 1<<(7*9):
    48  		return 9
    49  	default:
    50  		return 10
    51  	}
    52  }
    53  
    54  func WriteUVariant(writer io.Writer, value uint64) error {
    55  	var b [8]byte
    56  	return common.Error(writer.Write(b[:binary.PutUvarint(b[:], value)]))
    57  }
    58  
    59  func WriteVString(writer io.Writer, value string) error {
    60  	err := WriteUVariant(writer, uint64(len(value)))
    61  	if err != nil {
    62  		return err
    63  	}
    64  	return WriteString(writer, value)
    65  }
    66  
    67  func ReadVString(reader io.Reader) (string, error) {
    68  	length, err := binary.ReadUvarint(ToByteReader(reader))
    69  	if err != nil {
    70  		return "", err
    71  	}
    72  	value, err := ReadBytes(reader, int(length))
    73  	if err != nil {
    74  		return "", err
    75  	}
    76  	return string(value), nil
    77  }