diff --git a/data/builder/builder.go b/data/builder/builder.go new file mode 100644 index 0000000..212653d --- /dev/null +++ b/data/builder/builder.go @@ -0,0 +1,143 @@ +package builder + +import ( + "errors" + "strconv" + "time" + + "github.com/ipfs/go-unixfsnode/data" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/fluent/qp" +) + +// BuildUnixFS provides a clean, validated interface to building data structures +// that match the UnixFS protobuf encoded in the Data member of a ProtoNode +// with sensible defaults +// +// smallFileData, err := BuildUnixFS(func(b *Builder) { +// Data(b, []byte{"hello world"}) +// Mtime(b, func(tb TimeBuilder) { +// Time(tb, time.Now()) +// }) +// }) +// +func BuildUnixFS(fn func(*Builder)) (data.UnixFSData, error) { + nd, err := qp.BuildMap(data.Type.UnixFSData, -1, func(ma ipld.MapAssembler) { + b := &Builder{MapAssembler: ma} + fn(b) + if !b.hasBlockSizes { + qp.MapEntry(ma, data.Field__BlockSizes, qp.List(0, func(ipld.ListAssembler) {})) + } + if !b.hasDataType { + qp.MapEntry(ma, data.Field__DataType, qp.Int(data.Data_File)) + } + }) + if err != nil { + return nil, err + } + return nd.(data.UnixFSData), nil +} + +// Builder is an interface for making UnixFS data nodes +type Builder struct { + ipld.MapAssembler + hasDataType bool + hasBlockSizes bool +} + +// DataType sets the default on a builder for a UnixFS node - default is File +func DataType(b *Builder, dataType int64) { + _, ok := data.DataTypeNames[dataType] + if !ok { + panic(data.ErrInvalidDataType{dataType}) + } + qp.MapEntry(b.MapAssembler, data.Field__DataType, qp.Int(dataType)) + b.hasDataType = true +} + +// Data sets the data member inside the UnixFS data +func Data(b *Builder, dataBytes []byte) { + qp.MapEntry(b.MapAssembler, data.Field__Data, qp.Bytes(dataBytes)) +} + +// FileSize sets the file size which should be the size of actual bytes underneath +// this node for large files, w/o additional bytes to encode intermediate nodes +func FileSize(b *Builder, fileSize uint64) { + qp.MapEntry(b.MapAssembler, data.Field__FileSize, qp.Int(int64(fileSize))) +} + +// BlockSizes encodes block sizes for each child node +func BlockSizes(b *Builder, blockSizes []uint64) { + qp.MapEntry(b.MapAssembler, data.Field__BlockSizes, qp.List(int64(len(blockSizes)), func(la ipld.ListAssembler) { + for _, bs := range blockSizes { + qp.ListEntry(la, qp.Int(int64(bs))) + } + })) + b.hasBlockSizes = true +} + +// HashType sets the hash function for this node -- only applicable to HAMT +func HashType(b *Builder, hashType uint64) { + qp.MapEntry(b.MapAssembler, data.Field__HashType, qp.Int(int64(hashType))) +} + +// Fanout sets the fanout in a HAMT tree +func Fanout(b *Builder, fanout uint64) { + qp.MapEntry(b.MapAssembler, data.Field__Fanout, qp.Int(int64(fanout))) +} + +// Permissions sets file permissions for the Mode member of the UnixFS node +func Permissions(b *Builder, mode int) { + mode = mode & 0xFFF + qp.MapEntry(b.MapAssembler, data.Field__Mode, qp.Int(int64(mode))) +} + +func parseModeString(modeString string) (uint64, error) { + if len(modeString) > 0 && modeString[0] == '0' { + return strconv.ParseUint(modeString, 8, 32) + } + return strconv.ParseUint(modeString, 10, 32) +} + +// PermissionsString sets file permissions for the Mode member of the UnixFS node, +// parsed from a typical octect encoded permission string (eg '0755') +func PermissionsString(b *Builder, modeString string) { + mode64, err := parseModeString(modeString) + if err != nil { + panic(err) + } + mode64 = mode64 & 0xFFF + qp.MapEntry(b.MapAssembler, data.Field__Mode, qp.Int(int64(mode64))) +} + +// Mtime sets the modification time for this node using the time builder interface +// and associated methods +func Mtime(b *Builder, fn func(tb TimeBuilder)) { + qp.MapEntry(b.MapAssembler, data.Field__Mtime, qp.Map(-1, func(ma ipld.MapAssembler) { + fn(ma) + })) +} + +// TimeBuilder is a simple interface for constructing the time member of UnixFS data +type TimeBuilder ipld.MapAssembler + +// Time sets the modification time from a golang time value +func Time(ma TimeBuilder, t time.Time) { + Seconds(ma, t.Unix()) + FractionalNanoseconds(ma, int32(t.Nanosecond())) +} + +// Seconds sets the seconds for a modification time +func Seconds(ma TimeBuilder, seconds int64) { + qp.MapEntry(ma, data.Field__Seconds, qp.Int(seconds)) + +} + +// FractionalNanoseconds sets the nanoseconds for a modification time (must +// be between 0 & a billion) +func FractionalNanoseconds(ma TimeBuilder, nanoseconds int32) { + if nanoseconds < 0 || nanoseconds > 999999999 { + panic(errors.New("mtime-nsecs must be within the range [0,999999999]")) + } + qp.MapEntry(ma, data.Field__Nanoseconds, qp.Int(int64(nanoseconds))) +} diff --git a/data/datatypes.go b/data/datatypes.go new file mode 100644 index 0000000..5143848 --- /dev/null +++ b/data/datatypes.go @@ -0,0 +1,40 @@ +package data + +const ( + Data_Raw int64 = 0 + Data_Directory int64 = 1 + Data_File int64 = 2 + Data_Metadata int64 = 3 + Data_Symlink int64 = 4 + Data_HAMTShard int64 = 5 +) + +var DataTypeNames = map[int64]string{ + Data_Raw: "Raw", + Data_Directory: "Directory", + Data_File: "File", + Data_Metadata: "Metadata", + Data_Symlink: "Symlink", + Data_HAMTShard: "HAMTShard", +} + +var DataTypeValues = map[string]int64{ + "Raw": Data_Raw, + "Directory": Data_Directory, + "File": Data_File, + "Metadata": Data_Metadata, + "Symlink": Data_Symlink, + "HAMTShard": Data_HAMTShard, +} + +const Field__DataType = "DataType" +const Field__Data = "Data" +const Field__FileSize = "FileSize" +const Field__BlockSizes = "BlockSizes" +const Field__HashType = "HashType" +const Field__Fanout = "Fanout" +const Field__Mode = "Mode" +const Field__Mtime = "Mtime" +const Field__Seconds = "Seconds" +const Field__Nanoseconds = "FractionalNanoseconds" +const Field__MimeType = "MimeType" diff --git a/data/doc.go b/data/doc.go new file mode 100644 index 0000000..6bb9a49 --- /dev/null +++ b/data/doc.go @@ -0,0 +1,14 @@ +/* +Package data provides tools for working with the UnixFS data structure that +is encoded in the "Data" field of the larger a DagPB encoded IPLD node. + +See https://github.com/ipfs/specs/blob/master/UNIXFS.md for more information +about this data structure. + +This package provides an IPLD Prime compatible node interface for this data +structure, as well as methods for serializing and deserializing the data +structure to protobuf +*/ +package data + +//go:generate go run ./gen diff --git a/data/errors.go b/data/errors.go new file mode 100644 index 0000000..9ef5943 --- /dev/null +++ b/data/errors.go @@ -0,0 +1,43 @@ +package data + +import ( + "fmt" + + "google.golang.org/protobuf/encoding/protowire" +) + +type ErrWrongNodeType struct { + Expected int64 + Actual int64 +} + +func (e ErrWrongNodeType) Error() string { + expectedName, ok := DataTypeNames[e.Expected] + if !ok { + expectedName = "Unknown Type" + } + actualName, ok := DataTypeNames[e.Actual] + if !ok { + actualName = "Unknown Type" + } + return fmt.Sprintf("incorrect Node Type: (UnixFSData) expected type: %s, actual type: %s", expectedName, actualName) +} + +type ErrWrongWireType struct { + Module string + Field string + Expected protowire.Type + Actual protowire.Type +} + +func (e ErrWrongWireType) Error() string { + return fmt.Sprintf("protobuf: (%s) invalid wireType, field: %s, expected %d, got %d", e.Module, e.Field, e.Expected, e.Actual) +} + +type ErrInvalidDataType struct { + DataType int64 +} + +func (e ErrInvalidDataType) Error() string { + return fmt.Sprintf("type: %d is not valid", e.DataType) +} diff --git a/data/fixtures/directory.unixfs b/data/fixtures/directory.unixfs new file mode 100644 index 0000000..e19a122 --- /dev/null +++ b/data/fixtures/directory.unixfs @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/data/fixtures/directory/file.txt b/data/fixtures/directory/file.txt new file mode 100644 index 0000000..551a8b6 --- /dev/null +++ b/data/fixtures/directory/file.txt @@ -0,0 +1 @@ +Hello UnixFS diff --git a/data/fixtures/file.txt b/data/fixtures/file.txt new file mode 100644 index 0000000..551a8b6 --- /dev/null +++ b/data/fixtures/file.txt @@ -0,0 +1 @@ +Hello UnixFS diff --git a/data/fixtures/file.txt.unixfs b/data/fixtures/file.txt.unixfs new file mode 100644 index 0000000..3ea1525 --- /dev/null +++ b/data/fixtures/file.txt.unixfs @@ -0,0 +1,2 @@ + Hello UnixFS + \ No newline at end of file diff --git a/data/fixtures/raw.unixfs b/data/fixtures/raw.unixfs new file mode 100644 index 0000000..3ea1525 --- /dev/null +++ b/data/fixtures/raw.unixfs @@ -0,0 +1,2 @@ + Hello UnixFS + \ No newline at end of file diff --git a/data/fixtures/symlink.txt b/data/fixtures/symlink.txt new file mode 100644 index 0000000..551a8b6 --- /dev/null +++ b/data/fixtures/symlink.txt @@ -0,0 +1 @@ +Hello UnixFS diff --git a/data/fixtures/symlink.txt.unixfs b/data/fixtures/symlink.txt.unixfs new file mode 100644 index 0000000..87cc8aa --- /dev/null +++ b/data/fixtures/symlink.txt.unixfs @@ -0,0 +1 @@ +file.txt \ No newline at end of file diff --git a/data/format_test.go b/data/format_test.go new file mode 100644 index 0000000..776bca3 --- /dev/null +++ b/data/format_test.go @@ -0,0 +1,377 @@ +package data_test + +// adapted from https://github.com/ipfs/js-ipfs-unixfs/blob/master/packages/ipfs-unixfs/test/unixfs-format.spec.js + +import ( + "io/ioutil" + "os" + "path" + "runtime" + "strconv" + "testing" + "time" + + "github.com/ipfs/go-unixfsnode/data" + . "github.com/ipfs/go-unixfsnode/data" + "github.com/ipfs/go-unixfsnode/data/builder" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/fluent/qp" + "github.com/stretchr/testify/require" +) + +func loadFixture(name string) []byte { + _, filename, _, _ := runtime.Caller(0) + + f, err := os.Open(path.Join(path.Dir(filename), "fixtures", name)) + if err != nil { + panic(err) + } + data, err := ioutil.ReadAll(f) + if err != nil { + panic(err) + } + return data +} + +var raw = loadFixture("raw.unixfs") +var directory = loadFixture("directory.unixfs") +var file = loadFixture("file.txt.unixfs") +var symlink = loadFixture("symlink.txt.unixfs") + +func TestUnixfsFormat(t *testing.T) { + t.Run("defaults to file", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(*builder.Builder) {}) + require.NoError(t, err) + require.Equal(t, Data_File, data.FieldDataType().Int()) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("raw", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_Raw) + builder.Data(b, []byte("bananas")) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("directory", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_Directory) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("HAMTShard", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_HAMTShard) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("file", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.Data(b, []byte("batata")) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("file add blocksize", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.BlockSizes(b, []uint64{256}) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("mode", func(t *testing.T) { + mode, err := strconv.ParseInt("0555", 8, 32) + require.NoError(t, err) + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.Permissions(b, int(mode)) + }) + require.NoError(t, err) + unmarshaled, err := DecodeUnixFSData(EncodeUnixFSData(data)) + require.NoError(t, err) + require.True(t, unmarshaled.FieldMode().Exists()) + require.Equal(t, mode, unmarshaled.FieldMode().Must().Int()) + }) + + t.Run("default mode for files", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + }) + require.NoError(t, err) + unmarshaled, err := DecodeUnixFSData(EncodeUnixFSData(data)) + require.NoError(t, err) + + require.Equal(t, 0o0644, unmarshaled.Permissions()) + }) + + t.Run("default mode for directories", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_Directory) + }) + require.NoError(t, err) + unmarshaled, err := DecodeUnixFSData(EncodeUnixFSData(data)) + require.NoError(t, err) + + require.Equal(t, 0o0755, unmarshaled.Permissions()) + }) + + t.Run("default mode for hamt shards", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_HAMTShard) + }) + require.NoError(t, err) + unmarshaled, err := DecodeUnixFSData(EncodeUnixFSData(data)) + require.NoError(t, err) + + require.Equal(t, 0o0755, unmarshaled.Permissions()) + }) + + t.Run("mode as string", func(t *testing.T) { + mode, err := strconv.ParseInt("0555", 8, 32) + require.NoError(t, err) + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.PermissionsString(b, "0555") + }) + require.NoError(t, err) + unmarshaled, err := DecodeUnixFSData(EncodeUnixFSData(data)) + require.NoError(t, err) + require.True(t, unmarshaled.FieldMode().Exists()) + require.Equal(t, mode, unmarshaled.FieldMode().Must().Int()) + }) + + t.Run("mtime", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.Mtime(b, func(tb builder.TimeBuilder) { + builder.Seconds(tb, 5) + }) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldMtime(), data.FieldMtime()) + }) + + t.Run("mtime from time.Time", func(t *testing.T) { + now := time.Now() + seconds := now.Unix() + nanosecond := now.Nanosecond() + + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.Mtime(b, func(tb builder.TimeBuilder) { + builder.Time(tb, now) + }) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.True(t, unmarshaled.FieldMtime().Exists()) + mtime := unmarshaled.FieldMtime().Must() + require.Equal(t, seconds, mtime.FieldSeconds().Int()) + require.True(t, mtime.FieldFractionalNanoseconds().Exists()) + require.Equal(t, int64(nanosecond), mtime.FieldFractionalNanoseconds().Must().Int()) + }) + + t.Run("omits default file mode from protobuf", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.Permissions(b, 0o0644) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + + require.False(t, unmarshaled.FieldMode().Exists()) + require.Equal(t, 0o644, unmarshaled.Permissions()) + + }) + + t.Run("omits default directory mode from protobuf", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_Directory) + builder.Permissions(b, 0o0755) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + + require.False(t, unmarshaled.FieldMode().Exists()) + require.Equal(t, 0o0755, unmarshaled.Permissions()) + }) + + t.Run("respects high bits in mode read from buffer", func(t *testing.T) { + mode := 0o0100644 // similar to output from fs.stat + nd, err := qp.BuildMap(Type.UnixFSData, -1, func(ma ipld.MapAssembler) { + qp.MapEntry(ma, data.Field__DataType, qp.Int(Data_File)) + qp.MapEntry(ma, data.Field__BlockSizes, qp.List(0, func(ipld.ListAssembler) {})) + qp.MapEntry(ma, data.Field__Mode, qp.Int(int64(mode))) + }) + require.NoError(t, err) + und, ok := nd.(UnixFSData) + require.True(t, ok) + + marshaled := EncodeUnixFSData(und) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, 0o0644, unmarshaled.Permissions()) + require.True(t, unmarshaled.FieldMode().Exists()) + require.Equal(t, int64(mode), unmarshaled.FieldMode().Must().Int()) + + }) + + t.Run("ignores high bits in mode passed to constructor", func(t *testing.T) { + mode := 0o0100644 // similar to output from fs.stat + entry, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + builder.Permissions(b, mode) + }) + require.NoError(t, err) + require.True(t, entry.FieldMode().Exists()) + require.Equal(t, 0o644, entry.Permissions()) + // should have truncated mode to bits in the version of the spec this module supports + + marshaled := EncodeUnixFSData(entry) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + + require.False(t, unmarshaled.FieldMode().Exists()) + require.Equal(t, 0o644, unmarshaled.Permissions()) + }) + + // figuring out what is this metadata for https://github.com/ipfs/js-ipfs-data-importing/issues/3#issuecomment-182336526 + t.Run("metadata", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_Metadata) + }) + require.NoError(t, err) + + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + + require.Equal(t, Data_Metadata, unmarshaled.FieldDataType().Int()) + }) + + t.Run("symlink", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_Symlink) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + unmarshaled, err := DecodeUnixFSData(marshaled) + require.NoError(t, err) + require.Equal(t, unmarshaled.FieldDataType(), data.FieldDataType()) + require.Equal(t, unmarshaled.FieldData(), data.FieldData()) + require.Equal(t, unmarshaled.FieldBlockSizes(), data.FieldBlockSizes()) + require.Equal(t, unmarshaled.FieldFileSize(), data.FieldFileSize()) + }) + + t.Run("invalid type", func(t *testing.T) { + _, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, 9999) + }) + require.EqualError(t, err, "type: 9999 is not valid") + }) +} + +func TestInterop(t *testing.T) { + t.Run("raw", func(t *testing.T) { + unmarshaled, err := DecodeUnixFSData(raw) + require.NoError(t, err) + + require.True(t, unmarshaled.FieldData().Exists()) + require.Equal(t, []byte("Hello UnixFS\n"), unmarshaled.FieldData().Must().Bytes()) + require.Equal(t, Data_File, unmarshaled.FieldDataType().Int()) + require.Equal(t, raw, EncodeUnixFSData(unmarshaled)) + }) + + t.Run("directory", func(t *testing.T) { + unmarshaled, err := DecodeUnixFSData(directory) + require.NoError(t, err) + + require.False(t, unmarshaled.FieldData().Exists()) + require.Equal(t, Data_Directory, unmarshaled.FieldDataType().Int()) + require.Equal(t, directory, EncodeUnixFSData(unmarshaled)) + }) + + t.Run("file", func(t *testing.T) { + unmarshaled, err := DecodeUnixFSData(file) + require.NoError(t, err) + + require.True(t, unmarshaled.FieldData().Exists()) + require.Equal(t, []byte("Hello UnixFS\n"), unmarshaled.FieldData().Must().Bytes()) + require.Equal(t, Data_File, unmarshaled.FieldDataType().Int()) + require.Equal(t, file, EncodeUnixFSData(unmarshaled)) + }) + + t.Run("symlink", func(t *testing.T) { + unmarshaled, err := DecodeUnixFSData(symlink) + require.NoError(t, err) + + require.Equal(t, []byte("file.txt"), unmarshaled.FieldData().Must().Bytes()) + require.Equal(t, Data_Symlink, unmarshaled.FieldDataType().Int()) + require.Equal(t, symlink, EncodeUnixFSData(unmarshaled)) + }) + + t.Run("empty", func(t *testing.T) { + data, err := builder.BuildUnixFS(func(b *builder.Builder) { + builder.DataType(b, Data_File) + }) + require.NoError(t, err) + marshaled := EncodeUnixFSData(data) + + require.Equal(t, []byte{0x08, 0x02}, marshaled) + }) +} diff --git a/data/gen/main.go b/data/gen/main.go new file mode 100644 index 0000000..96c6f30 --- /dev/null +++ b/data/gen/main.go @@ -0,0 +1,87 @@ +package main + +import ( + "fmt" + "os" + + "github.com/ipld/go-ipld-prime/schema" + gengo "github.com/ipld/go-ipld-prime/schema/gen/go" +) + +func main() { + ts := schema.TypeSystem{} + ts.Init() + adjCfg := &gengo.AdjunctCfg{} + + pkgName := "data" + + ts.Accumulate(schema.SpawnString("String")) + ts.Accumulate(schema.SpawnInt("Int")) + ts.Accumulate(schema.SpawnBytes("Bytes")) + + ts.Accumulate(schema.SpawnList("BlockSizes", "Int", false)) + + /* + type UnixTime struct { + seconds Int + fractionalNanoseconds Int + } + */ + ts.Accumulate(schema.SpawnStruct("UnixTime", + []schema.StructField{ + schema.SpawnStructField("Seconds", "Int", false, false), + schema.SpawnStructField("FractionalNanoseconds", "Int", true, false), + }, + schema.SpawnStructRepresentationMap(nil), + )) + + /* + type UnixFSData struct { + dataType Int + data optional Bytes + filesize optional Int; + blocksizes [Int] + + hashType optional Int + fanout optional Int + mode optional Int + mtime optional UnixTime + } representation map + */ + + ts.Accumulate(schema.SpawnStruct("UnixFSData", + []schema.StructField{ + schema.SpawnStructField("DataType", "Int", false, false), + schema.SpawnStructField("Data", "Bytes", true, false), + schema.SpawnStructField("FileSize", "Int", true, false), + schema.SpawnStructField("BlockSizes", "BlockSizes", false, false), + schema.SpawnStructField("HashType", "Int", true, false), + schema.SpawnStructField("Fanout", "Int", true, false), + schema.SpawnStructField("Mode", "Int", true, false), + schema.SpawnStructField("Mtime", "UnixTime", true, false), + }, + schema.SpawnStructRepresentationMap(nil), + )) + + /* + type UnixFSMetadata struct { + mimeType optional String + } representation map + */ + + ts.Accumulate(schema.SpawnStruct("UnixFSMetadata", + []schema.StructField{ + schema.SpawnStructField("MimeType", "String", true, false), + }, + schema.SpawnStructRepresentationMap(nil), + )) + + if errs := ts.ValidateGraph(); errs != nil { + for _, err := range errs { + fmt.Printf("- %s\n", err) + } + os.Exit(1) + } + + gengo.Generate(".", pkgName, ts, adjCfg) +} diff --git a/data/ipldsch_minima.go b/data/ipldsch_minima.go new file mode 100644 index 0000000..64b5433 --- /dev/null +++ b/data/ipldsch_minima.go @@ -0,0 +1,50 @@ +package data + +// Code generated by go-ipld-prime gengo. DO NOT EDIT. + +import ( + "fmt" + + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/schema" +) + +const ( + midvalue = schema.Maybe(4) + allowNull = schema.Maybe(5) +) + +type maState uint8 + +const ( + maState_initial maState = iota + maState_midKey + maState_expectValue + maState_midValue + maState_finished +) + +type laState uint8 + +const ( + laState_initial laState = iota + laState_midValue + laState_finished +) +type _ErrorThunkAssembler struct { + e error +} + +func (ea _ErrorThunkAssembler) BeginMap(_ int64) (ipld.MapAssembler, error) { return nil, ea.e } +func (ea _ErrorThunkAssembler) BeginList(_ int64) (ipld.ListAssembler, error) { return nil, ea.e } +func (ea _ErrorThunkAssembler) AssignNull() error { return ea.e } +func (ea _ErrorThunkAssembler) AssignBool(bool) error { return ea.e } +func (ea _ErrorThunkAssembler) AssignInt(int64) error { return ea.e } +func (ea _ErrorThunkAssembler) AssignFloat(float64) error { return ea.e } +func (ea _ErrorThunkAssembler) AssignString(string) error { return ea.e } +func (ea _ErrorThunkAssembler) AssignBytes([]byte) error { return ea.e } +func (ea _ErrorThunkAssembler) AssignLink(ipld.Link) error { return ea.e } +func (ea _ErrorThunkAssembler) AssignNode(ipld.Node) error { return ea.e } +func (ea _ErrorThunkAssembler) Prototype() ipld.NodePrototype { + panic(fmt.Errorf("cannot get prototype from error-carrying assembler: already derailed with error: %w", ea.e)) +} diff --git a/data/ipldsch_satisfaction.go b/data/ipldsch_satisfaction.go new file mode 100644 index 0000000..f12024f --- /dev/null +++ b/data/ipldsch_satisfaction.go @@ -0,0 +1,4500 @@ +package data + +// Code generated by go-ipld-prime gengo. DO NOT EDIT. + +import ( + ipld "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/node/mixins" + "github.com/ipld/go-ipld-prime/schema" +) + +func (n *_BlockSizes) Lookup(idx int64) Int { + if n.Length() <= idx { + return nil + } + v := &n.x[idx] + return v +} +func (n *_BlockSizes) LookupMaybe(idx int64) MaybeInt { + if n.Length() <= idx { + return nil + } + v := &n.x[idx] + return &_Int__Maybe{ + m: schema.Maybe_Value, + v: v, + } +} + +var _BlockSizes__valueAbsent = _Int__Maybe{m:schema.Maybe_Absent} +func (n BlockSizes) Iterator() *BlockSizes__Itr { + return &BlockSizes__Itr{n, 0} +} + +type BlockSizes__Itr struct { + n BlockSizes + idx int +} + +func (itr *BlockSizes__Itr) Next() (idx int64, v Int) { + if itr.idx >= len(itr.n.x) { + return -1, nil + } + idx = int64(itr.idx) + v = &itr.n.x[itr.idx] + itr.idx++ + return +} +func (itr *BlockSizes__Itr) Done() bool { + return itr.idx >= len(itr.n.x) +} + +type _BlockSizes__Maybe struct { + m schema.Maybe + v BlockSizes +} +type MaybeBlockSizes = *_BlockSizes__Maybe + +func (m MaybeBlockSizes) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeBlockSizes) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeBlockSizes) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeBlockSizes) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeBlockSizes) Must() BlockSizes { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var _ ipld.Node = (BlockSizes)(&_BlockSizes{}) +var _ schema.TypedNode = (BlockSizes)(&_BlockSizes{}) +func (BlockSizes) Kind() ipld.Kind { + return ipld.Kind_List +} +func (BlockSizes) LookupByString(string) (ipld.Node, error) { + return mixins.List{"data.BlockSizes"}.LookupByString("") +} +func (n BlockSizes) LookupByNode(k ipld.Node) (ipld.Node, error) { + idx, err := k.AsInt() + if err != nil { + return nil, err + } + return n.LookupByIndex(idx) +} +func (n BlockSizes) LookupByIndex(idx int64) (ipld.Node, error) { + if n.Length() <= idx { + return nil, ipld.ErrNotExists{Segment: ipld.PathSegmentOfInt(idx)} + } + v := &n.x[idx] + return v, nil +} +func (n BlockSizes) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + i, err := seg.Index() + if err != nil { + return nil, ipld.ErrInvalidSegmentForList{TypeName: "data.BlockSizes", TroubleSegment: seg, Reason: err} + } + return n.LookupByIndex(i) +} +func (BlockSizes) MapIterator() ipld.MapIterator { + return nil +} +func (n BlockSizes) ListIterator() ipld.ListIterator { + return &_BlockSizes__ListItr{n, 0} +} + +type _BlockSizes__ListItr struct { + n BlockSizes + idx int +} + +func (itr *_BlockSizes__ListItr) Next() (idx int64, v ipld.Node, _ error) { + if itr.idx >= len(itr.n.x) { + return -1, nil, ipld.ErrIteratorOverread{} + } + idx = int64(itr.idx) + x := &itr.n.x[itr.idx] + v = x + itr.idx++ + return +} +func (itr *_BlockSizes__ListItr) Done() bool { + return itr.idx >= len(itr.n.x) +} + +func (n BlockSizes) Length() int64 { + return int64(len(n.x)) +} +func (BlockSizes) IsAbsent() bool { + return false +} +func (BlockSizes) IsNull() bool { + return false +} +func (BlockSizes) AsBool() (bool, error) { + return mixins.List{"data.BlockSizes"}.AsBool() +} +func (BlockSizes) AsInt() (int64, error) { + return mixins.List{"data.BlockSizes"}.AsInt() +} +func (BlockSizes) AsFloat() (float64, error) { + return mixins.List{"data.BlockSizes"}.AsFloat() +} +func (BlockSizes) AsString() (string, error) { + return mixins.List{"data.BlockSizes"}.AsString() +} +func (BlockSizes) AsBytes() ([]byte, error) { + return mixins.List{"data.BlockSizes"}.AsBytes() +} +func (BlockSizes) AsLink() (ipld.Link, error) { + return mixins.List{"data.BlockSizes"}.AsLink() +} +func (BlockSizes) Prototype() ipld.NodePrototype { + return _BlockSizes__Prototype{} +} +type _BlockSizes__Prototype struct{} + +func (_BlockSizes__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _BlockSizes__Builder + nb.Reset() + return &nb +} +type _BlockSizes__Builder struct { + _BlockSizes__Assembler +} +func (nb *_BlockSizes__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_BlockSizes__Builder) Reset() { + var w _BlockSizes + var m schema.Maybe + *nb = _BlockSizes__Builder{_BlockSizes__Assembler{w: &w, m: &m}} +} +type _BlockSizes__Assembler struct { + w *_BlockSizes + m *schema.Maybe + state laState + + cm schema.Maybe + va _Int__Assembler +} + +func (na *_BlockSizes__Assembler) reset() { + na.state = laState_initial + na.va.reset() +} +func (_BlockSizes__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.ListAssembler{"data.BlockSizes"}.BeginMap(0) +} +func (na *_BlockSizes__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if sizeHint < 0 { + sizeHint = 0 + } + if na.w == nil { + na.w = &_BlockSizes{} + } + if sizeHint > 0 { + na.w.x = make([]_Int, 0, sizeHint) + } + return na, nil +} +func (na *_BlockSizes__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.ListAssembler{"data.BlockSizes"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_BlockSizes__Assembler) AssignBool(bool) error { + return mixins.ListAssembler{"data.BlockSizes"}.AssignBool(false) +} +func (_BlockSizes__Assembler) AssignInt(int64) error { + return mixins.ListAssembler{"data.BlockSizes"}.AssignInt(0) +} +func (_BlockSizes__Assembler) AssignFloat(float64) error { + return mixins.ListAssembler{"data.BlockSizes"}.AssignFloat(0) +} +func (_BlockSizes__Assembler) AssignString(string) error { + return mixins.ListAssembler{"data.BlockSizes"}.AssignString("") +} +func (_BlockSizes__Assembler) AssignBytes([]byte) error { + return mixins.ListAssembler{"data.BlockSizes"}.AssignBytes(nil) +} +func (_BlockSizes__Assembler) AssignLink(ipld.Link) error { + return mixins.ListAssembler{"data.BlockSizes"}.AssignLink(nil) +} +func (na *_BlockSizes__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_BlockSizes); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_List { + return ipld.ErrWrongKind{TypeName: "data.BlockSizes", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustList, ActualKind: v.Kind()} + } + itr := v.ListIterator() + for !itr.Done() { + _, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_BlockSizes__Assembler) Prototype() ipld.NodePrototype { + return _BlockSizes__Prototype{} +} +func (la *_BlockSizes__Assembler) valueFinishTidy() bool { + switch la.cm { + case schema.Maybe_Value: + la.va.w = nil + la.cm = schema.Maybe_Absent + la.state = laState_initial + la.va.reset() + return true + default: + return false + } +} +func (la *_BlockSizes__Assembler) AssembleValue() ipld.NodeAssembler { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: AssembleValue cannot be called when still in the middle of assembling the previous value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + la.w.x = append(la.w.x, _Int{}) + la.state = laState_midValue + row := &la.w.x[len(la.w.x)-1] + la.va.w = row + la.va.m = &la.cm + return &la.va +} +func (la *_BlockSizes__Assembler) Finish() error { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + la.state = laState_finished + *la.m = schema.Maybe_Value + return nil +} +func (la *_BlockSizes__Assembler) ValuePrototype(_ int64) ipld.NodePrototype { + return _Int__Prototype{} +} +func (BlockSizes) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n BlockSizes) Representation() ipld.Node { + return (*_BlockSizes__Repr)(n) +} +type _BlockSizes__Repr _BlockSizes +var _ ipld.Node = &_BlockSizes__Repr{} +func (_BlockSizes__Repr) Kind() ipld.Kind { + return ipld.Kind_List +} +func (_BlockSizes__Repr) LookupByString(string) (ipld.Node, error) { + return mixins.List{"data.BlockSizes.Repr"}.LookupByString("") +} +func (nr *_BlockSizes__Repr) LookupByNode(k ipld.Node) (ipld.Node, error) { + v, err := (BlockSizes)(nr).LookupByNode(k) + if err != nil || v == ipld.Null { + return v, err + } + return v.(Int).Representation(), nil +} +func (nr *_BlockSizes__Repr) LookupByIndex(idx int64) (ipld.Node, error) { + v, err := (BlockSizes)(nr).LookupByIndex(idx) + if err != nil || v == ipld.Null { + return v, err + } + return v.(Int).Representation(), nil +} +func (n _BlockSizes__Repr) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + i, err := seg.Index() + if err != nil { + return nil, ipld.ErrInvalidSegmentForList{TypeName: "data.BlockSizes.Repr", TroubleSegment: seg, Reason: err} + } + return n.LookupByIndex(i) +} +func (_BlockSizes__Repr) MapIterator() ipld.MapIterator { + return nil +} +func (nr *_BlockSizes__Repr) ListIterator() ipld.ListIterator { + return &_BlockSizes__ReprListItr{(BlockSizes)(nr), 0} +} + +type _BlockSizes__ReprListItr _BlockSizes__ListItr + +func (itr *_BlockSizes__ReprListItr) Next() (idx int64, v ipld.Node, err error) { + idx, v, err = (*_BlockSizes__ListItr)(itr).Next() + if err != nil || v == ipld.Null { + return + } + return idx, v.(Int).Representation(), nil +} +func (itr *_BlockSizes__ReprListItr) Done() bool { + return (*_BlockSizes__ListItr)(itr).Done() +} + +func (rn *_BlockSizes__Repr) Length() int64 { + return int64(len(rn.x)) +} +func (_BlockSizes__Repr) IsAbsent() bool { + return false +} +func (_BlockSizes__Repr) IsNull() bool { + return false +} +func (_BlockSizes__Repr) AsBool() (bool, error) { + return mixins.List{"data.BlockSizes.Repr"}.AsBool() +} +func (_BlockSizes__Repr) AsInt() (int64, error) { + return mixins.List{"data.BlockSizes.Repr"}.AsInt() +} +func (_BlockSizes__Repr) AsFloat() (float64, error) { + return mixins.List{"data.BlockSizes.Repr"}.AsFloat() +} +func (_BlockSizes__Repr) AsString() (string, error) { + return mixins.List{"data.BlockSizes.Repr"}.AsString() +} +func (_BlockSizes__Repr) AsBytes() ([]byte, error) { + return mixins.List{"data.BlockSizes.Repr"}.AsBytes() +} +func (_BlockSizes__Repr) AsLink() (ipld.Link, error) { + return mixins.List{"data.BlockSizes.Repr"}.AsLink() +} +func (_BlockSizes__Repr) Prototype() ipld.NodePrototype { + return _BlockSizes__ReprPrototype{} +} +type _BlockSizes__ReprPrototype struct{} + +func (_BlockSizes__ReprPrototype) NewBuilder() ipld.NodeBuilder { + var nb _BlockSizes__ReprBuilder + nb.Reset() + return &nb +} +type _BlockSizes__ReprBuilder struct { + _BlockSizes__ReprAssembler +} +func (nb *_BlockSizes__ReprBuilder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_BlockSizes__ReprBuilder) Reset() { + var w _BlockSizes + var m schema.Maybe + *nb = _BlockSizes__ReprBuilder{_BlockSizes__ReprAssembler{w: &w, m: &m}} +} +type _BlockSizes__ReprAssembler struct { + w *_BlockSizes + m *schema.Maybe + state laState + + cm schema.Maybe + va _Int__ReprAssembler +} + +func (na *_BlockSizes__ReprAssembler) reset() { + na.state = laState_initial + na.va.reset() +} +func (_BlockSizes__ReprAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.BeginMap(0) +} +func (na *_BlockSizes__ReprAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if sizeHint < 0 { + sizeHint = 0 + } + if na.w == nil { + na.w = &_BlockSizes{} + } + if sizeHint > 0 { + na.w.x = make([]_Int, 0, sizeHint) + } + return na, nil +} +func (na *_BlockSizes__ReprAssembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.ListAssembler{"data.BlockSizes.Repr.Repr"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_BlockSizes__ReprAssembler) AssignBool(bool) error { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.AssignBool(false) +} +func (_BlockSizes__ReprAssembler) AssignInt(int64) error { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.AssignInt(0) +} +func (_BlockSizes__ReprAssembler) AssignFloat(float64) error { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.AssignFloat(0) +} +func (_BlockSizes__ReprAssembler) AssignString(string) error { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.AssignString("") +} +func (_BlockSizes__ReprAssembler) AssignBytes([]byte) error { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.AssignBytes(nil) +} +func (_BlockSizes__ReprAssembler) AssignLink(ipld.Link) error { + return mixins.ListAssembler{"data.BlockSizes.Repr"}.AssignLink(nil) +} +func (na *_BlockSizes__ReprAssembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_BlockSizes); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_List { + return ipld.ErrWrongKind{TypeName: "data.BlockSizes.Repr", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustList, ActualKind: v.Kind()} + } + itr := v.ListIterator() + for !itr.Done() { + _, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_BlockSizes__ReprAssembler) Prototype() ipld.NodePrototype { + return _BlockSizes__ReprPrototype{} +} +func (la *_BlockSizes__ReprAssembler) valueFinishTidy() bool { + switch la.cm { + case schema.Maybe_Value: + la.va.w = nil + la.cm = schema.Maybe_Absent + la.state = laState_initial + la.va.reset() + return true + default: + return false + } +} +func (la *_BlockSizes__ReprAssembler) AssembleValue() ipld.NodeAssembler { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: AssembleValue cannot be called when still in the middle of assembling the previous value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + la.w.x = append(la.w.x, _Int{}) + la.state = laState_midValue + row := &la.w.x[len(la.w.x)-1] + la.va.w = row + la.va.m = &la.cm + return &la.va +} +func (la *_BlockSizes__ReprAssembler) Finish() error { + switch la.state { + case laState_initial: + // carry on + case laState_midValue: + if !la.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case laState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + la.state = laState_finished + *la.m = schema.Maybe_Value + return nil +} +func (la *_BlockSizes__ReprAssembler) ValuePrototype(_ int64) ipld.NodePrototype { + return _Int__ReprPrototype{} +} + +func (n Bytes) Bytes() []byte { + return n.x +} +func (_Bytes__Prototype) FromBytes(v []byte) (Bytes, error) { + n := _Bytes{v} + return &n, nil +} +type _Bytes__Maybe struct { + m schema.Maybe + v Bytes +} +type MaybeBytes = *_Bytes__Maybe + +func (m MaybeBytes) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeBytes) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeBytes) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeBytes) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeBytes) Must() Bytes { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var _ ipld.Node = (Bytes)(&_Bytes{}) +var _ schema.TypedNode = (Bytes)(&_Bytes{}) +func (Bytes) Kind() ipld.Kind { + return ipld.Kind_Bytes +} +func (Bytes) LookupByString(string) (ipld.Node, error) { + return mixins.Bytes{"data.Bytes"}.LookupByString("") +} +func (Bytes) LookupByNode(ipld.Node) (ipld.Node, error) { + return mixins.Bytes{"data.Bytes"}.LookupByNode(nil) +} +func (Bytes) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Bytes{"data.Bytes"}.LookupByIndex(0) +} +func (Bytes) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return mixins.Bytes{"data.Bytes"}.LookupBySegment(seg) +} +func (Bytes) MapIterator() ipld.MapIterator { + return nil +} +func (Bytes) ListIterator() ipld.ListIterator { + return nil +} +func (Bytes) Length() int64 { + return -1 +} +func (Bytes) IsAbsent() bool { + return false +} +func (Bytes) IsNull() bool { + return false +} +func (Bytes) AsBool() (bool, error) { + return mixins.Bytes{"data.Bytes"}.AsBool() +} +func (Bytes) AsInt() (int64, error) { + return mixins.Bytes{"data.Bytes"}.AsInt() +} +func (Bytes) AsFloat() (float64, error) { + return mixins.Bytes{"data.Bytes"}.AsFloat() +} +func (Bytes) AsString() (string, error) { + return mixins.Bytes{"data.Bytes"}.AsString() +} +func (n Bytes) AsBytes() ([]byte, error) { + return n.x, nil +} +func (Bytes) AsLink() (ipld.Link, error) { + return mixins.Bytes{"data.Bytes"}.AsLink() +} +func (Bytes) Prototype() ipld.NodePrototype { + return _Bytes__Prototype{} +} +type _Bytes__Prototype struct{} + +func (_Bytes__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _Bytes__Builder + nb.Reset() + return &nb +} +type _Bytes__Builder struct { + _Bytes__Assembler +} +func (nb *_Bytes__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_Bytes__Builder) Reset() { + var w _Bytes + var m schema.Maybe + *nb = _Bytes__Builder{_Bytes__Assembler{w: &w, m: &m}} +} +type _Bytes__Assembler struct { + w *_Bytes + m *schema.Maybe +} + +func (na *_Bytes__Assembler) reset() {} +func (_Bytes__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.BytesAssembler{"data.Bytes"}.BeginMap(0) +} +func (_Bytes__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.BytesAssembler{"data.Bytes"}.BeginList(0) +} +func (na *_Bytes__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.BytesAssembler{"data.Bytes"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + panic("unreachable") +} +func (_Bytes__Assembler) AssignBool(bool) error { + return mixins.BytesAssembler{"data.Bytes"}.AssignBool(false) +} +func (_Bytes__Assembler) AssignInt(int64) error { + return mixins.BytesAssembler{"data.Bytes"}.AssignInt(0) +} +func (_Bytes__Assembler) AssignFloat(float64) error { + return mixins.BytesAssembler{"data.Bytes"}.AssignFloat(0) +} +func (_Bytes__Assembler) AssignString(string) error { + return mixins.BytesAssembler{"data.Bytes"}.AssignString("") +} +func (na *_Bytes__Assembler) AssignBytes(v []byte) error { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + if na.w == nil { + na.w = &_Bytes{} + } + na.w.x = v + *na.m = schema.Maybe_Value + return nil +} +func (_Bytes__Assembler) AssignLink(ipld.Link) error { + return mixins.BytesAssembler{"data.Bytes"}.AssignLink(nil) +} +func (na *_Bytes__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_Bytes); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v2, err := v.AsBytes(); err != nil { + return err + } else { + return na.AssignBytes(v2) + } +} +func (_Bytes__Assembler) Prototype() ipld.NodePrototype { + return _Bytes__Prototype{} +} +func (Bytes) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n Bytes) Representation() ipld.Node { + return (*_Bytes__Repr)(n) +} +type _Bytes__Repr = _Bytes +var _ ipld.Node = &_Bytes__Repr{} +type _Bytes__ReprPrototype = _Bytes__Prototype +type _Bytes__ReprAssembler = _Bytes__Assembler + +func (n Int) Int() int64 { + return n.x +} +func (_Int__Prototype) FromInt(v int64) (Int, error) { + n := _Int{v} + return &n, nil +} +type _Int__Maybe struct { + m schema.Maybe + v Int +} +type MaybeInt = *_Int__Maybe + +func (m MaybeInt) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeInt) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeInt) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeInt) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeInt) Must() Int { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var _ ipld.Node = (Int)(&_Int{}) +var _ schema.TypedNode = (Int)(&_Int{}) +func (Int) Kind() ipld.Kind { + return ipld.Kind_Int +} +func (Int) LookupByString(string) (ipld.Node, error) { + return mixins.Int{"data.Int"}.LookupByString("") +} +func (Int) LookupByNode(ipld.Node) (ipld.Node, error) { + return mixins.Int{"data.Int"}.LookupByNode(nil) +} +func (Int) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Int{"data.Int"}.LookupByIndex(0) +} +func (Int) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return mixins.Int{"data.Int"}.LookupBySegment(seg) +} +func (Int) MapIterator() ipld.MapIterator { + return nil +} +func (Int) ListIterator() ipld.ListIterator { + return nil +} +func (Int) Length() int64 { + return -1 +} +func (Int) IsAbsent() bool { + return false +} +func (Int) IsNull() bool { + return false +} +func (Int) AsBool() (bool, error) { + return mixins.Int{"data.Int"}.AsBool() +} +func (n Int) AsInt() (int64, error) { + return n.x, nil +} +func (Int) AsFloat() (float64, error) { + return mixins.Int{"data.Int"}.AsFloat() +} +func (Int) AsString() (string, error) { + return mixins.Int{"data.Int"}.AsString() +} +func (Int) AsBytes() ([]byte, error) { + return mixins.Int{"data.Int"}.AsBytes() +} +func (Int) AsLink() (ipld.Link, error) { + return mixins.Int{"data.Int"}.AsLink() +} +func (Int) Prototype() ipld.NodePrototype { + return _Int__Prototype{} +} +type _Int__Prototype struct{} + +func (_Int__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _Int__Builder + nb.Reset() + return &nb +} +type _Int__Builder struct { + _Int__Assembler +} +func (nb *_Int__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_Int__Builder) Reset() { + var w _Int + var m schema.Maybe + *nb = _Int__Builder{_Int__Assembler{w: &w, m: &m}} +} +type _Int__Assembler struct { + w *_Int + m *schema.Maybe +} + +func (na *_Int__Assembler) reset() {} +func (_Int__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.IntAssembler{"data.Int"}.BeginMap(0) +} +func (_Int__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.IntAssembler{"data.Int"}.BeginList(0) +} +func (na *_Int__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.IntAssembler{"data.Int"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + panic("unreachable") +} +func (_Int__Assembler) AssignBool(bool) error { + return mixins.IntAssembler{"data.Int"}.AssignBool(false) +} +func (na *_Int__Assembler) AssignInt(v int64) error { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + if na.w == nil { + na.w = &_Int{} + } + na.w.x = v + *na.m = schema.Maybe_Value + return nil +} +func (_Int__Assembler) AssignFloat(float64) error { + return mixins.IntAssembler{"data.Int"}.AssignFloat(0) +} +func (_Int__Assembler) AssignString(string) error { + return mixins.IntAssembler{"data.Int"}.AssignString("") +} +func (_Int__Assembler) AssignBytes([]byte) error { + return mixins.IntAssembler{"data.Int"}.AssignBytes(nil) +} +func (_Int__Assembler) AssignLink(ipld.Link) error { + return mixins.IntAssembler{"data.Int"}.AssignLink(nil) +} +func (na *_Int__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_Int); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v2, err := v.AsInt(); err != nil { + return err + } else { + return na.AssignInt(v2) + } +} +func (_Int__Assembler) Prototype() ipld.NodePrototype { + return _Int__Prototype{} +} +func (Int) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n Int) Representation() ipld.Node { + return (*_Int__Repr)(n) +} +type _Int__Repr = _Int +var _ ipld.Node = &_Int__Repr{} +type _Int__ReprPrototype = _Int__Prototype +type _Int__ReprAssembler = _Int__Assembler + +func (n String) String() string { + return n.x +} +func (_String__Prototype) fromString(w *_String, v string) error { + *w = _String{v} + return nil +} +func (_String__Prototype) FromString(v string) (String, error) { + n := _String{v} + return &n, nil +} +type _String__Maybe struct { + m schema.Maybe + v String +} +type MaybeString = *_String__Maybe + +func (m MaybeString) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeString) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeString) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeString) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeString) Must() String { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var _ ipld.Node = (String)(&_String{}) +var _ schema.TypedNode = (String)(&_String{}) +func (String) Kind() ipld.Kind { + return ipld.Kind_String +} +func (String) LookupByString(string) (ipld.Node, error) { + return mixins.String{"data.String"}.LookupByString("") +} +func (String) LookupByNode(ipld.Node) (ipld.Node, error) { + return mixins.String{"data.String"}.LookupByNode(nil) +} +func (String) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.String{"data.String"}.LookupByIndex(0) +} +func (String) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return mixins.String{"data.String"}.LookupBySegment(seg) +} +func (String) MapIterator() ipld.MapIterator { + return nil +} +func (String) ListIterator() ipld.ListIterator { + return nil +} +func (String) Length() int64 { + return -1 +} +func (String) IsAbsent() bool { + return false +} +func (String) IsNull() bool { + return false +} +func (String) AsBool() (bool, error) { + return mixins.String{"data.String"}.AsBool() +} +func (String) AsInt() (int64, error) { + return mixins.String{"data.String"}.AsInt() +} +func (String) AsFloat() (float64, error) { + return mixins.String{"data.String"}.AsFloat() +} +func (n String) AsString() (string, error) { + return n.x, nil +} +func (String) AsBytes() ([]byte, error) { + return mixins.String{"data.String"}.AsBytes() +} +func (String) AsLink() (ipld.Link, error) { + return mixins.String{"data.String"}.AsLink() +} +func (String) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} +type _String__Prototype struct{} + +func (_String__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _String__Builder + nb.Reset() + return &nb +} +type _String__Builder struct { + _String__Assembler +} +func (nb *_String__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_String__Builder) Reset() { + var w _String + var m schema.Maybe + *nb = _String__Builder{_String__Assembler{w: &w, m: &m}} +} +type _String__Assembler struct { + w *_String + m *schema.Maybe +} + +func (na *_String__Assembler) reset() {} +func (_String__Assembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.String"}.BeginMap(0) +} +func (_String__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.String"}.BeginList(0) +} +func (na *_String__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.StringAssembler{"data.String"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + panic("unreachable") +} +func (_String__Assembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.String"}.AssignBool(false) +} +func (_String__Assembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.String"}.AssignInt(0) +} +func (_String__Assembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.String"}.AssignFloat(0) +} +func (na *_String__Assembler) AssignString(v string) error { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + if na.w == nil { + na.w = &_String{} + } + na.w.x = v + *na.m = schema.Maybe_Value + return nil +} +func (_String__Assembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.String"}.AssignBytes(nil) +} +func (_String__Assembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.String"}.AssignLink(nil) +} +func (na *_String__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_String); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v2, err := v.AsString(); err != nil { + return err + } else { + return na.AssignString(v2) + } +} +func (_String__Assembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (String) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n String) Representation() ipld.Node { + return (*_String__Repr)(n) +} +type _String__Repr = _String +var _ ipld.Node = &_String__Repr{} +type _String__ReprPrototype = _String__Prototype +type _String__ReprAssembler = _String__Assembler + + +func (n _UnixFSData) FieldDataType() Int { + return &n.DataType +} +func (n _UnixFSData) FieldData() MaybeBytes { + return &n.Data +} +func (n _UnixFSData) FieldFileSize() MaybeInt { + return &n.FileSize +} +func (n _UnixFSData) FieldBlockSizes() BlockSizes { + return &n.BlockSizes +} +func (n _UnixFSData) FieldHashType() MaybeInt { + return &n.HashType +} +func (n _UnixFSData) FieldFanout() MaybeInt { + return &n.Fanout +} +func (n _UnixFSData) FieldMode() MaybeInt { + return &n.Mode +} +func (n _UnixFSData) FieldMtime() MaybeUnixTime { + return &n.Mtime +} +type _UnixFSData__Maybe struct { + m schema.Maybe + v UnixFSData +} +type MaybeUnixFSData = *_UnixFSData__Maybe + +func (m MaybeUnixFSData) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeUnixFSData) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeUnixFSData) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeUnixFSData) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeUnixFSData) Must() UnixFSData { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var ( + fieldName__UnixFSData_DataType = _String{"DataType"} + fieldName__UnixFSData_Data = _String{"Data"} + fieldName__UnixFSData_FileSize = _String{"FileSize"} + fieldName__UnixFSData_BlockSizes = _String{"BlockSizes"} + fieldName__UnixFSData_HashType = _String{"HashType"} + fieldName__UnixFSData_Fanout = _String{"Fanout"} + fieldName__UnixFSData_Mode = _String{"Mode"} + fieldName__UnixFSData_Mtime = _String{"Mtime"} +) +var _ ipld.Node = (UnixFSData)(&_UnixFSData{}) +var _ schema.TypedNode = (UnixFSData)(&_UnixFSData{}) +func (UnixFSData) Kind() ipld.Kind { + return ipld.Kind_Map +} +func (n UnixFSData) LookupByString(key string) (ipld.Node, error) { + switch key { + case "DataType": + return &n.DataType, nil + case "Data": + if n.Data.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.Data.v, nil + case "FileSize": + if n.FileSize.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.FileSize.v, nil + case "BlockSizes": + return &n.BlockSizes, nil + case "HashType": + if n.HashType.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.HashType.v, nil + case "Fanout": + if n.Fanout.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.Fanout.v, nil + case "Mode": + if n.Mode.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.Mode.v, nil + case "Mtime": + if n.Mtime.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.Mtime.v, nil + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } +} +func (n UnixFSData) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} +func (UnixFSData) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Map{"data.UnixFSData"}.LookupByIndex(0) +} +func (n UnixFSData) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} +func (n UnixFSData) MapIterator() ipld.MapIterator { + return &_UnixFSData__MapItr{n, 0} +} + +type _UnixFSData__MapItr struct { + n UnixFSData + idx int +} + +func (itr *_UnixFSData__MapItr) Next() (k ipld.Node, v ipld.Node, _ error) {if itr.idx >= 8 { + return nil, nil, ipld.ErrIteratorOverread{} + } + switch itr.idx { + case 0: + k = &fieldName__UnixFSData_DataType + v = &itr.n.DataType + case 1: + k = &fieldName__UnixFSData_Data + if itr.n.Data.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.Data.v + case 2: + k = &fieldName__UnixFSData_FileSize + if itr.n.FileSize.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.FileSize.v + case 3: + k = &fieldName__UnixFSData_BlockSizes + v = &itr.n.BlockSizes + case 4: + k = &fieldName__UnixFSData_HashType + if itr.n.HashType.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.HashType.v + case 5: + k = &fieldName__UnixFSData_Fanout + if itr.n.Fanout.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.Fanout.v + case 6: + k = &fieldName__UnixFSData_Mode + if itr.n.Mode.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.Mode.v + case 7: + k = &fieldName__UnixFSData_Mtime + if itr.n.Mtime.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.Mtime.v + default: + panic("unreachable") + } + itr.idx++ + return +} +func (itr *_UnixFSData__MapItr) Done() bool { + return itr.idx >= 8 +} + +func (UnixFSData) ListIterator() ipld.ListIterator { + return nil +} +func (UnixFSData) Length() int64 { + return 8 +} +func (UnixFSData) IsAbsent() bool { + return false +} +func (UnixFSData) IsNull() bool { + return false +} +func (UnixFSData) AsBool() (bool, error) { + return mixins.Map{"data.UnixFSData"}.AsBool() +} +func (UnixFSData) AsInt() (int64, error) { + return mixins.Map{"data.UnixFSData"}.AsInt() +} +func (UnixFSData) AsFloat() (float64, error) { + return mixins.Map{"data.UnixFSData"}.AsFloat() +} +func (UnixFSData) AsString() (string, error) { + return mixins.Map{"data.UnixFSData"}.AsString() +} +func (UnixFSData) AsBytes() ([]byte, error) { + return mixins.Map{"data.UnixFSData"}.AsBytes() +} +func (UnixFSData) AsLink() (ipld.Link, error) { + return mixins.Map{"data.UnixFSData"}.AsLink() +} +func (UnixFSData) Prototype() ipld.NodePrototype { + return _UnixFSData__Prototype{} +} +type _UnixFSData__Prototype struct{} + +func (_UnixFSData__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _UnixFSData__Builder + nb.Reset() + return &nb +} +type _UnixFSData__Builder struct { + _UnixFSData__Assembler +} +func (nb *_UnixFSData__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_UnixFSData__Builder) Reset() { + var w _UnixFSData + var m schema.Maybe + *nb = _UnixFSData__Builder{_UnixFSData__Assembler{w: &w, m: &m}} +} +type _UnixFSData__Assembler struct { + w *_UnixFSData + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + ca_DataType _Int__Assembler + ca_Data _Bytes__Assembler + ca_FileSize _Int__Assembler + ca_BlockSizes _BlockSizes__Assembler + ca_HashType _Int__Assembler + ca_Fanout _Int__Assembler + ca_Mode _Int__Assembler + ca_Mtime _UnixTime__Assembler + } + +func (na *_UnixFSData__Assembler) reset() { + na.state = maState_initial + na.s = 0 + na.ca_DataType.reset() + na.ca_Data.reset() + na.ca_FileSize.reset() + na.ca_BlockSizes.reset() + na.ca_HashType.reset() + na.ca_Fanout.reset() + na.ca_Mode.reset() + na.ca_Mtime.reset() +} + +var ( + fieldBit__UnixFSData_DataType = 1 << 0 + fieldBit__UnixFSData_Data = 1 << 1 + fieldBit__UnixFSData_FileSize = 1 << 2 + fieldBit__UnixFSData_BlockSizes = 1 << 3 + fieldBit__UnixFSData_HashType = 1 << 4 + fieldBit__UnixFSData_Fanout = 1 << 5 + fieldBit__UnixFSData_Mode = 1 << 6 + fieldBit__UnixFSData_Mtime = 1 << 7 + fieldBits__UnixFSData_sufficient = 0 + 1 << 0 + 1 << 3 +) +func (na *_UnixFSData__Assembler) BeginMap(int64) (ipld.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if na.w == nil { + na.w = &_UnixFSData{} + } + return na, nil +} +func (_UnixFSData__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.MapAssembler{"data.UnixFSData"}.BeginList(0) +} +func (na *_UnixFSData__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.MapAssembler{"data.UnixFSData"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_UnixFSData__Assembler) AssignBool(bool) error { + return mixins.MapAssembler{"data.UnixFSData"}.AssignBool(false) +} +func (_UnixFSData__Assembler) AssignInt(int64) error { + return mixins.MapAssembler{"data.UnixFSData"}.AssignInt(0) +} +func (_UnixFSData__Assembler) AssignFloat(float64) error { + return mixins.MapAssembler{"data.UnixFSData"}.AssignFloat(0) +} +func (_UnixFSData__Assembler) AssignString(string) error { + return mixins.MapAssembler{"data.UnixFSData"}.AssignString("") +} +func (_UnixFSData__Assembler) AssignBytes([]byte) error { + return mixins.MapAssembler{"data.UnixFSData"}.AssignBytes(nil) +} +func (_UnixFSData__Assembler) AssignLink(ipld.Link) error { + return mixins.MapAssembler{"data.UnixFSData"}.AssignLink(nil) +} +func (na *_UnixFSData__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_UnixFSData); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_Map { + return ipld.ErrWrongKind{TypeName: "data.UnixFSData", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_UnixFSData__Assembler) Prototype() ipld.NodePrototype { + return _UnixFSData__Prototype{} +} +func (ma *_UnixFSData__Assembler) valueFinishTidy() bool { + switch ma.f { + case 0: + switch ma.cm { + case schema.Maybe_Value: + ma.ca_DataType.w = nil + ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + case 1: + switch ma.w.Data.m { + case schema.Maybe_Value: + ma.w.Data.v = ma.ca_Data.w + ma.state = maState_initial + return true + default: + return false + } + case 2: + switch ma.w.FileSize.m { + case schema.Maybe_Value: + ma.w.FileSize.v = ma.ca_FileSize.w + ma.state = maState_initial + return true + default: + return false + } + case 3: + switch ma.cm { + case schema.Maybe_Value: + ma.ca_BlockSizes.w = nil + ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + case 4: + switch ma.w.HashType.m { + case schema.Maybe_Value: + ma.w.HashType.v = ma.ca_HashType.w + ma.state = maState_initial + return true + default: + return false + } + case 5: + switch ma.w.Fanout.m { + case schema.Maybe_Value: + ma.w.Fanout.v = ma.ca_Fanout.w + ma.state = maState_initial + return true + default: + return false + } + case 6: + switch ma.w.Mode.m { + case schema.Maybe_Value: + ma.w.Mode.v = ma.ca_Mode.w + ma.state = maState_initial + return true + default: + return false + } + case 7: + switch ma.w.Mtime.m { + case schema.Maybe_Value: + ma.w.Mtime.v = ma.ca_Mtime.w + ma.state = maState_initial + return true + default: + return false + } + default: + panic("unreachable") + } +} +func (ma *_UnixFSData__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + switch k { + case "DataType": + if ma.s & fieldBit__UnixFSData_DataType != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_DataType} + } + ma.s += fieldBit__UnixFSData_DataType + ma.state = maState_midValue + ma.f = 0 + ma.ca_DataType.w = &ma.w.DataType + ma.ca_DataType.m = &ma.cm + return &ma.ca_DataType, nil + case "Data": + if ma.s & fieldBit__UnixFSData_Data != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Data} + } + ma.s += fieldBit__UnixFSData_Data + ma.state = maState_midValue + ma.f = 1 + ma.ca_Data.w = ma.w.Data.v + ma.ca_Data.m = &ma.w.Data.m + return &ma.ca_Data, nil + case "FileSize": + if ma.s & fieldBit__UnixFSData_FileSize != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_FileSize} + } + ma.s += fieldBit__UnixFSData_FileSize + ma.state = maState_midValue + ma.f = 2 + ma.ca_FileSize.w = ma.w.FileSize.v + ma.ca_FileSize.m = &ma.w.FileSize.m + return &ma.ca_FileSize, nil + case "BlockSizes": + if ma.s & fieldBit__UnixFSData_BlockSizes != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_BlockSizes} + } + ma.s += fieldBit__UnixFSData_BlockSizes + ma.state = maState_midValue + ma.f = 3 + ma.ca_BlockSizes.w = &ma.w.BlockSizes + ma.ca_BlockSizes.m = &ma.cm + return &ma.ca_BlockSizes, nil + case "HashType": + if ma.s & fieldBit__UnixFSData_HashType != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_HashType} + } + ma.s += fieldBit__UnixFSData_HashType + ma.state = maState_midValue + ma.f = 4 + ma.ca_HashType.w = ma.w.HashType.v + ma.ca_HashType.m = &ma.w.HashType.m + return &ma.ca_HashType, nil + case "Fanout": + if ma.s & fieldBit__UnixFSData_Fanout != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Fanout} + } + ma.s += fieldBit__UnixFSData_Fanout + ma.state = maState_midValue + ma.f = 5 + ma.ca_Fanout.w = ma.w.Fanout.v + ma.ca_Fanout.m = &ma.w.Fanout.m + return &ma.ca_Fanout, nil + case "Mode": + if ma.s & fieldBit__UnixFSData_Mode != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mode} + } + ma.s += fieldBit__UnixFSData_Mode + ma.state = maState_midValue + ma.f = 6 + ma.ca_Mode.w = ma.w.Mode.v + ma.ca_Mode.m = &ma.w.Mode.m + return &ma.ca_Mode, nil + case "Mtime": + if ma.s & fieldBit__UnixFSData_Mtime != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mtime} + } + ma.s += fieldBit__UnixFSData_Mtime + ma.state = maState_midValue + ma.f = 7 + ma.ca_Mtime.w = ma.w.Mtime.v + ma.ca_Mtime.m = &ma.w.Mtime.m + return &ma.ca_Mtime, nil + } + return nil, ipld.ErrInvalidKey{TypeName:"data.UnixFSData", Key:&_String{k}} +} +func (ma *_UnixFSData__Assembler) AssembleKey() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_UnixFSData__KeyAssembler)(ma) +} +func (ma *_UnixFSData__Assembler) AssembleValue() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + case 0: + ma.ca_DataType.w = &ma.w.DataType + ma.ca_DataType.m = &ma.cm + return &ma.ca_DataType + case 1: + ma.ca_Data.w = ma.w.Data.v + ma.ca_Data.m = &ma.w.Data.m + return &ma.ca_Data + case 2: + ma.ca_FileSize.w = ma.w.FileSize.v + ma.ca_FileSize.m = &ma.w.FileSize.m + return &ma.ca_FileSize + case 3: + ma.ca_BlockSizes.w = &ma.w.BlockSizes + ma.ca_BlockSizes.m = &ma.cm + return &ma.ca_BlockSizes + case 4: + ma.ca_HashType.w = ma.w.HashType.v + ma.ca_HashType.m = &ma.w.HashType.m + return &ma.ca_HashType + case 5: + ma.ca_Fanout.w = ma.w.Fanout.v + ma.ca_Fanout.m = &ma.w.Fanout.m + return &ma.ca_Fanout + case 6: + ma.ca_Mode.w = ma.w.Mode.v + ma.ca_Mode.m = &ma.w.Mode.m + return &ma.ca_Mode + case 7: + ma.ca_Mtime.w = ma.w.Mtime.v + ma.ca_Mtime.m = &ma.w.Mtime.m + return &ma.ca_Mtime + default: + panic("unreachable") + } +} +func (ma *_UnixFSData__Assembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__UnixFSData_sufficient != fieldBits__UnixFSData_sufficient { + err := ipld.ErrMissingRequiredField{Missing: make([]string, 0)} + if ma.s & fieldBit__UnixFSData_DataType == 0 { + err.Missing = append(err.Missing, "DataType") + } + if ma.s & fieldBit__UnixFSData_BlockSizes == 0 { + err.Missing = append(err.Missing, "BlockSizes") + } + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil +} +func (ma *_UnixFSData__Assembler) KeyPrototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (ma *_UnixFSData__Assembler) ValuePrototype(k string) ipld.NodePrototype { + panic("todo structbuilder mapassembler valueprototype") +} +type _UnixFSData__KeyAssembler _UnixFSData__Assembler +func (_UnixFSData__KeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.BeginMap(0) +} +func (_UnixFSData__KeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.BeginList(0) +} +func (na *_UnixFSData__KeyAssembler) AssignNull() error { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.AssignNull() +} +func (_UnixFSData__KeyAssembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.AssignBool(false) +} +func (_UnixFSData__KeyAssembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.AssignInt(0) +} +func (_UnixFSData__KeyAssembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.AssignFloat(0) +} +func (ka *_UnixFSData__KeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + case "DataType": + if ka.s & fieldBit__UnixFSData_DataType != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_DataType} + } + ka.s += fieldBit__UnixFSData_DataType + ka.state = maState_expectValue + ka.f = 0 + case "Data": + if ka.s & fieldBit__UnixFSData_Data != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Data} + } + ka.s += fieldBit__UnixFSData_Data + ka.state = maState_expectValue + ka.f = 1 + case "FileSize": + if ka.s & fieldBit__UnixFSData_FileSize != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_FileSize} + } + ka.s += fieldBit__UnixFSData_FileSize + ka.state = maState_expectValue + ka.f = 2 + case "BlockSizes": + if ka.s & fieldBit__UnixFSData_BlockSizes != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_BlockSizes} + } + ka.s += fieldBit__UnixFSData_BlockSizes + ka.state = maState_expectValue + ka.f = 3 + case "HashType": + if ka.s & fieldBit__UnixFSData_HashType != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_HashType} + } + ka.s += fieldBit__UnixFSData_HashType + ka.state = maState_expectValue + ka.f = 4 + case "Fanout": + if ka.s & fieldBit__UnixFSData_Fanout != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Fanout} + } + ka.s += fieldBit__UnixFSData_Fanout + ka.state = maState_expectValue + ka.f = 5 + case "Mode": + if ka.s & fieldBit__UnixFSData_Mode != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mode} + } + ka.s += fieldBit__UnixFSData_Mode + ka.state = maState_expectValue + ka.f = 6 + case "Mtime": + if ka.s & fieldBit__UnixFSData_Mtime != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mtime} + } + ka.s += fieldBit__UnixFSData_Mtime + ka.state = maState_expectValue + ka.f = 7 + default: + return ipld.ErrInvalidKey{TypeName:"data.UnixFSData", Key:&_String{k}} + } + return nil +} +func (_UnixFSData__KeyAssembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.AssignBytes(nil) +} +func (_UnixFSData__KeyAssembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.UnixFSData.KeyAssembler"}.AssignLink(nil) +} +func (ka *_UnixFSData__KeyAssembler) AssignNode(v ipld.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } +} +func (_UnixFSData__KeyAssembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (UnixFSData) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n UnixFSData) Representation() ipld.Node { + return (*_UnixFSData__Repr)(n) +} +type _UnixFSData__Repr _UnixFSData +var ( + fieldName__UnixFSData_DataType_serial = _String{"DataType"} + fieldName__UnixFSData_Data_serial = _String{"Data"} + fieldName__UnixFSData_FileSize_serial = _String{"FileSize"} + fieldName__UnixFSData_BlockSizes_serial = _String{"BlockSizes"} + fieldName__UnixFSData_HashType_serial = _String{"HashType"} + fieldName__UnixFSData_Fanout_serial = _String{"Fanout"} + fieldName__UnixFSData_Mode_serial = _String{"Mode"} + fieldName__UnixFSData_Mtime_serial = _String{"Mtime"} +) +var _ ipld.Node = &_UnixFSData__Repr{} +func (_UnixFSData__Repr) Kind() ipld.Kind { + return ipld.Kind_Map +} +func (n *_UnixFSData__Repr) LookupByString(key string) (ipld.Node, error) { + switch key { + case "DataType": + return n.DataType.Representation(), nil + case "Data": + if n.Data.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.Data.v.Representation(), nil + case "FileSize": + if n.FileSize.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.FileSize.v.Representation(), nil + case "BlockSizes": + return n.BlockSizes.Representation(), nil + case "HashType": + if n.HashType.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.HashType.v.Representation(), nil + case "Fanout": + if n.Fanout.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.Fanout.v.Representation(), nil + case "Mode": + if n.Mode.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.Mode.v.Representation(), nil + case "Mtime": + if n.Mtime.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.Mtime.v.Representation(), nil + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } +} +func (n *_UnixFSData__Repr) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} +func (_UnixFSData__Repr) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Map{"data.UnixFSData.Repr"}.LookupByIndex(0) +} +func (n _UnixFSData__Repr) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} +func (n *_UnixFSData__Repr) MapIterator() ipld.MapIterator { + end := 8 + if n.Mtime.m == schema.Maybe_Absent { + end = 7 + } else { + goto done + } + if n.Mode.m == schema.Maybe_Absent { + end = 6 + } else { + goto done + } + if n.Fanout.m == schema.Maybe_Absent { + end = 5 + } else { + goto done + } + if n.HashType.m == schema.Maybe_Absent { + end = 4 + } else { + goto done + } +done: + return &_UnixFSData__ReprMapItr{n, 0, end} +} + +type _UnixFSData__ReprMapItr struct { + n *_UnixFSData__Repr + idx int + end int +} + +func (itr *_UnixFSData__ReprMapItr) Next() (k ipld.Node, v ipld.Node, _ error) {advance:if itr.idx >= 8 { + return nil, nil, ipld.ErrIteratorOverread{} + } + switch itr.idx { + case 0: + k = &fieldName__UnixFSData_DataType_serial + v = itr.n.DataType.Representation() + case 1: + k = &fieldName__UnixFSData_Data_serial + if itr.n.Data.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.Data.v.Representation() + case 2: + k = &fieldName__UnixFSData_FileSize_serial + if itr.n.FileSize.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.FileSize.v.Representation() + case 3: + k = &fieldName__UnixFSData_BlockSizes_serial + v = itr.n.BlockSizes.Representation() + case 4: + k = &fieldName__UnixFSData_HashType_serial + if itr.n.HashType.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.HashType.v.Representation() + case 5: + k = &fieldName__UnixFSData_Fanout_serial + if itr.n.Fanout.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.Fanout.v.Representation() + case 6: + k = &fieldName__UnixFSData_Mode_serial + if itr.n.Mode.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.Mode.v.Representation() + case 7: + k = &fieldName__UnixFSData_Mtime_serial + if itr.n.Mtime.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.Mtime.v.Representation() + default: + panic("unreachable") + } + itr.idx++ + return +} +func (itr *_UnixFSData__ReprMapItr) Done() bool { + return itr.idx >= itr.end +} +func (_UnixFSData__Repr) ListIterator() ipld.ListIterator { + return nil +} +func (rn *_UnixFSData__Repr) Length() int64 { + l := 8 + if rn.Data.m == schema.Maybe_Absent { + l-- + } + if rn.FileSize.m == schema.Maybe_Absent { + l-- + } + if rn.HashType.m == schema.Maybe_Absent { + l-- + } + if rn.Fanout.m == schema.Maybe_Absent { + l-- + } + if rn.Mode.m == schema.Maybe_Absent { + l-- + } + if rn.Mtime.m == schema.Maybe_Absent { + l-- + } + return int64(l) +} +func (_UnixFSData__Repr) IsAbsent() bool { + return false +} +func (_UnixFSData__Repr) IsNull() bool { + return false +} +func (_UnixFSData__Repr) AsBool() (bool, error) { + return mixins.Map{"data.UnixFSData.Repr"}.AsBool() +} +func (_UnixFSData__Repr) AsInt() (int64, error) { + return mixins.Map{"data.UnixFSData.Repr"}.AsInt() +} +func (_UnixFSData__Repr) AsFloat() (float64, error) { + return mixins.Map{"data.UnixFSData.Repr"}.AsFloat() +} +func (_UnixFSData__Repr) AsString() (string, error) { + return mixins.Map{"data.UnixFSData.Repr"}.AsString() +} +func (_UnixFSData__Repr) AsBytes() ([]byte, error) { + return mixins.Map{"data.UnixFSData.Repr"}.AsBytes() +} +func (_UnixFSData__Repr) AsLink() (ipld.Link, error) { + return mixins.Map{"data.UnixFSData.Repr"}.AsLink() +} +func (_UnixFSData__Repr) Prototype() ipld.NodePrototype { + return _UnixFSData__ReprPrototype{} +} +type _UnixFSData__ReprPrototype struct{} + +func (_UnixFSData__ReprPrototype) NewBuilder() ipld.NodeBuilder { + var nb _UnixFSData__ReprBuilder + nb.Reset() + return &nb +} +type _UnixFSData__ReprBuilder struct { + _UnixFSData__ReprAssembler +} +func (nb *_UnixFSData__ReprBuilder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_UnixFSData__ReprBuilder) Reset() { + var w _UnixFSData + var m schema.Maybe + *nb = _UnixFSData__ReprBuilder{_UnixFSData__ReprAssembler{w: &w, m: &m}} +} +type _UnixFSData__ReprAssembler struct { + w *_UnixFSData + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + ca_DataType _Int__ReprAssembler + ca_Data _Bytes__ReprAssembler + ca_FileSize _Int__ReprAssembler + ca_BlockSizes _BlockSizes__ReprAssembler + ca_HashType _Int__ReprAssembler + ca_Fanout _Int__ReprAssembler + ca_Mode _Int__ReprAssembler + ca_Mtime _UnixTime__ReprAssembler + } + +func (na *_UnixFSData__ReprAssembler) reset() { + na.state = maState_initial + na.s = 0 + na.ca_DataType.reset() + na.ca_Data.reset() + na.ca_FileSize.reset() + na.ca_BlockSizes.reset() + na.ca_HashType.reset() + na.ca_Fanout.reset() + na.ca_Mode.reset() + na.ca_Mtime.reset() +} +func (na *_UnixFSData__ReprAssembler) BeginMap(int64) (ipld.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if na.w == nil { + na.w = &_UnixFSData{} + } + return na, nil +} +func (_UnixFSData__ReprAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.BeginList(0) +} +func (na *_UnixFSData__ReprAssembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.MapAssembler{"data.UnixFSData.Repr.Repr"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_UnixFSData__ReprAssembler) AssignBool(bool) error { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.AssignBool(false) +} +func (_UnixFSData__ReprAssembler) AssignInt(int64) error { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.AssignInt(0) +} +func (_UnixFSData__ReprAssembler) AssignFloat(float64) error { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.AssignFloat(0) +} +func (_UnixFSData__ReprAssembler) AssignString(string) error { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.AssignString("") +} +func (_UnixFSData__ReprAssembler) AssignBytes([]byte) error { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.AssignBytes(nil) +} +func (_UnixFSData__ReprAssembler) AssignLink(ipld.Link) error { + return mixins.MapAssembler{"data.UnixFSData.Repr"}.AssignLink(nil) +} +func (na *_UnixFSData__ReprAssembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_UnixFSData); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_Map { + return ipld.ErrWrongKind{TypeName: "data.UnixFSData.Repr", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_UnixFSData__ReprAssembler) Prototype() ipld.NodePrototype { + return _UnixFSData__ReprPrototype{} +} +func (ma *_UnixFSData__ReprAssembler) valueFinishTidy() bool { + switch ma.f { + case 0: + switch ma.cm { + case schema.Maybe_Value:ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + case 1: + switch ma.w.Data.m { + case schema.Maybe_Value: + ma.w.Data.v = ma.ca_Data.w + ma.state = maState_initial + return true + default: + return false + } + case 2: + switch ma.w.FileSize.m { + case schema.Maybe_Value: + ma.w.FileSize.v = ma.ca_FileSize.w + ma.state = maState_initial + return true + default: + return false + } + case 3: + switch ma.cm { + case schema.Maybe_Value:ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + case 4: + switch ma.w.HashType.m { + case schema.Maybe_Value: + ma.w.HashType.v = ma.ca_HashType.w + ma.state = maState_initial + return true + default: + return false + } + case 5: + switch ma.w.Fanout.m { + case schema.Maybe_Value: + ma.w.Fanout.v = ma.ca_Fanout.w + ma.state = maState_initial + return true + default: + return false + } + case 6: + switch ma.w.Mode.m { + case schema.Maybe_Value: + ma.w.Mode.v = ma.ca_Mode.w + ma.state = maState_initial + return true + default: + return false + } + case 7: + switch ma.w.Mtime.m { + case schema.Maybe_Value: + ma.w.Mtime.v = ma.ca_Mtime.w + ma.state = maState_initial + return true + default: + return false + } + default: + panic("unreachable") + } +} +func (ma *_UnixFSData__ReprAssembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + switch k { + case "DataType": + if ma.s & fieldBit__UnixFSData_DataType != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_DataType_serial} + } + ma.s += fieldBit__UnixFSData_DataType + ma.state = maState_midValue + ma.f = 0 + ma.ca_DataType.w = &ma.w.DataType + ma.ca_DataType.m = &ma.cm + return &ma.ca_DataType, nil + case "Data": + if ma.s & fieldBit__UnixFSData_Data != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Data_serial} + } + ma.s += fieldBit__UnixFSData_Data + ma.state = maState_midValue + ma.f = 1 + ma.ca_Data.w = ma.w.Data.v + ma.ca_Data.m = &ma.w.Data.m + + return &ma.ca_Data, nil + case "FileSize": + if ma.s & fieldBit__UnixFSData_FileSize != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_FileSize_serial} + } + ma.s += fieldBit__UnixFSData_FileSize + ma.state = maState_midValue + ma.f = 2 + ma.ca_FileSize.w = ma.w.FileSize.v + ma.ca_FileSize.m = &ma.w.FileSize.m + + return &ma.ca_FileSize, nil + case "BlockSizes": + if ma.s & fieldBit__UnixFSData_BlockSizes != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_BlockSizes_serial} + } + ma.s += fieldBit__UnixFSData_BlockSizes + ma.state = maState_midValue + ma.f = 3 + ma.ca_BlockSizes.w = &ma.w.BlockSizes + ma.ca_BlockSizes.m = &ma.cm + return &ma.ca_BlockSizes, nil + case "HashType": + if ma.s & fieldBit__UnixFSData_HashType != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_HashType_serial} + } + ma.s += fieldBit__UnixFSData_HashType + ma.state = maState_midValue + ma.f = 4 + ma.ca_HashType.w = ma.w.HashType.v + ma.ca_HashType.m = &ma.w.HashType.m + + return &ma.ca_HashType, nil + case "Fanout": + if ma.s & fieldBit__UnixFSData_Fanout != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Fanout_serial} + } + ma.s += fieldBit__UnixFSData_Fanout + ma.state = maState_midValue + ma.f = 5 + ma.ca_Fanout.w = ma.w.Fanout.v + ma.ca_Fanout.m = &ma.w.Fanout.m + + return &ma.ca_Fanout, nil + case "Mode": + if ma.s & fieldBit__UnixFSData_Mode != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mode_serial} + } + ma.s += fieldBit__UnixFSData_Mode + ma.state = maState_midValue + ma.f = 6 + ma.ca_Mode.w = ma.w.Mode.v + ma.ca_Mode.m = &ma.w.Mode.m + + return &ma.ca_Mode, nil + case "Mtime": + if ma.s & fieldBit__UnixFSData_Mtime != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mtime_serial} + } + ma.s += fieldBit__UnixFSData_Mtime + ma.state = maState_midValue + ma.f = 7 + ma.ca_Mtime.w = ma.w.Mtime.v + ma.ca_Mtime.m = &ma.w.Mtime.m + + return &ma.ca_Mtime, nil + default: + } + return nil, ipld.ErrInvalidKey{TypeName:"data.UnixFSData.Repr", Key:&_String{k}} +} +func (ma *_UnixFSData__ReprAssembler) AssembleKey() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_UnixFSData__ReprKeyAssembler)(ma) +} +func (ma *_UnixFSData__ReprAssembler) AssembleValue() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + case 0: + ma.ca_DataType.w = &ma.w.DataType + ma.ca_DataType.m = &ma.cm + return &ma.ca_DataType + case 1: + ma.ca_Data.w = ma.w.Data.v + ma.ca_Data.m = &ma.w.Data.m + + return &ma.ca_Data + case 2: + ma.ca_FileSize.w = ma.w.FileSize.v + ma.ca_FileSize.m = &ma.w.FileSize.m + + return &ma.ca_FileSize + case 3: + ma.ca_BlockSizes.w = &ma.w.BlockSizes + ma.ca_BlockSizes.m = &ma.cm + return &ma.ca_BlockSizes + case 4: + ma.ca_HashType.w = ma.w.HashType.v + ma.ca_HashType.m = &ma.w.HashType.m + + return &ma.ca_HashType + case 5: + ma.ca_Fanout.w = ma.w.Fanout.v + ma.ca_Fanout.m = &ma.w.Fanout.m + + return &ma.ca_Fanout + case 6: + ma.ca_Mode.w = ma.w.Mode.v + ma.ca_Mode.m = &ma.w.Mode.m + + return &ma.ca_Mode + case 7: + ma.ca_Mtime.w = ma.w.Mtime.v + ma.ca_Mtime.m = &ma.w.Mtime.m + + return &ma.ca_Mtime + default: + panic("unreachable") + } +} +func (ma *_UnixFSData__ReprAssembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__UnixFSData_sufficient != fieldBits__UnixFSData_sufficient { + err := ipld.ErrMissingRequiredField{Missing: make([]string, 0)} + if ma.s & fieldBit__UnixFSData_DataType == 0 { + err.Missing = append(err.Missing, "DataType") + } + if ma.s & fieldBit__UnixFSData_BlockSizes == 0 { + err.Missing = append(err.Missing, "BlockSizes") + } + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil +} +func (ma *_UnixFSData__ReprAssembler) KeyPrototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (ma *_UnixFSData__ReprAssembler) ValuePrototype(k string) ipld.NodePrototype { + panic("todo structbuilder mapassembler repr valueprototype") +} +type _UnixFSData__ReprKeyAssembler _UnixFSData__ReprAssembler +func (_UnixFSData__ReprKeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.BeginMap(0) +} +func (_UnixFSData__ReprKeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.BeginList(0) +} +func (na *_UnixFSData__ReprKeyAssembler) AssignNull() error { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.AssignNull() +} +func (_UnixFSData__ReprKeyAssembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.AssignBool(false) +} +func (_UnixFSData__ReprKeyAssembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.AssignInt(0) +} +func (_UnixFSData__ReprKeyAssembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.AssignFloat(0) +} +func (ka *_UnixFSData__ReprKeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + case "DataType": + if ka.s & fieldBit__UnixFSData_DataType != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_DataType_serial} + } + ka.s += fieldBit__UnixFSData_DataType + ka.state = maState_expectValue + ka.f = 0 + return nil + case "Data": + if ka.s & fieldBit__UnixFSData_Data != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Data_serial} + } + ka.s += fieldBit__UnixFSData_Data + ka.state = maState_expectValue + ka.f = 1 + return nil + case "FileSize": + if ka.s & fieldBit__UnixFSData_FileSize != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_FileSize_serial} + } + ka.s += fieldBit__UnixFSData_FileSize + ka.state = maState_expectValue + ka.f = 2 + return nil + case "BlockSizes": + if ka.s & fieldBit__UnixFSData_BlockSizes != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_BlockSizes_serial} + } + ka.s += fieldBit__UnixFSData_BlockSizes + ka.state = maState_expectValue + ka.f = 3 + return nil + case "HashType": + if ka.s & fieldBit__UnixFSData_HashType != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_HashType_serial} + } + ka.s += fieldBit__UnixFSData_HashType + ka.state = maState_expectValue + ka.f = 4 + return nil + case "Fanout": + if ka.s & fieldBit__UnixFSData_Fanout != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Fanout_serial} + } + ka.s += fieldBit__UnixFSData_Fanout + ka.state = maState_expectValue + ka.f = 5 + return nil + case "Mode": + if ka.s & fieldBit__UnixFSData_Mode != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mode_serial} + } + ka.s += fieldBit__UnixFSData_Mode + ka.state = maState_expectValue + ka.f = 6 + return nil + case "Mtime": + if ka.s & fieldBit__UnixFSData_Mtime != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSData_Mtime_serial} + } + ka.s += fieldBit__UnixFSData_Mtime + ka.state = maState_expectValue + ka.f = 7 + return nil + } + return ipld.ErrInvalidKey{TypeName:"data.UnixFSData.Repr", Key:&_String{k}} +} +func (_UnixFSData__ReprKeyAssembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.AssignBytes(nil) +} +func (_UnixFSData__ReprKeyAssembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.UnixFSData.Repr.KeyAssembler"}.AssignLink(nil) +} +func (ka *_UnixFSData__ReprKeyAssembler) AssignNode(v ipld.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } +} +func (_UnixFSData__ReprKeyAssembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} + + +func (n _UnixFSMetadata) FieldMimeType() MaybeString { + return &n.MimeType +} +type _UnixFSMetadata__Maybe struct { + m schema.Maybe + v UnixFSMetadata +} +type MaybeUnixFSMetadata = *_UnixFSMetadata__Maybe + +func (m MaybeUnixFSMetadata) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeUnixFSMetadata) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeUnixFSMetadata) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeUnixFSMetadata) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeUnixFSMetadata) Must() UnixFSMetadata { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var ( + fieldName__UnixFSMetadata_MimeType = _String{"MimeType"} +) +var _ ipld.Node = (UnixFSMetadata)(&_UnixFSMetadata{}) +var _ schema.TypedNode = (UnixFSMetadata)(&_UnixFSMetadata{}) +func (UnixFSMetadata) Kind() ipld.Kind { + return ipld.Kind_Map +} +func (n UnixFSMetadata) LookupByString(key string) (ipld.Node, error) { + switch key { + case "MimeType": + if n.MimeType.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.MimeType.v, nil + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } +} +func (n UnixFSMetadata) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} +func (UnixFSMetadata) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Map{"data.UnixFSMetadata"}.LookupByIndex(0) +} +func (n UnixFSMetadata) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} +func (n UnixFSMetadata) MapIterator() ipld.MapIterator { + return &_UnixFSMetadata__MapItr{n, 0} +} + +type _UnixFSMetadata__MapItr struct { + n UnixFSMetadata + idx int +} + +func (itr *_UnixFSMetadata__MapItr) Next() (k ipld.Node, v ipld.Node, _ error) {if itr.idx >= 1 { + return nil, nil, ipld.ErrIteratorOverread{} + } + switch itr.idx { + case 0: + k = &fieldName__UnixFSMetadata_MimeType + if itr.n.MimeType.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.MimeType.v + default: + panic("unreachable") + } + itr.idx++ + return +} +func (itr *_UnixFSMetadata__MapItr) Done() bool { + return itr.idx >= 1 +} + +func (UnixFSMetadata) ListIterator() ipld.ListIterator { + return nil +} +func (UnixFSMetadata) Length() int64 { + return 1 +} +func (UnixFSMetadata) IsAbsent() bool { + return false +} +func (UnixFSMetadata) IsNull() bool { + return false +} +func (UnixFSMetadata) AsBool() (bool, error) { + return mixins.Map{"data.UnixFSMetadata"}.AsBool() +} +func (UnixFSMetadata) AsInt() (int64, error) { + return mixins.Map{"data.UnixFSMetadata"}.AsInt() +} +func (UnixFSMetadata) AsFloat() (float64, error) { + return mixins.Map{"data.UnixFSMetadata"}.AsFloat() +} +func (UnixFSMetadata) AsString() (string, error) { + return mixins.Map{"data.UnixFSMetadata"}.AsString() +} +func (UnixFSMetadata) AsBytes() ([]byte, error) { + return mixins.Map{"data.UnixFSMetadata"}.AsBytes() +} +func (UnixFSMetadata) AsLink() (ipld.Link, error) { + return mixins.Map{"data.UnixFSMetadata"}.AsLink() +} +func (UnixFSMetadata) Prototype() ipld.NodePrototype { + return _UnixFSMetadata__Prototype{} +} +type _UnixFSMetadata__Prototype struct{} + +func (_UnixFSMetadata__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _UnixFSMetadata__Builder + nb.Reset() + return &nb +} +type _UnixFSMetadata__Builder struct { + _UnixFSMetadata__Assembler +} +func (nb *_UnixFSMetadata__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_UnixFSMetadata__Builder) Reset() { + var w _UnixFSMetadata + var m schema.Maybe + *nb = _UnixFSMetadata__Builder{_UnixFSMetadata__Assembler{w: &w, m: &m}} +} +type _UnixFSMetadata__Assembler struct { + w *_UnixFSMetadata + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + ca_MimeType _String__Assembler + } + +func (na *_UnixFSMetadata__Assembler) reset() { + na.state = maState_initial + na.s = 0 + na.ca_MimeType.reset() +} + +var ( + fieldBit__UnixFSMetadata_MimeType = 1 << 0 + fieldBits__UnixFSMetadata_sufficient = 0 +) +func (na *_UnixFSMetadata__Assembler) BeginMap(int64) (ipld.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if na.w == nil { + na.w = &_UnixFSMetadata{} + } + return na, nil +} +func (_UnixFSMetadata__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.MapAssembler{"data.UnixFSMetadata"}.BeginList(0) +} +func (na *_UnixFSMetadata__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_UnixFSMetadata__Assembler) AssignBool(bool) error { + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignBool(false) +} +func (_UnixFSMetadata__Assembler) AssignInt(int64) error { + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignInt(0) +} +func (_UnixFSMetadata__Assembler) AssignFloat(float64) error { + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignFloat(0) +} +func (_UnixFSMetadata__Assembler) AssignString(string) error { + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignString("") +} +func (_UnixFSMetadata__Assembler) AssignBytes([]byte) error { + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignBytes(nil) +} +func (_UnixFSMetadata__Assembler) AssignLink(ipld.Link) error { + return mixins.MapAssembler{"data.UnixFSMetadata"}.AssignLink(nil) +} +func (na *_UnixFSMetadata__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_UnixFSMetadata); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_Map { + return ipld.ErrWrongKind{TypeName: "data.UnixFSMetadata", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_UnixFSMetadata__Assembler) Prototype() ipld.NodePrototype { + return _UnixFSMetadata__Prototype{} +} +func (ma *_UnixFSMetadata__Assembler) valueFinishTidy() bool { + switch ma.f { + case 0: + switch ma.w.MimeType.m { + case schema.Maybe_Value: + ma.w.MimeType.v = ma.ca_MimeType.w + ma.state = maState_initial + return true + default: + return false + } + default: + panic("unreachable") + } +} +func (ma *_UnixFSMetadata__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + switch k { + case "MimeType": + if ma.s & fieldBit__UnixFSMetadata_MimeType != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSMetadata_MimeType} + } + ma.s += fieldBit__UnixFSMetadata_MimeType + ma.state = maState_midValue + ma.f = 0 + ma.ca_MimeType.w = ma.w.MimeType.v + ma.ca_MimeType.m = &ma.w.MimeType.m + return &ma.ca_MimeType, nil + } + return nil, ipld.ErrInvalidKey{TypeName:"data.UnixFSMetadata", Key:&_String{k}} +} +func (ma *_UnixFSMetadata__Assembler) AssembleKey() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_UnixFSMetadata__KeyAssembler)(ma) +} +func (ma *_UnixFSMetadata__Assembler) AssembleValue() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + case 0: + ma.ca_MimeType.w = ma.w.MimeType.v + ma.ca_MimeType.m = &ma.w.MimeType.m + return &ma.ca_MimeType + default: + panic("unreachable") + } +} +func (ma *_UnixFSMetadata__Assembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__UnixFSMetadata_sufficient != fieldBits__UnixFSMetadata_sufficient { + err := ipld.ErrMissingRequiredField{Missing: make([]string, 0)} + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil +} +func (ma *_UnixFSMetadata__Assembler) KeyPrototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (ma *_UnixFSMetadata__Assembler) ValuePrototype(k string) ipld.NodePrototype { + panic("todo structbuilder mapassembler valueprototype") +} +type _UnixFSMetadata__KeyAssembler _UnixFSMetadata__Assembler +func (_UnixFSMetadata__KeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.BeginMap(0) +} +func (_UnixFSMetadata__KeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.BeginList(0) +} +func (na *_UnixFSMetadata__KeyAssembler) AssignNull() error { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.AssignNull() +} +func (_UnixFSMetadata__KeyAssembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.AssignBool(false) +} +func (_UnixFSMetadata__KeyAssembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.AssignInt(0) +} +func (_UnixFSMetadata__KeyAssembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.AssignFloat(0) +} +func (ka *_UnixFSMetadata__KeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + case "MimeType": + if ka.s & fieldBit__UnixFSMetadata_MimeType != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSMetadata_MimeType} + } + ka.s += fieldBit__UnixFSMetadata_MimeType + ka.state = maState_expectValue + ka.f = 0 + default: + return ipld.ErrInvalidKey{TypeName:"data.UnixFSMetadata", Key:&_String{k}} + } + return nil +} +func (_UnixFSMetadata__KeyAssembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.AssignBytes(nil) +} +func (_UnixFSMetadata__KeyAssembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.UnixFSMetadata.KeyAssembler"}.AssignLink(nil) +} +func (ka *_UnixFSMetadata__KeyAssembler) AssignNode(v ipld.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } +} +func (_UnixFSMetadata__KeyAssembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (UnixFSMetadata) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n UnixFSMetadata) Representation() ipld.Node { + return (*_UnixFSMetadata__Repr)(n) +} +type _UnixFSMetadata__Repr _UnixFSMetadata +var ( + fieldName__UnixFSMetadata_MimeType_serial = _String{"MimeType"} +) +var _ ipld.Node = &_UnixFSMetadata__Repr{} +func (_UnixFSMetadata__Repr) Kind() ipld.Kind { + return ipld.Kind_Map +} +func (n *_UnixFSMetadata__Repr) LookupByString(key string) (ipld.Node, error) { + switch key { + case "MimeType": + if n.MimeType.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.MimeType.v.Representation(), nil + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } +} +func (n *_UnixFSMetadata__Repr) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} +func (_UnixFSMetadata__Repr) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.LookupByIndex(0) +} +func (n _UnixFSMetadata__Repr) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} +func (n *_UnixFSMetadata__Repr) MapIterator() ipld.MapIterator { + end := 1 + if n.MimeType.m == schema.Maybe_Absent { + end = 0 + } else { + goto done + } +done: + return &_UnixFSMetadata__ReprMapItr{n, 0, end} +} + +type _UnixFSMetadata__ReprMapItr struct { + n *_UnixFSMetadata__Repr + idx int + end int +} + +func (itr *_UnixFSMetadata__ReprMapItr) Next() (k ipld.Node, v ipld.Node, _ error) {advance:if itr.idx >= 1 { + return nil, nil, ipld.ErrIteratorOverread{} + } + switch itr.idx { + case 0: + k = &fieldName__UnixFSMetadata_MimeType_serial + if itr.n.MimeType.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.MimeType.v.Representation() + default: + panic("unreachable") + } + itr.idx++ + return +} +func (itr *_UnixFSMetadata__ReprMapItr) Done() bool { + return itr.idx >= itr.end +} +func (_UnixFSMetadata__Repr) ListIterator() ipld.ListIterator { + return nil +} +func (rn *_UnixFSMetadata__Repr) Length() int64 { + l := 1 + if rn.MimeType.m == schema.Maybe_Absent { + l-- + } + return int64(l) +} +func (_UnixFSMetadata__Repr) IsAbsent() bool { + return false +} +func (_UnixFSMetadata__Repr) IsNull() bool { + return false +} +func (_UnixFSMetadata__Repr) AsBool() (bool, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.AsBool() +} +func (_UnixFSMetadata__Repr) AsInt() (int64, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.AsInt() +} +func (_UnixFSMetadata__Repr) AsFloat() (float64, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.AsFloat() +} +func (_UnixFSMetadata__Repr) AsString() (string, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.AsString() +} +func (_UnixFSMetadata__Repr) AsBytes() ([]byte, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.AsBytes() +} +func (_UnixFSMetadata__Repr) AsLink() (ipld.Link, error) { + return mixins.Map{"data.UnixFSMetadata.Repr"}.AsLink() +} +func (_UnixFSMetadata__Repr) Prototype() ipld.NodePrototype { + return _UnixFSMetadata__ReprPrototype{} +} +type _UnixFSMetadata__ReprPrototype struct{} + +func (_UnixFSMetadata__ReprPrototype) NewBuilder() ipld.NodeBuilder { + var nb _UnixFSMetadata__ReprBuilder + nb.Reset() + return &nb +} +type _UnixFSMetadata__ReprBuilder struct { + _UnixFSMetadata__ReprAssembler +} +func (nb *_UnixFSMetadata__ReprBuilder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_UnixFSMetadata__ReprBuilder) Reset() { + var w _UnixFSMetadata + var m schema.Maybe + *nb = _UnixFSMetadata__ReprBuilder{_UnixFSMetadata__ReprAssembler{w: &w, m: &m}} +} +type _UnixFSMetadata__ReprAssembler struct { + w *_UnixFSMetadata + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + ca_MimeType _String__ReprAssembler + } + +func (na *_UnixFSMetadata__ReprAssembler) reset() { + na.state = maState_initial + na.s = 0 + na.ca_MimeType.reset() +} +func (na *_UnixFSMetadata__ReprAssembler) BeginMap(int64) (ipld.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if na.w == nil { + na.w = &_UnixFSMetadata{} + } + return na, nil +} +func (_UnixFSMetadata__ReprAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.BeginList(0) +} +func (na *_UnixFSMetadata__ReprAssembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.MapAssembler{"data.UnixFSMetadata.Repr.Repr"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_UnixFSMetadata__ReprAssembler) AssignBool(bool) error { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.AssignBool(false) +} +func (_UnixFSMetadata__ReprAssembler) AssignInt(int64) error { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.AssignInt(0) +} +func (_UnixFSMetadata__ReprAssembler) AssignFloat(float64) error { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.AssignFloat(0) +} +func (_UnixFSMetadata__ReprAssembler) AssignString(string) error { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.AssignString("") +} +func (_UnixFSMetadata__ReprAssembler) AssignBytes([]byte) error { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.AssignBytes(nil) +} +func (_UnixFSMetadata__ReprAssembler) AssignLink(ipld.Link) error { + return mixins.MapAssembler{"data.UnixFSMetadata.Repr"}.AssignLink(nil) +} +func (na *_UnixFSMetadata__ReprAssembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_UnixFSMetadata); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_Map { + return ipld.ErrWrongKind{TypeName: "data.UnixFSMetadata.Repr", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_UnixFSMetadata__ReprAssembler) Prototype() ipld.NodePrototype { + return _UnixFSMetadata__ReprPrototype{} +} +func (ma *_UnixFSMetadata__ReprAssembler) valueFinishTidy() bool { + switch ma.f { + case 0: + switch ma.w.MimeType.m { + case schema.Maybe_Value: + ma.w.MimeType.v = ma.ca_MimeType.w + ma.state = maState_initial + return true + default: + return false + } + default: + panic("unreachable") + } +} +func (ma *_UnixFSMetadata__ReprAssembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + switch k { + case "MimeType": + if ma.s & fieldBit__UnixFSMetadata_MimeType != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSMetadata_MimeType_serial} + } + ma.s += fieldBit__UnixFSMetadata_MimeType + ma.state = maState_midValue + ma.f = 0 + ma.ca_MimeType.w = ma.w.MimeType.v + ma.ca_MimeType.m = &ma.w.MimeType.m + + return &ma.ca_MimeType, nil + default: + } + return nil, ipld.ErrInvalidKey{TypeName:"data.UnixFSMetadata.Repr", Key:&_String{k}} +} +func (ma *_UnixFSMetadata__ReprAssembler) AssembleKey() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_UnixFSMetadata__ReprKeyAssembler)(ma) +} +func (ma *_UnixFSMetadata__ReprAssembler) AssembleValue() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + case 0: + ma.ca_MimeType.w = ma.w.MimeType.v + ma.ca_MimeType.m = &ma.w.MimeType.m + + return &ma.ca_MimeType + default: + panic("unreachable") + } +} +func (ma *_UnixFSMetadata__ReprAssembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__UnixFSMetadata_sufficient != fieldBits__UnixFSMetadata_sufficient { + err := ipld.ErrMissingRequiredField{Missing: make([]string, 0)} + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil +} +func (ma *_UnixFSMetadata__ReprAssembler) KeyPrototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (ma *_UnixFSMetadata__ReprAssembler) ValuePrototype(k string) ipld.NodePrototype { + panic("todo structbuilder mapassembler repr valueprototype") +} +type _UnixFSMetadata__ReprKeyAssembler _UnixFSMetadata__ReprAssembler +func (_UnixFSMetadata__ReprKeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.BeginMap(0) +} +func (_UnixFSMetadata__ReprKeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.BeginList(0) +} +func (na *_UnixFSMetadata__ReprKeyAssembler) AssignNull() error { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.AssignNull() +} +func (_UnixFSMetadata__ReprKeyAssembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.AssignBool(false) +} +func (_UnixFSMetadata__ReprKeyAssembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.AssignInt(0) +} +func (_UnixFSMetadata__ReprKeyAssembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.AssignFloat(0) +} +func (ka *_UnixFSMetadata__ReprKeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + case "MimeType": + if ka.s & fieldBit__UnixFSMetadata_MimeType != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixFSMetadata_MimeType_serial} + } + ka.s += fieldBit__UnixFSMetadata_MimeType + ka.state = maState_expectValue + ka.f = 0 + return nil + } + return ipld.ErrInvalidKey{TypeName:"data.UnixFSMetadata.Repr", Key:&_String{k}} +} +func (_UnixFSMetadata__ReprKeyAssembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.AssignBytes(nil) +} +func (_UnixFSMetadata__ReprKeyAssembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.UnixFSMetadata.Repr.KeyAssembler"}.AssignLink(nil) +} +func (ka *_UnixFSMetadata__ReprKeyAssembler) AssignNode(v ipld.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } +} +func (_UnixFSMetadata__ReprKeyAssembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} + + +func (n _UnixTime) FieldSeconds() Int { + return &n.Seconds +} +func (n _UnixTime) FieldFractionalNanoseconds() MaybeInt { + return &n.FractionalNanoseconds +} +type _UnixTime__Maybe struct { + m schema.Maybe + v UnixTime +} +type MaybeUnixTime = *_UnixTime__Maybe + +func (m MaybeUnixTime) IsNull() bool { + return m.m == schema.Maybe_Null +} +func (m MaybeUnixTime) IsAbsent() bool { + return m.m == schema.Maybe_Absent +} +func (m MaybeUnixTime) Exists() bool { + return m.m == schema.Maybe_Value +} +func (m MaybeUnixTime) AsNode() ipld.Node { + switch m.m { + case schema.Maybe_Absent: + return ipld.Absent + case schema.Maybe_Null: + return ipld.Null + case schema.Maybe_Value: + return m.v + default: + panic("unreachable") + } +} +func (m MaybeUnixTime) Must() UnixTime { + if !m.Exists() { + panic("unbox of a maybe rejected") + } + return m.v +} +var ( + fieldName__UnixTime_Seconds = _String{"Seconds"} + fieldName__UnixTime_FractionalNanoseconds = _String{"FractionalNanoseconds"} +) +var _ ipld.Node = (UnixTime)(&_UnixTime{}) +var _ schema.TypedNode = (UnixTime)(&_UnixTime{}) +func (UnixTime) Kind() ipld.Kind { + return ipld.Kind_Map +} +func (n UnixTime) LookupByString(key string) (ipld.Node, error) { + switch key { + case "Seconds": + return &n.Seconds, nil + case "FractionalNanoseconds": + if n.FractionalNanoseconds.m == schema.Maybe_Absent { + return ipld.Absent, nil + } + return n.FractionalNanoseconds.v, nil + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } +} +func (n UnixTime) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} +func (UnixTime) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Map{"data.UnixTime"}.LookupByIndex(0) +} +func (n UnixTime) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} +func (n UnixTime) MapIterator() ipld.MapIterator { + return &_UnixTime__MapItr{n, 0} +} + +type _UnixTime__MapItr struct { + n UnixTime + idx int +} + +func (itr *_UnixTime__MapItr) Next() (k ipld.Node, v ipld.Node, _ error) {if itr.idx >= 2 { + return nil, nil, ipld.ErrIteratorOverread{} + } + switch itr.idx { + case 0: + k = &fieldName__UnixTime_Seconds + v = &itr.n.Seconds + case 1: + k = &fieldName__UnixTime_FractionalNanoseconds + if itr.n.FractionalNanoseconds.m == schema.Maybe_Absent { + v = ipld.Absent + break + } + v = itr.n.FractionalNanoseconds.v + default: + panic("unreachable") + } + itr.idx++ + return +} +func (itr *_UnixTime__MapItr) Done() bool { + return itr.idx >= 2 +} + +func (UnixTime) ListIterator() ipld.ListIterator { + return nil +} +func (UnixTime) Length() int64 { + return 2 +} +func (UnixTime) IsAbsent() bool { + return false +} +func (UnixTime) IsNull() bool { + return false +} +func (UnixTime) AsBool() (bool, error) { + return mixins.Map{"data.UnixTime"}.AsBool() +} +func (UnixTime) AsInt() (int64, error) { + return mixins.Map{"data.UnixTime"}.AsInt() +} +func (UnixTime) AsFloat() (float64, error) { + return mixins.Map{"data.UnixTime"}.AsFloat() +} +func (UnixTime) AsString() (string, error) { + return mixins.Map{"data.UnixTime"}.AsString() +} +func (UnixTime) AsBytes() ([]byte, error) { + return mixins.Map{"data.UnixTime"}.AsBytes() +} +func (UnixTime) AsLink() (ipld.Link, error) { + return mixins.Map{"data.UnixTime"}.AsLink() +} +func (UnixTime) Prototype() ipld.NodePrototype { + return _UnixTime__Prototype{} +} +type _UnixTime__Prototype struct{} + +func (_UnixTime__Prototype) NewBuilder() ipld.NodeBuilder { + var nb _UnixTime__Builder + nb.Reset() + return &nb +} +type _UnixTime__Builder struct { + _UnixTime__Assembler +} +func (nb *_UnixTime__Builder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_UnixTime__Builder) Reset() { + var w _UnixTime + var m schema.Maybe + *nb = _UnixTime__Builder{_UnixTime__Assembler{w: &w, m: &m}} +} +type _UnixTime__Assembler struct { + w *_UnixTime + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + ca_Seconds _Int__Assembler + ca_FractionalNanoseconds _Int__Assembler + } + +func (na *_UnixTime__Assembler) reset() { + na.state = maState_initial + na.s = 0 + na.ca_Seconds.reset() + na.ca_FractionalNanoseconds.reset() +} + +var ( + fieldBit__UnixTime_Seconds = 1 << 0 + fieldBit__UnixTime_FractionalNanoseconds = 1 << 1 + fieldBits__UnixTime_sufficient = 0 + 1 << 0 +) +func (na *_UnixTime__Assembler) BeginMap(int64) (ipld.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if na.w == nil { + na.w = &_UnixTime{} + } + return na, nil +} +func (_UnixTime__Assembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.MapAssembler{"data.UnixTime"}.BeginList(0) +} +func (na *_UnixTime__Assembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.MapAssembler{"data.UnixTime"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_UnixTime__Assembler) AssignBool(bool) error { + return mixins.MapAssembler{"data.UnixTime"}.AssignBool(false) +} +func (_UnixTime__Assembler) AssignInt(int64) error { + return mixins.MapAssembler{"data.UnixTime"}.AssignInt(0) +} +func (_UnixTime__Assembler) AssignFloat(float64) error { + return mixins.MapAssembler{"data.UnixTime"}.AssignFloat(0) +} +func (_UnixTime__Assembler) AssignString(string) error { + return mixins.MapAssembler{"data.UnixTime"}.AssignString("") +} +func (_UnixTime__Assembler) AssignBytes([]byte) error { + return mixins.MapAssembler{"data.UnixTime"}.AssignBytes(nil) +} +func (_UnixTime__Assembler) AssignLink(ipld.Link) error { + return mixins.MapAssembler{"data.UnixTime"}.AssignLink(nil) +} +func (na *_UnixTime__Assembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_UnixTime); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_Map { + return ipld.ErrWrongKind{TypeName: "data.UnixTime", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_UnixTime__Assembler) Prototype() ipld.NodePrototype { + return _UnixTime__Prototype{} +} +func (ma *_UnixTime__Assembler) valueFinishTidy() bool { + switch ma.f { + case 0: + switch ma.cm { + case schema.Maybe_Value: + ma.ca_Seconds.w = nil + ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + case 1: + switch ma.w.FractionalNanoseconds.m { + case schema.Maybe_Value: + ma.w.FractionalNanoseconds.v = ma.ca_FractionalNanoseconds.w + ma.state = maState_initial + return true + default: + return false + } + default: + panic("unreachable") + } +} +func (ma *_UnixTime__Assembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + switch k { + case "Seconds": + if ma.s & fieldBit__UnixTime_Seconds != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_Seconds} + } + ma.s += fieldBit__UnixTime_Seconds + ma.state = maState_midValue + ma.f = 0 + ma.ca_Seconds.w = &ma.w.Seconds + ma.ca_Seconds.m = &ma.cm + return &ma.ca_Seconds, nil + case "FractionalNanoseconds": + if ma.s & fieldBit__UnixTime_FractionalNanoseconds != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_FractionalNanoseconds} + } + ma.s += fieldBit__UnixTime_FractionalNanoseconds + ma.state = maState_midValue + ma.f = 1 + ma.ca_FractionalNanoseconds.w = ma.w.FractionalNanoseconds.v + ma.ca_FractionalNanoseconds.m = &ma.w.FractionalNanoseconds.m + return &ma.ca_FractionalNanoseconds, nil + } + return nil, ipld.ErrInvalidKey{TypeName:"data.UnixTime", Key:&_String{k}} +} +func (ma *_UnixTime__Assembler) AssembleKey() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_UnixTime__KeyAssembler)(ma) +} +func (ma *_UnixTime__Assembler) AssembleValue() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + case 0: + ma.ca_Seconds.w = &ma.w.Seconds + ma.ca_Seconds.m = &ma.cm + return &ma.ca_Seconds + case 1: + ma.ca_FractionalNanoseconds.w = ma.w.FractionalNanoseconds.v + ma.ca_FractionalNanoseconds.m = &ma.w.FractionalNanoseconds.m + return &ma.ca_FractionalNanoseconds + default: + panic("unreachable") + } +} +func (ma *_UnixTime__Assembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__UnixTime_sufficient != fieldBits__UnixTime_sufficient { + err := ipld.ErrMissingRequiredField{Missing: make([]string, 0)} + if ma.s & fieldBit__UnixTime_Seconds == 0 { + err.Missing = append(err.Missing, "Seconds") + } + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil +} +func (ma *_UnixTime__Assembler) KeyPrototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (ma *_UnixTime__Assembler) ValuePrototype(k string) ipld.NodePrototype { + panic("todo structbuilder mapassembler valueprototype") +} +type _UnixTime__KeyAssembler _UnixTime__Assembler +func (_UnixTime__KeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.BeginMap(0) +} +func (_UnixTime__KeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.BeginList(0) +} +func (na *_UnixTime__KeyAssembler) AssignNull() error { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.AssignNull() +} +func (_UnixTime__KeyAssembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.AssignBool(false) +} +func (_UnixTime__KeyAssembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.AssignInt(0) +} +func (_UnixTime__KeyAssembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.AssignFloat(0) +} +func (ka *_UnixTime__KeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + case "Seconds": + if ka.s & fieldBit__UnixTime_Seconds != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_Seconds} + } + ka.s += fieldBit__UnixTime_Seconds + ka.state = maState_expectValue + ka.f = 0 + case "FractionalNanoseconds": + if ka.s & fieldBit__UnixTime_FractionalNanoseconds != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_FractionalNanoseconds} + } + ka.s += fieldBit__UnixTime_FractionalNanoseconds + ka.state = maState_expectValue + ka.f = 1 + default: + return ipld.ErrInvalidKey{TypeName:"data.UnixTime", Key:&_String{k}} + } + return nil +} +func (_UnixTime__KeyAssembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.AssignBytes(nil) +} +func (_UnixTime__KeyAssembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.UnixTime.KeyAssembler"}.AssignLink(nil) +} +func (ka *_UnixTime__KeyAssembler) AssignNode(v ipld.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } +} +func (_UnixTime__KeyAssembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (UnixTime) Type() schema.Type { + return nil /*TODO:typelit*/ +} +func (n UnixTime) Representation() ipld.Node { + return (*_UnixTime__Repr)(n) +} +type _UnixTime__Repr _UnixTime +var ( + fieldName__UnixTime_Seconds_serial = _String{"Seconds"} + fieldName__UnixTime_FractionalNanoseconds_serial = _String{"FractionalNanoseconds"} +) +var _ ipld.Node = &_UnixTime__Repr{} +func (_UnixTime__Repr) Kind() ipld.Kind { + return ipld.Kind_Map +} +func (n *_UnixTime__Repr) LookupByString(key string) (ipld.Node, error) { + switch key { + case "Seconds": + return n.Seconds.Representation(), nil + case "FractionalNanoseconds": + if n.FractionalNanoseconds.m == schema.Maybe_Absent { + return ipld.Absent, ipld.ErrNotExists{Segment: ipld.PathSegmentOfString(key)} + } + return n.FractionalNanoseconds.v.Representation(), nil + default: + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } +} +func (n *_UnixTime__Repr) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} +func (_UnixTime__Repr) LookupByIndex(idx int64) (ipld.Node, error) { + return mixins.Map{"data.UnixTime.Repr"}.LookupByIndex(0) +} +func (n _UnixTime__Repr) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} +func (n *_UnixTime__Repr) MapIterator() ipld.MapIterator { + end := 2 + if n.FractionalNanoseconds.m == schema.Maybe_Absent { + end = 1 + } else { + goto done + } +done: + return &_UnixTime__ReprMapItr{n, 0, end} +} + +type _UnixTime__ReprMapItr struct { + n *_UnixTime__Repr + idx int + end int +} + +func (itr *_UnixTime__ReprMapItr) Next() (k ipld.Node, v ipld.Node, _ error) {advance:if itr.idx >= 2 { + return nil, nil, ipld.ErrIteratorOverread{} + } + switch itr.idx { + case 0: + k = &fieldName__UnixTime_Seconds_serial + v = itr.n.Seconds.Representation() + case 1: + k = &fieldName__UnixTime_FractionalNanoseconds_serial + if itr.n.FractionalNanoseconds.m == schema.Maybe_Absent { + itr.idx++ + goto advance + } + v = itr.n.FractionalNanoseconds.v.Representation() + default: + panic("unreachable") + } + itr.idx++ + return +} +func (itr *_UnixTime__ReprMapItr) Done() bool { + return itr.idx >= itr.end +} +func (_UnixTime__Repr) ListIterator() ipld.ListIterator { + return nil +} +func (rn *_UnixTime__Repr) Length() int64 { + l := 2 + if rn.FractionalNanoseconds.m == schema.Maybe_Absent { + l-- + } + return int64(l) +} +func (_UnixTime__Repr) IsAbsent() bool { + return false +} +func (_UnixTime__Repr) IsNull() bool { + return false +} +func (_UnixTime__Repr) AsBool() (bool, error) { + return mixins.Map{"data.UnixTime.Repr"}.AsBool() +} +func (_UnixTime__Repr) AsInt() (int64, error) { + return mixins.Map{"data.UnixTime.Repr"}.AsInt() +} +func (_UnixTime__Repr) AsFloat() (float64, error) { + return mixins.Map{"data.UnixTime.Repr"}.AsFloat() +} +func (_UnixTime__Repr) AsString() (string, error) { + return mixins.Map{"data.UnixTime.Repr"}.AsString() +} +func (_UnixTime__Repr) AsBytes() ([]byte, error) { + return mixins.Map{"data.UnixTime.Repr"}.AsBytes() +} +func (_UnixTime__Repr) AsLink() (ipld.Link, error) { + return mixins.Map{"data.UnixTime.Repr"}.AsLink() +} +func (_UnixTime__Repr) Prototype() ipld.NodePrototype { + return _UnixTime__ReprPrototype{} +} +type _UnixTime__ReprPrototype struct{} + +func (_UnixTime__ReprPrototype) NewBuilder() ipld.NodeBuilder { + var nb _UnixTime__ReprBuilder + nb.Reset() + return &nb +} +type _UnixTime__ReprBuilder struct { + _UnixTime__ReprAssembler +} +func (nb *_UnixTime__ReprBuilder) Build() ipld.Node { + if *nb.m != schema.Maybe_Value { + panic("invalid state: cannot call Build on an assembler that's not finished") + } + return nb.w +} +func (nb *_UnixTime__ReprBuilder) Reset() { + var w _UnixTime + var m schema.Maybe + *nb = _UnixTime__ReprBuilder{_UnixTime__ReprAssembler{w: &w, m: &m}} +} +type _UnixTime__ReprAssembler struct { + w *_UnixTime + m *schema.Maybe + state maState + s int + f int + + cm schema.Maybe + ca_Seconds _Int__ReprAssembler + ca_FractionalNanoseconds _Int__ReprAssembler + } + +func (na *_UnixTime__ReprAssembler) reset() { + na.state = maState_initial + na.s = 0 + na.ca_Seconds.reset() + na.ca_FractionalNanoseconds.reset() +} +func (na *_UnixTime__ReprAssembler) BeginMap(int64) (ipld.MapAssembler, error) { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: it makes no sense to 'begin' twice on the same assembler!") + } + *na.m = midvalue + if na.w == nil { + na.w = &_UnixTime{} + } + return na, nil +} +func (_UnixTime__ReprAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.MapAssembler{"data.UnixTime.Repr"}.BeginList(0) +} +func (na *_UnixTime__ReprAssembler) AssignNull() error { + switch *na.m { + case allowNull: + *na.m = schema.Maybe_Null + return nil + case schema.Maybe_Absent: + return mixins.MapAssembler{"data.UnixTime.Repr.Repr"}.AssignNull() + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + panic("unreachable") +} +func (_UnixTime__ReprAssembler) AssignBool(bool) error { + return mixins.MapAssembler{"data.UnixTime.Repr"}.AssignBool(false) +} +func (_UnixTime__ReprAssembler) AssignInt(int64) error { + return mixins.MapAssembler{"data.UnixTime.Repr"}.AssignInt(0) +} +func (_UnixTime__ReprAssembler) AssignFloat(float64) error { + return mixins.MapAssembler{"data.UnixTime.Repr"}.AssignFloat(0) +} +func (_UnixTime__ReprAssembler) AssignString(string) error { + return mixins.MapAssembler{"data.UnixTime.Repr"}.AssignString("") +} +func (_UnixTime__ReprAssembler) AssignBytes([]byte) error { + return mixins.MapAssembler{"data.UnixTime.Repr"}.AssignBytes(nil) +} +func (_UnixTime__ReprAssembler) AssignLink(ipld.Link) error { + return mixins.MapAssembler{"data.UnixTime.Repr"}.AssignLink(nil) +} +func (na *_UnixTime__ReprAssembler) AssignNode(v ipld.Node) error { + if v.IsNull() { + return na.AssignNull() + } + if v2, ok := v.(*_UnixTime); ok { + switch *na.m { + case schema.Maybe_Value, schema.Maybe_Null: + panic("invalid state: cannot assign into assembler that's already finished") + case midvalue: + panic("invalid state: cannot assign null into an assembler that's already begun working on recursive structures!") + } + if na.w == nil { + na.w = v2 + *na.m = schema.Maybe_Value + return nil + } + *na.w = *v2 + *na.m = schema.Maybe_Value + return nil + } + if v.Kind() != ipld.Kind_Map { + return ipld.ErrWrongKind{TypeName: "data.UnixTime.Repr", MethodName: "AssignNode", AppropriateKind: ipld.KindSet_JustMap, ActualKind: v.Kind()} + } + itr := v.MapIterator() + for !itr.Done() { + k, v, err := itr.Next() + if err != nil { + return err + } + if err := na.AssembleKey().AssignNode(k); err != nil { + return err + } + if err := na.AssembleValue().AssignNode(v); err != nil { + return err + } + } + return na.Finish() +} +func (_UnixTime__ReprAssembler) Prototype() ipld.NodePrototype { + return _UnixTime__ReprPrototype{} +} +func (ma *_UnixTime__ReprAssembler) valueFinishTidy() bool { + switch ma.f { + case 0: + switch ma.cm { + case schema.Maybe_Value:ma.cm = schema.Maybe_Absent + ma.state = maState_initial + return true + default: + return false + } + case 1: + switch ma.w.FractionalNanoseconds.m { + case schema.Maybe_Value: + ma.w.FractionalNanoseconds.v = ma.ca_FractionalNanoseconds.w + ma.state = maState_initial + return true + default: + return false + } + default: + panic("unreachable") + } +} +func (ma *_UnixTime__ReprAssembler) AssembleEntry(k string) (ipld.NodeAssembler, error) { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleEntry cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleEntry cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleEntry cannot be called on an assembler that's already finished") + } + switch k { + case "Seconds": + if ma.s & fieldBit__UnixTime_Seconds != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_Seconds_serial} + } + ma.s += fieldBit__UnixTime_Seconds + ma.state = maState_midValue + ma.f = 0 + ma.ca_Seconds.w = &ma.w.Seconds + ma.ca_Seconds.m = &ma.cm + return &ma.ca_Seconds, nil + case "FractionalNanoseconds": + if ma.s & fieldBit__UnixTime_FractionalNanoseconds != 0 { + return nil, ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_FractionalNanoseconds_serial} + } + ma.s += fieldBit__UnixTime_FractionalNanoseconds + ma.state = maState_midValue + ma.f = 1 + ma.ca_FractionalNanoseconds.w = ma.w.FractionalNanoseconds.v + ma.ca_FractionalNanoseconds.m = &ma.w.FractionalNanoseconds.m + + return &ma.ca_FractionalNanoseconds, nil + default: + } + return nil, ipld.ErrInvalidKey{TypeName:"data.UnixTime.Repr", Key:&_String{k}} +} +func (ma *_UnixTime__ReprAssembler) AssembleKey() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: AssembleKey cannot be called when in the middle of assembling another key") + case maState_expectValue: + panic("invalid state: AssembleKey cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: AssembleKey cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: AssembleKey cannot be called on an assembler that's already finished") + } + ma.state = maState_midKey + return (*_UnixTime__ReprKeyAssembler)(ma) +} +func (ma *_UnixTime__ReprAssembler) AssembleValue() ipld.NodeAssembler { + switch ma.state { + case maState_initial: + panic("invalid state: AssembleValue cannot be called when no key is primed") + case maState_midKey: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling a key") + case maState_expectValue: + // carry on + case maState_midValue: + panic("invalid state: AssembleValue cannot be called when in the middle of assembling another value") + case maState_finished: + panic("invalid state: AssembleValue cannot be called on an assembler that's already finished") + } + ma.state = maState_midValue + switch ma.f { + case 0: + ma.ca_Seconds.w = &ma.w.Seconds + ma.ca_Seconds.m = &ma.cm + return &ma.ca_Seconds + case 1: + ma.ca_FractionalNanoseconds.w = ma.w.FractionalNanoseconds.v + ma.ca_FractionalNanoseconds.m = &ma.w.FractionalNanoseconds.m + + return &ma.ca_FractionalNanoseconds + default: + panic("unreachable") + } +} +func (ma *_UnixTime__ReprAssembler) Finish() error { + switch ma.state { + case maState_initial: + // carry on + case maState_midKey: + panic("invalid state: Finish cannot be called when in the middle of assembling a key") + case maState_expectValue: + panic("invalid state: Finish cannot be called when expecting start of value assembly") + case maState_midValue: + if !ma.valueFinishTidy() { + panic("invalid state: Finish cannot be called when in the middle of assembling a value") + } // if tidy success: carry on + case maState_finished: + panic("invalid state: Finish cannot be called on an assembler that's already finished") + } + if ma.s & fieldBits__UnixTime_sufficient != fieldBits__UnixTime_sufficient { + err := ipld.ErrMissingRequiredField{Missing: make([]string, 0)} + if ma.s & fieldBit__UnixTime_Seconds == 0 { + err.Missing = append(err.Missing, "Seconds") + } + return err + } + ma.state = maState_finished + *ma.m = schema.Maybe_Value + return nil +} +func (ma *_UnixTime__ReprAssembler) KeyPrototype() ipld.NodePrototype { + return _String__Prototype{} +} +func (ma *_UnixTime__ReprAssembler) ValuePrototype(k string) ipld.NodePrototype { + panic("todo structbuilder mapassembler repr valueprototype") +} +type _UnixTime__ReprKeyAssembler _UnixTime__ReprAssembler +func (_UnixTime__ReprKeyAssembler) BeginMap(sizeHint int64) (ipld.MapAssembler, error) { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.BeginMap(0) +} +func (_UnixTime__ReprKeyAssembler) BeginList(sizeHint int64) (ipld.ListAssembler, error) { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.BeginList(0) +} +func (na *_UnixTime__ReprKeyAssembler) AssignNull() error { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.AssignNull() +} +func (_UnixTime__ReprKeyAssembler) AssignBool(bool) error { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.AssignBool(false) +} +func (_UnixTime__ReprKeyAssembler) AssignInt(int64) error { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.AssignInt(0) +} +func (_UnixTime__ReprKeyAssembler) AssignFloat(float64) error { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.AssignFloat(0) +} +func (ka *_UnixTime__ReprKeyAssembler) AssignString(k string) error { + if ka.state != maState_midKey { + panic("misuse: KeyAssembler held beyond its valid lifetime") + } + switch k { + case "Seconds": + if ka.s & fieldBit__UnixTime_Seconds != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_Seconds_serial} + } + ka.s += fieldBit__UnixTime_Seconds + ka.state = maState_expectValue + ka.f = 0 + return nil + case "FractionalNanoseconds": + if ka.s & fieldBit__UnixTime_FractionalNanoseconds != 0 { + return ipld.ErrRepeatedMapKey{Key: &fieldName__UnixTime_FractionalNanoseconds_serial} + } + ka.s += fieldBit__UnixTime_FractionalNanoseconds + ka.state = maState_expectValue + ka.f = 1 + return nil + } + return ipld.ErrInvalidKey{TypeName:"data.UnixTime.Repr", Key:&_String{k}} +} +func (_UnixTime__ReprKeyAssembler) AssignBytes([]byte) error { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.AssignBytes(nil) +} +func (_UnixTime__ReprKeyAssembler) AssignLink(ipld.Link) error { + return mixins.StringAssembler{"data.UnixTime.Repr.KeyAssembler"}.AssignLink(nil) +} +func (ka *_UnixTime__ReprKeyAssembler) AssignNode(v ipld.Node) error { + if v2, err := v.AsString(); err != nil { + return err + } else { + return ka.AssignString(v2) + } +} +func (_UnixTime__ReprKeyAssembler) Prototype() ipld.NodePrototype { + return _String__Prototype{} +} + diff --git a/data/ipldsch_types.go b/data/ipldsch_types.go new file mode 100644 index 0000000..5fc6ae0 --- /dev/null +++ b/data/ipldsch_types.go @@ -0,0 +1,83 @@ +package data + +// Code generated by go-ipld-prime gengo. DO NOT EDIT. + +import ( + ipld "github.com/ipld/go-ipld-prime" +) +var _ ipld.Node = nil // suppress errors when this dependency is not referenced +// Type is a struct embeding a NodePrototype/Type for every Node implementation in this package. +// One of its major uses is to start the construction of a value. +// You can use it like this: +// +// data.Type.YourTypeName.NewBuilder().BeginMap() //... +// +// and: +// +// data.Type.OtherTypeName.NewBuilder().AssignString("x") // ... +// +var Type typeSlab + +type typeSlab struct { + BlockSizes _BlockSizes__Prototype + BlockSizes__Repr _BlockSizes__ReprPrototype + Bytes _Bytes__Prototype + Bytes__Repr _Bytes__ReprPrototype + Int _Int__Prototype + Int__Repr _Int__ReprPrototype + String _String__Prototype + String__Repr _String__ReprPrototype + UnixFSData _UnixFSData__Prototype + UnixFSData__Repr _UnixFSData__ReprPrototype + UnixFSMetadata _UnixFSMetadata__Prototype + UnixFSMetadata__Repr _UnixFSMetadata__ReprPrototype + UnixTime _UnixTime__Prototype + UnixTime__Repr _UnixTime__ReprPrototype +} + +// --- type definitions follow --- + +// BlockSizes matches the IPLD Schema type "BlockSizes". It has list kind. +type BlockSizes = *_BlockSizes +type _BlockSizes struct { + x []_Int +} + +// Bytes matches the IPLD Schema type "Bytes". It has bytes kind. +type Bytes = *_Bytes +type _Bytes struct{ x []byte } + +// Int matches the IPLD Schema type "Int". It has int kind. +type Int = *_Int +type _Int struct{ x int64 } + +// String matches the IPLD Schema type "String". It has string kind. +type String = *_String +type _String struct{ x string } + +// UnixFSData matches the IPLD Schema type "UnixFSData". It has Struct type-kind, and may be interrogated like map kind. +type UnixFSData = *_UnixFSData +type _UnixFSData struct { + DataType _Int + Data _Bytes__Maybe + FileSize _Int__Maybe + BlockSizes _BlockSizes + HashType _Int__Maybe + Fanout _Int__Maybe + Mode _Int__Maybe + Mtime _UnixTime__Maybe +} + +// UnixFSMetadata matches the IPLD Schema type "UnixFSMetadata". It has Struct type-kind, and may be interrogated like map kind. +type UnixFSMetadata = *_UnixFSMetadata +type _UnixFSMetadata struct { + MimeType _String__Maybe +} + +// UnixTime matches the IPLD Schema type "UnixTime". It has Struct type-kind, and may be interrogated like map kind. +type UnixTime = *_UnixTime +type _UnixTime struct { + Seconds _Int + FractionalNanoseconds _Int__Maybe +} + diff --git a/data/marshal.go b/data/marshal.go new file mode 100644 index 0000000..79dbb50 --- /dev/null +++ b/data/marshal.go @@ -0,0 +1,84 @@ +package data + +import "google.golang.org/protobuf/encoding/protowire" + +// EncodeUnixFSData serializes a UnixFSData node to bytes +func EncodeUnixFSData(node UnixFSData) []byte { + // 1KiB can be allocated on the stack, and covers most small nodes + // without having to grow the buffer and cause allocations. + enc := make([]byte, 0, 1024) + + return AppendEncodeUnixFSData(enc, node) +} + +func AppendEncodeUnixFSData(enc []byte, node UnixFSData) []byte { + enc = protowire.AppendTag(enc, Data_DataTypeWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(node.FieldDataType().Int())) + if node.FieldData().Exists() { + enc = protowire.AppendTag(enc, Data_DataWireNum, protowire.BytesType) + enc = protowire.AppendBytes(enc, node.FieldData().Must().Bytes()) + } + if node.FieldFileSize().Exists() { + enc = protowire.AppendTag(enc, Data_FileSizeWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(node.FieldFileSize().Must().Int())) + } + itr := node.FieldBlockSizes().Iterator() + for !itr.Done() { + _, nd := itr.Next() + enc = protowire.AppendTag(enc, Data_BlockSizesWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(nd.Int())) + } + if node.FieldHashType().Exists() { + enc = protowire.AppendTag(enc, Data_HashTypeWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(node.FieldHashType().Must().Int())) + } + if node.FieldFanout().Exists() { + enc = protowire.AppendTag(enc, Data_FanoutWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(node.FieldFanout().Must().Int())) + } + if node.FieldMode().Exists() && node.FieldMode().Must().Int() != int64(DefaultPermissions(node)) { + enc = protowire.AppendTag(enc, Data_ModeWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(node.FieldMode().Must().Int())) + } + if node.FieldMtime().Exists() { + mtime := node.FieldMtime().Must() + size := 0 + size += protowire.SizeTag(1) + size += protowire.SizeVarint(uint64(mtime.FieldSeconds().Int())) + if mtime.FieldFractionalNanoseconds().Exists() { + size += protowire.SizeTag(2) + size += protowire.SizeFixed32() + } + enc = protowire.AppendTag(enc, Data_MtimeWireNum, protowire.BytesType) + enc = protowire.AppendVarint(enc, uint64(size)) + enc = AppendEncodeUnixTime(enc, mtime) + } + return enc +} + +func AppendEncodeUnixTime(enc []byte, node UnixTime) []byte { + enc = protowire.AppendTag(enc, UnixTime_SecondsWireNum, protowire.VarintType) + enc = protowire.AppendVarint(enc, uint64(node.FieldSeconds().Int())) + if node.FieldFractionalNanoseconds().Exists() { + enc = protowire.AppendTag(enc, UnixTime_FractionalNanosecondsWireNum, protowire.Fixed32Type) + enc = protowire.AppendFixed32(enc, uint32(node.FieldFractionalNanoseconds().Must().Int())) + } + return enc +} + +// EncodeUnixFSMetadata serializes a UnixFSMetadata node to bytes +func EncodeUnixFSMetadata(node UnixFSMetadata) []byte { + // 1KiB can be allocated on the stack, and covers most small nodes + // without having to grow the buffer and cause allocations. + enc := make([]byte, 0, 1024) + + return AppendEncodeUnixFSMetadata(enc, node) +} + +func AppendEncodeUnixFSMetadata(enc []byte, node UnixFSMetadata) []byte { + if node.FieldMimeType().Exists() { + enc = protowire.AppendTag(enc, Metadata_MimeTypeWireNum, protowire.BytesType) + enc = protowire.AppendBytes(enc, []byte(node.FieldMimeType().Must().String())) + } + return enc +} diff --git a/data/permissions.go b/data/permissions.go new file mode 100644 index 0000000..00652e6 --- /dev/null +++ b/data/permissions.go @@ -0,0 +1,27 @@ +package data + +const FilePermissionsDefault = 0o0644 +const DirectorPerimissionsDefault = 0o0755 +const HAMTShardPerimissionsDefault = 0o0755 + +func (u UnixFSData) Permissions() int { + if u.FieldMode().Exists() { + return int(u.FieldMode().Must().Int() & 0xFFF) + } + return DefaultPermissions(u) +} + +// DefaultPermissions gets the default permissions for a UnixFS object based on its +// type +func DefaultPermissions(u UnixFSData) int { + switch u.FieldDataType().Int() { + case Data_File: + return FilePermissionsDefault + case Data_Directory: + return DirectorPerimissionsDefault + case Data_HAMTShard: + return HAMTShardPerimissionsDefault + default: + return 0 + } +} diff --git a/data/unmarshal.go b/data/unmarshal.go new file mode 100644 index 0000000..c46ed62 --- /dev/null +++ b/data/unmarshal.go @@ -0,0 +1,293 @@ +package data + +import ( + "errors" + "math" + + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/fluent/qp" + "google.golang.org/protobuf/encoding/protowire" +) + +func DecodeUnixFSData(src []byte) (UnixFSData, error) { + nd, err := qp.BuildMap(Type.UnixFSData, -1, func(ma ipld.MapAssembler) { + err := consumeUnixFSData(src, ma) + if err != nil { + panic(err) + } + }) + if err != nil { + return nil, err + } + return nd.(UnixFSData), nil +} + +func consumeUnixFSData(remaining []byte, ma ipld.MapAssembler) error { + var bsa ipld.NodeBuilder + var la ipld.ListAssembler + var packedBlockSizes bool + for len(remaining) != 0 { + + fieldNum, wireType, n := protowire.ConsumeTag(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + switch fieldNum { + case Data_DataTypeWireNum: + if wireType != protowire.VarintType { + return ErrWrongWireType{"UnixFSData", Field__DataType, protowire.VarintType, wireType} + } + dataType, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__DataType, qp.Int(int64(dataType))) + case Data_DataWireNum: + if wireType != protowire.BytesType { + return ErrWrongWireType{"UnixFSData", Field__Data, protowire.VarintType, wireType} + } + data, n := protowire.ConsumeBytes(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__Data, qp.Bytes(data)) + case Data_FileSizeWireNum: + if wireType != protowire.VarintType { + return ErrWrongWireType{"UnixFSData", Field__FileSize, protowire.VarintType, wireType} + } + fileSize, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__FileSize, qp.Int(int64(fileSize))) + case Data_BlockSizesWireNum: + switch wireType { + case protowire.VarintType: + if packedBlockSizes { + return errors.New("cannot build blocksizes twice") + } + if la == nil { + bsa = Type.BlockSizes.NewBuilder() + var err error + la, err = bsa.BeginList(1) + if err != nil { + return err + } + } + blockSize, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.ListEntry(la, qp.Int(int64(blockSize))) + case protowire.BytesType: + if la != nil { + return errors.New("cannot build blocksizes twice") + } + blockSizesBytes, n := protowire.ConsumeBytes(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + // count the number of varints in the array by looking at most + // significant bit not set + var blockSizeCount int64 + for _, integer := range blockSizesBytes { + if integer < 128 { + blockSizeCount++ + } + } + qp.MapEntry(ma, Field__BlockSizes, qp.List(blockSizeCount, func(la ipld.ListAssembler) { + err := consumeBlockSizes(blockSizesBytes, blockSizeCount, la) + if err != nil { + panic(err) + } + })) + default: + return ErrWrongWireType{"UnixFSData", Field__BlockSizes, protowire.VarintType, wireType} + } + case Data_HashTypeWireNum: + if wireType != protowire.VarintType { + return ErrWrongWireType{"UnixFSData", Field__HashType, protowire.VarintType, wireType} + } + hashType, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__HashType, qp.Int(int64(hashType))) + case Data_FanoutWireNum: + if wireType != protowire.VarintType { + return ErrWrongWireType{"UnixFSData", Field__Fanout, protowire.VarintType, wireType} + } + fanout, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__Fanout, qp.Int(int64(fanout))) + case Data_ModeWireNum: + if wireType != protowire.VarintType { + return ErrWrongWireType{"UnixFSData", Field__Mode, protowire.VarintType, wireType} + } + mode, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + if mode > math.MaxUint32 { + return errors.New("mode should be a 32 bit value") + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__Mode, qp.Int(int64(mode))) + case Data_MtimeWireNum: + if wireType != protowire.BytesType { + return ErrWrongWireType{"UnixFSData", Field__Mtime, protowire.BytesType, wireType} + } + mTimeBytes, n := protowire.ConsumeBytes(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__Mtime, qp.Map(-1, func(ma ipld.MapAssembler) { + err := consumeUnixTime(mTimeBytes, ma) + if err != nil { + panic(err) + } + })) + default: + n := protowire.ConsumeFieldValue(fieldNum, wireType, remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + } + } + if !packedBlockSizes { + if la == nil { + qp.MapEntry(ma, Field__BlockSizes, qp.List(0, func(ipld.ListAssembler) {})) + } else { + err := la.Finish() + if err != nil { + return err + } + nd := bsa.Build() + qp.MapEntry(ma, Field__BlockSizes, qp.Node(nd)) + } + } + return nil +} + +func consumeBlockSizes(remaining []byte, count int64, la ipld.ListAssembler) error { + for i := 0; i < int(count); i++ { + blockSize, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.ListEntry(la, qp.Int(int64(blockSize))) + } + if len(remaining) > 0 { + return errors.New("did not consume all block sizes") + } + return nil +} + +func consumeUnixTime(remaining []byte, ma ipld.MapAssembler) error { + for len(remaining) != 0 { + fieldNum, wireType, n := protowire.ConsumeTag(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + + switch fieldNum { + case UnixTime_SecondsWireNum: + if wireType != protowire.VarintType { + return ErrWrongWireType{"UnixTime", Field__Seconds, protowire.VarintType, wireType} + } + seconds, n := protowire.ConsumeVarint(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__Seconds, qp.Int(int64(seconds))) + case UnixTime_FractionalNanosecondsWireNum: + if wireType != protowire.Fixed32Type { + return ErrWrongWireType{"UnixTime", Field__Nanoseconds, protowire.Fixed32Type, wireType} + } + fractionalNanoseconds, n := protowire.ConsumeFixed32(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__Nanoseconds, qp.Int(int64(fractionalNanoseconds))) + default: + n := protowire.ConsumeFieldValue(fieldNum, wireType, remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + } + } + return nil +} +func DecodeUnixTime(src []byte) (UnixTime, error) { + nd, err := qp.BuildMap(Type.UnixTime, -1, func(ma ipld.MapAssembler) { + err := consumeUnixTime(src, ma) + if err != nil { + panic(err) + } + }) + if err != nil { + return nil, err + } + return nd.(UnixTime), err +} + +func DecodeUnixFSMetadata(src []byte) (UnixFSMetadata, error) { + nd, err := qp.BuildMap(Type.UnixFSMetadata, -1, func(ma ipld.MapAssembler) { + err := consumeUnixFSMetadata(src, ma) + if err != nil { + panic(err) + } + }) + if err != nil { + return nil, err + } + return nd.(UnixFSMetadata), nil +} + +func consumeUnixFSMetadata(remaining []byte, ma ipld.MapAssembler) error { + for len(remaining) != 0 { + + fieldNum, wireType, n := protowire.ConsumeTag(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + + switch fieldNum { + case Metadata_MimeTypeWireNum: + if wireType != protowire.BytesType { + return ErrWrongWireType{"UnixFSMetadata", Field__MimeType, protowire.VarintType, wireType} + } + mimeTypeBytes, n := protowire.ConsumeBytes(remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + qp.MapEntry(ma, Field__MimeType, qp.String(string(mimeTypeBytes))) + default: + n := protowire.ConsumeFieldValue(fieldNum, wireType, remaining) + if n < 0 { + return protowire.ParseError(n) + } + remaining = remaining[n:] + } + } + return nil +} diff --git a/data/wirenumbers.go b/data/wirenumbers.go new file mode 100644 index 0000000..5bb1462 --- /dev/null +++ b/data/wirenumbers.go @@ -0,0 +1,17 @@ +package data + +import "google.golang.org/protobuf/encoding/protowire" + +const ( + Data_DataTypeWireNum protowire.Number = 1 + Data_DataWireNum protowire.Number = 2 + Data_FileSizeWireNum protowire.Number = 3 + Data_BlockSizesWireNum protowire.Number = 4 + Data_HashTypeWireNum protowire.Number = 5 + Data_FanoutWireNum protowire.Number = 6 + Data_ModeWireNum protowire.Number = 7 + Data_MtimeWireNum protowire.Number = 8 + UnixTime_SecondsWireNum protowire.Number = 1 + UnixTime_FractionalNanosecondsWireNum protowire.Number = 2 + Metadata_MimeTypeWireNum protowire.Number = 1 +) diff --git a/directory/basicdir.go b/directory/basicdir.go new file mode 100644 index 0000000..efa7c56 --- /dev/null +++ b/directory/basicdir.go @@ -0,0 +1,152 @@ +package directory + +import ( + "context" + + "github.com/ipfs/go-unixfsnode/data" + "github.com/ipfs/go-unixfsnode/iter" + "github.com/ipfs/go-unixfsnode/utils" + dagpb "github.com/ipld/go-codec-dagpb" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/schema" +) + +var _ ipld.Node = UnixFSBasicDir(nil) +var _ schema.TypedNode = UnixFSBasicDir(nil) + +type UnixFSBasicDir = *_UnixFSBasicDir + +type _UnixFSBasicDir struct { + _substrate dagpb.PBNode +} + +func NewUnixFSBasicDir(ctx context.Context, substrate dagpb.PBNode, nddata data.UnixFSData, _ *ipld.LinkSystem) (ipld.Node, error) { + if nddata.FieldDataType().Int() != data.Data_Directory { + return nil, data.ErrWrongNodeType{data.Data_Directory, nddata.FieldDataType().Int()} + } + return &_UnixFSBasicDir{_substrate: substrate}, nil +} + +func (n UnixFSBasicDir) Kind() ipld.Kind { + return n._substrate.Kind() +} + +// LookupByString looks for the key in the list of links with a matching name +func (n UnixFSBasicDir) LookupByString(key string) (ipld.Node, error) { + links := n._substrate.FieldLinks() + link := utils.Lookup(links, key) + if link == nil { + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} + } + return link, nil +} + +func (n UnixFSBasicDir) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} + +func (n UnixFSBasicDir) LookupByIndex(idx int64) (ipld.Node, error) { + return n._substrate.LookupByIndex(idx) +} + +func (n UnixFSBasicDir) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} + +func (n UnixFSBasicDir) MapIterator() ipld.MapIterator { + return iter.NewUnixFSDirMapIterator(n._substrate.Links.Iterator(), nil) +} + +// ListIterator returns an iterator which yields key-value pairs +// traversing the node. +// If the node kind is anything other than a list, nil will be returned. +// +// The iterator will yield every entry in the list; that is, it +// can be expected that itr.Next will be called node.Length times +// before itr.Done becomes true. +func (n UnixFSBasicDir) ListIterator() ipld.ListIterator { + return nil +} + +// Length returns the length of a list, or the number of entries in a map, +// or -1 if the node is not of list nor map kind. +func (n UnixFSBasicDir) Length() int64 { + return n._substrate.FieldLinks().Length() +} + +func (n UnixFSBasicDir) IsAbsent() bool { + return false +} + +func (n UnixFSBasicDir) IsNull() bool { + return false +} + +func (n UnixFSBasicDir) AsBool() (bool, error) { + return n._substrate.AsBool() +} + +func (n UnixFSBasicDir) AsInt() (int64, error) { + return n._substrate.AsInt() +} + +func (n UnixFSBasicDir) AsFloat() (float64, error) { + return n._substrate.AsFloat() +} + +func (n UnixFSBasicDir) AsString() (string, error) { + return n._substrate.AsString() +} + +func (n UnixFSBasicDir) AsBytes() ([]byte, error) { + return n._substrate.AsBytes() +} + +func (n UnixFSBasicDir) AsLink() (ipld.Link, error) { + return n._substrate.AsLink() +} + +func (n UnixFSBasicDir) Prototype() ipld.NodePrototype { + // TODO: should this return something? + // probobly not until we write the write interfaces + return nil +} + +// satisfy schema.TypedNode +func (UnixFSBasicDir) Type() schema.Type { + return nil /*TODO:typelit*/ +} + +func (n UnixFSBasicDir) Representation() ipld.Node { + return n._substrate.Representation() +} + +// Native map accessors + +func (n UnixFSBasicDir) Iterator() *iter.UnixFSDir__Itr { + + return iter.NewUnixFSDirIterator(n._substrate.Links.Iterator(), nil) +} + +func (n UnixFSBasicDir) Lookup(key dagpb.String) dagpb.Link { + return utils.Lookup(n._substrate.FieldLinks(), key.String()) +} + +// direct access to the links and data + +func (n UnixFSBasicDir) FieldLinks() dagpb.PBLinks { + return n._substrate.FieldLinks() +} + +func (n UnixFSBasicDir) FieldData() dagpb.MaybeBytes { + return n._substrate.FieldData() +} + +// Substrate returns the underlying PBNode -- note: only the substrate will encode successfully to protobuf if writing +func (n UnixFSBasicDir) Substrate() ipld.Node { + return n._substrate +} diff --git a/go.mod b/go.mod index b24f372..76d505f 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,13 @@ module github.com/ipfs/go-unixfsnode go 1.15 require ( - github.com/ipld/go-codec-dagpb v1.1.0 - github.com/ipld/go-ipld-prime v0.9.0 + github.com/Stebalien/go-bitfield v0.0.1 + github.com/ipfs/go-ipld-format v0.2.0 + github.com/ipfs/go-merkledag v0.3.2 + github.com/ipfs/go-unixfs v0.2.4 + github.com/ipld/go-codec-dagpb v1.2.1-0.20210330082435-8ec6b0fbad18 + github.com/ipld/go-ipld-prime v0.9.1-0.20210402181957-7406578571d1 + github.com/spaolacci/murmur3 v1.1.0 + github.com/stretchr/testify v1.7.0 + google.golang.org/protobuf v1.26.0 ) diff --git a/go.sum b/go.sum index 2d33d17..77b3507 100644 --- a/go.sum +++ b/go.sum @@ -1,27 +1,212 @@ +github.com/AndreasBriese/bbloom v0.0.0-20180913140656-343706a395b7/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= +github.com/Kubuxu/go-os-helper v0.0.1/go.mod h1:N8B+I7vPCT80IcP58r50u4+gEEcsZETFUpAzWW2ep1Y= +github.com/Stebalien/go-bitfield v0.0.1 h1:X3kbSSPUaJK60wV2hjOPZwmpljr6VGCqdq4cBLhbQBo= +github.com/Stebalien/go-bitfield v0.0.1/go.mod h1:GNjFpasyUVkHMsfEOk8EFLJ9syQ6SI+XWrX9Wf2XH0s= +github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII= +github.com/btcsuite/btcd v0.0.0-20190213025234-306aecffea32/go.mod h1:DrZx5ec/dmnfpw9KyYoQyYo7d0KEvTkk/5M/vbZjAr8= +github.com/btcsuite/btcd v0.0.0-20190523000118-16327141da8c/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btcd v0.0.0-20190605094302-a0d1e3e36d50/go.mod h1:3J08xEfcugPacsc34/LKRU2yO7YmuT8yt28J8k2+rrI= +github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA= +github.com/btcsuite/btcutil v0.0.0-20190207003914-4c204d697803/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg= +github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg= +github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY= +github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc= +github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY= +github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs= +github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TIRis= +github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgraph-io/badger v1.5.5-0.20190226225317-8115aed38f8f/go.mod h1:VZxzAIRPHRVNRKRo6AXrX9BJegn6il06VMTZVJYCIjQ= +github.com/dgryski/go-farm v0.0.0-20190104051053-3adb47b1fb0f/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k= +github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= +github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.3.0/go.mod h1:Qd/q+1AKNOZr9uGQzbzCmRO6sUih6GTPZv6a1/R87v0= +github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= +github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= +github.com/gxed/hashland/keccakpg v0.0.1/go.mod h1:kRzw3HkwxFU1mpmPP8v1WyQzwdGfmKFJ6tItnhQ67kU= +github.com/gxed/hashland/murmur3 v0.0.1/go.mod h1:KjXop02n4/ckmZSnY2+HKcLud/tcmvhST0bie/0lS48= +github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= +github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/huin/goupnp v1.0.0/go.mod h1:n9v9KO1tAxYH82qOn+UTIFQDmx5n1Zxd/ClZDMX7Bnc= +github.com/huin/goutil v0.0.0-20170803182201-1ca381bf3150/go.mod h1:PpLOETDnJ0o3iZrZfqZzyLl6l7F3c6L1oWn7OICBi6o= +github.com/ipfs/bbloom v0.0.1/go.mod h1:oqo8CVWsJFMOZqTglBG4wydCE4IQA/G2/SEofB0rjUI= +github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= +github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/go-bitswap v0.1.0/go.mod h1:FFJEf18E9izuCqUtHxbWEvq+reg7o4CW5wSAE1wsxj0= +github.com/ipfs/go-bitswap v0.1.2/go.mod h1:qxSWS4NXGs7jQ6zQvoPY3+NmOfHHG47mhkiLzBpJQIs= +github.com/ipfs/go-block-format v0.0.1/go.mod h1:DK/YYcsSUIVAFNwo/KZCdIIbpN0ROH/baNLgayt4pFc= +github.com/ipfs/go-block-format v0.0.2 h1:qPDvcP19izTjU8rgo6p7gTXZlkMkF5bz5G3fqIsSCPE= +github.com/ipfs/go-block-format v0.0.2/go.mod h1:AWR46JfpcObNfg3ok2JHDUfdiHRgWhJgCQF+KIgOPJY= +github.com/ipfs/go-blockservice v0.1.0 h1:dh2i7xjMbCtf0ZSMyQAF2qpV/pEEmM7yVpQ00+gik6U= +github.com/ipfs/go-blockservice v0.1.0/go.mod h1:hzmMScl1kXHg3M2BjTymbVPjv627N7sYcvYaKbop39M= +github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= +github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM= github.com/ipfs/go-cid v0.0.4/go.mod h1:4LLaPOQwmk5z9LBgQnpkivrx8BJjUyGwTXCd5Xfj6+M= github.com/ipfs/go-cid v0.0.7 h1:ysQJVJA3fNDF1qigJbsSQOdjhVLsOEoPdh0+R97k3jY= github.com/ipfs/go-cid v0.0.7/go.mod h1:6Ux9z5e+HpkQdckYoX1PG/6xqKspzlEIR5SDmgqgC/I= -github.com/ipld/go-codec-dagpb v1.1.0 h1:MO3Fa6ZHiXUy6f6o6hSyHmItfKKNyBfBSk838kXDZmI= -github.com/ipld/go-codec-dagpb v1.1.0/go.mod h1:6nBN7X7h8EOsEejZGqC7tej5drsdBAXbMHyBT+Fne5s= +github.com/ipfs/go-datastore v0.0.1/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.0.5/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.1.0/go.mod h1:d4KVXhMt913cLBEI/PXAy6ko+W7e9AhyAKBGh803qeE= +github.com/ipfs/go-datastore v0.3.1 h1:SS1t869a6cctoSYmZXUk8eL6AzVXgASmKIWFNQkQ1jU= +github.com/ipfs/go-datastore v0.3.1/go.mod h1:w38XXW9kVFNp57Zj5knbKWM2T+KOZCGDRVNdgPHtbHw= +github.com/ipfs/go-detect-race v0.0.1/go.mod h1:8BNT7shDZPo99Q74BpGMK+4D8Mn4j46UU0LZ723meps= +github.com/ipfs/go-ds-badger v0.0.2/go.mod h1:Y3QpeSFWQf6MopLTiZD+VT6IC1yZqaGmjvRcKeSGij8= +github.com/ipfs/go-ds-leveldb v0.0.1/go.mod h1:feO8V3kubwsEF22n0YRQCffeb79OOYIykR4L04tMOYc= +github.com/ipfs/go-ipfs-blockstore v0.0.1/go.mod h1:d3WClOmRQKFnJ0Jz/jj/zmksX0ma1gROTlovZKBmN08= +github.com/ipfs/go-ipfs-blockstore v0.1.0 h1:V1GZorHFUIB6YgTJQdq7mcaIpUfCM3fCyVi+MTo9O88= +github.com/ipfs/go-ipfs-blockstore v0.1.0/go.mod h1:5aD0AvHPi7mZc6Ci1WCAhiBQu2IsfTduLl+422H6Rqw= +github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= +github.com/ipfs/go-ipfs-chunker v0.0.1/go.mod h1:tWewYK0we3+rMbOh7pPFGDyypCtvGcBFymgY4rSDLAw= +github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= +github.com/ipfs/go-ipfs-ds-help v0.0.1 h1:QBg+Ts2zgeemK/dB0saiF/ykzRGgfoFMT90Rzo0OnVU= +github.com/ipfs/go-ipfs-ds-help v0.0.1/go.mod h1:gtP9xRaZXqIQRh1HRpp595KbBEdgqWFxefeVKOV8sxo= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1 h1:LJXIo9W7CAmugqI+uofioIpRb6rY30GUu7G6LUfpMvM= +github.com/ipfs/go-ipfs-exchange-interface v0.0.1/go.mod h1:c8MwfHjtQjPoDyiy9cFquVtVHkO9b9Ob3FG91qJnWCM= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1 h1:P56jYKZF7lDDOLx5SotVh5KFxoY6C81I1NSHW1FxGew= +github.com/ipfs/go-ipfs-exchange-offline v0.0.1/go.mod h1:WhHSFCVYX36H/anEKQboAzpUws3x7UeEGkzQc3iNkM0= +github.com/ipfs/go-ipfs-files v0.0.3/go.mod h1:INEFm0LL2LWXBhNJ2PMIIb2w45hpXgPjNoE7yA8Y1d4= +github.com/ipfs/go-ipfs-posinfo v0.0.1/go.mod h1:SwyeVP+jCwiDu0C313l/8jg6ZxM0qqtlt2a0vILTc1A= +github.com/ipfs/go-ipfs-pq v0.0.1/go.mod h1:LWIqQpqfRG3fNc5XsnIhz/wQ2XXGyugQwls7BgUmUfY= +github.com/ipfs/go-ipfs-routing v0.1.0/go.mod h1:hYoUkJLyAUKhF58tysKpids8RNDPO42BVMgK5dNsoqY= +github.com/ipfs/go-ipfs-util v0.0.1 h1:Wz9bL2wB2YBJqggkA4dD7oSmqB4cAnpNbGrlHJulv50= +github.com/ipfs/go-ipfs-util v0.0.1/go.mod h1:spsl5z8KUnrve+73pOhSVZND1SIxPW5RyBCNzQxlJBc= +github.com/ipfs/go-ipld-cbor v0.0.2/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-cbor v0.0.3 h1:ENsxvybwkmke7Z/QJOmeJfoguj6GH3Y0YOaGrfy9Q0I= +github.com/ipfs/go-ipld-cbor v0.0.3/go.mod h1:wTBtrQZA3SoFKMVkp6cn6HMRteIB1VsmHA0AQFOn7Nc= +github.com/ipfs/go-ipld-format v0.0.1/go.mod h1:kyJtbkDALmFHv3QR6et67i35QzO3S0dCDnkOJhcZkms= +github.com/ipfs/go-ipld-format v0.0.2/go.mod h1:4B6+FM2u9OJ9zCV+kSbgFAZlOrv1Hqbf0INGQgiKf9k= +github.com/ipfs/go-ipld-format v0.2.0 h1:xGlJKkArkmBvowr+GMCX0FEZtkro71K1AwiKnL37mwA= +github.com/ipfs/go-ipld-format v0.2.0/go.mod h1:3l3C1uKoadTPbeNfrDi+xMInYKlx2Cvg1BuydPSdzQs= +github.com/ipfs/go-log v0.0.1 h1:9XTUN/rW64BCG1YhPK9Hoy3q8nr4gOmHHBpgFdfw6Lc= +github.com/ipfs/go-log v0.0.1/go.mod h1:kL1d2/hzSpI0thNYjiKfjanbVNU+IIGA/WnNESY9leM= +github.com/ipfs/go-merkledag v0.2.3/go.mod h1:SQiXrtSts3KGNmgOzMICy5c0POOpUNQLvB3ClKnBAlk= +github.com/ipfs/go-merkledag v0.3.2 h1:MRqj40QkrWkvPswXs4EfSslhZ4RVPRbxwX11js0t1xY= +github.com/ipfs/go-merkledag v0.3.2/go.mod h1:fvkZNNZixVW6cKSZ/JfLlON5OlgTXNdRLz0p6QG/I2M= +github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fGD6n0jO4kdg= +github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= +github.com/ipfs/go-peertaskqueue v0.1.0/go.mod h1:Jmk3IyCcfl1W3jTW3YpghSwSEC6IJ3Vzz/jUmWw8Z0U= +github.com/ipfs/go-unixfs v0.2.4 h1:6NwppOXefWIyysZ4LR/qUBPvXd5//8J3jiMdvpbw6Lo= +github.com/ipfs/go-unixfs v0.2.4/go.mod h1:SUdisfUjNoSDzzhGVxvCL9QO/nKdwXdr+gbMUdqcbYw= +github.com/ipfs/go-verifcid v0.0.1 h1:m2HI7zIuR5TFyQ1b79Da5N9dnnCP1vcu2QqawmWlK2E= +github.com/ipfs/go-verifcid v0.0.1/go.mod h1:5Hrva5KBeIog4A+UpqlaIU+DEstipcJYQQZc0g37pY0= +github.com/ipld/go-codec-dagpb v1.2.1-0.20210330082435-8ec6b0fbad18 h1:TpjpdzJdasjzZ2xw7rmoj4+u9WBkWBTKBYGcyyLXX68= +github.com/ipld/go-codec-dagpb v1.2.1-0.20210330082435-8ec6b0fbad18/go.mod h1:GMLfso6KSkYJlIbd2cGKdGMe/hM5/IukeXRQ+u6zTrQ= github.com/ipld/go-ipld-prime v0.9.0 h1:N2OjJMb+fhyFPwPnVvJcWU/NsumP8etal+d2v3G4eww= github.com/ipld/go-ipld-prime v0.9.0/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db h1:kFwGn8rXa/Z31ev1OFNQsYeNKNCdifnTPl/NvPy5L38= +github.com/ipld/go-ipld-prime v0.9.1-0.20210324083106-dc342a9917db/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/ipld/go-ipld-prime v0.9.1-0.20210402181957-7406578571d1 h1:dIKSj9r+CCXz9t6p4TfbDx34CfSjLfasRZf37SXlNjg= +github.com/ipld/go-ipld-prime v0.9.1-0.20210402181957-7406578571d1/go.mod h1:KvBLMr4PX1gWptgkzRjVZCrLmSGcZCb/jioOQwCqZN8= +github.com/jackpal/gateway v1.0.5/go.mod h1:lTpwd4ACLXmpyiCTRtfiNyVnUmqT9RivzCDQetPfnjA= +github.com/jackpal/go-nat-pmp v1.0.1/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= +github.com/jbenet/go-cienv v0.0.0-20150120210510-1bb1476777ec/go.mod h1:rGaEvXB4uRSZMmzKNLoXvTu1sfx+1kv/DojUlPrSZGs= +github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.0.0-20150120210811-aac704a3f4f2/go.mod h1:8GXXJV31xl8whumTzdZsTt3RnUIiPqzkyf7mxToRCMs= +github.com/jbenet/goprocess v0.0.0-20160826012719-b497e2f366b8/go.mod h1:Ly/wlsjFq/qrU3Rar62tu1gASgGw6chQbSh/XgIIXCY= +github.com/jbenet/goprocess v0.1.3 h1:YKyIEECS/XvcfHtBzxtjBBbWK+MbvA6dG8ASiqwvr10= +github.com/jbenet/goprocess v0.1.3/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= +github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= +github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ= +github.com/jtolds/gls v4.2.1+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo= github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= +github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4= github.com/klauspost/cpuid/v2 v2.0.4 h1:g0I61F2K2DjRHz1cnxlkNSBIaePVoJIjjnHui8QHbiw= github.com/klauspost/cpuid/v2 v2.0.4/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/koron/go-ssdp v0.0.0-20180514024734-4a0ed625a78b/go.mod h1:5Ky9EC2xfoUKUor0Hjgi2BJhCSXJfMOFlmyYrVKGQMk= +github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/libp2p/go-addr-util v0.0.1/go.mod h1:4ac6O7n9rIAKB1dnd+s8IbbMXkt+oBpzX4/+RACcnlQ= +github.com/libp2p/go-buffer-pool v0.0.1/go.mod h1:xtyIz9PMobb13WaxR6Zo1Pd1zXJKYg0a8KiIvDp3TzQ= +github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= +github.com/libp2p/go-conn-security-multistream v0.1.0/go.mod h1:aw6eD7LOsHEX7+2hJkDxw1MteijaVcI+/eP2/x3J1xc= +github.com/libp2p/go-flow-metrics v0.0.1/go.mod h1:Iv1GH0sG8DtYN3SVJ2eG221wMiNpZxBdp967ls1g+k8= +github.com/libp2p/go-libp2p v0.1.0/go.mod h1:6D/2OBauqLUoqcADOJpn9WbKqvaM07tDw68qHM0BxUM= +github.com/libp2p/go-libp2p v0.1.1/go.mod h1:I00BRo1UuUSdpuc8Q2mN7yDF/oTUTRAX6JWpTiK9Rp8= +github.com/libp2p/go-libp2p-autonat v0.1.0/go.mod h1:1tLf2yXxiE/oKGtDwPYWTSYG3PtvYlJmg7NeVtPRqH8= +github.com/libp2p/go-libp2p-blankhost v0.1.1/go.mod h1:pf2fvdLJPsC1FsVrNP3DUUvMzUts2dsLLBEpo1vW1ro= +github.com/libp2p/go-libp2p-circuit v0.1.0/go.mod h1:Ahq4cY3V9VJcHcn1SBXjr78AbFkZeIRmfunbA7pmFh8= +github.com/libp2p/go-libp2p-core v0.0.1/go.mod h1:g/VxnTZ/1ygHxH3dKok7Vno1VfpvGcGip57wjTU4fco= +github.com/libp2p/go-libp2p-core v0.0.2/go.mod h1:9dAcntw/n46XycV4RnlBq3BpgrmyUi9LuoTNdPrbUco= +github.com/libp2p/go-libp2p-core v0.0.3/go.mod h1:j+YQMNz9WNSkNezXOsahp9kwZBKBvxLpKD316QWSJXE= +github.com/libp2p/go-libp2p-crypto v0.1.0/go.mod h1:sPUokVISZiy+nNuTTH/TY+leRSxnFj/2GLjtOTW90hI= +github.com/libp2p/go-libp2p-discovery v0.1.0/go.mod h1:4F/x+aldVHjHDHuX85x1zWoFTGElt8HnoDzwkFZm29g= +github.com/libp2p/go-libp2p-loggables v0.1.0/go.mod h1:EyumB2Y6PrYjr55Q3/tiJ/o3xoDasoRYM7nOzEpoa90= +github.com/libp2p/go-libp2p-mplex v0.2.0/go.mod h1:Ejl9IyjvXJ0T9iqUTE1jpYATQ9NM3g+OtR+EMMODbKo= +github.com/libp2p/go-libp2p-mplex v0.2.1/go.mod h1:SC99Rxs8Vuzrf/6WhmH41kNn13TiYdAWNYHrwImKLnE= +github.com/libp2p/go-libp2p-nat v0.0.4/go.mod h1:N9Js/zVtAXqaeT99cXgTV9e75KpnWCvVOiGzlcHmBbY= +github.com/libp2p/go-libp2p-netutil v0.1.0/go.mod h1:3Qv/aDqtMLTUyQeundkKsA+YCThNdbQD54k3TqjpbFU= +github.com/libp2p/go-libp2p-peer v0.2.0/go.mod h1:RCffaCvUyW2CJmG2gAWVqwePwW7JMgxjsHm7+J5kjWY= +github.com/libp2p/go-libp2p-peerstore v0.1.0/go.mod h1:2CeHkQsr8svp4fZ+Oi9ykN1HBb6u0MOvdJ7YIsmcwtY= +github.com/libp2p/go-libp2p-record v0.1.0/go.mod h1:ujNc8iuE5dlKWVy6wuL6dd58t0n7xI4hAIl8pE6wu5Q= +github.com/libp2p/go-libp2p-secio v0.1.0/go.mod h1:tMJo2w7h3+wN4pgU2LSYeiKPrfqBgkOsdiKK77hE7c8= +github.com/libp2p/go-libp2p-swarm v0.1.0/go.mod h1:wQVsCdjsuZoc730CgOvh5ox6K8evllckjebkdiY5ta4= +github.com/libp2p/go-libp2p-testing v0.0.2/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.3/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-testing v0.0.4/go.mod h1:gvchhf3FQOtBdr+eFUABet5a4MBLK8jM3V4Zghvmi+E= +github.com/libp2p/go-libp2p-transport-upgrader v0.1.1/go.mod h1:IEtA6or8JUbsV07qPW4r01GnTenLW4oi3lOPbUMGJJA= +github.com/libp2p/go-libp2p-yamux v0.2.0/go.mod h1:Db2gU+XfLpm6E4rG5uGCFX6uXA8MEXOxFcRoXUODaK8= +github.com/libp2p/go-libp2p-yamux v0.2.1/go.mod h1:1FBXiHDk1VyRM1C0aez2bCfHQ4vMZKkAQzZbkSQt5fI= +github.com/libp2p/go-maddr-filter v0.0.4/go.mod h1:6eT12kSQMA9x2pvFQa+xesMKUBlj9VImZbj3B9FBH/Q= +github.com/libp2p/go-mplex v0.0.3/go.mod h1:pK5yMLmOoBR1pNCqDlA2GQrdAVTMkqFalaTWe7l4Yd0= +github.com/libp2p/go-mplex v0.1.0/go.mod h1:SXgmdki2kwCUlCCbfGLEgHjC4pFqhTp0ZoV6aiKgxDU= +github.com/libp2p/go-msgio v0.0.2/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-msgio v0.0.3/go.mod h1:63lBBgOTDKQL6EWazRMCwXsEeEeK9O2Cd+0+6OOuipQ= +github.com/libp2p/go-nat v0.0.3/go.mod h1:88nUEt0k0JD45Bk93NIwDqjlhiOwOoV36GchpcVc1yI= +github.com/libp2p/go-reuseport v0.0.1/go.mod h1:jn6RmB1ufnQwl0Q1f+YxAj8isJgDCQzaaxIFYDhcYEA= +github.com/libp2p/go-reuseport-transport v0.0.2/go.mod h1:YkbSDrvjUVDL6b8XqriyA20obEtsW9BLkuOUyQAOCbs= +github.com/libp2p/go-stream-muxer v0.0.1/go.mod h1:bAo8x7YkSpadMTbtTaxGVHWUQsR/l5MEaHbKaliuT14= +github.com/libp2p/go-stream-muxer-multistream v0.2.0/go.mod h1:j9eyPol/LLRqT+GPLSxvimPhNph4sfYfMoDPd7HkzIc= +github.com/libp2p/go-tcp-transport v0.1.0/go.mod h1:oJ8I5VXryj493DEJ7OsBieu8fcg2nHGctwtInJVpipc= +github.com/libp2p/go-testutil v0.1.0/go.mod h1:81b2n5HypcVyrCg/MJx4Wgfp/VHojytjVe/gLzZ2Ehc= +github.com/libp2p/go-ws-transport v0.1.0/go.mod h1:rjw1MG1LU9YDC6gzmwObkPd/Sqwhw7yT74kj3raBFuo= +github.com/libp2p/go-yamux v1.2.2/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/libp2p/go-yamux v1.2.3/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow= +github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ= +github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/miekg/dns v1.1.12/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1 h1:lYpkrQH5ajf0OXOcUbGjvZxxijuBwbbmlSxLiuofa+g= github.com/minio/blake2b-simd v0.0.0-20160723061019-3f5f724cb5b1/go.mod h1:pD8RvIylQ358TN4wwqatJ8rNavkEINozVn9DtGI3dfQ= +github.com/minio/sha256-simd v0.0.0-20190131020904-2d45a736cd16/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.0.0-20190328051042-05b4dd3047e5/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= +github.com/minio/sha256-simd v0.1.0/go.mod h1:2FMWW+8GMoPweT6+pI63m9YE3Lmw4J71hV56Chs1E/U= github.com/minio/sha256-simd v0.1.1-0.20190913151208-6de447530771/go.mod h1:B5e1o+1/KgNmWrSQK08Y6Z1Vb5pwIktudl0J58iy0KM= github.com/minio/sha256-simd v1.0.0 h1:v1ta+49hkWZyvaKwrQB8elexRqm6Y0aMLjCNsrYxo6g= github.com/minio/sha256-simd v1.0.0/go.mod h1:OuYzVNI5vcoYIAmbIvHPl3N3jUzVedXbKy5RFepssQM= github.com/mr-tron/base58 v1.1.0/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= +github.com/mr-tron/base58 v1.1.1/go.mod h1:xcD2VGqlgYjBdcBLw+TuYLr8afG+Hj8g2eTVqeSzSU8= github.com/mr-tron/base58 v1.1.2/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.1.3/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -30,41 +215,118 @@ github.com/multiformats/go-base32 v0.0.3 h1:tw5+NhuwaOjJCC5Pp82QuXbrmLzWg7uxlMFp github.com/multiformats/go-base32 v0.0.3/go.mod h1:pLiuGC8y0QR3Ue4Zug5UzK9LjgbkL8NSQj0zQ5Nz/AA= github.com/multiformats/go-base36 v0.1.0 h1:JR6TyF7JjGd3m6FbLU2cOxhC0Li8z8dLNGQ89tUg4F4= github.com/multiformats/go-base36 v0.1.0/go.mod h1:kFGE83c6s80PklsHO9sRn2NCoffoRdUUOENyW/Vv6sM= +github.com/multiformats/go-multiaddr v0.0.1/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.2/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr v0.0.4/go.mod h1:xKVEak1K9cS1VdmPZW3LSIb6lgmoS58qz/pzqmAxV44= +github.com/multiformats/go-multiaddr-dns v0.0.1/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-dns v0.0.2/go.mod h1:9kWcqw/Pj6FwxAwW38n/9403szc57zJPs45fmnznu3Q= +github.com/multiformats/go-multiaddr-fmt v0.0.1/go.mod h1:aBYjqL4T/7j4Qx+R73XSv/8JsgnRFlf0w2KGLCmXl3Q= +github.com/multiformats/go-multiaddr-net v0.0.1/go.mod h1:nw6HSxNmCIQH27XPGBuX+d1tnvM7ihcFwHMSstNAVUU= github.com/multiformats/go-multibase v0.0.1/go.mod h1:bja2MqRZ3ggyXtZSEDKpl0uO/gviWFaSteVbWT51qgs= github.com/multiformats/go-multibase v0.0.3 h1:l/B6bJDQjvQ5G52jw4QGSYeOTZoAwIO77RblWplfIqk= github.com/multiformats/go-multibase v0.0.3/go.mod h1:5+1R4eQrT3PkYZ24C3W2Ue2tPwIdYQD509ZjSb5y9Oc= +github.com/multiformats/go-multihash v0.0.1/go.mod h1:w/5tugSrLEbWqlcgJabL3oHFKTwfvkofsjW2Qa1ct4U= +github.com/multiformats/go-multihash v0.0.5/go.mod h1:lt/HCbqlQwlPBz7lv0sQCdtfcMtlJvakRUn/0Ual8po= github.com/multiformats/go-multihash v0.0.10/go.mod h1:YSLudS+Pi8NHE7o6tb3D8vrpKa63epEDmG8nTduyAew= github.com/multiformats/go-multihash v0.0.13/go.mod h1:VdAWLKTwram9oKAatUcLxBNUjdtcVwxObEQBtRfuyjc= github.com/multiformats/go-multihash v0.0.15 h1:hWOPdrNqDjwHDx82vsYGSDZNyktOJJ2dzZJzFkOV1jM= github.com/multiformats/go-multihash v0.0.15/go.mod h1:D6aZrWNLFTV/ynMpKsNtB40mJzmCl4jb1alC0OvHiHg= +github.com/multiformats/go-multistream v0.1.0/go.mod h1:fJTiDfXJVmItycydCnNx4+wSzZ5NwG2FEVAI30fiovg= github.com/multiformats/go-varint v0.0.5/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= github.com/multiformats/go-varint v0.0.6 h1:gk85QWKxh3TazbLxED/NlDVv8+q+ReFJk7Y2W/KhfNY= github.com/multiformats/go-varint v0.0.6/go.mod h1:3Ls8CIEsrijN6+B7PbrXRPxHRPuXSrVKRY101jdMZYE= +github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/ginkgo v1.8.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= +github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= +github.com/opentracing/opentracing-go v1.0.2/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/opentracing/opentracing-go v1.1.0 h1:pWlfV3Bxv7k65HYwkikxat0+s3pV4bsqf19k25Ur8rU= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polydawn/refmt v0.0.0-20190221155625-df39d6c2d992/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190408063855-01bf1e26dd14/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= +github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1 h1:CskT+S6Ay54OwxBGB0R3Rsx4Muto6UnEYTyKJbyRIAI= github.com/polydawn/refmt v0.0.0-20190807091052-3d65705ee9f1/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e h1:ZOcivgkkFRnjfoTcGsDq3UQYiBmekwLA+qg0OjyB/ls= -github.com/polydawn/refmt v0.0.0-20201211092308-30ac6d18308e/go.mod h1:uIp+gprXxxrWSjjklXD+mN4wed/tMfjMMmN/9+JsA9o= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.0.0/go.mod h1:kHHU4qYBaI3q23Pp3VPrmWhuIUrLW/7eUrw0BU5VaoM= +github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2RVY1rIf+2J2o/IM9+vPq9RzmHDSseB7FoXiSNIUsoU= +github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/spacemonkeygo/openssl v0.0.0-20181017203307-c2dcc5cca94a/go.mod h1:7AyxJNCJ7SBZ1MfVQCWD6Uqo2oubI2Eq2y2eqf+A5r0= +github.com/spacemonkeygo/spacelog v0.0.0-20180420211403-2296661a0572/go.mod h1:w0SWMsp6j9O/dk4/ZpIhL+3CkG8ofA2vuv7k+ltqUMc= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/syndtr/goleveldb v1.0.0/go.mod h1:ZVVdQEZoIme9iO1Ch2Jdy24qqXrMMOU6lpPAyBWyWuQ= +github.com/warpfork/go-wish v0.0.0-20180510122957-5ad1f5abf436/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/warpfork/go-wish v0.0.0-20190328234359-8b3e70f8e830/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a h1:G++j5e0OC488te356JvdhaM8YS6nMsjLAYF7JxCv07w= github.com/warpfork/go-wish v0.0.0-20200122115046-b9ea61034e4a/go.mod h1:x6AKhvSSexNrVSrViXSHUEbICjmGXhtgABaHIySUSGw= +github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= +github.com/whyrusleeping/go-keyspace v0.0.0-20160322163242-5b898ac5add1/go.mod h1:8UvriyWtv5Q5EOgjHaSseUEdkQfvwFv1I/In/O2M9gc= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc h1:9lDbC6Rz4bwmou+oE6Dt4Cb2BGMur5eR/GYptkKUVHo= +github.com/whyrusleeping/go-logging v0.0.0-20170515211332-0457bb6b88fc/go.mod h1:bopw91TMyo8J3tvftk8xmU2kPmlrt4nScJQZU2hE5EM= +github.com/whyrusleeping/go-notifier v0.0.0-20170827234753-097c5d47330f/go.mod h1:cZNvX9cFybI01GriPRMXDtczuvUhgbcYr9iCGaNlRv8= +github.com/whyrusleeping/mafmt v1.2.8/go.mod h1:faQJFPbLSxzD9xpA02ttW/tS9vZykNvXwGvqIpk20FA= +github.com/whyrusleeping/mdns v0.0.0-20180901202407-ef14215e6b30/go.mod h1:j4l84WPFclQPj320J9gp0XwNKBb3U0zt5CBqjPp22G4= +github.com/whyrusleeping/multiaddr-filter v0.0.0-20160516205228-e903e4adabd7/go.mod h1:X2c0RVCI1eSUFI8eLcY3c0423ykwiUdxLJtkDvruhjI= +golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190211182817-74369b46fc67/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +golang.org/x/crypto v0.0.0-20190225124518-7f87c0fbb88b/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190426145343-a29dc8fdc734/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190530122614-20be4c3c3ed5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83 h1:/ZScEX8SfEmUGRHs0gxpqteO5nfNW6axyZbBdw9A12g= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181011144130-49bb7cea24b1/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= +golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190219092855-153ac476189d/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190228124157-a34e9553db1e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190302025703-b6889370fb10/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190524122548-abf6ff778158/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2 h1:46ULzRKLh1CwgRq2dC5SlBzEqqNCi8rreOZnNrbqcIY= golang.org/x/sys v0.0.0-20210309074719-68d13333faf2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= +google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= +google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk= +google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/hamt/errors.go b/hamt/errors.go new file mode 100644 index 0000000..e24e936 --- /dev/null +++ b/hamt/errors.go @@ -0,0 +1,40 @@ +package hamt + +import "fmt" + +type errorType string + +func (e errorType) Error() string { + return string(e) +} + +const ( + // ErrNotProtobuf indicates an error attempting to load a HAMT from a non-protobuf node + ErrNotProtobuf errorType = "node was not a protobuf node" + // ErrNotUnixFSNode indicates an error attempting to load a HAMT from a generic protobuf node + ErrNotUnixFSNode errorType = "node was not a UnixFS node" + // ErrInvalidChildIndex indicates there is no link to load for the given child index + ErrInvalidChildIndex errorType = "invalid index passed to operate children (likely corrupt bitfield)" + // ErrHAMTTooDeep indicates we attempted to load from a HAMT node that went past the depth of the tree + ErrHAMTTooDeep errorType = "sharded directory too deep" + // ErrInvalidHashType indicates the HAMT node's hash function is unsupported (must be Murmur3) + ErrInvalidHashType errorType = "only murmur3 supported as hash function" + // ErrNoDataField indicates the HAMT node's UnixFS structure lacked a data field, which is + // where a bit mask is stored + ErrNoDataField errorType = "'Data' field not present" + // ErrNoFanoutField indicates the HAMT node's UnixFS structure lacked a fanout field, which is required + ErrNoFanoutField errorType = "'Fanout' field not present" + // ErrHAMTSizeInvalid indicates the HAMT's size property was not an exact power of 2 + ErrHAMTSizeInvalid errorType = "hamt size should be a power of two" + // ErrMissingLinkName indicates a link in a HAMT had no Name property (required for all HAMTs) + ErrMissingLinkName errorType = "missing link name" +) + +// ErrInvalidLinkName indicates a link's name was too short for a HAMT +type ErrInvalidLinkName struct { + Name string +} + +func (e ErrInvalidLinkName) Error() string { + return fmt.Sprintf("invalid link name '%s'", e.Name) +} diff --git a/hamt/shardeddir.go b/hamt/shardeddir.go new file mode 100644 index 0000000..553baea --- /dev/null +++ b/hamt/shardeddir.go @@ -0,0 +1,363 @@ +package hamt + +import ( + "context" + "fmt" + + "github.com/Stebalien/go-bitfield" + "github.com/ipfs/go-unixfsnode/data" + "github.com/ipfs/go-unixfsnode/iter" + dagpb "github.com/ipld/go-codec-dagpb" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/schema" +) + +const ( + // HashMurmur3 is the multiformats identifier for Murmur3 + HashMurmur3 uint64 = 0x22 +) + +var _ ipld.Node = UnixFSHAMTShard(nil) +var _ schema.TypedNode = UnixFSHAMTShard(nil) + +// UnixFSHAMTShared is an IPLD Prime Node that provides a read interface +// to a UnixFS HAMT +type UnixFSHAMTShard = *_UnixFSHAMTShard + +type _UnixFSHAMTShard struct { + ctx context.Context + _substrate dagpb.PBNode + data data.UnixFSData + lsys *ipld.LinkSystem + bitfield bitfield.Bitfield + shardCache map[ipld.Link]*_UnixFSHAMTShard + cachedLength int64 +} + +// NewUnixFSHAMTShard attempts to construct a UnixFSHAMTShard node from the base protobuf node plus +// a decoded UnixFSData structure +func NewUnixFSHAMTShard(ctx context.Context, substrate dagpb.PBNode, data data.UnixFSData, lsys *ipld.LinkSystem) (ipld.Node, error) { + if err := validateHAMTData(data); err != nil { + return nil, err + } + shardCache := make(map[ipld.Link]*_UnixFSHAMTShard, substrate.FieldLinks().Length()) + bf := bitField(data) + return &_UnixFSHAMTShard{ + ctx: ctx, + _substrate: substrate, + data: data, + lsys: lsys, + shardCache: shardCache, + bitfield: bf, + cachedLength: -1, + }, nil +} + +func (n UnixFSHAMTShard) Kind() ipld.Kind { + return n._substrate.Kind() +} + +// LookupByString looks for the key in the list of links with a matching name +func (n *_UnixFSHAMTShard) LookupByString(key string) (ipld.Node, error) { + hv := &hashBits{b: hash([]byte(key))} + return n.lookup(key, hv) +} + +func (n UnixFSHAMTShard) lookup(key string, hv *hashBits) (dagpb.Link, error) { + log2 := log2Size(n.data) + maxPadLen := maxPadLength(n.data) + childIndex, err := hv.Next(log2) + if err != nil { + return nil, err + } + + if n.hasChild(childIndex) { + pbLink, err := n.getChildLink(childIndex) + if err != nil { + return nil, err + } + isValue, err := isValueLink(pbLink, maxPadLen) + if err != nil { + return nil, err + } + if isValue { + if MatchKey(pbLink, key, maxPadLen) { + return pbLink.FieldHash(), nil + } + } else { + childNd, err := n.loadChild(pbLink) + if err != nil { + return nil, err + } + return childNd.lookup(key, hv) + } + } + return nil, schema.ErrNoSuchField{Type: nil /*TODO*/, Field: ipld.PathSegmentOfString(key)} +} + +// AttemptHAMTShardFromNode attempts to read a HAMT shard from a general protobuf node +func AttemptHAMTShardFromNode(ctx context.Context, nd ipld.Node, lsys *ipld.LinkSystem) (UnixFSHAMTShard, error) { + // shortcut if node is already a hamt + hnd, ok := nd.(UnixFSHAMTShard) + if ok { + return hnd, nil + } + pbnd, ok := nd.(dagpb.PBNode) + if !ok { + return nil, fmt.Errorf("hamt.AttemptHAMTShardFromNode: %w", ErrNotProtobuf) + } + if !pbnd.FieldData().Exists() { + return nil, fmt.Errorf("hamt.AttemptHAMTShardFromNode: %w", ErrNotUnixFSNode) + } + data, err := data.DecodeUnixFSData(pbnd.FieldData().Must().Bytes()) + if err != nil { + return nil, err + } + und, err := NewUnixFSHAMTShard(ctx, pbnd, data, lsys) + if err != nil { + return nil, err + } + return und.(UnixFSHAMTShard), nil +} + +func (n UnixFSHAMTShard) loadChild(pbLink dagpb.PBLink) (UnixFSHAMTShard, error) { + cached, ok := n.shardCache[pbLink.FieldHash().Link()] + if ok { + return cached, nil + } + nd, err := n.lsys.Load(ipld.LinkContext{Ctx: n.ctx}, pbLink.FieldHash().Link(), dagpb.Type.PBNode) + if err != nil { + return nil, err + } + und, err := AttemptHAMTShardFromNode(n.ctx, nd, n.lsys) + if err != nil { + return nil, err + } + n.shardCache[pbLink.FieldHash().Link()] = und + return und, nil +} + +func (n UnixFSHAMTShard) LookupByNode(key ipld.Node) (ipld.Node, error) { + ks, err := key.AsString() + if err != nil { + return nil, err + } + return n.LookupByString(ks) +} + +func (n UnixFSHAMTShard) LookupByIndex(idx int64) (ipld.Node, error) { + return n._substrate.LookupByIndex(idx) +} + +func (n UnixFSHAMTShard) LookupBySegment(seg ipld.PathSegment) (ipld.Node, error) { + return n.LookupByString(seg.String()) +} + +func (n UnixFSHAMTShard) MapIterator() ipld.MapIterator { + maxPadLen := maxPadLength(n.data) + listItr := &_UnixFSShardedDir__ListItr{ + _substrate: n.FieldLinks().Iterator(), + maxPadLen: maxPadLen, + nd: n, + } + st := stringTransformer{maxPadLen: maxPadLen} + return iter.NewUnixFSDirMapIterator(listItr, st.transformNameNode) +} + +type _UnixFSShardedDir__ListItr struct { + _substrate *dagpb.PBLinks__Itr + childIter *_UnixFSShardedDir__ListItr + nd UnixFSHAMTShard + maxPadLen int + total int64 +} + +func (itr *_UnixFSShardedDir__ListItr) Next() (int64, dagpb.PBLink) { + next := itr.next() + if next == nil { + return -1, next + } + total := itr.total + itr.total++ + return total, next +} + +func (itr *_UnixFSShardedDir__ListItr) next() dagpb.PBLink { + + if itr.childIter == nil { + if itr._substrate.Done() { + return nil + } + _, next := itr._substrate.Next() + isValue, err := isValueLink(next, itr.maxPadLen) + if err != nil { + return nil + } + if isValue { + return next + } + child, err := itr.nd.loadChild(next) + if err != nil { + return nil + } + itr.childIter = &_UnixFSShardedDir__ListItr{ + _substrate: child._substrate.FieldLinks().Iterator(), + nd: child, + maxPadLen: maxPadLength(child.data), + } + + } + _, next := itr.childIter.Next() + if itr.childIter.Done() { + itr.childIter = nil + } + return next +} + +func (itr *_UnixFSShardedDir__ListItr) Done() bool { + return itr.childIter == nil && itr._substrate.Done() +} + +// ListIterator returns an iterator which yields key-value pairs +// traversing the node. +// If the node kind is anything other than a list, nil will be returned. +// +// The iterator will yield every entry in the list; that is, it +// can be expected that itr.Next will be called node.Length times +// before itr.Done becomes true. +func (n UnixFSHAMTShard) ListIterator() ipld.ListIterator { + return nil +} + +// Length returns the length of a list, or the number of entries in a map, +// or -1 if the node is not of list nor map kind. +func (n UnixFSHAMTShard) Length() int64 { + if n.cachedLength != -1 { + return n.cachedLength + } + maxPadLen := maxPadLength(n.data) + total := int64(0) + itr := n.FieldLinks().Iterator() + for !itr.Done() { + _, pbLink := itr.Next() + isValue, err := isValueLink(pbLink, maxPadLen) + if err != nil { + continue + } + if isValue { + total++ + } else { + child, err := n.loadChild(pbLink) + if err != nil { + continue + } + total += child.Length() + } + } + n.cachedLength = total + return total +} + +func (n UnixFSHAMTShard) IsAbsent() bool { + return false +} + +func (n UnixFSHAMTShard) IsNull() bool { + return false +} + +func (n UnixFSHAMTShard) AsBool() (bool, error) { + return n._substrate.AsBool() +} + +func (n UnixFSHAMTShard) AsInt() (int64, error) { + return n._substrate.AsInt() +} + +func (n UnixFSHAMTShard) AsFloat() (float64, error) { + return n._substrate.AsFloat() +} + +func (n UnixFSHAMTShard) AsString() (string, error) { + return n._substrate.AsString() +} + +func (n UnixFSHAMTShard) AsBytes() ([]byte, error) { + return n._substrate.AsBytes() +} + +func (n UnixFSHAMTShard) AsLink() (ipld.Link, error) { + return n._substrate.AsLink() +} + +func (n UnixFSHAMTShard) Prototype() ipld.NodePrototype { + // TODO: should this return something? + // probobly not until we write the write interfaces + return nil +} + +// satisfy schema.TypedNode +func (UnixFSHAMTShard) Type() schema.Type { + return nil /*TODO:typelit*/ +} + +func (n UnixFSHAMTShard) Representation() ipld.Node { + return n._substrate.Representation() +} + +// Native map accessors + +func (n UnixFSHAMTShard) Iterator() *iter.UnixFSDir__Itr { + maxPadLen := maxPadLength(n.data) + listItr := &_UnixFSShardedDir__ListItr{ + _substrate: n.FieldLinks().Iterator(), + maxPadLen: maxPadLen, + nd: n, + } + st := stringTransformer{maxPadLen: maxPadLen} + return iter.NewUnixFSDirIterator(listItr, st.transformNameNode) +} + +func (n UnixFSHAMTShard) Lookup(key dagpb.String) dagpb.Link { + hv := &hashBits{b: hash([]byte(key.String()))} + link, err := n.lookup(key.String(), hv) + if err != nil { + return nil + } + return link +} + +// direct access to the links and data + +func (n UnixFSHAMTShard) FieldLinks() dagpb.PBLinks { + return n._substrate.FieldLinks() +} + +func (n UnixFSHAMTShard) FieldData() dagpb.MaybeBytes { + return n._substrate.FieldData() +} + +func (n UnixFSHAMTShard) getChildLink(childIndex int) (dagpb.PBLink, error) { + linkIndex := n.bitfield.OnesBefore(childIndex) + if linkIndex >= int(n.FieldLinks().Length()) || linkIndex < 0 { + return nil, ErrInvalidChildIndex + } + return n.FieldLinks().Lookup(int64(linkIndex)), nil +} + +func (n UnixFSHAMTShard) hasChild(childIndex int) bool { + return n.bitfield.Bit(childIndex) +} + +type stringTransformer struct { + maxPadLen int +} + +func (s stringTransformer) transformNameNode(nd dagpb.String) dagpb.String { + nb := dagpb.Type.String.NewBuilder() + err := nb.AssignString(nd.String()[s.maxPadLen:]) + if err != nil { + return nil + } + return nb.Build().(dagpb.String) +} diff --git a/hamt/shardeddir_test.go b/hamt/shardeddir_test.go new file mode 100644 index 0000000..c4f2ec9 --- /dev/null +++ b/hamt/shardeddir_test.go @@ -0,0 +1,203 @@ +package hamt_test + +import ( + "bytes" + "context" + "fmt" + "io" + "math/rand" + "sort" + "testing" + "time" + + format "github.com/ipfs/go-ipld-format" + "github.com/ipfs/go-merkledag" + dag "github.com/ipfs/go-merkledag" + mdtest "github.com/ipfs/go-merkledag/test" + ft "github.com/ipfs/go-unixfs" + legacy "github.com/ipfs/go-unixfs/hamt" + "github.com/ipfs/go-unixfsnode/hamt" + dagpb "github.com/ipld/go-codec-dagpb" + "github.com/ipld/go-ipld-prime" + "github.com/ipld/go-ipld-prime/fluent/qp" + cidlink "github.com/ipld/go-ipld-prime/linking/cid" + "github.com/ipld/go-ipld-prime/schema" + "github.com/stretchr/testify/require" +) + +// For now these tests use legacy UnixFS HAMT builders until we finish a builder +// in go-ipld-prime +func shuffle(seed int64, arr []string) { + r := rand.New(rand.NewSource(seed)) + for i := 0; i < len(arr); i++ { + a := r.Intn(len(arr)) + b := r.Intn(len(arr)) + arr[a], arr[b] = arr[b], arr[a] + } +} + +func makeDir(ds format.DAGService, size int) ([]string, *legacy.Shard, error) { + return makeDirWidth(ds, size, 256) +} + +func makeDirWidth(ds format.DAGService, size, width int) ([]string, *legacy.Shard, error) { + ctx := context.Background() + + s, _ := legacy.NewShard(ds, width) + + var dirs []string + for i := 0; i < size; i++ { + dirs = append(dirs, fmt.Sprintf("DIRNAME%d", i)) + } + + shuffle(time.Now().UnixNano(), dirs) + + for i := 0; i < len(dirs); i++ { + nd := ft.EmptyDirNode() + ds.Add(ctx, nd) + err := s.Set(ctx, dirs[i], nd) + if err != nil { + return nil, nil, err + } + } + + return dirs, s, nil +} + +func assertLinksEqual(linksA []*format.Link, linksB []*format.Link) error { + + if len(linksA) != len(linksB) { + return fmt.Errorf("links arrays are different sizes") + } + + sort.Stable(dag.LinkSlice(linksA)) + sort.Stable(dag.LinkSlice(linksB)) + for i, a := range linksA { + b := linksB[i] + if a.Name != b.Name { + return fmt.Errorf("links names mismatch") + } + + if a.Cid.String() != b.Cid.String() { + return fmt.Errorf("link hashes dont match") + } + } + + return nil +} + +func mockDag() (format.DAGService, *ipld.LinkSystem) { + bsrv := mdtest.Bserv() + dsrv := merkledag.NewDAGService(bsrv) + lsys := cidlink.DefaultLinkSystem() + lsys.StorageReadOpener = func(lnkCtx ipld.LinkContext, lnk ipld.Link) (io.Reader, error) { + cidLink, ok := lnk.(cidlink.Link) + if !ok { + return nil, fmt.Errorf("invalid link type for loading: %v", lnk) + } + + blk, err := bsrv.GetBlock(lnkCtx.Ctx, cidLink.Cid) + if err != nil { + return nil, err + } + + return bytes.NewReader(blk.RawData()), nil + } + lsys.TrustedStorage = true + return dsrv, &lsys +} + +func TestBasicSet(t *testing.T) { + ds, lsys := mockDag() + for _, w := range []int{128, 256, 512, 1024, 2048, 4096} { + t.Run(fmt.Sprintf("BasicSet%d", w), func(t *testing.T) { + names, s, err := makeDirWidth(ds, 1000, w) + require.NoError(t, err) + ctx := context.Background() + legacyNode, err := s.Node() + require.NoError(t, err) + nd, err := lsys.Load(ipld.LinkContext{Ctx: ctx}, cidlink.Link{Cid: legacyNode.Cid()}, dagpb.Type.PBNode) + require.NoError(t, err) + hamtShard, err := hamt.AttemptHAMTShardFromNode(ctx, nd, lsys) + require.NoError(t, err) + for _, d := range names { + _, err := hamtShard.LookupByString(d) + require.NoError(t, err) + } + }) + } +} + +func TestIterator(t *testing.T) { + ds, lsys := mockDag() + _, s, err := makeDir(ds, 300) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + + legacyNode, err := s.Node() + require.NoError(t, err) + nds, err := legacy.NewHamtFromDag(ds, legacyNode) + require.NoError(t, err) + nd, err := lsys.Load(ipld.LinkContext{Ctx: ctx}, cidlink.Link{Cid: legacyNode.Cid()}, dagpb.Type.PBNode) + require.NoError(t, err) + hamtShard, err := hamt.AttemptHAMTShardFromNode(ctx, nd, lsys) + require.NoError(t, err) + + linksA, err := nds.EnumLinks(ctx) + require.NoError(t, err) + + require.Equal(t, int64(len(linksA)), hamtShard.Length()) + + linksB := make([]*format.Link, 0, len(linksA)) + iter := hamtShard.Iterator() + for !iter.Done() { + name, link := iter.Next() + linksB = append(linksB, &format.Link{ + Name: name.String(), + Cid: link.Link().(cidlink.Link).Cid, + }) + } + require.NoError(t, assertLinksEqual(linksA, linksB)) +} + +func TestLoadFailsFromNonShard(t *testing.T) { + ds, lsys := mockDag() + ctx := context.Background() + legacyNode := ft.EmptyDirNode() + ds.Add(ctx, legacyNode) + nd, err := lsys.Load(ipld.LinkContext{Ctx: ctx}, cidlink.Link{Cid: legacyNode.Cid()}, dagpb.Type.PBNode) + require.NoError(t, err) + _, err = hamt.AttemptHAMTShardFromNode(ctx, nd, lsys) + require.Error(t, err) + + // empty protobuf w/o data + nd, err = qp.BuildMap(dagpb.Type.PBNode, -1, func(ma ipld.MapAssembler) { + qp.MapEntry(ma, "Links", qp.List(-1, func(ipld.ListAssembler) {})) + }) + require.NoError(t, err) + + _, err = hamt.AttemptHAMTShardFromNode(ctx, nd, lsys) + require.Error(t, err) +} + +func TestFindNonExisting(t *testing.T) { + ds, lsys := mockDag() + _, s, err := makeDir(ds, 100) + if err != nil { + t.Fatal(err) + } + ctx := context.Background() + legacyNode, err := s.Node() + require.NoError(t, err) + nd, err := lsys.Load(ipld.LinkContext{Ctx: ctx}, cidlink.Link{Cid: legacyNode.Cid()}, dagpb.Type.PBNode) + require.NoError(t, err) + hamtShard, err := hamt.AttemptHAMTShardFromNode(ctx, nd, lsys) + require.NoError(t, err) + for i := 0; i < 200; i++ { + key := fmt.Sprintf("notfound%d", i) + _, err := hamtShard.LookupByString(key) + require.EqualError(t, err, schema.ErrNoSuchField{Field: ipld.PathSegmentOfString(key)}.Error()) + } +} diff --git a/hamt/util.go b/hamt/util.go new file mode 100644 index 0000000..7d412fd --- /dev/null +++ b/hamt/util.go @@ -0,0 +1,130 @@ +package hamt + +// adapted from https://github.com/ipfs/go-unixfs/blob/master/hamt/util.go + +import ( + "fmt" + + "math/bits" + + "github.com/Stebalien/go-bitfield" + "github.com/ipfs/go-unixfsnode/data" + dagpb "github.com/ipld/go-codec-dagpb" + "github.com/spaolacci/murmur3" +) + +// hashBits is a helper that allows the reading of the 'next n bits' as an integer. +type hashBits struct { + b []byte + consumed int +} + +func mkmask(n int) byte { + return (1 << uint(n)) - 1 +} + +// Next returns the next 'i' bits of the hashBits value as an integer, or an +// error if there aren't enough bits. +func (hb *hashBits) Next(i int) (int, error) { + if hb.consumed+i > len(hb.b)*8 { + return 0, ErrHAMTTooDeep + } + return hb.next(i), nil +} + +func (hb *hashBits) next(i int) int { + curbi := hb.consumed / 8 + leftb := 8 - (hb.consumed % 8) + + curb := hb.b[curbi] + if i == leftb { + out := int(mkmask(i) & curb) + hb.consumed += i + return out + } + if i < leftb { + a := curb & mkmask(leftb) // mask out the high bits we don't want + b := a & ^mkmask(leftb-i) // mask out the low bits we don't want + c := b >> uint(leftb-i) // shift whats left down + hb.consumed += i + return int(c) + } + out := int(mkmask(leftb) & curb) + out <<= uint(i - leftb) + hb.consumed += leftb + out += hb.next(i - leftb) + return out + +} + +func validateHAMTData(nd data.UnixFSData) error { + if nd.FieldDataType().Int() != data.Data_HAMTShard { + return data.ErrWrongNodeType{data.Data_HAMTShard, nd.FieldDataType().Int()} + } + + if !nd.FieldHashType().Exists() || uint64(nd.FieldHashType().Must().Int()) != HashMurmur3 { + return ErrInvalidHashType + } + + if !nd.FieldData().Exists() { + return ErrNoDataField + } + + if !nd.FieldFanout().Exists() { + return ErrNoFanoutField + } + if err := checkLogTwo(int(nd.FieldFanout().Must().Int())); err != nil { + return err + } + + return nil +} + +func log2Size(nd data.UnixFSData) int { + return bits.TrailingZeros(uint(nd.FieldFanout().Must().Int())) +} + +func maxPadLength(nd data.UnixFSData) int { + return len(fmt.Sprintf("%X", nd.FieldFanout().Must().Int()-1)) +} + +func bitField(nd data.UnixFSData) bitfield.Bitfield { + bf := bitfield.NewBitfield(int(nd.FieldFanout().Must().Int())) + bf.SetBytes(nd.FieldData().Must().Bytes()) + return bf +} + +func checkLogTwo(v int) error { + if v <= 0 { + return ErrHAMTSizeInvalid + } + lg2 := bits.TrailingZeros(uint(v)) + if 1<