diff options
| author | Shulhan <ms@kilabit.info> | 2018-09-03 22:27:44 +0700 |
|---|---|---|
| committer | Shulhan <ms@kilabit.info> | 2018-09-03 22:55:06 +0700 |
| commit | d3e6c2e902eb3a00c2dfdcde09bf35282ea63396 (patch) | |
| tree | 63432c09e0dddb08942e7172f24666a811432bb5 /lib/bytes | |
| parent | aab053ef5c49bcc67f6de5477d9760ea4e3bf6ab (diff) | |
| download | pakakeh.go-d3e6c2e902eb3a00c2dfdcde09bf35282ea63396.tar.xz | |
Move all byte(s) related constant and functions from package text to bytes
Diffstat (limited to 'lib/bytes')
| -rw-r--r-- | lib/bytes/bytes.go | 20 | ||||
| -rw-r--r-- | lib/bytes/bytes_test.go | 3 | ||||
| -rw-r--r-- | lib/bytes/is.go | 70 | ||||
| -rw-r--r-- | lib/bytes/json.go | 172 | ||||
| -rw-r--r-- | lib/bytes/random.go | 22 |
5 files changed, 284 insertions, 3 deletions
diff --git a/lib/bytes/bytes.go b/lib/bytes/bytes.go index 549d82db..ad777180 100644 --- a/lib/bytes/bytes.go +++ b/lib/bytes/bytes.go @@ -2,13 +2,31 @@ // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. -// Packages bytes contains common functions to manipulate slice of bytes. +// Packages bytes provide a library for working with byte or slice of bytes. package bytes import ( "fmt" ) +const ( + // ASCIILetters contains list of lower and upper case characters in + // ASCII. + ASCIILetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + // HexaLETTERS contains list of hexadecimal characters in upper cases. + HexaLETTERS = "0123456789ABCDEF" + // HexaLetters contains list of hexadecimal characters in lower and + // upper cases. + HexaLetters = "0123456789abcedfABCDEF" + // HexaLetters contains list of hexadecimal characters in lower cases. + Hexaletters = "0123456789abcedf" +) + +var ( + // ASCIISpaces contains list of white spaces in ASCII. + ASCIISpaces = []byte{'\t', '\n', '\v', '\f', '\r', ' '} +) + // // PrintHex will print each byte in slice as hexadecimal value into N column // length. diff --git a/lib/bytes/bytes_test.go b/lib/bytes/bytes_test.go index d4fef2a6..50669c4f 100644 --- a/lib/bytes/bytes_test.go +++ b/lib/bytes/bytes_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/shuLhan/share/lib/test" - libtext "github.com/shuLhan/share/lib/text" ) func TestToLower(t *testing.T) { @@ -35,7 +34,7 @@ func TestToLower(t *testing.T) { } } -var randomInput256 = libtext.Random([]byte(libtext.HexaLetters), 256) +var randomInput256 = Random([]byte(HexaLetters), 256) func BenchmarkToLowerStd(b *testing.B) { in := make([]byte, len(randomInput256)) diff --git a/lib/bytes/is.go b/lib/bytes/is.go new file mode 100644 index 00000000..4ad06805 --- /dev/null +++ b/lib/bytes/is.go @@ -0,0 +1,70 @@ +// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytes + +// +// IsAlpha will return true if byte is ASCII alphabet character, otherwise +// it will return false. +// +func IsAlpha(b byte) bool { + if (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z') { + return true + } + return false +} + +// +// IsAlnum will return true if byte is ASCII alphanumeric character, otherwise +// it will return false. +// +func IsAlnum(b byte) bool { + return IsAlpha(b) || IsDigit(b) +} + +// +// IsDigit will return true if byte is ASCII digit, otherwise it will return +// false. +// +func IsDigit(b byte) bool { + if b >= '0' && b <= '9' { + return true + } + return false +} + +// +// IsDigits will return true if all bytes are ASCII digit, otherwise it will +// return false. +// +func IsDigits(data []byte) bool { + for x := 0; x < len(data); x++ { + if !IsDigit(data[x]) { + return false + } + } + return true +} + +// +// IsHex will return true if byte is hexadecimal number, otherwise it will +// return false. +// +func IsHex(b byte) bool { + if (b >= '1' && b <= '9') || (b >= 'a' && b <= 'f') || (b >= 'A' && b <= 'F') { + return true + } + return false +} + +// +// IsSpace will return true if byte is ASCII white spaces character, +// otherwise it will return false. +// +func IsSpace(b byte) bool { + if b == '\t' || b == '\n' || b == '\v' || b == '\f' || b == '\r' || b == ' ' { + return true + } + return false +} diff --git a/lib/bytes/json.go b/lib/bytes/json.go new file mode 100644 index 00000000..1a296a3b --- /dev/null +++ b/lib/bytes/json.go @@ -0,0 +1,172 @@ +// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytes + +import ( + "bytes" + "fmt" + "strconv" +) + +const ( + errInvalidSyntax = "%s: invalid syntax at %d" +) + +const ( + bDoubleQuote = '"' + bRevSolidus = '\\' + bSolidus = '/' + bBackspace = '\b' + bFormFeed = '\f' + bLineFeed = '\n' + bCarReturn = '\r' + bTab = '\t' +) + +// +// JSONEscape escape the following character: `"` (quotation mark), +// `\` (reverse solidus), `/` (solidus), `\b` (backspace), `\f` (formfeed), +// `\n` (newline), `\r` (carriage return`), `\t` (horizontal tab), and control +// character from 0 - 31. +// +// References: +// +// * https://tools.ietf.org/html/rfc7159#page-8 +// +func JSONEscape(in []byte) []byte { + var buf bytes.Buffer + + for x := 0; x < len(in); x++ { + if in[x] == bDoubleQuote || in[x] == bRevSolidus || in[x] == bSolidus { + buf.WriteByte(bRevSolidus) + buf.WriteByte(in[x]) + continue + } + if in[x] == bBackspace { + buf.WriteByte(bRevSolidus) + buf.WriteByte('b') + continue + } + if in[x] == bFormFeed { + buf.WriteByte(bRevSolidus) + buf.WriteByte('f') + continue + } + if in[x] == bLineFeed { + buf.WriteByte(bRevSolidus) + buf.WriteByte('n') + continue + } + if in[x] == bCarReturn { + buf.WriteByte(bRevSolidus) + buf.WriteByte('r') + continue + } + if in[x] == bTab { + buf.WriteByte(bRevSolidus) + buf.WriteByte('t') + continue + } + if in[x] <= 31 { + buf.WriteString(fmt.Sprintf("\\u%04X", in[x])) + continue + } + + buf.WriteByte(in[x]) + } + + return buf.Bytes() +} + +// +// JSONUnescape unescape JSON bytes, reversing what BytesJSONEscape do. +// +// If strict is true, any unknown control character will be returned as error. +// For example, in string "\x", "x" is not valid control character, and the +// function will return empty string and error. +// If strict is false, it will return "x". +// +func JSONUnescape(in []byte, strict bool) ([]byte, error) { + var ( + buf bytes.Buffer + uni bytes.Buffer + esc bool + ) + + for x := 0; x < len(in); x++ { + if esc { + if in[x] == 'u' { + uni.Reset() + x++ + + for y := 0; y < 4 && x < len(in); x++ { + uni.WriteByte(in[x]) + y++ + } + + dec, err := strconv.ParseUint(uni.String(), 16, 32) + if err != nil { + return nil, err + } + + if dec <= 31 { + buf.WriteByte(byte(dec)) + } else { + buf.WriteRune(rune(dec)) + } + + esc = false + x-- + continue + } + if in[x] == 't' { + buf.WriteByte(bTab) + esc = false + continue + } + if in[x] == 'r' { + buf.WriteByte(bCarReturn) + esc = false + continue + } + if in[x] == 'n' { + buf.WriteByte(bLineFeed) + esc = false + continue + } + if in[x] == 'f' { + buf.WriteByte(bFormFeed) + esc = false + continue + } + if in[x] == 'b' { + buf.WriteByte(bBackspace) + esc = false + continue + } + if in[x] == bDoubleQuote || in[x] == bRevSolidus || in[x] == bSolidus { + buf.WriteByte(in[x]) + esc = false + continue + } + + if strict { + err := fmt.Errorf(errInvalidSyntax, "BytesJSONUnescape", x) + return nil, err + } + + buf.WriteByte(in[x]) + esc = false + continue + } + if in[x] == bRevSolidus { + esc = true + continue + } + buf.WriteByte(in[x]) + } + + return buf.Bytes(), nil +} diff --git a/lib/bytes/random.go b/lib/bytes/random.go new file mode 100644 index 00000000..73945788 --- /dev/null +++ b/lib/bytes/random.go @@ -0,0 +1,22 @@ +// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package bytes + +import ( + "math/rand" +) + +// +// Random generate random sequence of value from seed with fixed length. +// +// This function assume that random generator has been seeded. +// +func Random(seed []byte, n int) []byte { + b := make([]byte, n) + for x := 0; x < n; x++ { + b[x] = seed[rand.Intn(len(seed))] + } + return b +} |
