multicodec.go 1.41 KB
Newer Older
1
package dagjson
2 3

import (
4
	"fmt"
5 6
	"io"

7 8
	"github.com/polydawn/refmt/json"

Eric Myhre's avatar
Eric Myhre committed
9
	"github.com/ipld/go-ipld-prime"
10
	"github.com/ipld/go-ipld-prime/multicodec"
11 12 13
)

var (
Eric Myhre's avatar
Eric Myhre committed
14 15
	_ ipld.Decoder = Decode
	_ ipld.Encoder = Encode
16 17
)

18
func init() {
19 20
	multicodec.RegisterEncoder(0x0129, Encode)
	multicodec.RegisterDecoder(0x0129, Decode)
21 22
}

Eric Myhre's avatar
Eric Myhre committed
23
func Decode(na ipld.NodeAssembler, r io.Reader) error {
Will Scott's avatar
Will Scott committed
24
	err := Unmarshal(na, json.NewDecoder(r), true)
25
	if err != nil {
26
		return err
27 28 29 30 31 32 33 34 35 36 37
	}
	// Slurp any remaining whitespace.
	//  (This is relevant if our reader is tee'ing bytes to a hasher, and
	//   the json contained any trailing whitespace.)
	//  (We can't actually support multiple objects per reader from here;
	//   we can't unpeek if we find a non-whitespace token, so our only
	//    option is to error if this reader seems to contain more content.)
	var buf [1]byte
	for {
		_, err := r.Read(buf[:])
		switch buf[0] {
38
		case ' ', 0x0, '\t', '\r', '\n': // continue
39
		default:
40
			return fmt.Errorf("unexpected content after end of json object")
41 42 43 44
		}
		if err == nil {
			continue
		} else if err == io.EOF {
45
			return nil
46
		} else {
47
			return err
48 49
		}
	}
50 51
}

Eric Myhre's avatar
Eric Myhre committed
52
func Encode(n ipld.Node, w io.Writer) error {
53 54 55
	// Shell out directly to generic inspection path.
	//  (There's not really any fastpaths of note for json.)
	// Write another function if you need to tune encoding options about whitespace.
Rod Vagg's avatar
Rod Vagg committed
56
	return Marshal(n, json.NewEncoder(w, json.EncodeOptions{}), true)
57
}