json_unmarshaller.go 1.69 KB
Newer Older
1 2 3 4 5
package dagjson

import (
	"io"

tavit ohanian's avatar
tavit ohanian committed
6 7
	"gitlab.dms3.io/ld/go-ld-prime/codec/codectools"
	jsontoken "gitlab.dms3.io/ld/go-ld-prime/codec/dagjson2/token"
8 9 10 11 12 13 14 15 16 17 18
)

// Unmarshal reads data from input, parses it as DAG-JSON,
// and unfolds the data into the given NodeAssembler.
//
// The strict interpretation of DAG-JSON is used.
// Use a ReusableMarshaller and set its DecoderConfig if you need
// looser or otherwise customized decoding rules.
//
// This function is the same as the function found for DAG-JSON
// in the default multicodec registry.
tavit ohanian's avatar
tavit ohanian committed
19
func Unmarshal(into ld.NodeAssembler, input io.Reader) error {
20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
	// FUTURE: consider doing a whole sync.Pool jazz around this.
	r := ReusableUnmarshaller{}
	r.SetDecoderConfig(jsontoken.DecoderConfig{
		AllowDanglingComma:  false,
		AllowWhitespace:     false,
		AllowEscapedUnicode: false,
		ParseUtf8C8:         true,
	})
	r.SetInitialBudget(1 << 20)
	return r.Unmarshal(into, input)
}

// ReusableUnmarshaller has an Unmarshal method, and also supports
// customizable DecoderConfig and resource budgets.
//
// The Unmarshal method may be used repeatedly (although not concurrently).
// Keeping a ReusableUnmarshaller around and using it repeatedly may allow
// the user to amortize some allocations (some internal buffers can be reused).
type ReusableUnmarshaller struct {
	d jsontoken.Decoder

41
	InitialBudget int64
42 43 44 45 46
}

func (r *ReusableUnmarshaller) SetDecoderConfig(cfg jsontoken.DecoderConfig) {
	r.d.DecoderConfig = cfg
}
47
func (r *ReusableUnmarshaller) SetInitialBudget(budget int64) {
48 49 50
	r.InitialBudget = budget
}

tavit ohanian's avatar
tavit ohanian committed
51
func (r *ReusableUnmarshaller) Unmarshal(into ld.NodeAssembler, input io.Reader) error {
52 53 54
	r.d.Init(input)
	return codectools.TokenAssemble(into, r.d.Step, r.InitialBudget)
}