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

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

Issue 2538553003: Add base128 encoding library. (Closed)
Patch Set: 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') | common/data/base128/base128_test.go » ('J')
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 cap(dst) < ret {
dnj 2016/11/29 02:03:13 I think capacity is misleading, and can lead to in
iannucci 2016/11/29 02:14:55 Done.
32 panic("dst has insufficient capacity")
33 }
34 dst = dst[:0]
35 whichByte := 0
dnj 2016/11/29 02:03:13 nit: Just make this a uint, and cycle 1..7 instead
iannucci 2016/11/29 02:14:55 Done.
36 bufByte := byte(0)
37 for _, v := range src {
38 dst = append(dst, bufByte|(v>>uint(whichByte+1)))
39 bufByte = (v&(1<<uint(whichByte+1)) - 1) << uint(6-whichByte)
40 if whichByte == 6 {
41 dst = append(dst, bufByte)
42 bufByte = 0
dnj 2016/11/29 02:03:13 Instead of using modulus below, just reset whichby
iannucci 2016/11/29 02:14:55 Done.
43 }
44 whichByte = (whichByte + 1) % 7
dnj 2016/11/29 02:03:13 whichByte += 1
iannucci 2016/11/29 02:14:55 Done.
45 }
46 dst = append(dst, bufByte)
47 return ret
48 }
49
50 // Decode decodes src into DecodedLen(len(src)) bytes, returning the actual
51 // number of bytes written to dst.
52 //
53 // If Decode encounters invalid input, it returns an error describing the
54 // failure.
55 func Decode(dst, src []byte) (int, error) {
56 dLen := DecodedLen(len(src))
57 if EncodedLen(dLen) != len(src) {
58 return 0, ErrLength
59 }
60 if cap(dst) < dLen {
dnj 2016/11/29 02:03:13 Same RE cap, uint comments, etc.
iannucci 2016/11/29 02:14:55 Done.
61 panic("dst has insufficient capacity")
62 }
63 dst = dst[:0]
64 whichByte := 0
65 bufByte := byte(0)
66 for _, v := range src {
67 if (v & 0x80) != 0 {
68 return len(dst), ErrBit
69 }
70 if whichByte > 0 {
71 dst = append(dst, bufByte|(v>>uint(7-whichByte)))
72 }
73 bufByte = v << uint(whichByte+1)
74 whichByte = (whichByte + 1) % 8
75 }
76 return len(dst), nil
77 }
78
79 // DecodeString returns the bytes represented by the base128 string s.
80 func DecodeString(s string) ([]byte, error) {
81 src := []byte(s)
82 dst := make([]byte, DecodedLen(len(src)))
dnj 2016/11/29 02:03:13 Doing "DecodedLen" calculation twice here. Fall th
iannucci 2016/11/29 02:14:55 meh
83 _, err := Decode(dst, src)
dnj 2016/11/29 02:03:13 nit: if _, err := ...; err != nil {}
iannucci 2016/11/29 02:14:55 Done.
84 if err != nil {
85 return nil, err
86 }
87 return dst, nil
88 }
89
90 // DecodedLen returns the number of bytes `encLen` encoded bytes decodes to.
91 func DecodedLen(encLen int) int {
92 ret := (encLen / 8) * 7
dnj 2016/11/29 02:03:13 Consider: func DecodedLen(v int) int { return (v
iannucci 2016/11/29 02:14:55 Done.
93 if v := encLen % 8; v > 0 {
94 ret += v - 1
95 }
96 return ret
97 }
98
99 // EncodedLen returns the number of bytes that `dataLen` bytes will encode to.
100 func EncodedLen(dataLen int) int {
101 pre := ((dataLen * 8) - 1)
dnj 2016/11/29 02:03:13 Consider: func EncodedLen(v int) int { return (((
iannucci 2016/11/29 02:14:55 Done.
102 if pre < 0 {
103 return 0
104 }
105 return (pre / 7) + 1
106 }
107
108 // EncodeToString returns the base128 encoding of src.
109 func EncodeToString(src []byte) string {
110 dst := make([]byte, EncodedLen(len(src)))
dnj 2016/11/29 02:03:13 nit: you're calculating EncodedLen twice in Encode
iannucci 2016/11/29 02:14:55 meh
111 Encode(dst, src)
112 return string(dst)
113 }
OLDNEW
« no previous file with comments | « no previous file | common/data/base128/base128_test.go » ('j') | common/data/base128/base128_test.go » ('J')

Powered by Google App Engine
This is Rietveld 408576698