Source file src/net/http/internal/http3/varint.go

     1  // Copyright 2026 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // The functions in this file are copied from golang.org/x/net/internal/quic/quicwire.
     6  package http3
     7  
     8  // consumeVarint parses a variable-length integer, reporting its length.
     9  // It returns a negative length upon an error.
    10  //
    11  // https://www.rfc-editor.org/rfc/rfc9000.html#section-16
    12  func consumeVarint(b []byte) (v uint64, n int) {
    13  	if len(b) < 1 {
    14  		return 0, -1
    15  	}
    16  	b0 := b[0] & 0x3f
    17  	switch b[0] >> 6 {
    18  	case 0:
    19  		return uint64(b0), 1
    20  	case 1:
    21  		if len(b) < 2 {
    22  			return 0, -1
    23  		}
    24  		return uint64(b0)<<8 | uint64(b[1]), 2
    25  	case 2:
    26  		if len(b) < 4 {
    27  			return 0, -1
    28  		}
    29  		return uint64(b0)<<24 | uint64(b[1])<<16 | uint64(b[2])<<8 | uint64(b[3]), 4
    30  	case 3:
    31  		if len(b) < 8 {
    32  			return 0, -1
    33  		}
    34  		return uint64(b0)<<56 | uint64(b[1])<<48 | uint64(b[2])<<40 | uint64(b[3])<<32 | uint64(b[4])<<24 | uint64(b[5])<<16 | uint64(b[6])<<8 | uint64(b[7]), 8
    35  	}
    36  	return 0, -1
    37  }
    38  
    39  // consumeVarintInt64 parses a variable-length integer as an int64.
    40  func consumeVarintInt64(b []byte) (v int64, n int) {
    41  	u, n := consumeVarint(b)
    42  	// QUIC varints are 62-bits large, so this conversion can never overflow.
    43  	return int64(u), n
    44  }
    45  
    46  // appendVarint appends a variable-length integer to b.
    47  //
    48  // https://www.rfc-editor.org/rfc/rfc9000.html#section-16
    49  func appendVarint(b []byte, v uint64) []byte {
    50  	switch {
    51  	case v <= 63:
    52  		return append(b, byte(v))
    53  	case v <= 16383:
    54  		return append(b, (1<<6)|byte(v>>8), byte(v))
    55  	case v <= 1073741823:
    56  		return append(b, (2<<6)|byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
    57  	case v <= 4611686018427387903:
    58  		return append(b, (3<<6)|byte(v>>56), byte(v>>48), byte(v>>40), byte(v>>32), byte(v>>24), byte(v>>16), byte(v>>8), byte(v))
    59  	default:
    60  		panic("varint too large")
    61  	}
    62  }
    63  
    64  // sizeVarint returns the size of the variable-length integer encoding of f.
    65  func sizeVarint(v uint64) int {
    66  	switch {
    67  	case v <= 63:
    68  		return 1
    69  	case v <= 16383:
    70  		return 2
    71  	case v <= 1073741823:
    72  		return 4
    73  	case v <= 4611686018427387903:
    74  		return 8
    75  	default:
    76  		panic("varint too large")
    77  	}
    78  }
    79  

View as plain text