github.com/daeuniverse/quic-go@v0.0.0-20240413031024-943f218e0810/quicvarint/varint_test.go (about)

     1  package quicvarint
     2  
     3  import (
     4  	"bytes"
     5  
     6  	. "github.com/onsi/ginkgo/v2"
     7  	. "github.com/onsi/gomega"
     8  )
     9  
    10  var _ = Describe("Varint encoding / decoding", func() {
    11  	Context("limits", func() {
    12  		Specify("Min == 0", func() {
    13  			Expect(Min).To(Equal(0))
    14  		})
    15  
    16  		Specify("Max == 2^62-1", func() {
    17  			Expect(uint64(Max)).To(Equal(uint64(1<<62 - 1)))
    18  		})
    19  	})
    20  
    21  	Context("decoding", func() {
    22  		It("reads a 1 byte number", func() {
    23  			b := bytes.NewReader([]byte{0b00011001})
    24  			val, err := Read(b)
    25  			Expect(err).ToNot(HaveOccurred())
    26  			Expect(val).To(Equal(uint64(25)))
    27  			Expect(b.Len()).To(BeZero())
    28  		})
    29  
    30  		It("reads a number that is encoded too long", func() {
    31  			b := bytes.NewReader([]byte{0b01000000, 0x25})
    32  			val, err := Read(b)
    33  			Expect(err).ToNot(HaveOccurred())
    34  			Expect(val).To(Equal(uint64(37)))
    35  			Expect(b.Len()).To(BeZero())
    36  		})
    37  
    38  		It("reads a 2 byte number", func() {
    39  			b := bytes.NewReader([]byte{0b01111011, 0xbd})
    40  			val, err := Read(b)
    41  			Expect(err).ToNot(HaveOccurred())
    42  			Expect(val).To(Equal(uint64(15293)))
    43  			Expect(b.Len()).To(BeZero())
    44  		})
    45  
    46  		It("reads a 4 byte number", func() {
    47  			b := bytes.NewReader([]byte{0b10011101, 0x7f, 0x3e, 0x7d})
    48  			val, err := Read(b)
    49  			Expect(err).ToNot(HaveOccurred())
    50  			Expect(val).To(Equal(uint64(494878333)))
    51  			Expect(b.Len()).To(BeZero())
    52  		})
    53  
    54  		It("reads an 8 byte number", func() {
    55  			b := bytes.NewReader([]byte{0b11000010, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c})
    56  			val, err := Read(b)
    57  			Expect(err).ToNot(HaveOccurred())
    58  			Expect(val).To(Equal(uint64(151288809941952652)))
    59  			Expect(b.Len()).To(BeZero())
    60  		})
    61  	})
    62  
    63  	Context("encoding", func() {
    64  		Context("with minimal length", func() {
    65  			It("writes a 1 byte number", func() {
    66  				Expect(Append(nil, 37)).To(Equal([]byte{0x25}))
    67  			})
    68  
    69  			It("writes the maximum 1 byte number in 1 byte", func() {
    70  				Expect(Append(nil, maxVarInt1)).To(Equal([]byte{0b00111111}))
    71  			})
    72  
    73  			It("writes the minimum 2 byte number in 2 bytes", func() {
    74  				Expect(Append(nil, maxVarInt1+1)).To(Equal([]byte{0x40, maxVarInt1 + 1}))
    75  			})
    76  
    77  			It("writes a 2 byte number", func() {
    78  				Expect(Append(nil, 15293)).To(Equal([]byte{0b01000000 ^ 0x3b, 0xbd}))
    79  			})
    80  
    81  			It("writes the maximum 2 byte number in 2 bytes", func() {
    82  				Expect(Append(nil, maxVarInt2)).To(Equal([]byte{0b01111111, 0xff}))
    83  			})
    84  
    85  			It("writes the minimum 4 byte number in 4 bytes", func() {
    86  				b := Append(nil, maxVarInt2+1)
    87  				Expect(b).To(HaveLen(4))
    88  				num, err := Read(bytes.NewReader(b))
    89  				Expect(err).ToNot(HaveOccurred())
    90  				Expect(num).To(Equal(uint64(maxVarInt2 + 1)))
    91  			})
    92  
    93  			It("writes a 4 byte number", func() {
    94  				Expect(Append(nil, 494878333)).To(Equal([]byte{0b10000000 ^ 0x1d, 0x7f, 0x3e, 0x7d}))
    95  			})
    96  
    97  			It("writes the maximum 4 byte number in 4 bytes", func() {
    98  				Expect(Append(nil, maxVarInt4)).To(Equal([]byte{0b10111111, 0xff, 0xff, 0xff}))
    99  			})
   100  
   101  			It("writes the minimum 8 byte number in 8 bytes", func() {
   102  				b := Append(nil, maxVarInt4+1)
   103  				Expect(b).To(HaveLen(8))
   104  				num, err := Read(bytes.NewReader(b))
   105  				Expect(err).ToNot(HaveOccurred())
   106  				Expect(num).To(Equal(uint64(maxVarInt4 + 1)))
   107  			})
   108  
   109  			It("writes an 8 byte number", func() {
   110  				Expect(Append(nil, 151288809941952652)).To(Equal([]byte{0xc2, 0x19, 0x7c, 0x5e, 0xff, 0x14, 0xe8, 0x8c}))
   111  			})
   112  
   113  			It("writes the maximum 8 byte number in 8 bytes", func() {
   114  				Expect(Append(nil, maxVarInt8)).To(Equal([]byte{0xff /* 11111111 */, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}))
   115  			})
   116  
   117  			It("panics when given a too large number (> 62 bit)", func() {
   118  				Expect(func() { Append(nil, maxVarInt8+1) }).Should(Panic())
   119  			})
   120  		})
   121  
   122  		Context("with fixed length", func() {
   123  			It("panics when given an invalid length", func() {
   124  				Expect(func() { AppendWithLen(nil, 25, 3) }).Should(Panic())
   125  			})
   126  
   127  			It("panics when given a too short length", func() {
   128  				Expect(func() { AppendWithLen(nil, maxVarInt1+1, 1) }).Should(Panic())
   129  				Expect(func() { AppendWithLen(nil, maxVarInt2+1, 2) }).Should(Panic())
   130  				Expect(func() { AppendWithLen(nil, maxVarInt4+1, 4) }).Should(Panic())
   131  			})
   132  
   133  			It("writes a 1-byte number in minimal encoding", func() {
   134  				Expect(AppendWithLen(nil, 37, 1)).To(Equal([]byte{0x25}))
   135  			})
   136  
   137  			It("writes a 1-byte number in 2 bytes", func() {
   138  				b := AppendWithLen(nil, 37, 2)
   139  				Expect(b).To(Equal([]byte{0b01000000, 0x25}))
   140  				Expect(Read(bytes.NewReader(b))).To(BeEquivalentTo(37))
   141  			})
   142  
   143  			It("writes a 1-byte number in 4 bytes", func() {
   144  				b := AppendWithLen(nil, 37, 4)
   145  				Expect(b).To(Equal([]byte{0b10000000, 0, 0, 0x25}))
   146  				Expect(Read(bytes.NewReader(b))).To(BeEquivalentTo(37))
   147  			})
   148  
   149  			It("writes a 1-byte number in 8 bytes", func() {
   150  				b := AppendWithLen(nil, 37, 8)
   151  				Expect(b).To(Equal([]byte{0b11000000, 0, 0, 0, 0, 0, 0, 0x25}))
   152  				Expect(Read(bytes.NewReader(b))).To(BeEquivalentTo(37))
   153  			})
   154  
   155  			It("writes a 2-byte number in 4 bytes", func() {
   156  				b := AppendWithLen(nil, 15293, 4)
   157  				Expect(b).To(Equal([]byte{0b10000000, 0, 0x3b, 0xbd}))
   158  				Expect(Read(bytes.NewReader(b))).To(BeEquivalentTo(15293))
   159  			})
   160  
   161  			It("write a 4-byte number in 8 bytes", func() {
   162  				b := AppendWithLen(nil, 494878333, 8)
   163  				Expect(b).To(Equal([]byte{0b11000000, 0, 0, 0, 0x1d, 0x7f, 0x3e, 0x7d}))
   164  				Expect(Read(bytes.NewReader(b))).To(BeEquivalentTo(494878333))
   165  			})
   166  		})
   167  	})
   168  
   169  	Context("determining the length needed for encoding", func() {
   170  		It("for numbers that need 1 byte", func() {
   171  			Expect(Len(0)).To(BeEquivalentTo(1))
   172  			Expect(Len(maxVarInt1)).To(BeEquivalentTo(1))
   173  		})
   174  
   175  		It("for numbers that need 2 bytes", func() {
   176  			Expect(Len(maxVarInt1 + 1)).To(BeEquivalentTo(2))
   177  			Expect(Len(maxVarInt2)).To(BeEquivalentTo(2))
   178  		})
   179  
   180  		It("for numbers that need 4 bytes", func() {
   181  			Expect(Len(maxVarInt2 + 1)).To(BeEquivalentTo(4))
   182  			Expect(Len(maxVarInt4)).To(BeEquivalentTo(4))
   183  		})
   184  
   185  		It("for numbers that need 8 bytes", func() {
   186  			Expect(Len(maxVarInt4 + 1)).To(BeEquivalentTo(8))
   187  			Expect(Len(maxVarInt8)).To(BeEquivalentTo(8))
   188  		})
   189  
   190  		It("panics when given a too large number (> 62 bit)", func() {
   191  			Expect(func() { Len(maxVarInt8 + 1) }).Should(Panic())
   192  		})
   193  	})
   194  })