| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2016 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. |
| 4 |
| 5 // Package base128 implements base128 encoding and decoding. |
| 6 // |
| 7 // Encoded results are UTF8-safe, and will retain the same memcmp sorting |
| 8 // properties of the input data. |
| 9 package base128 |
| 10 |
| 11 import "errors" |
| 12 |
| 13 var ( |
| 14 // ErrLength is returned from the Decode* methods if the input has an |
| 15 // impossible length. |
| 16 ErrLength = errors.New("base128: invalid length base128 string") |
| 17 |
| 18 // ErrBit is returned from the Decode* methods if the input has a byte w
ith |
| 19 // the high-bit set (e.g. 0x80). This will never be the case for strings |
| 20 // produced from the Encode* methods in this package. |
| 21 ErrBit = errors.New("base128: high bit set in base128 string") |
| 22 ) |
| 23 |
| 24 // Encode encodes src into EncodedLen(len(src)) bytes of dst. As a convenience, |
| 25 // it returns the number of bytes written to dst, but this value is always |
| 26 // EncodedLen(len(src)). |
| 27 // |
| 28 // Encode implements base128 encoding. |
| 29 func Encode(dst, src []byte) int { |
| 30 ret := EncodedLen(len(src)) |
| 31 if len(dst) < ret { |
| 32 panic("dst has insufficient length") |
| 33 } |
| 34 dst = dst[:0] |
| 35 whichByte := uint(1) |
| 36 bufByte := byte(0) |
| 37 for _, v := range src { |
| 38 dst = append(dst, bufByte|(v>>whichByte)) |
| 39 bufByte = (v&(1<<whichByte) - 1) << (7 - whichByte) |
| 40 if whichByte == 7 { |
| 41 dst = append(dst, bufByte) |
| 42 bufByte = 0 |
| 43 whichByte = 0 |
| 44 } |
| 45 whichByte++ |
| 46 } |
| 47 dst = append(dst, bufByte) |
| 48 return ret |
| 49 } |
| 50 |
| 51 // Decode decodes src into DecodedLen(len(src)) bytes, returning the actual |
| 52 // number of bytes written to dst. |
| 53 // |
| 54 // If Decode encounters invalid input, it returns an error describing the |
| 55 // failure. |
| 56 func Decode(dst, src []byte) (int, error) { |
| 57 dLen := DecodedLen(len(src)) |
| 58 if EncodedLen(dLen) != len(src) { |
| 59 return 0, ErrLength |
| 60 } |
| 61 if len(dst) < dLen { |
| 62 panic("dst has insufficient length") |
| 63 } |
| 64 dst = dst[:0] |
| 65 whichByte := uint(1) |
| 66 bufByte := byte(0) |
| 67 for _, v := range src { |
| 68 if (v & 0x80) != 0 { |
| 69 return len(dst), ErrBit |
| 70 } |
| 71 if whichByte > 1 { |
| 72 dst = append(dst, bufByte|(v>>(8-whichByte))) |
| 73 } |
| 74 bufByte = v << whichByte |
| 75 if whichByte == 8 { |
| 76 whichByte = 0 |
| 77 } |
| 78 whichByte++ |
| 79 } |
| 80 return len(dst), nil |
| 81 } |
| 82 |
| 83 // DecodeString returns the bytes represented by the base128 string s. |
| 84 func DecodeString(s string) ([]byte, error) { |
| 85 src := []byte(s) |
| 86 dst := make([]byte, DecodedLen(len(src))) |
| 87 if _, err := Decode(dst, src); err != nil { |
| 88 return nil, err |
| 89 } |
| 90 return dst, nil |
| 91 } |
| 92 |
| 93 // DecodedLen returns the number of bytes `encLen` encoded bytes decodes to. |
| 94 func DecodedLen(encLen int) int { |
| 95 return (encLen * 7 / 8) |
| 96 } |
| 97 |
| 98 // EncodedLen returns the number of bytes that `dataLen` bytes will encode to. |
| 99 func EncodedLen(dataLen int) int { |
| 100 return (((dataLen * 8) + 6) / 7) |
| 101 } |
| 102 |
| 103 // EncodeToString returns the base128 encoding of src. |
| 104 func EncodeToString(src []byte) string { |
| 105 dst := make([]byte, EncodedLen(len(src))) |
| 106 Encode(dst, src) |
| 107 return string(dst) |
| 108 } |
| OLD | NEW |