From 8d5ffba2d9483f049385d37bc468f2a114548eb0 Mon Sep 17 00:00:00 2001 From: Shulhan Date: Fri, 14 Jun 2019 19:02:22 +0700 Subject: ascii: new library for working with ASCII characters This library previously part of bytes package. To make it bytes package consistent (only working with slice of byte), we move all ASCII related constants, variables, and functions into new package. --- CHANGELOG.adoc | 12 ++++ CHANGELOG.html | 62 +++++++++++++++----- README.adoc | 3 + README.html | 6 +- lib/ascii/ascii.go | 135 ++++++++++++++++++++++++++++++++++++++++++++ lib/ascii/benchmark_test.go | 49 ++++++++++++++++ lib/ascii/example_test.go | 29 ++++++++++ lib/bytes/bytes.go | 48 ---------------- lib/bytes/bytes_test.go | 58 +------------------ lib/bytes/is.go | 70 ----------------------- lib/bytes/random.go | 22 -------- lib/dns/hosts.go | 4 +- lib/dns/masterfile.go | 25 ++++---- lib/dns/message.go | 5 +- lib/email/dkim/func.go | 3 +- lib/email/dkim/parser.go | 4 +- lib/email/dkim/tag.go | 8 +-- lib/email/field.go | 8 +-- lib/email/field_test.go | 4 +- lib/io/is.go | 4 +- lib/io/reader.go | 8 +-- lib/memfs/template.go | 3 +- lib/net/is.go | 8 +-- lib/net/resolvconf.go | 12 ++-- lib/net/resolvconf_test.go | 4 +- lib/smtp/command_test.go | 7 +-- lib/smtp/response.go | 4 +- lib/smtp/smtp.go | 4 +- lib/spf/macro.go | 6 +- lib/time/duration.go | 6 +- 30 files changed, 347 insertions(+), 274 deletions(-) create mode 100644 lib/ascii/ascii.go create mode 100644 lib/ascii/benchmark_test.go create mode 100644 lib/ascii/example_test.go delete mode 100644 lib/bytes/is.go delete mode 100644 lib/bytes/random.go diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index a1d422aa..8bff711b 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -4,6 +4,18 @@ This library is released each month, either at the end of month or at the first week of next month. +== share v0.8.0 (2019-07-xx) + +=== Breaking changes + +* All ASCII related contants and functions now being moved from `bytes` + package to `ascii` package. + +=== New Features + +* ascii: new library for working with ASCII characters. + + == share v0.7.0 (2019-06-14) This release bring major refactoring on `ini` package to provide a clean and diff --git a/CHANGELOG.html b/CHANGELOG.html index b1342519..d73564bd 100644 --- a/CHANGELOG.html +++ b/CHANGELOG.html @@ -15,10 +15,16 @@
Table of Contents
+

share v0.8.0 (2019-07-xx)

+
+
+

Breaking changes

+
+
    +
  • +

    All ASCII related contants and functions now being moved from bytes +package to ascii package.

    +
  • +
+
+
+
+

New Features

+
+
    +
  • +

    ascii: new library for working with ASCII characters.

    +
  • +
+
+
+
+
+

share v0.7.0 (2019-06-14)

@@ -79,7 +111,7 @@ first week of next month.

simple API.

-

Breaking Changes

+

Breaking Changes

  • @@ -92,7 +124,7 @@ simple API.

-

New Features

+

New Features

  • @@ -217,7 +249,7 @@ Most notable changes are adding caches and query forwarding (recursion), and removing the server handler.

-

Breaking Changes

+

Breaking Changes

  • @@ -291,7 +323,7 @@ removing the server handler.

-

New Features

+

New Features

  • @@ -427,7 +459,7 @@ server and client API to make it easy and extensible. The websocket is now 100% pass the autobahn testsuite (minus compression feature).

-

New Features

+

New Features

  • @@ -494,7 +526,7 @@ testsuite

    share v0.4.0 (2019-03-01)

    -

    New Features

    +

    New Features

    • @@ -740,7 +772,7 @@ testsuite

      share v0.2.0 (2019-01-02)

      -

      New Features

      +

      New Features

      • @@ -792,7 +824,7 @@ and several libraries.

      diff --git a/README.adoc b/README.adoc index 89ac519f..b44153a2 100644 --- a/README.adoc +++ b/README.adoc @@ -23,6 +23,9 @@ A collection of libraries and tools written in Go. == Libraries +* link:{url-godoc}/lib/ascii[*ascii*^]: A library for working with ASCII + characters. + * link:{url-godoc}/lib/bytes[*bytes*^]: A library for working with slice of bytes. diff --git a/README.html b/README.html index debed9f3..e8d80bb4 100644 --- a/README.html +++ b/README.html @@ -66,6 +66,10 @@ line interface to SMTP client protocol.

      • +

        ascii: A library for working with ASCII +characters.

        +
      • +
      • bytes: A library for working with slice of bytes.

      • @@ -371,7 +375,7 @@ files.

      diff --git a/lib/ascii/ascii.go b/lib/ascii/ascii.go new file mode 100644 index 00000000..314c3a53 --- /dev/null +++ b/lib/ascii/ascii.go @@ -0,0 +1,135 @@ +// Copyright 2019, Shulhan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +// Package ascii provide a library for working with ASCII characters. +package ascii + +import ( + "math/rand" +) + +const ( + // Letters contains list of lower and upper case characters in ASCII. + Letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" + + // LettersNumber contains list of lower and upper case characters in + // ASCII along with numbers. + LettersNumber = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" + + // 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" +) + +//nolint:gochecknoglobals +var ( + // Spaces contains list of white spaces in ASCII. + Spaces = []byte{'\t', '\n', '\v', '\f', '\r', ' '} +) + +// +// 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) +} + +// +// 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 +} + +// +// 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 +} + +// +// Random generate random sequence of value from source with fixed length. +// +// This function assume that random generator has been seeded. +// +func Random(source []byte, n int) []byte { + b := make([]byte, n) + for x := 0; x < n; x++ { + b[x] = source[rand.Intn(len(source))] + } + return b +} + +// +// ToLower convert slice of ASCII characters to lower cases, in places. +// +func ToLower(data *[]byte) { + for x := 0; x < len(*data); x++ { + if (*data)[x] < 'A' || (*data)[x] > 'Z' { + continue + } + (*data)[x] += 32 + } +} + +// +// ToUpper convert slice of ASCII characters to upper cases, in places. +// +func ToUpper(data *[]byte) { + for x := 0; x < len(*data); x++ { + if (*data)[x] < 'a' || (*data)[x] > 'z' { + continue + } + (*data)[x] -= 32 + } +} diff --git a/lib/ascii/benchmark_test.go b/lib/ascii/benchmark_test.go new file mode 100644 index 00000000..1a2d4a4b --- /dev/null +++ b/lib/ascii/benchmark_test.go @@ -0,0 +1,49 @@ +// Copyright 2019, Shulhan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ascii + +import ( + "bytes" + "testing" +) + +func BenchmarkToLowerStd(b *testing.B) { + randomInput256 := Random([]byte(HexaLetters), 256) + + in := make([]byte, len(randomInput256)) + copy(in, randomInput256) + + b.ResetTimer() + + for x := 0; x < b.N; x++ { + bytes.ToLower(in) + } +} + +func BenchmarkToLower(b *testing.B) { + randomInput256 := Random([]byte(HexaLetters), 256) + + in := make([]byte, len(randomInput256)) + copy(in, randomInput256) + + b.ResetTimer() + + for x := 0; x < b.N; x++ { + ToLower(&in) + copy(in, randomInput256) + } +} + +// +// Output of above benchmarks, +// +// goos: linux +// goarch: amd64 +// pkg: github.com/shuLhan/share/lib/ascii +// BenchmarkToLowerStd-4 2066588 563 ns/op 256 B/op 1 allocs/op +// BenchmarkToLower-4 5476693 213 ns/op 0 B/op 0 allocs/op +// PASS +// ok github.com/shuLhan/share/lib/ascii 3.149s +// diff --git a/lib/ascii/example_test.go b/lib/ascii/example_test.go new file mode 100644 index 00000000..c5b76492 --- /dev/null +++ b/lib/ascii/example_test.go @@ -0,0 +1,29 @@ +// Copyright 2019, Shulhan . All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package ascii + +import ( + "fmt" +) + +func ExampleToLower() { + in := []byte("@ABCDEFGhijklmnoPQRSTUVWxyz{12345678") + + ToLower(&in) + + fmt.Println(string(in)) + // Output: + // @abcdefghijklmnopqrstuvwxyz{12345678 +} + +func ExampleToUpper() { + in := []byte("@ABCDEFGhijklmnoPQRSTUVWxyz{12345678") + + ToUpper(&in) + + fmt.Println(string(in)) + // Output: + // @ABCDEFGHIJKLMNOPQRSTUVWXYZ{12345678 +} diff --git a/lib/bytes/bytes.go b/lib/bytes/bytes.go index 8a1e94f7..62e7d307 100644 --- a/lib/bytes/bytes.go +++ b/lib/bytes/bytes.go @@ -10,30 +10,6 @@ import ( "reflect" ) -const ( - // ASCIILetters contains list of lower and upper case characters in - // ASCII. - ASCIILetters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - - // ASCIILettersNumber contains list of lower and upper case - // characters in ASCII with numbers. - ASCIILettersNumber = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" - - // 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" -) - -//nolint:gochecknoglobals -var ( - // ASCIISpaces contains list of white spaces in ASCII. - ASCIISpaces = []byte{'\t', '\n', '\v', '\f', '\r', ' '} -) - // // AppendInt16 into slice of byte. // @@ -444,30 +420,6 @@ func SkipAfterToken(line, token []byte, startAt int, checkEsc bool) (int, bool) return p, false } -// -// ToLower convert slice of bytes to lower cases, in places. -// -func ToLower(data *[]byte) { - for x := 0; x < len(*data); x++ { - if (*data)[x] < 'A' || (*data)[x] > 'Z' { - continue - } - (*data)[x] += 32 - } -} - -// -// ToUpper convert slice of bytes to upper cases, in places. -// -func ToUpper(data *[]byte) { - for x := 0; x < len(*data); x++ { - if (*data)[x] < 'a' || (*data)[x] > 'z' { - continue - } - (*data)[x] -= 32 - } -} - // // TokenFind return the first index of matched token in line, start at custom // index. diff --git a/lib/bytes/bytes_test.go b/lib/bytes/bytes_test.go index e5eb2ac4..938f4ca1 100644 --- a/lib/bytes/bytes_test.go +++ b/lib/bytes/bytes_test.go @@ -1,9 +1,9 @@ package bytes import ( - "bytes" "testing" + "github.com/shuLhan/share/lib/ascii" "github.com/shuLhan/share/lib/test" ) @@ -280,33 +280,6 @@ func TestSkipAfterToken(t *testing.T) { } } -func TestToLower(t *testing.T) { - cases := []struct { - in []byte - exp []byte - }{{ - in: []byte("@ABCDEFG"), - exp: []byte("@abcdefg"), - }, { - in: []byte("@ABCDEFG12345678"), - exp: []byte("@abcdefg12345678"), - }, { - in: []byte("@ABCDEFGhijklmno12345678"), - exp: []byte("@abcdefghijklmno12345678"), - }, { - in: []byte("@ABCDEFGhijklmnoPQRSTUVW12345678"), - exp: []byte("@abcdefghijklmnopqrstuvw12345678"), - }, { - in: []byte("@ABCDEFGhijklmnoPQRSTUVWxyz{12345678"), - exp: []byte("@abcdefghijklmnopqrstuvwxyz{12345678"), - }} - - for _, c := range cases { - ToLower(&c.in) - test.Assert(t, "ToLower", c.exp, c.in, true) - } -} - func testTokenFind(t *testing.T, line, token []byte, startat int, exp []int) { got := []int{} tokenlen := len(token) @@ -354,35 +327,8 @@ func TestInReplace(t *testing.T) { }} for _, c := range cases { - got := InReplace([]byte(c.in), []byte(ASCIILettersNumber), '_') + got := InReplace([]byte(c.in), []byte(ascii.LettersNumber), '_') test.Assert(t, "InReplace", c.exp, string(got), true) } } - -func BenchmarkToLowerStd(b *testing.B) { - randomInput256 := Random([]byte(HexaLetters), 256) - - in := make([]byte, len(randomInput256)) - copy(in, randomInput256) - - b.ResetTimer() - - for x := 0; x < b.N; x++ { - bytes.ToLower(in) - } -} - -func BenchmarkToLower(b *testing.B) { - randomInput256 := Random([]byte(HexaLetters), 256) - - in := make([]byte, len(randomInput256)) - copy(in, randomInput256) - - b.ResetTimer() - - for x := 0; x < b.N; x++ { - ToLower(&in) - copy(in, randomInput256) - } -} diff --git a/lib/bytes/is.go b/lib/bytes/is.go deleted file mode 100644 index 4ad06805..00000000 --- a/lib/bytes/is.go +++ /dev/null @@ -1,70 +0,0 @@ -// Copyright 2018, Shulhan . 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/random.go b/lib/bytes/random.go deleted file mode 100644 index 73945788..00000000 --- a/lib/bytes/random.go +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018, Shulhan . 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 -} diff --git a/lib/dns/hosts.go b/lib/dns/hosts.go index f8852653..1a39454c 100644 --- a/lib/dns/hosts.go +++ b/lib/dns/hosts.go @@ -4,7 +4,7 @@ import ( "net" "runtime" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" libio "github.com/shuLhan/share/lib/io" libnet "github.com/shuLhan/share/lib/net" ) @@ -62,7 +62,7 @@ func newMessage(addr, hname []byte) *Message { } } - libbytes.ToLower(&hname) + ascii.ToLower(&hname) rrName := make([]byte, len(hname)) copy(rrName, hname) diff --git a/lib/dns/masterfile.go b/lib/dns/masterfile.go index c6a49cea..8b6417cb 100644 --- a/lib/dns/masterfile.go +++ b/lib/dns/masterfile.go @@ -13,6 +13,7 @@ import ( "strings" "time" + "github.com/shuLhan/share/lib/ascii" libbytes "github.com/shuLhan/share/lib/bytes" "github.com/shuLhan/share/lib/debug" libio "github.com/shuLhan/share/lib/io" @@ -210,7 +211,7 @@ func (m *master) parse() (err error) { return } - libbytes.ToUpper(&tok) + ascii.ToUpper(&tok) stok := string(tok) switch stok { @@ -261,7 +262,7 @@ func (m *master) parseDirectiveOrigin() (err error) { return fmt.Errorf("! %s:%d Empty $origin directive", m.file, m.lineno) } - libbytes.ToLower(&tok) + ascii.ToLower(&tok) m.origin = string(tok) if isTerm { @@ -302,7 +303,7 @@ func (m *master) parseDirectiveInclude() (err error) { var incfile, dname string - libbytes.ToLower(&tok) + ascii.ToLower(&tok) incfile = string(tok) // check if include followed by domain name. @@ -360,7 +361,7 @@ func (m *master) parseDirectiveTTL() (err error) { return fmt.Errorf("! %s:%d Empty $ttl directive", m.file, m.lineno) } - libbytes.ToLower(&tok) + ascii.ToLower(&tok) stok := string(tok) m.ttl, err = parseTTL(tok, stok) @@ -397,7 +398,7 @@ func parseTTL(tok []byte, stok string) (seconds uint32, err error) { dur time.Duration ) - if libbytes.IsDigits(tok) { + if ascii.IsDigits(tok) { v, err = strconv.ParseUint(stok, 10, 32) if err != nil { return 0, err @@ -457,7 +458,7 @@ func (m *master) parseRR(prevRR *ResourceRecord, tok []byte) (rr *ResourceRecord rr.TTL = prevRR.TTL rr.Class = prevRR.Class - if libbytes.IsDigit(tok[0]) { + if ascii.IsDigit(tok[0]) { ttl, err := parseTTL(tok, stok) if err != nil { return nil, err @@ -490,12 +491,12 @@ func (m *master) parseRR(prevRR *ResourceRecord, tok []byte) (rr *ResourceRecord } orgtok := libbytes.Copy(tok) - libbytes.ToUpper(&tok) + ascii.ToUpper(&tok) stok = string(tok) switch m.flag { case parseRRStart: - if libbytes.IsDigit(tok[0]) { + if ascii.IsDigit(tok[0]) { rr.TTL, err = parseTTL(tok, stok) if err != nil { return nil, err @@ -520,7 +521,7 @@ func (m *master) parseRR(prevRR *ResourceRecord, tok []byte) (rr *ResourceRecord } case parseRRClass: - if libbytes.IsDigit(tok[0]) { + if ascii.IsDigit(tok[0]) { rr.TTL, err = parseTTL(tok, stok) if err != nil { return nil, err @@ -667,7 +668,7 @@ func (m *master) parseRRData(rr *ResourceRecord, tok []byte) (err error) { } func (m *master) parseSOA(rr *ResourceRecord, tok []byte) (err error) { - libbytes.ToLower(&tok) + ascii.ToLower(&tok) rr.SOA = &RDataSOA{ MName: m.generateDomainName(tok), @@ -685,7 +686,7 @@ func (m *master) parseSOA(rr *ResourceRecord, tok []byte) (err error) { m.file, m.lineno, string(tok)) } - libbytes.ToLower(&tok) + ascii.ToLower(&tok) rr.SOA.RName = m.generateDomainName(tok) var v int @@ -995,7 +996,7 @@ out: } func (m *master) generateDomainName(dname []byte) (out []byte) { - libbytes.ToLower(&dname) + ascii.ToLower(&dname) switch { case dname[0] == '@': out = []byte(m.origin) diff --git a/lib/dns/message.go b/lib/dns/message.go index 09b0e2fd..8a0aa93c 100644 --- a/lib/dns/message.go +++ b/lib/dns/message.go @@ -11,6 +11,7 @@ import ( "strconv" "strings" + "github.com/shuLhan/share/lib/ascii" libbytes "github.com/shuLhan/share/lib/bytes" "github.com/shuLhan/share/lib/debug" ) @@ -118,7 +119,7 @@ func (msg *Message) packDomainName(dname []byte, doCompress bool) (n int) { d int ) - libbytes.ToLower(&dname) + ascii.ToLower(&dname) msg.dname = string(dname) if doCompress { @@ -147,7 +148,7 @@ func (msg *Message) packDomainName(dname []byte, doCompress bool) (n int) { // corresponding to the decimal number described by // DDD. The resulting octet is assumed to be text and // is not checked for special meaning. - if libbytes.IsDigit(c) { + if ascii.IsDigit(c) { if x+2 >= len(dname) { return n } diff --git a/lib/email/dkim/func.go b/lib/email/dkim/func.go index 93fcbbb4..2ad8a9d0 100644 --- a/lib/email/dkim/func.go +++ b/lib/email/dkim/func.go @@ -5,6 +5,7 @@ package dkim import ( + "github.com/shuLhan/share/lib/ascii" libbytes "github.com/shuLhan/share/lib/bytes" ) @@ -19,7 +20,7 @@ func DecodeQP(raw []byte) (out []byte) { out = make([]byte, 0, len(raw)) for x := 0; x < len(raw); x++ { - if libbytes.IsSpace(raw[x]) { + if ascii.IsSpace(raw[x]) { continue } if raw[x] == '=' { diff --git a/lib/email/dkim/parser.go b/lib/email/dkim/parser.go index b132cdb7..24f0c91e 100644 --- a/lib/email/dkim/parser.go +++ b/lib/email/dkim/parser.go @@ -7,7 +7,7 @@ package dkim import ( "fmt" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" libio "github.com/shuLhan/share/lib/io" ) @@ -83,7 +83,7 @@ func (p *parser) fetchTag() (t *tag, err error) { // fetchTagKey parse and fetch tag's key. // func (p *parser) fetchTagKey() (t *tag, err error) { - p.tok, p.isTerm, p.c = p.r.ReadUntil(p.sepKey, libbytes.ASCIISpaces) + p.tok, p.isTerm, p.c = p.r.ReadUntil(p.sepKey, ascii.Spaces) t, err = newTag(p.tok) if err != nil || t == nil { diff --git a/lib/email/dkim/tag.go b/lib/email/dkim/tag.go index 36430bb0..847b60bc 100644 --- a/lib/email/dkim/tag.go +++ b/lib/email/dkim/tag.go @@ -8,7 +8,7 @@ import ( "bytes" "fmt" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" ) type tagKey int @@ -102,11 +102,11 @@ func newTag(key []byte) (t *tag, err error) { if len(key) == 0 { return nil, nil } - if !libbytes.IsAlpha(key[0]) { + if !ascii.IsAlpha(key[0]) { return nil, fmt.Errorf("dkim: invalid tag key: '%s'", key) } for x := 0; x < len(key); x++ { - if libbytes.IsAlnum(key[x]) || key[x] == '_' { + if ascii.IsAlnum(key[x]) || key[x] == '_' { continue } return nil, fmt.Errorf("dkim: invalid tag key: '%s'", key) @@ -141,7 +141,7 @@ func (t *tag) setValue(val []byte) (err error) { } for x := 0; x < len(val); x++ { switch { - case libbytes.IsSpace(val[x]): + case ascii.IsSpace(val[x]): continue case val[x] < '!' || val[x] == ';' || val[x] > '~': if !isBase64 { diff --git a/lib/email/field.go b/lib/email/field.go index a777a67c..89887a60 100644 --- a/lib/email/field.go +++ b/lib/email/field.go @@ -10,7 +10,7 @@ import ( "log" "time" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" "github.com/shuLhan/share/lib/debug" libio "github.com/shuLhan/share/lib/io" libtime "github.com/shuLhan/share/lib/time" @@ -205,14 +205,14 @@ func (field *Field) setValue(raw []byte) { x := 0 // Skip leading spaces. for ; x < len(raw); x++ { - if !libbytes.IsSpace(raw[x]) { + if !ascii.IsSpace(raw[x]) { break } } spaces := 0 for ; x < len(raw); x++ { - if libbytes.IsSpace(raw[x]) { + if ascii.IsSpace(raw[x]) { spaces++ continue } @@ -346,7 +346,7 @@ func (field *Field) unpackDate() (err error) { r.Init(field.Value) c = r.SkipSpaces() - if !libbytes.IsDigit(c) { + if !ascii.IsDigit(c) { v, _, c = r.ReadUntil([]byte{','}, nil) if len(v) == 0 || c != ',' { return fmt.Errorf("unpackDate: invalid date format") diff --git a/lib/email/field_test.go b/lib/email/field_test.go index 162e23ea..e25f0f1f 100644 --- a/lib/email/field_test.go +++ b/lib/email/field_test.go @@ -8,12 +8,12 @@ import ( "testing" "time" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" "github.com/shuLhan/share/lib/test" ) func TestParseField(t *testing.T) { - longValue := string(libbytes.Random([]byte(libbytes.ASCIILetters), 994)) + longValue := string(ascii.Random([]byte(ascii.Letters), 994)) cases := []struct { desc string diff --git a/lib/io/is.go b/lib/io/is.go index c11ef063..04ba20c1 100644 --- a/lib/io/is.go +++ b/lib/io/is.go @@ -9,7 +9,7 @@ import ( "os" "path/filepath" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" ) // @@ -39,7 +39,7 @@ func IsBinary(file string) bool { content = content[:n] for x := 0; x < len(content); x++ { - if libbytes.IsSpace(content[x]) { + if ascii.IsSpace(content[x]) { continue } if content[x] >= 33 && content[x] <= 126 { diff --git a/lib/io/reader.go b/lib/io/reader.go index c91dce61..6b708dd7 100644 --- a/lib/io/reader.go +++ b/lib/io/reader.go @@ -7,7 +7,7 @@ package io import ( "io/ioutil" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" ) // @@ -138,7 +138,7 @@ func (r *Reader) ScanInt64() (n int64, c byte) { for ; r.X < len(r.V); r.X++ { c = r.V[r.X] - if !libbytes.IsSpace(c) { + if !ascii.IsSpace(c) { break } } @@ -150,7 +150,7 @@ func (r *Reader) ScanInt64() (n int64, c byte) { } for r.X < len(r.V) { c = r.V[r.X] - if !libbytes.IsDigit(c) { + if !ascii.IsDigit(c) { break } c -= '0' @@ -186,7 +186,7 @@ func (r *Reader) SkipN(n int) bool { func (r *Reader) SkipSpaces() (c byte) { for r.X < len(r.V) { c = r.V[r.X] - if libbytes.IsSpace(c) { + if ascii.IsSpace(c) { r.X++ continue } diff --git a/lib/memfs/template.go b/lib/memfs/template.go index 2a06a4b7..83d4b5bf 100644 --- a/lib/memfs/template.go +++ b/lib/memfs/template.go @@ -8,6 +8,7 @@ import ( "fmt" "text/template" + "github.com/shuLhan/share/lib/ascii" libbytes "github.com/shuLhan/share/lib/bytes" ) @@ -51,7 +52,7 @@ func init() { ` tmplFuncs := template.FuncMap{ "funcname": func(path string) []byte { - return libbytes.InReplace([]byte(path), []byte(libbytes.ASCIILettersNumber), '_') + return libbytes.InReplace([]byte(path), []byte(ascii.LettersNumber), '_') }, "maxline": func(x int) bool { if x != 0 && x%16 == 0 { diff --git a/lib/net/is.go b/lib/net/is.go index 86d48827..a1261a6a 100644 --- a/lib/net/is.go +++ b/lib/net/is.go @@ -4,7 +4,7 @@ import ( "net" "strings" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" ) // @@ -25,10 +25,10 @@ func IsHostnameValid(hname []byte, isFQDN bool) bool { if n == 0 { return false } - if !libbytes.IsAlnum(hname[0]) && hname[0] != '_' { + if !ascii.IsAlnum(hname[0]) && hname[0] != '_' { return false } - if !libbytes.IsAlnum(hname[n-1]) { + if !ascii.IsAlnum(hname[n-1]) { return false } var ndot int @@ -37,7 +37,7 @@ func IsHostnameValid(hname []byte, isFQDN bool) bool { ndot++ continue } - if hname[x] == '-' || hname[x] == '_' || libbytes.IsAlnum(hname[x]) { + if hname[x] == '-' || hname[x] == '_' || ascii.IsAlnum(hname[x]) { continue } return false diff --git a/lib/net/resolvconf.go b/lib/net/resolvconf.go index 6311a768..25c1e6e3 100644 --- a/lib/net/resolvconf.go +++ b/lib/net/resolvconf.go @@ -9,7 +9,7 @@ import ( "strconv" "strings" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" libio "github.com/shuLhan/share/lib/io" ) @@ -160,13 +160,13 @@ func (rc *ResolvConf) parse(reader *libio.Reader) { continue } - tok, isTerm, _ := reader.ReadUntil(libbytes.ASCIISpaces, newLineTerms) + tok, isTerm, _ := reader.ReadUntil(ascii.Spaces, newLineTerms) if isTerm { // We found keyword without value. continue } - libbytes.ToLower(&tok) + ascii.ToLower(&tok) v := string(tok) switch v { case "domain": @@ -195,7 +195,7 @@ func (rc *ResolvConf) parseValue(reader *libio.Reader, out *string) { return } - tok, isTerm, _ := reader.ReadUntil(libbytes.ASCIISpaces, newLineTerms) + tok, isTerm, _ := reader.ReadUntil(ascii.Spaces, newLineTerms) if len(tok) > 0 { *out = string(tok) } @@ -223,7 +223,7 @@ func (rc *ResolvConf) parseSearch(reader *libio.Reader) { break } - tok, isTerm, _ := reader.ReadUntil(libbytes.ASCIISpaces, newLineTerms) + tok, isTerm, _ := reader.ReadUntil(ascii.Spaces, newLineTerms) if len(tok) > 0 { if curLen+len(tok) > maxLen { break @@ -256,7 +256,7 @@ func (rc *ResolvConf) parseOptions(reader *libio.Reader) { break } - tok, isTerm, _ = reader.ReadUntil(libbytes.ASCIISpaces, newLineTerms) + tok, isTerm, _ = reader.ReadUntil(ascii.Spaces, newLineTerms) if len(tok) > 0 { rc.parseOptionsKV(tok) } diff --git a/lib/net/resolvconf_test.go b/lib/net/resolvconf_test.go index 29d06854..50c88c07 100644 --- a/lib/net/resolvconf_test.go +++ b/lib/net/resolvconf_test.go @@ -8,7 +8,7 @@ import ( "os" "testing" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" "github.com/shuLhan/share/lib/test" ) @@ -54,7 +54,7 @@ func TestResolvConf_Init(t *testing.T) { return "kilabit.info", nil } - veryLongName := string(libbytes.Random([]byte(libbytes.ASCIILetters), 255)) + veryLongName := string(ascii.Random([]byte(ascii.Letters), 255)) cases := []struct { desc string diff --git a/lib/smtp/command_test.go b/lib/smtp/command_test.go index e4b54573..46a84cec 100644 --- a/lib/smtp/command_test.go +++ b/lib/smtp/command_test.go @@ -7,7 +7,7 @@ package smtp import ( "testing" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" "github.com/shuLhan/share/lib/test" ) @@ -26,9 +26,8 @@ func TestUnpack(t *testing.T) { b: "DAT\r\n", expErr: errCmdUnknown, }, { - desc: "With length too long", - b: "VRFY " + string(libbytes.Random( - []byte(libbytes.ASCIILetters), 513)), + desc: "With length too long", + b: "VRFY " + string(ascii.Random([]byte(ascii.Letters), 513)), expErr: errCmdTooLong, }, { desc: "Without CRLF", diff --git a/lib/smtp/response.go b/lib/smtp/response.go index 6c2aead5..1bff05ee 100644 --- a/lib/smtp/response.go +++ b/lib/smtp/response.go @@ -9,7 +9,7 @@ import ( "errors" "strconv" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" libio "github.com/shuLhan/share/lib/io" ) @@ -70,7 +70,7 @@ func (res *Response) parseCode(raw []byte) (code []byte, isMultiline bool, err e code = raw[0:3] for _, b := range code { - if !libbytes.IsDigit(b) { + if !ascii.IsDigit(b) { return code, false, errors.New("invalid response code") } } diff --git a/lib/smtp/smtp.go b/lib/smtp/smtp.go index 9705be89..072f3b66 100644 --- a/lib/smtp/smtp.go +++ b/lib/smtp/smtp.go @@ -8,7 +8,7 @@ import ( "bytes" "errors" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" ) // List of SMTP status codes. @@ -204,7 +204,7 @@ func parseLocalDomain(data []byte, allow []byte) (out []byte) { out = append(out, '.') isDot = false } - if libbytes.IsAlnum(data[x]) { + if ascii.IsAlnum(data[x]) { out = append(out, data[x]) continue } diff --git a/lib/spf/macro.go b/lib/spf/macro.go index 0f01dd55..918e5b18 100644 --- a/lib/spf/macro.go +++ b/lib/spf/macro.go @@ -11,7 +11,7 @@ import ( "strconv" "time" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" libdns "github.com/shuLhan/share/lib/dns" libnet "github.com/shuLhan/share/lib/net" ) @@ -144,13 +144,13 @@ func (m *macro) parse(data []byte) (err error) { // *DIGIT [ "r" ] *delimiter case 3: - if libbytes.IsDigit(data[x]) { + if ascii.IsDigit(data[x]) { digits := make([]byte, 0, 3) digits = append(digits, data[x]) x++ for ; x < len(data); x++ { - if !libbytes.IsDigit(data[x]) { + if !ascii.IsDigit(data[x]) { break } digits = append(digits, data[x]) diff --git a/lib/time/duration.go b/lib/time/duration.go index 3432c6b4..79bee1a0 100644 --- a/lib/time/duration.go +++ b/lib/time/duration.go @@ -9,7 +9,7 @@ import ( "strconv" "time" - libbytes "github.com/shuLhan/share/lib/bytes" + "github.com/shuLhan/share/lib/ascii" libio "github.com/shuLhan/share/lib/io" ) @@ -45,12 +45,12 @@ func ParseDuration(s string) (time.Duration, error) { reader.Init([]byte(s)) c := reader.SkipSpaces() - if !libbytes.IsDigit(c) { + if !ascii.IsDigit(c) { return 0, ErrDurationMissingValue } for { - tok, _, c := reader.ReadUntil(seps, libbytes.ASCIISpaces) + tok, _, c := reader.ReadUntil(seps, ascii.Spaces) if c == 0 { break } -- cgit v1.3