From fc05dfd75ca29b696b902659ac15d0df37cb3437 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Mon, 25 Mar 2019 21:56:23 +0100 Subject: [PATCH 1/2] fix doc --- doc.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/doc.go b/doc.go index 4eb0a74..b3cc06a 100644 --- a/doc.go +++ b/doc.go @@ -7,12 +7,12 @@ Optional Properties All optional properties whose default value does not match with the golang type zero value are defines as pointers or as zero arrays. Guidelines when working with optional values: -* It is safe to not define them when saving the glTF if the desired value is the default one. -* It is safe to expect that the optional values are not nil when opening a glTF. -* When assigning values to optional properties one can use the utility functions that take the reference of basic types. Examples: +It is safe to not define them when saving the glTF if the desired value is the default one. +It is safe to expect that the optional values are not nil when opening a glTF. +When quering values of optional properties that are not indices it is recommended to use the utility functions that returns the property as value +if not nil or the default value if nil. +When assigning values to optional properties one can use the utility functions that take the reference of basic types. Examples: gltf.Index(1) gltf.Float64(0.5) -* When quering values of optional properties that are not indices it is recommended to use the utility functions that returns the property as value -if not nil or the default value if nil. */ package gltf From f50c8fb99bdba692db22274d09e299200d85f9a3 Mon Sep 17 00:00:00 2001 From: Quim Muntal Date: Mon, 25 Mar 2019 22:31:33 +0100 Subject: [PATCH 2/2] do not overwritte files when Buffer is not loaded in memory --- decoder.go | 3 ++- encode.go | 5 +++++ encode_test.go | 7 ++++++- struct.go | 10 ++++++++-- struct_test.go | 6 +++--- 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/decoder.go b/decoder.go index 3d3ca7a..f28cb41 100644 --- a/decoder.go +++ b/decoder.go @@ -22,6 +22,7 @@ type ReadQuotas struct { // ReadResourceCallback defines a callback that will be called when an external resource should be loaded. // The string parameter is the URI of the resource. +// If the reader and the error are nil the buffer data won't be loaded into memory. type ReadResourceCallback = func(string) (io.ReadCloser, error) // Open will open a glTF or GLB file specified by name and return the Document. @@ -149,7 +150,7 @@ func (d *Decoder) decodeBuffer(buffer *Buffer) error { buffer.Data, err = buffer.marshalData() } else if err = validateBufferURI(buffer.URI); err == nil { r, err = d.cb(buffer.URI) - if err == nil { + if r != nil && err == nil { buffer.Data = make([]uint8, buffer.ByteLength) _, err = r.Read(buffer.Data) r.Close() diff --git a/encode.go b/encode.go index 0657585..989053e 100644 --- a/encode.go +++ b/encode.go @@ -75,6 +75,11 @@ func (e *Encoder) encodeBuffer(buffer *Buffer) error { if buffer.IsEmbeddedResource() { return nil } + + if len(buffer.Data) == 0 { + return nil + } + if err := validateBufferURI(buffer.URI); err != nil { return err } diff --git a/encode_test.go b/encode_test.go index aa72529..1e86a30 100644 --- a/encode_test.go +++ b/encode_test.go @@ -27,7 +27,11 @@ func saveMemory(doc *Document, asBinary bool) (*Decoder, error) { return nil, err } rcb := func(uri string) (io.ReadCloser, error) { - return ioutil.NopCloser(chunks[uri]), nil + if chunk, ok := chunks[uri]; ok { + return ioutil.NopCloser(chunk), nil + } else { + return nil, nil + } } return NewDecoder(buff, rcb), nil } @@ -72,6 +76,7 @@ func TestEncoder_Encode(t *testing.T) { {Extras: 8.0, Name: "binary", ByteLength: 3, URI: "a.bin", Data: []uint8{1, 2, 3}}, {Extras: 8.0, Name: "embedded", ByteLength: 2, URI: "data:application/octet-stream;base64,YW55ICsgb2xkICYgZGF0YQ==", Data: []byte("any + old & data")}, {Extras: 8.0, Name: "external", ByteLength: 4, URI: "b.bin", Data: []uint8{4, 5, 6, 7}}, + {Extras: 8.0, Name: "external", ByteLength: 4, URI: "a.drc"}, }}}, false}, {"withBufView", args{&Document{BufferViews: []BufferView{ {Extras: 8.0, Buffer: 0, ByteOffset: 1, ByteLength: 2, ByteStride: 5, Target: ArrayBuffer}, diff --git a/struct.go b/struct.go index eeb8456..e4b0796 100644 --- a/struct.go +++ b/struct.go @@ -97,6 +97,8 @@ type SparseIndices struct { } // A Buffer points to binary geometry, animation, or skins. +// If Data length is 0 and the Buffer is an external resource the Data won't be flushed, +// which can be useful when there is no need to load data in memory. type Buffer struct { Extensions Extensions `json:"extensions,omitempty"` Extras interface{} `json:"extras,omitempty"` @@ -119,10 +121,14 @@ func (b *Buffer) EmbeddedResource() { // marshalData decode the buffer from the URI. If the buffer is not en embedded resource the returned array will be empty. func (b *Buffer) marshalData() ([]uint8, error) { if !b.IsEmbeddedResource() { - return []uint8{}, nil + return nil, nil } startPos := len(mimetypeApplicationOctet) + 1 - return base64.StdEncoding.DecodeString(b.URI[startPos:]) + sl, err := base64.StdEncoding.DecodeString(b.URI[startPos:]) + if len(sl) == 0 || err != nil { + return nil, err + } + return sl, nil } // BufferView is a view into a buffer generally representing a subset of the buffer. diff --git a/struct_test.go b/struct_test.go index 168a403..99f38f9 100644 --- a/struct_test.go +++ b/struct_test.go @@ -403,9 +403,9 @@ func TestBuffer_marshalData(t *testing.T) { want []uint8 wantErr bool }{ - {"error", &Buffer{URI: "data:application/octet-stream;base64,_"}, []uint8{}, true}, - {"external", &Buffer{URI: "http://web.com"}, []uint8{}, false}, - {"empty", &Buffer{URI: "data:application/octet-stream;base64,"}, []uint8{}, false}, + {"error", &Buffer{URI: "data:application/octet-stream;base64,_"}, nil, true}, + {"external", &Buffer{URI: "http://web.com"}, nil, false}, + {"empty", &Buffer{URI: "data:application/octet-stream;base64,"}, nil, false}, {"test", &Buffer{URI: "data:application/octet-stream;base64,TEST"}, []uint8{76, 68, 147}, false}, {"complex", &Buffer{URI: "data:application/octet-stream;base64,YW55IGNhcm5hbCBwbGVhcw=="}, []uint8{97, 110, 121, 32, 99, 97, 114, 110, 97, 108, 32, 112, 108, 101, 97, 115}, false}, }