Skip to content

Commit 78d62e5

Browse files
authored
Merge pull request #59 from oschwald/greg/prefix-length
Add LookupNetwork method
2 parents 2905694 + 37f6024 commit 78d62e5

File tree

11 files changed

+515
-268
lines changed

11 files changed

+515
-268
lines changed

.golangci.toml

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[run]
2+
deadline = "10m"
3+
tests = true
4+
5+
[linters]
6+
disable-all = true
7+
enable = [
8+
"deadcode",
9+
"depguard",
10+
"errcheck",
11+
"goconst",
12+
"gocyclo",
13+
"gocritic",
14+
"gofmt",
15+
"golint",
16+
"gosec",
17+
"gosimple",
18+
"ineffassign",
19+
"maligned",
20+
"misspell",
21+
"nakedret",
22+
"staticcheck",
23+
"structcheck",
24+
"typecheck",
25+
"unconvert",
26+
"unparam",
27+
"varcheck",
28+
"vet",
29+
"vetshadow",
30+
]

.travis.yml

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,15 @@ matrix:
1717
allow_failures:
1818
- go: tip
1919

20-
before_install:
21-
- "if [[ $TRAVIS_GO_VERSION == 1.11 ]]; then go get -u golang.org/x/lint/golint; fi"
22-
2320
install:
2421
- go get -v -t ./...
2522

23+
before_script:
24+
- |
25+
if [[ $TRAVIS_GO_VERSION == 1.12 && $(arch) != 'ppc64le' ]]; then
26+
curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -b $(go env GOPATH)/bin
27+
fi
28+
2629
script:
2730
- |
2831
if [ $(arch) == "ppc64le" ]; then
@@ -36,7 +39,9 @@ script:
3639
else
3740
go test -race -v -tags appengine
3841
fi
39-
- "if [[ $TRAVIS_GO_VERSION == 1.11 ]]; then go vet ./...; fi"
40-
- "if [[ $TRAVIS_GO_VERSION == 1.11 ]]; then golint .; fi"
42+
- |
43+
if [[ $TRAVIS_GO_VERSION == 1.12 && $(arch) != 'ppc64le' ]]; then
44+
golangci-lint run
45+
fi
4146
4247
sudo: false

decoder.go

Lines changed: 32 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,10 @@ const (
2727
_Uint64
2828
_Uint128
2929
_Slice
30-
_Container
31-
_Marker
30+
// We don't use the next two. They are placeholders. See the spec
31+
// for more details.
32+
_Container // nolint: deadcode, varcheck
33+
_Marker // nolint: deadcode, varcheck
3234
_Bool
3335
_Float32
3436
)
@@ -159,10 +161,8 @@ func (d *decoder) unmarshalBool(size uint, offset uint, result reflect.Value) (u
159161
if size > 1 {
160162
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (bool size of %v)", size)
161163
}
162-
value, newOffset, err := d.decodeBool(size, offset)
163-
if err != nil {
164-
return 0, err
165-
}
164+
value, newOffset := d.decodeBool(size, offset)
165+
166166
switch result.Kind() {
167167
case reflect.Bool:
168168
result.SetBool(value)
@@ -207,10 +207,8 @@ func (d *decoder) indirect(result reflect.Value) reflect.Value {
207207
var sliceType = reflect.TypeOf([]byte{})
208208

209209
func (d *decoder) unmarshalBytes(size uint, offset uint, result reflect.Value) (uint, error) {
210-
value, newOffset, err := d.decodeBytes(size, offset)
211-
if err != nil {
212-
return 0, err
213-
}
210+
value, newOffset := d.decodeBytes(size, offset)
211+
214212
switch result.Kind() {
215213
case reflect.Slice:
216214
if result.Type() == sliceType {
@@ -230,10 +228,7 @@ func (d *decoder) unmarshalFloat32(size uint, offset uint, result reflect.Value)
230228
if size != 4 {
231229
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (float32 size of %v)", size)
232230
}
233-
value, newOffset, err := d.decodeFloat32(size, offset)
234-
if err != nil {
235-
return 0, err
236-
}
231+
value, newOffset := d.decodeFloat32(size, offset)
237232

238233
switch result.Kind() {
239234
case reflect.Float32, reflect.Float64:
@@ -253,10 +248,8 @@ func (d *decoder) unmarshalFloat64(size uint, offset uint, result reflect.Value)
253248
if size != 8 {
254249
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (float 64 size of %v)", size)
255250
}
256-
value, newOffset, err := d.decodeFloat64(size, offset)
257-
if err != nil {
258-
return 0, err
259-
}
251+
value, newOffset := d.decodeFloat64(size, offset)
252+
260253
switch result.Kind() {
261254
case reflect.Float32, reflect.Float64:
262255
if result.OverflowFloat(value) {
@@ -277,10 +270,7 @@ func (d *decoder) unmarshalInt32(size uint, offset uint, result reflect.Value) (
277270
if size > 4 {
278271
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (int32 size of %v)", size)
279272
}
280-
value, newOffset, err := d.decodeInt(size, offset)
281-
if err != nil {
282-
return 0, err
283-
}
273+
value, newOffset := d.decodeInt(size, offset)
284274

285275
switch result.Kind() {
286276
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@@ -360,11 +350,8 @@ func (d *decoder) unmarshalSlice(
360350
}
361351

362352
func (d *decoder) unmarshalString(size uint, offset uint, result reflect.Value) (uint, error) {
363-
value, newOffset, err := d.decodeString(size, offset)
353+
value, newOffset := d.decodeString(size, offset)
364354

365-
if err != nil {
366-
return 0, err
367-
}
368355
switch result.Kind() {
369356
case reflect.String:
370357
result.SetString(value)
@@ -384,10 +371,7 @@ func (d *decoder) unmarshalUint(size uint, offset uint, result reflect.Value, ui
384371
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (uint%v size of %v)", uintType, size)
385372
}
386373

387-
value, newOffset, err := d.decodeUint(size, offset)
388-
if err != nil {
389-
return 0, err
390-
}
374+
value, newOffset := d.decodeUint(size, offset)
391375

392376
switch result.Kind() {
393377
case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
@@ -416,10 +400,7 @@ func (d *decoder) unmarshalUint128(size uint, offset uint, result reflect.Value)
416400
if size > 16 {
417401
return 0, newInvalidDatabaseError("the MaxMind DB file's data section contains bad data (uint128 size of %v)", size)
418402
}
419-
value, newOffset, err := d.decodeUint128(size, offset)
420-
if err != nil {
421-
return 0, err
422-
}
403+
value, newOffset := d.decodeUint128(size, offset)
423404

424405
switch result.Kind() {
425406
case reflect.Struct:
@@ -436,36 +417,36 @@ func (d *decoder) unmarshalUint128(size uint, offset uint, result reflect.Value)
436417
return newOffset, newUnmarshalTypeError(value, result.Type())
437418
}
438419

439-
func (d *decoder) decodeBool(size uint, offset uint) (bool, uint, error) {
440-
return size != 0, offset, nil
420+
func (d *decoder) decodeBool(size uint, offset uint) (bool, uint) {
421+
return size != 0, offset
441422
}
442423

443-
func (d *decoder) decodeBytes(size uint, offset uint) ([]byte, uint, error) {
424+
func (d *decoder) decodeBytes(size uint, offset uint) ([]byte, uint) {
444425
newOffset := offset + size
445426
bytes := make([]byte, size)
446427
copy(bytes, d.buffer[offset:newOffset])
447-
return bytes, newOffset, nil
428+
return bytes, newOffset
448429
}
449430

450-
func (d *decoder) decodeFloat64(size uint, offset uint) (float64, uint, error) {
431+
func (d *decoder) decodeFloat64(size uint, offset uint) (float64, uint) {
451432
newOffset := offset + size
452433
bits := binary.BigEndian.Uint64(d.buffer[offset:newOffset])
453-
return math.Float64frombits(bits), newOffset, nil
434+
return math.Float64frombits(bits), newOffset
454435
}
455436

456-
func (d *decoder) decodeFloat32(size uint, offset uint) (float32, uint, error) {
437+
func (d *decoder) decodeFloat32(size uint, offset uint) (float32, uint) {
457438
newOffset := offset + size
458439
bits := binary.BigEndian.Uint32(d.buffer[offset:newOffset])
459-
return math.Float32frombits(bits), newOffset, nil
440+
return math.Float32frombits(bits), newOffset
460441
}
461442

462-
func (d *decoder) decodeInt(size uint, offset uint) (int, uint, error) {
443+
func (d *decoder) decodeInt(size uint, offset uint) (int, uint) {
463444
newOffset := offset + size
464445
var val int32
465446
for _, b := range d.buffer[offset:newOffset] {
466447
val = (val << 8) | int32(b)
467448
}
468-
return int(val), newOffset, nil
449+
return int(val), newOffset
469450
}
470451

471452
func (d *decoder) decodeMap(
@@ -511,7 +492,7 @@ func (d *decoder) decodePointer(
511492
if pointerSize == 4 {
512493
prefix = 0
513494
} else {
514-
prefix = uint(size & 0x7)
495+
prefix = size & 0x7
515496
}
516497
unpacked := uintFromBytes(prefix, pointerBytes)
517498

@@ -549,9 +530,9 @@ func (d *decoder) decodeSlice(
549530
return offset, nil
550531
}
551532

552-
func (d *decoder) decodeString(size uint, offset uint) (string, uint, error) {
533+
func (d *decoder) decodeString(size uint, offset uint) (string, uint) {
553534
newOffset := offset + size
554-
return string(d.buffer[offset:newOffset]), newOffset, nil
535+
return string(d.buffer[offset:newOffset]), newOffset
555536
}
556537

557538
type fieldsType struct {
@@ -638,23 +619,23 @@ func (d *decoder) decodeStruct(
638619
return offset, nil
639620
}
640621

641-
func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint, error) {
622+
func (d *decoder) decodeUint(size uint, offset uint) (uint64, uint) {
642623
newOffset := offset + size
643624
bytes := d.buffer[offset:newOffset]
644625

645626
var val uint64
646627
for _, b := range bytes {
647628
val = (val << 8) | uint64(b)
648629
}
649-
return val, newOffset, nil
630+
return val, newOffset
650631
}
651632

652-
func (d *decoder) decodeUint128(size uint, offset uint) (*big.Int, uint, error) {
633+
func (d *decoder) decodeUint128(size uint, offset uint) (*big.Int, uint) {
653634
newOffset := offset + size
654635
val := new(big.Int)
655636
val.SetBytes(d.buffer[offset:newOffset])
656637

657-
return val, newOffset, nil
638+
return val, newOffset
658639
}
659640

660641
func uintFromBytes(prefix uint, uintBytes []byte) uint {

decoder_test.go

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"testing"
1010

1111
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
1213
)
1314

1415
func TestBool(t *testing.T) {
@@ -69,9 +70,9 @@ func TestInt32(t *testing.T) {
6970

7071
func TestMap(t *testing.T) {
7172
maps := map[string]interface{}{
72-
"e0": map[string]interface{}{},
73-
"e142656e43466f6f": map[string]interface{}{"en": "Foo"},
74-
"e242656e43466f6f427a6843e4baba": map[string]interface{}{"en": "Foo", "zh": "人"},
73+
"e0": map[string]interface{}{},
74+
"e142656e43466f6f": map[string]interface{}{"en": "Foo"},
75+
"e242656e43466f6f427a6843e4baba": map[string]interface{}{"en": "Foo", "zh": "人"},
7576
"e1446e616d65e242656e43466f6f427a6843e4baba": map[string]interface{}{"name": map[string]interface{}{"en": "Foo", "zh": "人"}},
7677
"e1496c616e677561676573020442656e427a68": map[string]interface{}{"languages": []interface{}{"en", "zh"}},
7778
}
@@ -205,7 +206,7 @@ func validateDecoding(t *testing.T, tests map[string]interface{}) {
205206

206207
var result interface{}
207208
_, err := d.decode(0, reflect.ValueOf(&result), 0)
208-
assert.Nil(t, err)
209+
assert.NoError(t, err)
209210

210211
if !reflect.DeepEqual(result, expected) {
211212
// A big case statement would produce nicer errors
@@ -215,8 +216,8 @@ func validateDecoding(t *testing.T, tests map[string]interface{}) {
215216
}
216217

217218
func TestPointers(t *testing.T) {
218-
bytes, err := ioutil.ReadFile("test-data/test-data/maps-with-pointers.raw")
219-
assert.Nil(t, err)
219+
bytes, err := ioutil.ReadFile(testFile("maps-with-pointers.raw"))
220+
require.NoError(t, err)
220221
d := decoder{bytes}
221222

222223
expected := map[uint]map[string]string{
@@ -231,7 +232,7 @@ func TestPointers(t *testing.T) {
231232
for offset, expectedValue := range expected {
232233
var actual map[string]string
233234
_, err := d.decode(offset, reflect.ValueOf(&actual), 0)
234-
assert.Nil(t, err)
235+
assert.NoError(t, err)
235236
if !reflect.DeepEqual(actual, expectedValue) {
236237
t.Errorf("Decode for pointer at %d failed", offset)
237238
}

node.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package maxminddb
2+
3+
type nodeReader interface {
4+
readLeft(uint) uint
5+
readRight(uint) uint
6+
}
7+
8+
type nodeReader24 struct {
9+
buffer []byte
10+
}
11+
12+
func (n nodeReader24) readLeft(nodeNumber uint) uint {
13+
return (uint(n.buffer[nodeNumber]) << 16) | (uint(n.buffer[nodeNumber+1]) << 8) | uint(n.buffer[nodeNumber+2])
14+
}
15+
16+
func (n nodeReader24) readRight(nodeNumber uint) uint {
17+
return (uint(n.buffer[nodeNumber+3]) << 16) | (uint(n.buffer[nodeNumber+4]) << 8) | uint(n.buffer[nodeNumber+5])
18+
}
19+
20+
type nodeReader28 struct {
21+
buffer []byte
22+
}
23+
24+
func (n nodeReader28) readLeft(nodeNumber uint) uint {
25+
return ((uint(n.buffer[nodeNumber+3]) & 0xF0) << 20) | (uint(n.buffer[nodeNumber]) << 16) | (uint(n.buffer[nodeNumber+1]) << 8) | uint(n.buffer[nodeNumber+2])
26+
}
27+
28+
func (n nodeReader28) readRight(nodeNumber uint) uint {
29+
return ((uint(n.buffer[nodeNumber+3]) & 0x0F) << 24) | (uint(n.buffer[nodeNumber+4]) << 16) | (uint(n.buffer[nodeNumber+5]) << 8) | uint(n.buffer[nodeNumber+6])
30+
}
31+
32+
type nodeReader32 struct {
33+
buffer []byte
34+
}
35+
36+
func (n nodeReader32) readLeft(nodeNumber uint) uint {
37+
return (uint(n.buffer[nodeNumber]) << 24) | (uint(n.buffer[nodeNumber+1]) << 16) | (uint(n.buffer[nodeNumber+2]) << 8) | uint(n.buffer[nodeNumber+3])
38+
}
39+
40+
func (n nodeReader32) readRight(nodeNumber uint) uint {
41+
return (uint(n.buffer[nodeNumber+4]) << 24) | (uint(n.buffer[nodeNumber+5]) << 16) | (uint(n.buffer[nodeNumber+6]) << 8) | uint(n.buffer[nodeNumber+7])
42+
}

0 commit comments

Comments
 (0)