mirror of https://github.com/perkeep/perkeep.git
Start of a schema library for camput.
This commit is contained in:
parent
5ea7504c84
commit
eb60cd6f71
|
@ -9,6 +9,7 @@ import (
|
|||
"camli/blobref"
|
||||
"camli/clientconfig"
|
||||
"camli/http"
|
||||
"camli/schema"
|
||||
"crypto/sha1"
|
||||
"encoding/base64"
|
||||
"flag"
|
||||
|
@ -224,6 +225,13 @@ func (a *Agent) UploadFile(filename string) (*PutResult, os.Error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmap, err := schema.NewFileMap(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
fmt.Printf("map: %q\n", fmap)
|
||||
fmt.Println("Got blobref for file blob: ", blobpr.BlobRef.String())
|
||||
return nil, nil
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@ Camli Blob Magic
|
|||
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
|
||||
|
||||
[Note: not totally happy with this yet...]
|
||||
|
||||
Ideal Camli JSON blobs should begin with the following 15 bytes:
|
||||
|
||||
{"camliVersion"
|
||||
|
@ -11,4 +12,15 @@ However, it's acknowledged that some JSON serialization libraries will
|
|||
format things differently, so additional whitespace should be
|
||||
tolerated.
|
||||
|
||||
An ideal camli serializer will strive for the above header, though, by
|
||||
doing something like:
|
||||
|
||||
-- removing the "camliVersion" from the object, noting its value
|
||||
(and requiring it to be present)
|
||||
|
||||
-- serializing the JSON with an existing JSON serialization library,
|
||||
|
||||
-- removing the serialized JSON's leading "{" character and prepending
|
||||
the 15 byte header above, as well as the colon and saved version
|
||||
and comma (which can have whitespace as desired)
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
_test*
|
||||
*.out
|
||||
*.[865]
|
|
@ -0,0 +1,7 @@
|
|||
include $(GOROOT)/src/Make.inc
|
||||
|
||||
TARG=camli/schema
|
||||
GOFILES=\
|
||||
schema.go\
|
||||
|
||||
include $(GOROOT)/src/Make.pkg
|
|
@ -0,0 +1,58 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"json"
|
||||
"os"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func isValidUtf8(s string) bool {
|
||||
for _, rune := range []int(s) {
|
||||
if rune == 0xfffd {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
var NoCamliVersionErr = os.NewError("No camliVersion key in map")
|
||||
|
||||
func MapToCamliJson(m map[string]interface{}) (string, os.Error) {
|
||||
version, hasVersion := m["camliVersion"]
|
||||
if !hasVersion {
|
||||
return "", NoCamliVersionErr
|
||||
}
|
||||
m["camliVersion"] = 0, false
|
||||
jsonBytes, err := json.MarshalIndent(m, "", " ")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
m["camliVersion"] = version
|
||||
buf := new(bytes.Buffer)
|
||||
fmt.Fprintf(buf, "{\"camliVersion\": %v,\n", version)
|
||||
buf.Write(jsonBytes[2:])
|
||||
return string(buf.Bytes()), nil
|
||||
}
|
||||
|
||||
func NewMapForFileName(fileName string) map[string]interface{} {
|
||||
ret := make(map[string]interface{})
|
||||
ret["camliVersion"] = 1
|
||||
ret["camliType"] = "" // undefined at this point
|
||||
|
||||
lastSlash := strings.LastIndex(fileName, "/")
|
||||
baseName := fileName[lastSlash+1:]
|
||||
if isValidUtf8(baseName) {
|
||||
ret["fileName"] = baseName
|
||||
} else {
|
||||
ret["fileNameBytes"] = []uint8(baseName)
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
func NewFileMap(fileName string) (map[string]interface{}, os.Error) {
|
||||
ret := NewMapForFileName(fileName)
|
||||
// TODO: ...
|
||||
return ret, nil
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
package schema
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
type isUtf8Test struct {
|
||||
s string
|
||||
e bool
|
||||
}
|
||||
|
||||
func TestIsUtf8(t *testing.T) {
|
||||
tests := []isUtf8Test{
|
||||
{"foo", true},
|
||||
{"Straße", true},
|
||||
{string([]uint8{65, 234, 234, 192, 23, 123}), false},
|
||||
{string([]uint8{65, 97}), true},
|
||||
}
|
||||
for idx, test := range tests {
|
||||
if isValidUtf8(test.s) != test.e {
|
||||
t.Errorf("expected isutf8==%d for test index %d", test.e, idx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const kExpectedHeader = `{"camliVersion"`
|
||||
|
||||
func TestJson(t *testing.T) {
|
||||
m := NewMapForFileName("schema_test.go")
|
||||
json, err := MapToCamliJson(m)
|
||||
if err != nil {
|
||||
t.Fatalf("Unexpected error: %v", err)
|
||||
}
|
||||
t.Logf("Got json: [%s]\n", json)
|
||||
// TODO: test it parses back
|
||||
|
||||
if !strings.HasPrefix(json, kExpectedHeader) {
|
||||
t.Errorf("JSON does't start with expected header.")
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue