Compare commits

..

2 Commits

Author SHA1 Message Date
Thomas Pelletier 171a592663 Prepare repository for v2.0.0 (#762) 2022-04-27 21:29:16 -04:00
Thomas Pelletier 5aaf5ef13b Fix internal entry size test (#761)
The test meant to assert that the size of entry does not grow beyond
what it is today. 48 is the current size in bytes on x64. On 32-bit
platform that value should be less. As written the test was doing the
opposite comparison.

Fixes #760
2022-04-24 18:50:54 -04:00
4 changed files with 18 additions and 105 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
The MIT License (MIT) The MIT License (MIT)
Copyright (c) 2013 - 2021 Thomas Pelletier, Eric Anderton Copyright (c) 2013 - 2022 Thomas Pelletier, Eric Anderton
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal
-11
View File
@@ -4,17 +4,6 @@ Go library for the [TOML](https://toml.io/en/) format.
This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0). This library supports [TOML v1.0.0](https://toml.io/en/v1.0.0).
## Development status
This is the upcoming major version of go-toml. It is currently in active
development. As of release v2.0.0-beta.1, the library has reached feature parity
with v1, and fixes a lot known bugs and performance issues along the way.
If you do not need the advanced document editing features of v1, you are
encouraged to try out this version.
[👉 Roadmap for v2](https://github.com/pelletier/go-toml/discussions/506)
[🐞 Bug Reports](https://github.com/pelletier/go-toml/issues) [🐞 Bug Reports](https://github.com/pelletier/go-toml/issues)
[💬 Anything else](https://github.com/pelletier/go-toml/discussions) [💬 Anything else](https://github.com/pelletier/go-toml/discussions)
+2 -1
View File
@@ -11,5 +11,6 @@ func TestEntrySize(t *testing.T) {
// Validate no regression on the size of entry{}. This is a critical bit for // Validate no regression on the size of entry{}. This is a critical bit for
// performance of unmarshaling documents. Should only be increased with care // performance of unmarshaling documents. Should only be increased with care
// and a very good reason. // and a very good reason.
require.LessOrEqual(t, 48, int(unsafe.Sizeof(entry{}))) maxExpectedEntrySize := 48
require.LessOrEqual(t, int(unsafe.Sizeof(entry{})), maxExpectedEntrySize)
} }
+15 -92
View File
@@ -230,6 +230,15 @@ func (d *decoder) fromParser(root reflect.Value) error {
return d.p.Error() return d.p.Error()
} }
/*
Rules for the unmarshal code:
- The stack is used to keep track of which values need to be set where.
- handle* functions <=> switch on a given ast.Kind.
- unmarshalX* functions need to unmarshal a node of kind X.
- An "object" is either a struct or a map.
*/
func (d *decoder) handleRootExpression(expr *ast.Node, v reflect.Value) error { func (d *decoder) handleRootExpression(expr *ast.Node, v reflect.Value) error {
var x reflect.Value var x reflect.Value
var err error var err error
@@ -391,84 +400,6 @@ func (d *decoder) handleArrayTableCollection(key ast.Iterator, v reflect.Value)
return d.handleArrayTable(key, v) return d.handleArrayTable(key, v)
} }
func (d *decoder) handleKeyValuePartMapStringInterface(key ast.Iterator, value *ast.Node, m map[string]interface{}) (reflect.Value, error) {
k := string(key.Node().Data)
newMap := false
if m == nil {
newMap = true
m = make(map[string]interface{}, 8)
}
set := false
v, ok := m[k]
if !ok || key.IsLast() {
set = true
v = nil
}
mv := reflect.ValueOf(&v).Elem()
x, err := d.handleKeyValueInner(key, value, mv)
if err != nil {
return reflect.Value{}, err
}
if x.IsValid() {
mv = x
set = true
}
if set {
m[k] = mv.Interface()
}
if newMap {
return reflect.ValueOf(m), nil
}
return reflect.Value{}, nil
}
func (d *decoder) handleKeyPartMapStringInterface(key ast.Iterator, m map[string]interface{}, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
newMap := false
k := string(key.Node().Data)
if m == nil {
newMap = true
m = make(map[string]interface{}, 8)
}
v, ok := m[k]
set := false
if !ok || v == nil {
set = true
v = makeFn().Interface()
}
mv := reflect.ValueOf(v)
x, err := nextFn(key, mv)
if err != nil {
return reflect.Value{}, err
}
if x.IsValid() {
mv = x
set = true
}
if set {
m[k] = mv.Interface()
}
if newMap {
return reflect.ValueOf(m), nil
}
return reflect.Value{}, nil
}
func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) { func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handlerFn, makeFn valueMakerFn) (reflect.Value, error) {
var rv reflect.Value var rv reflect.Value
@@ -485,11 +416,6 @@ func (d *decoder) handleKeyPart(key ast.Iterator, v reflect.Value, nextFn handle
case reflect.Map: case reflect.Map:
vt := v.Type() vt := v.Type()
if vt == mapStringInterfaceType {
m := v.Interface().(map[string]interface{})
return d.handleKeyPartMapStringInterface(key, m, nextFn, makeFn)
}
// Create the key for the map element. Convert to key type. // Create the key for the map element. Convert to key type.
mk := reflect.ValueOf(string(key.Node().Data)).Convert(vt.Key()) mk := reflect.ValueOf(string(key.Node().Data)).Convert(vt.Key())
@@ -1073,11 +999,6 @@ func (d *decoder) handleKeyValuePart(key ast.Iterator, value *ast.Node, v reflec
case reflect.Map: case reflect.Map:
vt := v.Type() vt := v.Type()
if vt == mapStringInterfaceType {
m := v.Interface().(map[string]interface{})
return d.handleKeyValuePartMapStringInterface(key, value, m)
}
mk := reflect.ValueOf(string(key.Node().Data)) mk := reflect.ValueOf(string(key.Node().Data))
mkt := stringType mkt := stringType
@@ -1101,10 +1022,12 @@ func (d *decoder) handleKeyValuePart(key ast.Iterator, value *ast.Node, v reflec
if !mv.IsValid() { if !mv.IsValid() {
set = true set = true
mv = reflect.New(v.Type().Elem()).Elem() mv = reflect.New(v.Type().Elem()).Elem()
} else if key.IsLast() { } else {
var x interface{} if key.IsLast() {
mv = reflect.ValueOf(&x).Elem() var x interface{}
set = true mv = reflect.ValueOf(&x).Elem()
set = true
}
} }
nv, err := d.handleKeyValueInner(key, value, mv) nv, err := d.handleKeyValueInner(key, value, mv)