-
Notifications
You must be signed in to change notification settings - Fork 362
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: encoding/binary (for encoding/base64) (#816)
- Loading branch information
Showing
3 changed files
with
393 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
// Copyright 2009 The Go Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
// Package binary implements simple translation between numbers and byte | ||
// sequences and encoding and decoding of varints. | ||
// | ||
// Numbers are translated by reading and writing fixed-size values. | ||
// A fixed-size value is either a fixed-size arithmetic | ||
// type (bool, int8, uint8, int16, float32, complex64, ...) | ||
// or an array or struct containing only fixed-size values. | ||
// | ||
// The varint functions encode and decode single integer values using | ||
// a variable-length encoding; smaller values require fewer bytes. | ||
// For a specification, see | ||
// https://developers.google.com/protocol-buffers/docs/encoding. | ||
// | ||
// This package favors simplicity over efficiency. Clients that require | ||
// high-performance serialization, especially for large data structures, | ||
// should look at more advanced solutions such as the encoding/gob | ||
// package or protocol buffers. | ||
package binary | ||
|
||
// A ByteOrder specifies how to convert byte slices into | ||
// 16-, 32-, or 64-bit unsigned integers. | ||
type ByteOrder interface { | ||
Uint16([]byte) uint16 | ||
Uint32([]byte) uint32 | ||
Uint64([]byte) uint64 | ||
PutUint16([]byte, uint16) | ||
PutUint32([]byte, uint32) | ||
PutUint64([]byte, uint64) | ||
String() string | ||
} | ||
|
||
// AppendByteOrder specifies how to append 16-, 32-, or 64-bit unsigned integers | ||
// into a byte slice. | ||
type AppendByteOrder interface { | ||
AppendUint16([]byte, uint16) []byte | ||
AppendUint32([]byte, uint32) []byte | ||
AppendUint64([]byte, uint64) []byte | ||
String() string | ||
} | ||
|
||
// LittleEndian is the little-endian implementation of ByteOrder and AppendByteOrder. | ||
var LittleEndian littleEndian | ||
|
||
// BigEndian is the big-endian implementation of ByteOrder and AppendByteOrder. | ||
var BigEndian bigEndian | ||
|
||
type littleEndian struct{} | ||
|
||
func (littleEndian) Uint16(b []byte) uint16 { | ||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 | ||
return uint16(b[0]) | uint16(b[1])<<8 | ||
} | ||
|
||
func (littleEndian) PutUint16(b []byte, v uint16) { | ||
_ = b[1] // early bounds check to guarantee safety of writes below | ||
b[0] = byte(v) | ||
b[1] = byte(v >> 8) | ||
} | ||
|
||
func (littleEndian) AppendUint16(b []byte, v uint16) []byte { | ||
return append(b, | ||
byte(v), | ||
byte(v>>8), | ||
) | ||
} | ||
|
||
func (littleEndian) Uint32(b []byte) uint32 { | ||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 | ||
return uint32(b[0]) | uint32(b[1])<<8 | uint32(b[2])<<16 | uint32(b[3])<<24 | ||
} | ||
|
||
func (littleEndian) PutUint32(b []byte, v uint32) { | ||
_ = b[3] // early bounds check to guarantee safety of writes below | ||
b[0] = byte(v) | ||
b[1] = byte(v >> 8) | ||
b[2] = byte(v >> 16) | ||
b[3] = byte(v >> 24) | ||
} | ||
|
||
func (littleEndian) AppendUint32(b []byte, v uint32) []byte { | ||
return append(b, | ||
byte(v), | ||
byte(v>>8), | ||
byte(v>>16), | ||
byte(v>>24), | ||
) | ||
} | ||
|
||
func (littleEndian) Uint64(b []byte) uint64 { | ||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 | ||
return uint64(b[0]) | uint64(b[1])<<8 | uint64(b[2])<<16 | uint64(b[3])<<24 | | ||
uint64(b[4])<<32 | uint64(b[5])<<40 | uint64(b[6])<<48 | uint64(b[7])<<56 | ||
} | ||
|
||
func (littleEndian) PutUint64(b []byte, v uint64) { | ||
_ = b[7] // early bounds check to guarantee safety of writes below | ||
b[0] = byte(v) | ||
b[1] = byte(v >> 8) | ||
b[2] = byte(v >> 16) | ||
b[3] = byte(v >> 24) | ||
b[4] = byte(v >> 32) | ||
b[5] = byte(v >> 40) | ||
b[6] = byte(v >> 48) | ||
b[7] = byte(v >> 56) | ||
} | ||
|
||
func (littleEndian) AppendUint64(b []byte, v uint64) []byte { | ||
return append(b, | ||
byte(v), | ||
byte(v>>8), | ||
byte(v>>16), | ||
byte(v>>24), | ||
byte(v>>32), | ||
byte(v>>40), | ||
byte(v>>48), | ||
byte(v>>56), | ||
) | ||
} | ||
|
||
func (littleEndian) String() string { return "LittleEndian" } | ||
|
||
func (littleEndian) GoString() string { return "binary.LittleEndian" } | ||
|
||
type bigEndian struct{} | ||
|
||
func (bigEndian) Uint16(b []byte) uint16 { | ||
_ = b[1] // bounds check hint to compiler; see golang.org/issue/14808 | ||
return uint16(b[1]) | uint16(b[0])<<8 | ||
} | ||
|
||
func (bigEndian) PutUint16(b []byte, v uint16) { | ||
_ = b[1] // early bounds check to guarantee safety of writes below | ||
b[0] = byte(v >> 8) | ||
b[1] = byte(v) | ||
} | ||
|
||
func (bigEndian) AppendUint16(b []byte, v uint16) []byte { | ||
return append(b, | ||
byte(v>>8), | ||
byte(v), | ||
) | ||
} | ||
|
||
func (bigEndian) Uint32(b []byte) uint32 { | ||
_ = b[3] // bounds check hint to compiler; see golang.org/issue/14808 | ||
return uint32(b[3]) | uint32(b[2])<<8 | uint32(b[1])<<16 | uint32(b[0])<<24 | ||
} | ||
|
||
func (bigEndian) PutUint32(b []byte, v uint32) { | ||
_ = b[3] // early bounds check to guarantee safety of writes below | ||
b[0] = byte(v >> 24) | ||
b[1] = byte(v >> 16) | ||
b[2] = byte(v >> 8) | ||
b[3] = byte(v) | ||
} | ||
|
||
func (bigEndian) AppendUint32(b []byte, v uint32) []byte { | ||
return append(b, | ||
byte(v>>24), | ||
byte(v>>16), | ||
byte(v>>8), | ||
byte(v), | ||
) | ||
} | ||
|
||
func (bigEndian) Uint64(b []byte) uint64 { | ||
_ = b[7] // bounds check hint to compiler; see golang.org/issue/14808 | ||
return uint64(b[7]) | uint64(b[6])<<8 | uint64(b[5])<<16 | uint64(b[4])<<24 | | ||
uint64(b[3])<<32 | uint64(b[2])<<40 | uint64(b[1])<<48 | uint64(b[0])<<56 | ||
} | ||
|
||
func (bigEndian) PutUint64(b []byte, v uint64) { | ||
_ = b[7] // early bounds check to guarantee safety of writes below | ||
b[0] = byte(v >> 56) | ||
b[1] = byte(v >> 48) | ||
b[2] = byte(v >> 40) | ||
b[3] = byte(v >> 32) | ||
b[4] = byte(v >> 24) | ||
b[5] = byte(v >> 16) | ||
b[6] = byte(v >> 8) | ||
b[7] = byte(v) | ||
} | ||
|
||
func (bigEndian) AppendUint64(b []byte, v uint64) []byte { | ||
return append(b, | ||
byte(v>>56), | ||
byte(v>>48), | ||
byte(v>>40), | ||
byte(v>>32), | ||
byte(v>>24), | ||
byte(v>>16), | ||
byte(v>>8), | ||
byte(v), | ||
) | ||
} | ||
|
||
func (bigEndian) String() string { return "BigEndian" } | ||
|
||
func (bigEndian) GoString() string { return "binary.BigEndian" } |
Oops, something went wrong.