Skip to content

Commit

Permalink
Merge pull request #144 from oschwald/v2
Browse files Browse the repository at this point in the history
v2
  • Loading branch information
oschwald committed Aug 18, 2024
2 parents 42e7f85 + cb27d1e commit b8ac5c0
Show file tree
Hide file tree
Showing 13 changed files with 699 additions and 541 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/go.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:
name: Build
strategy:
matrix:
go-version: [1.21.x, 1.22.x]
go-version: [1.23.0-rc.1]
platform: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.platform }}
steps:
Expand Down
1 change: 1 addition & 0 deletions .golangci.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ disable = [
"forcetypeassert",
"funlen",
"gochecknoglobals",
"gocognit",
"godox",
"gomnd",
"inamedparam",
Expand Down
80 changes: 78 additions & 2 deletions decoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ const (
_Slice
// We don't use the next two. They are placeholders. See the spec
// for more details.
_Container //nolint: deadcode, varcheck // above
_Marker //nolint: deadcode, varcheck // above
_Container //nolint:deadcode,varcheck // above
_Marker //nolint:deadcode,varcheck // above
_Bool
_Float32
)
Expand Down Expand Up @@ -89,6 +89,82 @@ func (d *decoder) decodeToDeserializer(
return d.decodeFromTypeToDeserializer(typeNum, size, newOffset, dser, depth+1)
}

func (d *decoder) decodePath(
offset uint,
path []any,
result reflect.Value,
) error {
PATH:
for i, v := range path {
var (
typeNum dataType
size uint
err error
)
typeNum, size, offset, err = d.decodeCtrlData(offset)
if err != nil {
return err
}

if typeNum == _Pointer {
pointer, _, err := d.decodePointer(size, offset)
if err != nil {
return err
}

typeNum, size, offset, err = d.decodeCtrlData(pointer)
if err != nil {
return err
}
}

switch v := v.(type) {
case string:
// We are expecting a map
if typeNum != _Map {
// XXX - use type names in errors.
return fmt.Errorf("expected a map for %s but found %d", v, typeNum)
}
for i := uint(0); i < size; i++ {
var key []byte
key, offset, err = d.decodeKey(offset)
if err != nil {
return err
}
if string(key) == v {
continue PATH
}
offset, err = d.nextValueOffset(offset, 1)
if err != nil {
return err
}
}
// Not found. Maybe return a boolean?
return nil
case int:
// We are expecting an array
if typeNum != _Slice {
// XXX - use type names in errors.
return fmt.Errorf("expected a slice for %d but found %d", v, typeNum)
}
if size < uint(v) {
// Slice is smaller than index, not found
return nil
}
// TODO: support negative indexes? Seems useful for subdivisions in
// particular.
offset, err = d.nextValueOffset(offset, uint(v))
if err != nil {
return err
}
default:
return fmt.Errorf("unexpected type for %d value in path, %v: %T", i, v, v)
}
}
_, err := d.decode(offset, result, len(path))
return err
}

func (d *decoder) decodeCtrlData(offset uint) (dataType, uint, uint, error) {
newOffset := offset + 1
if offset >= uint(len(d.buffer)) {
Expand Down
4 changes: 2 additions & 2 deletions decoder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -207,7 +207,7 @@ func validateDecoding(t *testing.T, tests map[string]any) {
for inputStr, expected := range tests {
inputBytes, err := hex.DecodeString(inputStr)
require.NoError(t, err)
d := decoder{inputBytes}
d := decoder{buffer: inputBytes}

var result any
_, err = d.decode(0, reflect.ValueOf(&result), 0)
Expand All @@ -223,7 +223,7 @@ func validateDecoding(t *testing.T, tests map[string]any) {
func TestPointers(t *testing.T) {
bytes, err := os.ReadFile(testFile("maps-with-pointers.raw"))
require.NoError(t, err)
d := decoder{bytes}
d := decoder{buffer: bytes}

expected := map[uint]map[string]string{
0: {"long_key": "long_value1"},
Expand Down
4 changes: 2 additions & 2 deletions deserializer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package maxminddb

import (
"math/big"
"net"
"net/netip"
"testing"

"github.com/stretchr/testify/require"
Expand All @@ -13,7 +13,7 @@ func TestDecodingToDeserializer(t *testing.T) {
require.NoError(t, err, "unexpected error while opening database: %v", err)

dser := testDeserializer{}
err = reader.Lookup(net.ParseIP("::1.1.1.0"), &dser)
err = reader.Lookup(netip.MustParseAddr("::1.1.1.0")).Decode(&dser)
require.NoError(t, err, "unexpected error while doing lookup: %v", err)

checkDecodingToInterface(t, dser.rv)
Expand Down
35 changes: 13 additions & 22 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package maxminddb_test
import (
"fmt"
"log"
"net"
"net/netip"

"github.com/oschwald/maxminddb-golang"
"github.com/oschwald/maxminddb-golang/v2"
)

// This example shows how to decode to a struct.
Expand All @@ -16,15 +16,15 @@ func ExampleReader_Lookup_struct() {
}
defer db.Close()

ip := net.ParseIP("81.2.69.142")
addr := netip.MustParseAddr("81.2.69.142")

var record struct {
Country struct {
ISOCode string `maxminddb:"iso_code"`
} `maxminddb:"country"`
} // Or any appropriate struct

err = db.Lookup(ip, &record)
err = db.Lookup(addr).Decode(&record)
if err != nil {
log.Panic(err)
}
Expand All @@ -41,10 +41,10 @@ func ExampleReader_Lookup_interface() {
}
defer db.Close()

ip := net.ParseIP("81.2.69.142")
addr := netip.MustParseAddr("81.2.69.142")

var record any
err = db.Lookup(ip, &record)
err = db.Lookup(addr).Decode(&record)
if err != nil {
log.Panic(err)
}
Expand All @@ -63,20 +63,16 @@ func ExampleReader_Networks() {
}
defer db.Close()

networks := db.Networks(maxminddb.SkipAliasedNetworks)
for networks.Next() {
for result := range db.Networks() {
record := struct {
Domain string `maxminddb:"connection_type"`
}{}

subnet, err := networks.Network(&record)
err := result.Decode(&record)
if err != nil {
log.Panic(err)
}
fmt.Printf("%s: %s\n", subnet.String(), record.Domain)
}
if networks.Err() != nil {
log.Panic(networks.Err())
fmt.Printf("%s: %s\n", result.Prefix(), record.Domain)
}
// Output:
// 1.0.0.0/24: Cable/DSL
Expand Down Expand Up @@ -114,25 +110,20 @@ func ExampleReader_NetworksWithin() {
}
defer db.Close()

_, network, err := net.ParseCIDR("1.0.0.0/8")
prefix, err := netip.ParsePrefix("1.0.0.0/8")
if err != nil {
log.Panic(err)
}

networks := db.NetworksWithin(network, maxminddb.SkipAliasedNetworks)
for networks.Next() {
for result := range db.NetworksWithin(prefix) {
record := struct {
Domain string `maxminddb:"connection_type"`
}{}

subnet, err := networks.Network(&record)
err := result.Decode(&record)
if err != nil {
log.Panic(err)
}
fmt.Printf("%s: %s\n", subnet.String(), record.Domain)
}
if networks.Err() != nil {
log.Panic(networks.Err())
fmt.Printf("%s: %s\n", result.Prefix(), record.Domain)
}

// Output:
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/oschwald/maxminddb-golang
module github.com/oschwald/maxminddb-golang/v2

go 1.21
go 1.23

require (
github.com/stretchr/testify v1.9.0
Expand Down
Loading

0 comments on commit b8ac5c0

Please sign in to comment.