github.com/sagernet/quic-go@v0.43.1-beta.1/internal/utils/byteorder_big_endian.go (about)

     1  package utils
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/binary"
     6  	"io"
     7  )
     8  
     9  // BigEndian is the big-endian implementation of ByteOrder.
    10  var BigEndian ByteOrder = bigEndian{}
    11  
    12  type bigEndian struct{}
    13  
    14  var _ ByteOrder = &bigEndian{}
    15  
    16  // ReadUintN reads N bytes
    17  func (bigEndian) ReadUintN(b io.ByteReader, length uint8) (uint64, error) {
    18  	var res uint64
    19  	for i := uint8(0); i < length; i++ {
    20  		bt, err := b.ReadByte()
    21  		if err != nil {
    22  			return 0, err
    23  		}
    24  		res ^= uint64(bt) << ((length - 1 - i) * 8)
    25  	}
    26  	return res, nil
    27  }
    28  
    29  // ReadUint32 reads a uint32
    30  func (bigEndian) ReadUint32(b io.ByteReader) (uint32, error) {
    31  	var b1, b2, b3, b4 uint8
    32  	var err error
    33  	if b4, err = b.ReadByte(); err != nil {
    34  		return 0, err
    35  	}
    36  	if b3, err = b.ReadByte(); err != nil {
    37  		return 0, err
    38  	}
    39  	if b2, err = b.ReadByte(); err != nil {
    40  		return 0, err
    41  	}
    42  	if b1, err = b.ReadByte(); err != nil {
    43  		return 0, err
    44  	}
    45  	return uint32(b1) + uint32(b2)<<8 + uint32(b3)<<16 + uint32(b4)<<24, nil
    46  }
    47  
    48  // ReadUint24 reads a uint24
    49  func (bigEndian) ReadUint24(b io.ByteReader) (uint32, error) {
    50  	var b1, b2, b3 uint8
    51  	var err error
    52  	if b3, err = b.ReadByte(); err != nil {
    53  		return 0, err
    54  	}
    55  	if b2, err = b.ReadByte(); err != nil {
    56  		return 0, err
    57  	}
    58  	if b1, err = b.ReadByte(); err != nil {
    59  		return 0, err
    60  	}
    61  	return uint32(b1) + uint32(b2)<<8 + uint32(b3)<<16, nil
    62  }
    63  
    64  // ReadUint16 reads a uint16
    65  func (bigEndian) ReadUint16(b io.ByteReader) (uint16, error) {
    66  	var b1, b2 uint8
    67  	var err error
    68  	if b2, err = b.ReadByte(); err != nil {
    69  		return 0, err
    70  	}
    71  	if b1, err = b.ReadByte(); err != nil {
    72  		return 0, err
    73  	}
    74  	return uint16(b1) + uint16(b2)<<8, nil
    75  }
    76  
    77  func (bigEndian) Uint32(b []byte) uint32 {
    78  	return binary.BigEndian.Uint32(b)
    79  }
    80  
    81  func (bigEndian) Uint24(b []byte) uint32 {
    82  	_ = b[2] // bounds check hint to compiler; see golang.org/issue/14808
    83  	return uint32(b[2]) | uint32(b[1])<<8 | uint32(b[0])<<16
    84  }
    85  
    86  func (bigEndian) Uint16(b []byte) uint16 {
    87  	return binary.BigEndian.Uint16(b)
    88  }
    89  
    90  // WriteUint32 writes a uint32
    91  func (bigEndian) WriteUint32(b *bytes.Buffer, i uint32) {
    92  	b.Write([]byte{uint8(i >> 24), uint8(i >> 16), uint8(i >> 8), uint8(i)})
    93  }
    94  
    95  // WriteUint24 writes a uint24
    96  func (bigEndian) WriteUint24(b *bytes.Buffer, i uint32) {
    97  	b.Write([]byte{uint8(i >> 16), uint8(i >> 8), uint8(i)})
    98  }
    99  
   100  // WriteUint16 writes a uint16
   101  func (bigEndian) WriteUint16(b *bytes.Buffer, i uint16) {
   102  	b.Write([]byte{uint8(i >> 8), uint8(i)})
   103  }