NomDL: Use base64 for Blobs for now

Encode embedded blobs as base64 encoded strings.
This commit is contained in:
Erik Arvidsson
2015-10-12 16:51:49 -04:00
parent 8b2b46f07b
commit 0d6f8be3e8
4 changed files with 121 additions and 3 deletions
+13 -2
View File
@@ -1,6 +1,9 @@
package types
import (
"encoding/base64"
"strings"
"github.com/attic-labs/noms/chunks"
"github.com/attic-labs/noms/d"
"github.com/attic-labs/noms/ref"
@@ -100,6 +103,14 @@ func (r *jsonArrayReader) readTypeRefAsTag() TypeRef {
panic("unreachable")
}
func (r *jsonArrayReader) readBlob(t TypeRef) NomsValue {
s := r.readString()
decoder := base64.NewDecoder(base64.StdEncoding, strings.NewReader(s))
b, err := NewBlob(decoder)
d.Exp.NoError(err)
return valueAsNomsValue{b, t}
}
func (r *jsonArrayReader) readList(t TypeRef, pkg *Package) NomsValue {
desc := t.Desc.(CompoundDesc)
ll := []Value{}
@@ -153,6 +164,8 @@ func (r *jsonArrayReader) readTopLevelValue() NomsValue {
func (r *jsonArrayReader) readValueWithoutTag(t TypeRef, pkg *Package) NomsValue {
switch t.Kind() {
case BlobKind:
return r.readBlob(t)
case BoolKind:
return valueAsNomsValue{Bool(r.read().(bool)), t}
case UInt8Kind:
@@ -177,8 +190,6 @@ func (r *jsonArrayReader) readValueWithoutTag(t TypeRef, pkg *Package) NomsValue
return valueAsNomsValue{Float64(r.read().(float64)), t}
case StringKind:
return valueAsNomsValue{NewString(r.readString()), t}
case BlobKind:
panic("not implemented")
case ValueKind:
// The value is always tagged
t := r.readTypeRefAsTag()
+68
View File
@@ -1,6 +1,7 @@
package types
import (
"bytes"
"encoding/json"
"fmt"
"strings"
@@ -54,6 +55,41 @@ func TestReadTypeRefAsTag(t *testing.T) {
test(MakePrimitiveTypeRef(TypeRefKind), `[%d, %d, "%s", "S"]`, TypeRefKind, TypeRefKind, r.String())
}
func TestReadPrimitives(t *testing.T) {
assert := assert.New(t)
cs := chunks.NewMemoryStore()
test := func(expected Value, s string, vs ...interface{}) {
a := parseJson(s, vs...)
r := newJsonArrayReader(a, cs)
v := r.readTopLevelValue().NomsValue()
assert.True(expected.Equals(v))
}
test(Bool(true), "[%d, true]", BoolKind)
test(Bool(true), "[%d, true]", BoolKind)
test(Bool(false), "[%d, false]", BoolKind)
test(UInt8(0), "[%d, 0]", UInt8Kind)
test(UInt16(0), "[%d, 0]", UInt16Kind)
test(UInt32(0), "[%d, 0]", UInt32Kind)
test(UInt64(0), "[%d, 0]", UInt64Kind)
test(Int8(0), "[%d, 0]", Int8Kind)
test(Int16(0), "[%d, 0]", Int16Kind)
test(Int32(0), "[%d, 0]", Int32Kind)
test(Int64(0), "[%d, 0]", Int64Kind)
test(Float32(0), "[%d, 0]", Float32Kind)
test(Float64(0), "[%d, 0]", Float64Kind)
test(NewString("hi"), `[%d, "hi"]`, StringKind)
blob, err := NewBlob(bytes.NewBuffer([]byte{0x00, 0x01}))
assert.NoError(err)
test(blob, `[%d, "AAE="]`, BlobKind)
}
func TestReadListOfInt32(t *testing.T) {
assert := assert.New(t)
cs := chunks.NewMemoryStore()
@@ -480,6 +516,38 @@ func TestReadStructWithEnum(t *testing.T) {
assert.True(v.Get(NewString("b")).Equals(Bool(true)))
}
func TestReadStructWithBlob(t *testing.T) {
assert := assert.New(t)
cs := chunks.NewMemoryStore()
// struct A5 {
// b: Blob
// }
tref := MakeStructTypeRef("A5", []Field{
Field{"b", MakePrimitiveTypeRef(BlobKind), false},
}, Choices{})
pkg := NewPackage().SetNamedTypes(NewMapOfStringToTypeRef().Set("A5", tref))
pkgRef := RegisterPackage(&pkg)
// TODO: Should use ordinal of type and not name
a := parseJson(`[%d, "%s", "A5", "AAE="]`, TypeRefKind, pkgRef.String())
r := newJsonArrayReader(a, cs)
structTr := MakeTypeRef("A5", pkgRef)
RegisterFromValFunction(structTr, func(v Value) NomsValue {
return valueAsNomsValue{v, structTr}
})
v := r.readTopLevelValue().NomsValue().(Map)
assert.True(v.Get(NewString("$name")).Equals(NewString("A5")))
assert.True(v.Get(NewString("$type")).Equals(structTr))
blob, err := NewBlob(bytes.NewBuffer([]byte{0x00, 0x01}))
assert.NoError(err)
assert.True(v.Get(NewString("b")).Equals(blob))
}
func TestReadTypeRefValue(t *testing.T) {
assert := assert.New(t)
cs := chunks.NewMemoryStore()
+15 -1
View File
@@ -1,6 +1,10 @@
package types
import (
"bytes"
"encoding/base64"
"io"
"github.com/attic-labs/noms/chunks"
"github.com/attic-labs/noms/d"
"github.com/attic-labs/noms/ref"
@@ -73,7 +77,7 @@ func (w *jsonArrayWriter) writeTopLevelValue(v NomsValue) {
func (w *jsonArrayWriter) writeValue(v Value, tr TypeRef, pkg *Package) {
switch tr.Kind() {
case BlobKind:
panic("not yet implemented")
w.writeBlob(v.(Blob))
case BoolKind, Float32Kind, Float64Kind, Int16Kind, Int32Kind, Int64Kind, Int8Kind, UInt16Kind, UInt32Kind, UInt64Kind, UInt8Kind:
w.write(v.(primitive).ToPrimitive())
case ListKind:
@@ -182,6 +186,16 @@ func (w *jsonArrayWriter) writeTypeRefKindValue(v Value, tr TypeRef, pkg *Packag
}
}
func (w *jsonArrayWriter) writeBlob(b Blob) {
var buf bytes.Buffer
encoder := base64.NewEncoder(base64.StdEncoding, &buf)
n, err := io.Copy(encoder, b.Reader())
encoder.Close()
d.Exp.Equal(uint64(n), b.Len())
d.Exp.NoError(err)
w.write(buf.String())
}
func (w *jsonArrayWriter) writeStruct(m Map, t TypeRef, pkg *Package) {
desc := t.Desc.(StructDesc)
for _, f := range desc.Fields {
+25
View File
@@ -1,6 +1,7 @@
package types
import (
"bytes"
"testing"
"github.com/attic-labs/noms/Godeps/_workspace/src/github.com/stretchr/testify/assert"
@@ -32,6 +33,10 @@ func TestWritePrimitives(t *testing.T) {
f(Float64Kind, Float64(0), float64(0))
f(StringKind, NewString("hi"), "hi")
blob, err := NewBlob(bytes.NewBuffer([]byte{0x00, 0x01}))
assert.NoError(err)
f(BlobKind, blob, "AAE=")
}
func TestWriteList(t *testing.T) {
@@ -228,6 +233,23 @@ func TestWriteStructWithStruct(t *testing.T) {
assert.EqualValues([]interface{}{TypeRefKind, pkgRef.String(), "S", int32(42)}, *w)
}
func TestWriteStructWithBlob(t *testing.T) {
assert := assert.New(t)
pkg := NewPackage().SetNamedTypes(NewMapOfStringToTypeRef().Set("S",
MakeStructTypeRef("S", []Field{
Field{"b", MakePrimitiveTypeRef(BlobKind), false},
}, Choices{})))
pkgRef := RegisterPackage(&pkg)
tref := MakeTypeRef("S", pkgRef)
b, _ := NewBlob(bytes.NewBuffer([]byte{0x00, 0x01}))
v := NewMap(NewString("b"), b)
w := newJsonArrayWriter()
w.writeTopLevelValue(valueAsNomsValue{Value: v, t: tref})
assert.EqualValues([]interface{}{TypeRefKind, pkgRef.String(), "S", "AAE="}, *w)
}
func TestWriteEnum(t *testing.T) {
assert := assert.New(t)
@@ -261,6 +283,7 @@ func TestWriteListOfValue(t *testing.T) {
assert := assert.New(t)
tref := MakeCompoundTypeRef("", ListKind, MakePrimitiveTypeRef(ValueKind))
blob, _ := NewBlob(bytes.NewBuffer([]byte{0x01}))
v := NewList(
Bool(true),
UInt8(1),
@@ -274,6 +297,7 @@ func TestWriteListOfValue(t *testing.T) {
Float32(1),
Float64(1),
NewString("hi"),
blob,
)
w := newJsonArrayWriter()
@@ -292,6 +316,7 @@ func TestWriteListOfValue(t *testing.T) {
Float32Kind, float32(1),
Float64Kind, float64(1),
StringKind, "hi",
BlobKind, "AQ==",
}}, *w)
}