Skip to content

Commit 61853bd

Browse files
committed
Add a hex wrapper.
1 parent ee35ee5 commit 61853bd

File tree

7 files changed

+297
-1
lines changed

7 files changed

+297
-1
lines changed

hex/README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# hex [![GoDoc](https://godoc.org/github.com/vadv/gopher-lua-libs/hex?status.svg)](https://godoc.org/github.com/vadv/gopher-lua-libs/hex)
2+
3+
Lua module for [encoding/hex](https://pkg.go.dev/encoding/hex)
4+
5+
## Usage
6+
7+
### Encoding
8+
9+
```lua
10+
local hex = require("hex")
11+
12+
s = hex.RawStdEncoding:encode_to_string("foo\01bar")
13+
print(s)
14+
Zm9vAWJhcg
15+
16+
s = hex.StdEncoding:encode_to_string("foo\01bar")
17+
print(s)
18+
Zm9vAWJhcg==
19+
20+
s = hex.RawURLEncoding:encode_to_string("this is a <tag> and should be encoded")
21+
print(s)
22+
dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA
23+
24+
s = hex.URLEncoding:encode_to_string("this is a <tag> and should be encoded")
25+
print(s)
26+
dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA==
27+
28+
```
29+
30+
### Decoding
31+
32+
```lua
33+
local hex = require 'hex'
34+
35+
s, err = hex.decode_string("Zm9vAWJhcg")
36+
assert(not err, err)
37+
print(s)
38+
foobar
39+
40+
s, err = hex.StdEncoding:decode_string("Zm9vAWJhcg==")
41+
assert(not err, err)
42+
print(s)
43+
foobar
44+
45+
s, err = hex.RawURLEncoding:decode_string("dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA")
46+
assert(not err, err)
47+
print(s)
48+
this is a <tag> and should be encoded
49+
50+
s, err = hex.URLEncoding:decode_string("dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA==")
51+
assert(not err, err)
52+
print(s)
53+
this is a <tag> and should be encoded
54+
```

hex/api.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// Package hex implements base64 encode/decode functionality for lua.
2+
package hex
3+
4+
import (
5+
"encoding/hex"
6+
"io"
7+
8+
lio "github.com/vadv/gopher-lua-libs/io"
9+
lua "github.com/yuin/gopher-lua"
10+
)
11+
12+
const (
13+
hexEncoderType = "hex.Encoder"
14+
hexDecoderType = "hex.Decoder"
15+
)
16+
17+
// LVHexEncoder creates a new Lua user data for the hex encoder
18+
func LVHexEncoder(L *lua.LState, writer io.Writer) lua.LValue {
19+
ud := L.NewUserData()
20+
ud.Value = writer
21+
L.SetMetatable(ud, L.GetTypeMetatable(hexEncoderType))
22+
return ud
23+
}
24+
25+
// LVHexDecoder creates a new Lua user data for the hex decoder
26+
func LVHexDecoder(L *lua.LState, reader io.Reader) lua.LValue {
27+
ud := L.NewUserData()
28+
ud.Value = reader
29+
L.SetMetatable(ud, L.GetTypeMetatable(hexDecoderType))
30+
return ud
31+
}
32+
33+
// DecodeString decodes the encoded string with the encoding
34+
func DecodeString(L *lua.LState) int {
35+
encoded := L.CheckString(1)
36+
L.Pop(L.GetTop())
37+
decoded, err := hex.DecodeString(encoded)
38+
if err != nil {
39+
L.Push(lua.LNil)
40+
L.Push(lua.LString(err.Error()))
41+
return 2
42+
}
43+
L.Push(lua.LString(decoded))
44+
return 1
45+
}
46+
47+
// EncodeToString decodes the string with the encoding
48+
func EncodeToString(L *lua.LState) int {
49+
decoded := L.CheckString(1)
50+
L.Pop(L.GetTop())
51+
encoded := hex.EncodeToString([]byte(decoded))
52+
L.Push(lua.LString(encoded))
53+
return 1
54+
}
55+
56+
// registerHexEncoder Registers the encoder type and its methods
57+
func registerHexEncoder(L *lua.LState) {
58+
mt := L.NewTypeMetatable(hexEncoderType)
59+
L.SetGlobal(hexEncoderType, mt)
60+
L.SetField(mt, "__index", lio.WriterFuncTable(L))
61+
}
62+
63+
// registerHexDecoder Registers the decoder type and its methods
64+
func registerHexDecoder(L *lua.LState) {
65+
mt := L.NewTypeMetatable(hexDecoderType)
66+
L.SetGlobal(hexDecoderType, mt)
67+
L.SetField(mt, "__index", lio.ReaderFuncTable(L))
68+
}
69+
70+
func NewEncoder(L *lua.LState) int {
71+
writer := lio.CheckIOWriter(L, 1)
72+
L.Pop(L.GetTop())
73+
encoder := hex.NewEncoder(writer)
74+
L.Push(LVHexEncoder(L, encoder))
75+
return 1
76+
}
77+
78+
func NewDecoder(L *lua.LState) int {
79+
reader := lio.CheckIOReader(L, 1)
80+
L.Pop(L.GetTop())
81+
decoder := hex.NewDecoder(reader)
82+
L.Push(LVHexDecoder(L, decoder))
83+
return 1
84+
}

hex/api_test.go

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package hex
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
"github.com/vadv/gopher-lua-libs/strings"
8+
"github.com/vadv/gopher-lua-libs/tests"
9+
)
10+
11+
func TestApi(t *testing.T) {
12+
preload := tests.SeveralPreloadFuncs(Preload, strings.Preload)
13+
assert.NotZero(t, tests.RunLuaTestFile(t, preload, "./test/test_api.lua"))
14+
}

hex/example_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package hex
2+
3+
import (
4+
"log"
5+
6+
lua "github.com/yuin/gopher-lua"
7+
)
8+
9+
func ExampleEncodeToString() {
10+
state := lua.NewState()
11+
defer state.Close()
12+
Preload(state)
13+
source := `
14+
local base64 = require("base64")
15+
s = base64.RawStdEncoding:encode_to_string("foo\01bar")
16+
print(s)
17+
18+
s = base64.StdEncoding:encode_to_string("foo\01bar")
19+
print(s)
20+
21+
s = base64.RawURLEncoding:encode_to_string("this is a <tag> and should be encoded")
22+
print(s)
23+
24+
s = base64.URLEncoding:encode_to_string("this is a <tag> and should be encoded")
25+
print(s)
26+
27+
`
28+
if err := state.DoString(source); err != nil {
29+
log.Fatal(err.Error())
30+
}
31+
// Output:
32+
// Zm9vAWJhcg
33+
// Zm9vAWJhcg==
34+
// dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA
35+
// dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA==
36+
}
37+
38+
func ExampleDecodeString() {
39+
state := lua.NewState()
40+
defer state.Close()
41+
Preload(state)
42+
source := `
43+
local base64 = require("base64")
44+
s, err = base64.RawStdEncoding:decode_string("Zm9vAWJhcg")
45+
assert(not err, err)
46+
print(s)
47+
48+
s, err = base64.StdEncoding:decode_string("Zm9vAWJhcg==")
49+
assert(not err, err)
50+
print(s)
51+
52+
s, err = base64.RawURLEncoding:decode_string("dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA")
53+
assert(not err, err)
54+
print(s)
55+
56+
s, err = base64.URLEncoding:decode_string("dGhpcyBpcyBhIDx0YWc-IGFuZCBzaG91bGQgYmUgZW5jb2RlZA==")
57+
assert(not err, err)
58+
print(s)
59+
60+
`
61+
if err := state.DoString(source); err != nil {
62+
log.Fatal(err.Error())
63+
}
64+
// Output:
65+
// foobar
66+
// foobar
67+
// this is a <tag> and should be encoded
68+
// this is a <tag> and should be encoded
69+
}

hex/loader.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package hex
2+
3+
import (
4+
lua "github.com/yuin/gopher-lua"
5+
)
6+
7+
// Preload adds yaml to the given Lua state's package.preload table. After it
8+
// has been preloaded, it can be loaded using require:
9+
//
10+
// local yaml = require("yaml")
11+
func Preload(L *lua.LState) {
12+
L.PreloadModule("hex", Loader)
13+
}
14+
15+
// Loader is the module loader function.
16+
func Loader(L *lua.LState) int {
17+
registerHexDecoder(L)
18+
registerHexEncoder(L)
19+
20+
// Register the encodings offered by base64 go module.
21+
t := L.NewTable()
22+
L.SetFuncs(t, map[string]lua.LGFunction{
23+
"decode_string": DecodeString,
24+
"encode_to_string": EncodeToString,
25+
"new_encoder": NewEncoder,
26+
"new_decoder": NewDecoder,
27+
})
28+
L.Push(t)
29+
return 1
30+
}

hex/test/test_api.lua

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
local hex = require 'hex'
2+
local strings = require 'strings'
3+
local assert = require 'assert'
4+
5+
function TestHexCodec(t)
6+
local tests = {
7+
{
8+
encoded = "48656c6c6f20776f726c64", -- "Hello world" in hex
9+
decoded = "Hello world",
10+
},
11+
{
12+
encoded = "",
13+
decoded = "",
14+
},
15+
}
16+
for _, tt in ipairs(tests) do
17+
t:Run("hex.decode_string(" .. tostring(tt.encoded) .. ")", function(t)
18+
local got = hex.decode_string(tt.encoded)
19+
assert:Equal(t, tt.decoded, got)
20+
end)
21+
22+
t:Run("hex.encode_to_string(" .. tostring(tt.decoded) .. ")", function(t)
23+
local got = hex.encode_to_string(tt.decoded)
24+
assert:Equal(t, tt.encoded, got)
25+
end)
26+
end
27+
end
28+
29+
function TestEncoder(t)
30+
local writer = strings.new_builder()
31+
local encoder = hex.new_encoder(writer)
32+
encoder:write("foo", "bar", "baz")
33+
encoder:close()
34+
local s = writer:string()
35+
assert:Equal(t, "666f6f62617262617a", s)
36+
end
37+
38+
function TestDecoder(t)
39+
local reader = strings.new_reader("666f6f62617262617a")
40+
local decoder = hex.new_decoder(reader)
41+
local s = decoder:read("*a")
42+
assert:Equal(t, "foobarbaz", s)
43+
end

plugin/preload.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/vadv/gopher-lua-libs/db"
1313
"github.com/vadv/gopher-lua-libs/filepath"
1414
"github.com/vadv/gopher-lua-libs/goos"
15+
"github.com/vadv/gopher-lua-libs/hex"
1516
"github.com/vadv/gopher-lua-libs/http"
1617
"github.com/vadv/gopher-lua-libs/humanize"
1718
"github.com/vadv/gopher-lua-libs/inspect"
@@ -44,6 +45,7 @@ func PreloadAll(L *lua.LState) {
4445

4546
argparse.Preload(L)
4647
base64.Preload(L)
48+
bit.Preload(L)
4749
cert_util.Preload(L)
4850
chef.Preload(L)
4951
cloudwatch.Preload(L)
@@ -52,6 +54,7 @@ func PreloadAll(L *lua.LState) {
5254
db.Preload(L)
5355
filepath.Preload(L)
5456
goos.Preload(L)
57+
hex.Preload(L)
5558
http.Preload(L)
5659
humanize.Preload(L)
5760
inspect.Preload(L)
@@ -75,5 +78,4 @@ func PreloadAll(L *lua.LState) {
7578
xmlpath.Preload(L)
7679
yaml.Preload(L)
7780
zabbix.Preload(L)
78-
bit.Preload(L)
7981
}

0 commit comments

Comments
 (0)