Documentation ¶
Overview ¶
Package bytes provide a library for working with byte or slice of bytes.
Index ¶
- func AppendInt16(data []byte, v int16) []byte
- func AppendInt32(data []byte, v int32) []byte
- func AppendInt64(data []byte, v int64) []byte
- func AppendUint16(data []byte, v uint16) []byte
- func AppendUint32(data []byte, v uint32) []byte
- func AppendUint64(data []byte, v uint64) []byte
- func Concat(args ...interface{}) (out []byte)
- func Copy(src []byte) (dst []byte)
- func CutUntilToken(text, token []byte, startAt int, checkEsc bool) (cut []byte, pos int, found bool)
- func DumpPrettyTable(w io.Writer, title string, data []byte)
- func EncloseRemove(text, leftToken, rightToken []byte) (cut []byte, found bool)
- func EncloseToken(text, token, leftcap, rightcap []byte) (newtext []byte, found bool)
- func InReplace(text, allowed []byte, c byte) []byte
- func Indexes(text, token []byte) (idxs []int)
- func IsTokenAt(text, token []byte, p int) bool
- func MergeSpaces(in []byte) (out []byte)
- func ParseHexDump(in []byte, networkByteOrder bool) (out []byte, err error)
- func PrintHex(title string, data []byte, col int)
- func ReadHexByte(data []byte, x int) (b byte, ok bool)
- func ReadInt16(data []byte, x uint) (v int16)
- func ReadInt32(data []byte, x uint) (v int32)
- func ReadUint16(data []byte, x uint) (v uint16)
- func ReadUint32(data []byte, x uint) (v uint32)
- func RemoveSpaces(in []byte) (out []byte)
- func SkipAfterToken(text, token []byte, startAt int, checkEsc bool) (int, bool)
- func SnippetByIndexes(s []byte, indexes []int, sniplen int) (snippets [][]byte)
- func SplitEach(data []byte, n int) (chunks [][]byte)
- func TokenFind(text, token []byte, startat int) (at int)
- func TrimNull(in []byte) (out []byte)
- func WordIndexes(s []byte, word []byte) (idxs []int)
- func WriteUint16(data []byte, x uint, v uint16)
- func WriteUint32(data []byte, x uint, v uint32)
- type Parser
- func (bp *Parser) AddDelimiters(delims []byte)
- func (bp *Parser) Delimiters() []byte
- func (bp *Parser) Read() (token []byte, d byte)
- func (bp *Parser) ReadLine() (line []byte, c byte)
- func (bp *Parser) ReadN(n int) (token []byte, d byte)
- func (bp *Parser) ReadNoSpace() (token []byte, d byte)
- func (bp *Parser) Remaining() []byte
- func (bp *Parser) RemoveDelimiters(delims []byte)
- func (bp *Parser) Reset(content, delims []byte)
- func (bp *Parser) SetDelimiters(delims []byte)
- func (bp *Parser) Skip() (c byte)
- func (bp *Parser) SkipHorizontalSpaces() (n int, c byte)
- func (bp *Parser) SkipLine() (c byte)
- func (bp *Parser) SkipN(n int) (c byte)
- func (bp *Parser) SkipSpaces() (n int, c byte)
- func (bp *Parser) Stop() (remain []byte, pos int)
- func (bp *Parser) UnreadN(n int) byte
Examples ¶
- AppendInt16
- AppendInt32
- AppendInt64
- AppendUint16
- AppendUint32
- AppendUint64
- Concat
- Copy
- CutUntilToken
- DumpPrettyTable
- EncloseRemove
- EncloseToken
- InReplace
- Indexes
- IsTokenAt
- MergeSpaces
- ParseHexDump
- Parser.AddDelimiters
- Parser.Delimiters
- Parser.Read
- Parser.ReadLine
- Parser.ReadN
- Parser.ReadNoSpace
- Parser.Remaining
- Parser.RemoveDelimiters
- Parser.Reset
- Parser.SetDelimiters
- Parser.Skip
- Parser.SkipHorizontalSpaces
- Parser.SkipLine
- Parser.SkipN
- Parser.SkipSpaces
- Parser.Stop
- Parser.UnreadN
- PrintHex
- ReadHexByte
- ReadInt16
- ReadInt32
- ReadUint16
- ReadUint32
- RemoveSpaces
- SkipAfterToken
- SnippetByIndexes
- SplitEach
- TokenFind
- TrimNull
- WordIndexes
- WriteUint16
- WriteUint32
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AppendInt16 ¶
AppendInt16 append an int16 value into slice of byte.
Example ¶
package main import ( "fmt" "math" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { for _, v := range []int16{math.MinInt16, 0xab, 0xabc, math.MaxInt16} { out := libbytes.AppendInt16([]byte{}, v) fmt.Printf("%6d => %#04x => %#02v\n", v, v, out) } }
Output: -32768 => -0x8000 => []byte{0x80, 0x00} 171 => 0x00ab => []byte{0x00, 0xab} 2748 => 0x0abc => []byte{0x0a, 0xbc} 32767 => 0x7fff => []byte{0x7f, 0xff}
func AppendInt32 ¶
AppendInt32 append an int32 value into slice of byte.
Example ¶
package main import ( "fmt" "math" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { for _, v := range []int32{math.MinInt32, 0xab, 0xabc, math.MaxInt32} { out := libbytes.AppendInt32([]byte{}, v) fmt.Printf("%11d => %#x => %#v\n", v, v, out) } }
Output: -2147483648 => -0x80000000 => []byte{0x80, 0x0, 0x0, 0x0} 171 => 0xab => []byte{0x0, 0x0, 0x0, 0xab} 2748 => 0xabc => []byte{0x0, 0x0, 0xa, 0xbc} 2147483647 => 0x7fffffff => []byte{0x7f, 0xff, 0xff, 0xff}
func AppendInt64 ¶ added in v0.58.0
AppendInt64 append an int64 value into slice of byte.
Example ¶
package main import ( "fmt" "math" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var listInt64 = []int64{ math.MaxInt64, 1000, math.MinInt64, } var ( v int64 out []byte ) for _, v = range listInt64 { out = libbytes.AppendInt64(nil, v) fmt.Printf("%d\n=> %#x\n=> %#v\n", v, v, out) } }
Output: 9223372036854775807 => 0x7fffffffffffffff => []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 1000 => 0x3e8 => []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe8} -9223372036854775808 => -0x8000000000000000 => []byte{0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}
func AppendUint16 ¶
AppendUint16 append an uint16 value into slice of byte.
Example ¶
package main import ( "fmt" "math" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { inputs := []uint16{0, 0xab, 0xabc, math.MaxInt16, math.MaxUint16} for _, v := range inputs { out := libbytes.AppendUint16([]byte{}, v) fmt.Printf("%5d => %#04x => %#02v\n", v, v, out) } v := inputs[4] + 1 // MaxUint16 + 1 out := libbytes.AppendUint16([]byte{}, v) fmt.Printf("%5d => %#04x => %#02v\n", v, v, out) }
Output: 0 => 0x0000 => []byte{0x00, 0x00} 171 => 0x00ab => []byte{0x00, 0xab} 2748 => 0x0abc => []byte{0x0a, 0xbc} 32767 => 0x7fff => []byte{0x7f, 0xff} 65535 => 0xffff => []byte{0xff, 0xff} 0 => 0x0000 => []byte{0x00, 0x00}
func AppendUint32 ¶
AppendUint32 append an uint32 value into slice of byte.
Example ¶
package main import ( "fmt" "math" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { inputs := []uint32{0, 0xab, 0xabc, math.MaxInt32, math.MaxUint32} for _, v := range inputs { out := libbytes.AppendUint32([]byte{}, v) fmt.Printf("%11d => %#x => %#v\n", v, v, out) } v := inputs[4] + 2 // MaxUint32 + 2 out := libbytes.AppendUint32([]byte{}, v) fmt.Printf("%11d => %#x => %#v\n", v, v, out) }
Output: 0 => 0x0 => []byte{0x0, 0x0, 0x0, 0x0} 171 => 0xab => []byte{0x0, 0x0, 0x0, 0xab} 2748 => 0xabc => []byte{0x0, 0x0, 0xa, 0xbc} 2147483647 => 0x7fffffff => []byte{0x7f, 0xff, 0xff, 0xff} 4294967295 => 0xffffffff => []byte{0xff, 0xff, 0xff, 0xff} 1 => 0x1 => []byte{0x0, 0x0, 0x0, 0x1}
func AppendUint64 ¶ added in v0.58.0
AppendUint64 append an uint64 value into slice of byte.
Example ¶
package main import ( "fmt" "math" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var listUint64 = []uint64{ math.MaxUint64, math.MaxInt64, 1000, } var ( v uint64 out []byte ) for _, v = range listUint64 { out = libbytes.AppendUint64(nil, v) fmt.Printf("%d\n=> %#x\n=> %#v\n", v, v, out) } }
Output: 18446744073709551615 => 0xffffffffffffffff => []byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 9223372036854775807 => 0x7fffffffffffffff => []byte{0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff} 1000 => 0x3e8 => []byte{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x3, 0xe8}
func Concat ¶
func Concat(args ...interface{}) (out []byte)
Concat merge one or more []byte or string in args into slice of byte. Any type that is not []byte or string in args will be ignored.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Printf("%s\n", libbytes.Concat()) fmt.Printf("%s\n", libbytes.Concat([]byte{})) fmt.Printf("%s\n", libbytes.Concat([]byte{}, []byte("B"))) fmt.Printf("%s\n", libbytes.Concat("with []int:", []int{1, 2})) fmt.Printf("%s\n", libbytes.Concat([]byte("bytes"), " and ", []byte("string"))) fmt.Printf("%s\n", libbytes.Concat([]byte("A"), 1, []int{2}, []byte{}, []byte("C"))) }
Output: B with []int: bytes and string AC
func Copy ¶
Copy slice of bytes from parameter.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { // Copying empty slice. org := []byte{} cp := libbytes.Copy(org) fmt.Printf("%d %q\n", len(cp), cp) org = []byte("slice of life") tmp := org cp = libbytes.Copy(org) fmt.Printf("%d %q\n", len(cp), cp) fmt.Printf("Original address == tmp address: %v\n", &org[0] == &tmp[0]) fmt.Printf("Original address == copy address: %v\n", &org[0] == &cp[0]) }
Output: 0 "" 13 "slice of life" Original address == tmp address: true Original address == copy address: false
func CutUntilToken ¶
func CutUntilToken(text, token []byte, startAt int, checkEsc bool) (cut []byte, pos int, found bool)
CutUntilToken cut text until we found token.
If token found, it will return all bytes before token, position of byte after token, and true.
If no token found, it will return false.
If checkEsc is true, token that is prefixed with escaped character ('\') will be skipped, the escape character will be removed.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte(`\\abc \def \deg`) cut, pos, found := libbytes.CutUntilToken(text, nil, 0, false) fmt.Printf("'%s' %d %t\n", cut, pos, found) cut, pos, found = libbytes.CutUntilToken(text, []byte("def"), 0, false) fmt.Printf("'%s' %d %t\n", cut, pos, found) cut, pos, found = libbytes.CutUntilToken(text, []byte("def"), 0, true) fmt.Printf("'%s' %d %t\n", cut, pos, found) cut, pos, found = libbytes.CutUntilToken(text, []byte("ef"), -1, true) fmt.Printf("'%s' %d %t\n", cut, pos, found) cut, pos, found = libbytes.CutUntilToken(text, []byte("hi"), 0, true) fmt.Printf("'%s' %d %t\n", cut, pos, found) }
Output: '\\abc \def \deg' -1 false '\\abc \' 10 true '\abc def \deg' 15 false '\abc \d' 10 true '\abc \def \deg' 15 false
func DumpPrettyTable ¶
DumpPrettyTable write each byte in slice data as hexadecimal, ASCII character, and integer with 8 columns width.
Example ¶
package main import ( "bytes" "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( data = []byte{1, 2, 3, 'H', 'e', 'l', 'l', 'o', 254, 255} bb bytes.Buffer ) libbytes.DumpPrettyTable(&bb, `DumpPrettyTable`, data) fmt.Println(bb.String()) }
Output: DumpPrettyTable | 0 1 2 3 4 5 6 7 | 01234567 | 0 1 2 3 4 5 6 7 | | 8 9 A B C D E F | 89ABCDEF | 8 9 A B C D E F | 0x00000000| 01 02 03 48 65 6c 6c 6f | ...Hello | 1 2 3 72 101 108 108 111 |0 0x00000008| fe ff | .. | 254 255 |8
func EncloseRemove ¶
EncloseRemove given a text, find the leftToken and rightToken and cut the content in between them and return it with status true. Keep doing it until no more leftToken and rightToken found.
If no leftToken or rightToken is found, it will return text as is and false.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte(`[[ A ]]-[[ B ]] C`) got, isCut := libbytes.EncloseRemove(text, []byte("[["), []byte("]]")) fmt.Printf("'%s' %t\n", got, isCut) got, isCut = libbytes.EncloseRemove(text, []byte("[["), []byte("}}")) fmt.Printf("'%s' %t\n", got, isCut) text = []byte(`// Copyright 2016-2018 "Shulhan <ms@kilabit.info>". All rights reserved.`) got, isCut = libbytes.EncloseRemove(text, []byte("<"), []byte(">")) fmt.Printf("'%s' %t\n", got, isCut) got, isCut = libbytes.EncloseRemove(text, []byte(`"`), []byte(`"`)) fmt.Printf("'%s' %t\n", got, isCut) got, isCut = libbytes.EncloseRemove(text, []byte(`/`), []byte(`/`)) fmt.Printf("'%s' %t\n", got, isCut) text = []byte(`/* TEST */`) got, isCut = libbytes.EncloseRemove(text, []byte(`/*`), []byte(`*/`)) fmt.Printf("'%s' %t\n", got, isCut) }
Output: '- C' true '[[ A ]]-[[ B ]] C' false '// Copyright 2016-2018 "Shulhan ". All rights reserved.' true '// Copyright 2016-2018 . All rights reserved.' true ' Copyright 2016-2018 "Shulhan <ms@kilabit.info>". All rights reserved.' true '' true
func EncloseToken ¶
EncloseToken find "token" in "text" and enclose it with bytes from "leftcap" and "rightcap". If at least one token found, it will return modified text with true status. If no token is found, it will return the same text with false status.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte(`// Copyright 2016-2018 "Shulhan <ms@kilabit.info>". All rights reserved.`) got, isChanged := libbytes.EncloseToken(text, []byte(`"`), []byte(`\`), []byte(`_`)) fmt.Printf("%t '%s'\n", isChanged, got) got, isChanged = libbytes.EncloseToken(text, []byte(`_`), []byte(`-`), []byte(`-`)) fmt.Printf("%t '%s'\n", isChanged, got) got, isChanged = libbytes.EncloseToken(text, []byte(`/`), []byte(`\`), nil) fmt.Printf("%t '%s'\n", isChanged, got) got, isChanged = libbytes.EncloseToken(text, []byte(`<`), []byte(`<`), []byte(` `)) fmt.Printf("%t '%s'\n", isChanged, got) }
Output: true '// Copyright 2016-2018 \"_Shulhan <ms@kilabit.info>\"_. All rights reserved.' false '// Copyright 2016-2018 "Shulhan <ms@kilabit.info>". All rights reserved.' true '\/\/ Copyright 2016-2018 "Shulhan <ms@kilabit.info>". All rights reserved.' true '// Copyright 2016-2018 "Shulhan << ms@kilabit.info>". All rights reserved.'
func InReplace ¶
InReplace replace any characters in "text" that is not in "allowed" with character "c". The replacement occur inside the "text" backing storage, which means the passed "text" will changes and returned.
Example ¶
package main import ( "fmt" "git.sr.ht/~shulhan/pakakeh.go/lib/ascii" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := libbytes.InReplace([]byte{}, []byte(ascii.LettersNumber), '_') fmt.Printf("%q\n", text) text = libbytes.InReplace([]byte("/a/b/c"), []byte(ascii.LettersNumber), '_') fmt.Printf("%q\n", text) _ = libbytes.InReplace(text, []byte(ascii.LettersNumber), '/') fmt.Printf("%q\n", text) }
Output: "" "_a_b_c" "/a/b/c"
func Indexes ¶
Indexes returns the index of the all instance of "token" in "text", or nil if no "token" found.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Println(libbytes.Indexes([]byte(""), []byte("moo"))) fmt.Println(libbytes.Indexes([]byte("moo moomoo"), []byte{})) fmt.Println(libbytes.Indexes([]byte("moo moomoo"), []byte("moo"))) }
Output: [] [] [0 4 7]
func IsTokenAt ¶
IsTokenAt return true if `text` at index `p` match with `token`, otherwise it will return false. Empty token always return false.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte("Hello, world") tokenWorld := []byte("world") tokenWorlds := []byte("worlds") tokenEmpty := []byte{} fmt.Printf("%t\n", libbytes.IsTokenAt(text, tokenEmpty, 6)) fmt.Printf("%t\n", libbytes.IsTokenAt(text, tokenWorld, -1)) fmt.Printf("%t\n", libbytes.IsTokenAt(text, tokenWorld, 6)) fmt.Printf("%t\n", libbytes.IsTokenAt(text, tokenWorld, 7)) fmt.Printf("%t\n", libbytes.IsTokenAt(text, tokenWorld, 8)) fmt.Printf("%t\n", libbytes.IsTokenAt(text, tokenWorlds, 8)) }
Output: false false false true false false
func MergeSpaces ¶
MergeSpaces convert sequences of white spaces into single space ' '.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Printf("%s\n", libbytes.MergeSpaces([]byte(""))) fmt.Printf("%s\n", libbytes.MergeSpaces([]byte(" \t\v\r\n\r\n\fa \t\v\r\n\r\n\f"))) }
Output: a
func ParseHexDump ¶
ParseHexDump parse the default output of hexdump(1) utility from parameter in back into stream of byte.
An example of default output of hexdump is
0000000 7865 5f70 6964 2f72 0000 0000 0000 0000 0000010 0000 0000 0000 0000 0000 0000 0000 0000 * 0000060 0000 0000 3030 3030 3537 0035 3030 3130
The first column is the address and the rest of the column is the data.
Each data column is 16-bit words in big-endian order, so in the above example, the first byte would be 65, second byte is 78 and so on. If parameter networkByteOrder is true, the first byte would be 78, second by is 65, and so on.
The asterisk "*" means that the address from 0000020 to 0000050 is equal to the previous line, 0000010.
Example ¶
package main import ( "fmt" "log" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( in = []byte("0000000 6548 6c6c 2c6f 7720 726f 646c 0021") out []byte err error ) out, err = libbytes.ParseHexDump(in, false) if err != nil { log.Fatal(err) } fmt.Printf(`%s`, libbytes.TrimNull(out)) }
Output: Hello, world!
func PrintHex ¶
PrintHex will print each byte in slice as hexadecimal value into N column length.
Example ¶
package main import ( libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { title := "PrintHex" data := []byte("Hello, world !") libbytes.PrintHex(title, data, 5) }
Output: PrintHex 0 - 48 65 6C 6C 6F || H e l l o 5 - 2C 20 77 6F 72 || , . w o r 10 - 6C 64 20 21 || l d . !
func ReadHexByte ¶
ReadHexByte read two hexadecimal characters from "data" start from index "x" and convert them to byte. It will return the byte and true if its read exactly two hexadecimal characters, otherwise it will return 0 and false.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Println(libbytes.ReadHexByte([]byte{}, 0)) fmt.Println(libbytes.ReadHexByte([]byte("x0"), 0)) fmt.Println(libbytes.ReadHexByte([]byte("00"), 0)) fmt.Println(libbytes.ReadHexByte([]byte("01"), 0)) fmt.Println(libbytes.ReadHexByte([]byte("10"), 0)) fmt.Println(libbytes.ReadHexByte([]byte("1A"), 0)) fmt.Println(libbytes.ReadHexByte([]byte("1a"), 0)) fmt.Println(libbytes.ReadHexByte([]byte("1a"), -1)) }
Output: 0 false 0 false 0 true 1 true 16 true 26 true 26 true 0 false
func ReadInt16 ¶
ReadInt16 read int16 value from "data" start at index "x". It will return 0 if "x" is out of range.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Println(libbytes.ReadInt16([]byte{0x01, 0x02, 0x03, 0x04}, 3)) // x is out of range. fmt.Println(libbytes.ReadInt16([]byte{0x01, 0x02, 0x03, 0x04}, 0)) // 0x0102 fmt.Println(libbytes.ReadInt16([]byte{0x01, 0x02, 0xf0, 0x04}, 2)) // 0xf004 }
Output: 0 258 -4092
func ReadInt32 ¶
ReadInt32 read int32 value from "data" start at index "x". It will return 0 if "x" is out of range.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Println(libbytes.ReadInt32([]byte{0x01, 0x02, 0x03, 0x04}, 1)) // x is out of range. fmt.Println(libbytes.ReadInt32([]byte{0x01, 0x02, 0x03, 0x04}, 0)) // 0x01020304 fmt.Println(libbytes.ReadInt32([]byte{0xf1, 0x02, 0x03, 0x04}, 0)) // 0xf1020304 }
Output: 0 16909060 -251526396
func ReadUint16 ¶
ReadUint16 read uint16 value from "data" start at index "x". If x is out of range, it will return 0.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Println(libbytes.ReadUint16([]byte{0x01, 0x02, 0xf0, 0x04}, 3)) // x is out of range. fmt.Println(libbytes.ReadUint16([]byte{0x01, 0x02, 0xf0, 0x04}, 0)) // 0x0102 fmt.Println(libbytes.ReadUint16([]byte{0x01, 0x02, 0xf0, 0x04}, 2)) // 0xf004 }
Output: 0 258 61444
func ReadUint32 ¶
ReadUint32 read uint32 value from "data" start at index "x". If x is out of range, it will return 0.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { fmt.Println(libbytes.ReadUint32([]byte{0x01, 0x02, 0x03, 0x04}, 1)) // x is out of range. fmt.Println(libbytes.ReadUint32([]byte{0x01, 0x02, 0x03, 0x04}, 0)) // 0x01020304 fmt.Println(libbytes.ReadUint32([]byte{0xf1, 0x02, 0x03, 0x04}, 0)) // 0xf1020304 }
Output: 0 16909060 4043440900
func RemoveSpaces ¶
RemoveSpaces remove all spaces from input in.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( in = []byte(" a\nb\tc d\r") out = libbytes.RemoveSpaces(in) ) fmt.Printf("%s\n", out) }
Output: abcd
func SkipAfterToken ¶
SkipAfterToken skip all bytes until matched "token" is found and return the index after the token and boolean true.
If "checkEsc" is true, token that is prefixed with escaped character '\' will be considered as non-match token.
If no token found it will return -1 and boolean false.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte(`abc \def ghi`) fmt.Println(libbytes.SkipAfterToken(text, []byte("def"), -1, false)) fmt.Println(libbytes.SkipAfterToken(text, []byte("def"), 0, true)) fmt.Println(libbytes.SkipAfterToken(text, []byte("deg"), 0, false)) fmt.Println(libbytes.SkipAfterToken(text, []byte("deg"), 0, true)) fmt.Println(libbytes.SkipAfterToken(text, []byte("ef"), 0, true)) fmt.Println(libbytes.SkipAfterToken(text, []byte("hi"), 0, true)) }
Output: 8 true -1 false -1 false -1 false 8 true 12 true
func SnippetByIndexes ¶
SnippetByIndexes take snippet in between of each index with minimum snippet length. The sniplen is the length before and after index, not the length of all snippet.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { s := []byte("// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved.") indexes := []int{3, 20, len(s) - 4} snippets := libbytes.SnippetByIndexes(s, indexes, 5) for _, snip := range snippets { fmt.Printf("%s\n", snip) } }
Output: // Copyr 18, Shulha reserved.
func SplitEach ¶
SplitEach split the data into n number of bytes. If n is less or equal than zero, it will return the data as chunks.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var data = []byte(`Hello`) fmt.Printf("%s\n", libbytes.SplitEach(data, 0)) fmt.Printf("%s\n", libbytes.SplitEach(data, 1)) fmt.Printf("%s\n", libbytes.SplitEach(data, 2)) fmt.Printf("%s\n", libbytes.SplitEach(data, 5)) fmt.Printf("%s\n", libbytes.SplitEach(data, 10)) }
Output: [Hello] [H e l l o] [He ll o] [Hello] [Hello]
func TokenFind ¶
TokenFind return the first index of matched token in text, start at custom index. If "startat" parameter is less than 0, then it will be set to 0. If token is empty or no token found it will return -1.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte("// Copyright 2018, Shulhan <ms@kilabit.info>. All rights reserved.") fmt.Println(libbytes.TokenFind(text, []byte{}, 0)) fmt.Println(libbytes.TokenFind(text, []byte("right"), -1)) fmt.Println(libbytes.TokenFind(text, []byte("."), 0)) fmt.Println(libbytes.TokenFind(text, []byte("."), 42)) fmt.Println(libbytes.TokenFind(text, []byte("."), 48)) fmt.Println(libbytes.TokenFind(text, []byte("d."), 0)) }
Output: -1 7 38 44 65 64
func TrimNull ¶
TrimNull remove 0 value ("\0" or NULL in C) at leading and trailing of in.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var in = []byte{0, 'H', 'e', 'l', 'l', 'o', 0, 0} in = libbytes.TrimNull(in) fmt.Printf(`%s`, in) }
Output: Hello
func WordIndexes ¶
WordIndexes returns the index of the all instance of word in s as long as word is separated by space or at the beginning or end of s.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { text := []byte("moo moomoo moo") fmt.Println(libbytes.WordIndexes(text, []byte("mo"))) fmt.Println(libbytes.WordIndexes(text, []byte("moo"))) fmt.Println(libbytes.WordIndexes(text, []byte("mooo"))) }
Output: [] [0 11] []
func WriteUint16 ¶
WriteUint16 write uint16 value "v" into "data" start at position "x". If x is out range, the data will not change.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { data := []byte("Hello, world!") var v uint16 v = 'h' << 8 v |= 'E' libbytes.WriteUint16(data, uint(len(data)-1), v) // Index out of range fmt.Println(string(data)) libbytes.WriteUint16(data, 0, v) fmt.Println(string(data)) }
Output: Hello, world! hEllo, world!
func WriteUint32 ¶
WriteUint32 write uint32 value into "data" start at position "x". If x is out range, the data will not change.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { data := []byte("Hello, world!") var v uint32 v = 'h' << 24 v |= 'E' << 16 v |= 'L' << 8 v |= 'L' libbytes.WriteUint32(data, uint(len(data)-1), v) // Index out of range fmt.Println(string(data)) libbytes.WriteUint32(data, 0, v) fmt.Println(string(data)) libbytes.WriteUint32(data, 7, v) fmt.Println(string(data)) }
Output: Hello, world! hELLo, world! hELLo, hELLd!
Types ¶
type Parser ¶
type Parser struct {
// contains filtered or unexported fields
}
Parser implement tokenize parser for stream of byte using one or more delimiters as separator between token.
func (*Parser) AddDelimiters ¶
AddDelimiters add another delimiters to the current parser.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(` a = b ; c = d `) delims = []byte(`=`) parser = libbytes.NewParser(content, delims) ) token, d := parser.ReadNoSpace() fmt.Printf("%s:%c\n", token, d) parser.AddDelimiters([]byte{';'}) token, d = parser.ReadNoSpace() fmt.Printf("%s:%c\n", token, d) }
Output: a:= b:;
func (*Parser) Delimiters ¶
Delimiters return the copy of current delimiters.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a=b;c=d;`) delims = []byte{'=', ';'} parser = libbytes.NewParser(content, delims) ) fmt.Printf("%s\n", parser.Delimiters()) }
Output: =;
func (*Parser) Read ¶
Read read a token until one of the delimiters found. If one of delimiter match, it will return it as d. When end of content encountered, the returned token may be not empty but the d will be zero.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte("a = b; ") delims = []byte{'=', ';'} parser = libbytes.NewParser(content, delims) ) token, c := parser.Read() fmt.Printf("token:'%s' c:%q\n", token, c) token, c = parser.Read() fmt.Printf("token:'%s' c:%q\n", token, c) token, c = parser.Read() fmt.Printf("token:'%s' c:%q\n", token, c) }
Output: token:'a ' c:'=' token:' b' c:';' token:' ' c:'\x00'
func (*Parser) ReadLine ¶
ReadLine read until it found new line ('\n') or end of content, ignoring all delimiters. The returned line will not contain '\n'.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte("a=b;\nc=d;") delims = []byte{'=', ';'} parser = libbytes.NewParser(content, delims) ) token, c := parser.ReadLine() fmt.Printf("token:%s c:%q\n", token, c) token, c = parser.ReadLine() fmt.Printf("token:%s c:%q\n", token, c) }
Output: token:a=b; c:'\n' token:c=d; c:'\x00'
func (*Parser) ReadN ¶
ReadN read exactly n characters ignoring the delimiters. It will return the token and the character after n or 0 if end-of-content.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a=b;c=d;`) delims = []byte{'=', ';'} parser = libbytes.NewParser(content, delims) ) token, c := parser.ReadN(2) fmt.Printf("token:%s c:%q\n", token, c) token, c = parser.ReadN(0) fmt.Printf("token:%s c:%q\n", token, c) token, c = parser.ReadN(10) fmt.Printf("token:%s c:%q\n", token, c) }
Output: token:a= c:'b' token: c:'b' token:b;c=d; c:'\x00'
func (*Parser) ReadNoSpace ¶
ReadNoSpace read the next token by ignoring the leading spaces, even if its one of the delimiter. The returned token will have no trailing spaces.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(` a = b ;`) delims = []byte(`=;`) parser = libbytes.NewParser(content, delims) ) for { token, d := parser.ReadNoSpace() fmt.Printf("%s:%q\n", token, d) if d == 0 { break } } }
Output: a:'=' b:';' :'\x00'
func (*Parser) Remaining ¶
Remaining return the copy of un-parsed content.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(` a = b ;`) delims = []byte(`=;`) parser = libbytes.NewParser(content, delims) ) token, d := parser.ReadNoSpace() remain := parser.Remaining() fmt.Printf("token:%s d:%c remain:%s\n", token, d, remain) }
Output: token:a d:= remain: b ;
func (*Parser) RemoveDelimiters ¶
RemoveDelimiters remove delimiters delims from current delimiters.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(` a = b ; c = d `) delims = []byte(`=;`) parser = libbytes.NewParser(content, delims) ) token, _ := parser.ReadNoSpace() fmt.Printf("%s\n", token) parser.RemoveDelimiters([]byte{';'}) token, _ = parser.ReadNoSpace() fmt.Printf("%s\n", token) }
Output: a b ; c
func (*Parser) Reset ¶
Reset the Parser by setting all internal state to new content and delimiters.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a.b.c;`) delims = []byte(`.`) parser = libbytes.NewParser(content, delims) ) parser.Read() parser.Reset(content, delims) remain, pos := parser.Stop() fmt.Printf("remain:%s pos:%d\n", remain, pos) }
Output: remain:a.b.c; pos:0
func (*Parser) SetDelimiters ¶
SetDelimiters replace the current delimiters with delims.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a.b.c;`) delims = []byte(`.`) parser = libbytes.NewParser(content, delims) token []byte ) token, _ = parser.Read() fmt.Println(string(token)) parser.SetDelimiters([]byte(`;`)) token, _ = parser.Read() fmt.Println(string(token)) }
Output: a b.c
func (*Parser) Skip ¶
Skip skip parsing token until one of the delimiters found or end-of-content.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a = b; c = d;`) delims = []byte{'=', ';'} parser = libbytes.NewParser(content, delims) token []byte ) parser.Skip() token, _ = parser.ReadNoSpace() fmt.Println(string(token)) parser.Skip() token, _ = parser.ReadNoSpace() fmt.Println(string(token)) parser.Skip() token, _ = parser.ReadNoSpace() fmt.Println(string(token)) }
Output: b d
func (*Parser) SkipHorizontalSpaces ¶
SkipHorizontalSpaces skip space (" "), tab ("\t"), carriage return ("\r"), and form feed ("\f") characters; and return the number of space skipped and first non-space character or 0 if it reach end-of-content.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(" \t\r\fA. \nB.") delims = []byte{'.'} parser = libbytes.NewParser(content, delims) n int ) n, _ = parser.SkipHorizontalSpaces() token, d := parser.Read() fmt.Printf("n:%d token:%s delim:%q\n", n, token, d) n, _ = parser.SkipHorizontalSpaces() token, d = parser.Read() // The token include \n. fmt.Printf("n:%d token:%s delim:%q\n", n, token, d) n, _ = parser.SkipHorizontalSpaces() token, d = parser.Read() // The token include \n. fmt.Printf("n:%d token:%s delim:%q\n", n, token, d) }
Output: n:4 token:A delim:'.' n:1 token: B delim:'.' n:0 token: delim:'\x00'
func (*Parser) SkipLine ¶
SkipLine skip all characters until new line. It will return 0 if EOF.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte("a\nb\nc\nd e\n") delims = []byte("\n") parser = libbytes.NewParser(content, delims) ) parser.SkipLine() token, _ := parser.Read() fmt.Printf("token:'%s'\n", token) parser.SkipLine() token, _ = parser.Read() fmt.Printf("token:'%s'\n", token) }
Output: token:'b' token:'d e'
func (*Parser) SkipN ¶
SkipN skip exactly N characters ignoring delimiters. It will return the next character after N or 0 if it reach end-of-content.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a=b;c=d;`) delims = []byte{'=', ';'} parser = libbytes.NewParser(content, delims) token []byte c byte ) c = parser.SkipN(2) fmt.Printf("Skip: %c\n", c) token, _ = parser.ReadNoSpace() fmt.Println(string(token)) c = parser.SkipN(2) fmt.Printf("Skip: %c\n", c) token, _ = parser.ReadNoSpace() fmt.Println(string(token)) _ = parser.SkipN(2) token, _ = parser.ReadNoSpace() fmt.Println(string(token)) }
Output: Skip: b b Skip: d d
func (*Parser) SkipSpaces ¶
SkipSpaces skip all spaces character (' ', '\f', '\n', '\r', '\t') and return the number of spaces skipped and first non-space character or 0 if it reach end-of-content.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(" \t\r\fA. \nB.") delims = []byte{'.'} parser = libbytes.NewParser(content, delims) n int ) n, _ = parser.SkipSpaces() token, d := parser.Read() fmt.Printf("n:%d token:%s delim:%q\n", n, token, d) n, _ = parser.SkipSpaces() token, d = parser.Read() // The token include \n. fmt.Printf("n:%d token:%s delim:%q\n", n, token, d) n, _ = parser.SkipSpaces() token, d = parser.Read() // The token include \n. fmt.Printf("n:%d token:%s delim:%q\n", n, token, d) }
Output: n:4 token:A delim:'.' n:2 token:B delim:'.' n:0 token: delim:'\x00'
func (*Parser) Stop ¶
Stop the parser, return the remaining unparsed content and its last position, and then call Reset to reset the internal state back to zero.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( content = []byte(`a.b.c;`) delims = []byte(`.`) parser = libbytes.NewParser(content, delims) remain []byte pos int ) parser.Read() remain, pos = parser.Stop() fmt.Printf("remain:%s pos:%d\n", remain, pos) parser.Reset(content, []byte(`;`)) parser.Read() remain, pos = parser.Stop() fmt.Printf("remain:%s pos:%d\n", remain, pos) }
Output: remain:b.c; pos:2 remain: pos:6
func (*Parser) UnreadN ¶
UnreadN unread N characters and return the character its pointed to. If N greater than current position index, it will reset the read pointer index back to zero.
Example ¶
package main import ( "fmt" libbytes "git.sr.ht/~shulhan/pakakeh.go/lib/bytes" ) func main() { var ( parser = libbytes.NewParser([]byte(`a,b.c/d`), []byte(`,./`)) token []byte c byte ) parser.Read() parser.Read() parser.Read() parser.Read() // All content should be readed now. c = parser.UnreadN(2) // Move the index to '/'. fmt.Printf("UnreadN(2): %c\n", c) token, c = parser.Read() fmt.Printf("Read: %s %c\n", token, c) // Position 99 greater than current index, this will reset index to 0. c = parser.UnreadN(99) fmt.Printf("UnreadN(99): %c\n", c) token, c = parser.Read() fmt.Printf("Read: %s %c\n", token, c) }
Output: UnreadN(2): / Read: / UnreadN(99): a Read: a ,