Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(964)

Side by Side Diff: common/data/base128/base128.go

Issue 2538553003: Add base128 encoding library. (Closed)
Patch Set: Fix nits Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | common/data/base128/base128_test.go » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(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 }
OLDNEW
« no previous file with comments | « no previous file | common/data/base128/base128_test.go » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698