mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-01 11:49:54 -05:00
NomDL: Use base64 for Blobs for now
Encode embedded blobs as base64 encoded strings.
This commit is contained in:
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user