schema/filereader: support zero regions, start of subfile support

This commit is contained in:
Brad Fitzpatrick 2011-06-06 11:31:45 -07:00
parent 6a74ef1e80
commit 319a12f982
3 changed files with 70 additions and 7 deletions

View File

@ -47,10 +47,37 @@ func part(blob *test.Blob, offset, size uint64) *ContentPart {
return &ContentPart{BlobRef: blob.BlobRef(), Size: size, Offset: offset}
}
// filePart returns a ContentPart that references a file JSON schema
// blob made of the provided content parts.
func filePart(cps []*ContentPart) *ContentPart {
m := NewCommonFilenameMap("")
fileSize := int64(0)
cpl := []ContentPart{}
for _, cp := range cps {
fileSize += int64(cp.Size)
cpl = append(cpl, *cp)
}
err := PopulateRegularFileMap(m, fileSize, cpl)
if err != nil {
panic(err.String())
}
json, err := MapToCamliJson(m)
if err != nil {
panic(err.String())
}
tb := &test.Blob{json}
testFetcher.AddBlob(tb)
return &ContentPart{SubBlobRef: tb.BlobRef(), Size: uint64(fileSize)}
}
func all(blob *test.Blob) *ContentPart {
return part(blob, 0, uint64(blob.Size()))
}
func zero(size uint64) *ContentPart {
return &ContentPart{Size: size}
}
func parts(parts ...*ContentPart) []*ContentPart {
return parts
}
@ -78,6 +105,7 @@ var readTests = []readTest{
{parts(all(blobA), all(blobB), all(blobC)), 20, "CCCCCccccc"},
{parts(all(blobA), all(blobB), all(blobC)), 22, "CCCccccc"},
{parts(part(blobA, 5, 5), part(blobB, 0, 5), part(blobC, 4, 2)), 1, "aaaaBBBBBCc"},
{parts(all(blobA), zero(2), all(blobB)), 5, "aaaaa\x00\x00BBBBBbbbbb"},
}
func TestReader(t *testing.T) {

View File

@ -88,14 +88,18 @@ func (fr *FileReader) closeOpenBlobs() {
}
}
func (fr *FileReader) readerFor(br *blobref.BlobRef) (blobref.ReadSeekCloser, os.Error) {
func (fr *FileReader) readerFor(br *blobref.BlobRef) (rsc blobref.ReadSeekCloser, err os.Error) {
if fr.crbr == br {
return fr.cr, nil
}
fr.closeOpenBlobs()
rsc, _, ferr := fr.fetcher.Fetch(br)
if ferr != nil {
return nil, ferr
if br != nil {
rsc, _, err = fr.fetcher.Fetch(br)
if err != nil {
return
}
} else {
rsc = &zeroReader{}
}
fr.crbr = br
fr.cr = rsc
@ -127,8 +131,13 @@ func (fr *FileReader) Read(p []byte) (n int, err os.Error) {
}
br := cp.blobref()
if br == nil {
return 0, fmt.Errorf("no blobref in content part %d", fr.ci)
sbr := cp.subblobref()
if br != nil && sbr != nil {
return 0, fmt.Errorf("content part index %d has both blobRef and subFileBlobRef", fr.ci)
}
if sbr != nil {
// TODO
return 0, fmt.Errorf("TODO: unsupported subFileBlobRef in content part index %d", fr.ci)
}
rsc, ferr := fr.readerFor(br)
@ -164,3 +173,22 @@ func minu64(a, b uint64) uint64 {
}
return b
}
type zeroReader struct {}
func (*zeroReader) Read(p []byte) (int, os.Error) {
for i := range p {
p[i] = 0
}
return len(p), nil
}
func (*zeroReader) Close() os.Error {
return nil
}
func (*zeroReader) Seek(offset int64, whence int) (newFilePos int64, err os.Error) {
// Caller is ignoring our newFilePos return value.
return 0, nil
}

View File

@ -99,12 +99,19 @@ type ContentPart struct {
}
func (cp *ContentPart) blobref() *blobref.BlobRef {
if cp.BlobRef == nil {
if cp.BlobRef == nil && cp.BlobRefString != "" {
cp.BlobRef = blobref.Parse(cp.BlobRefString)
}
return cp.BlobRef
}
func (cp *ContentPart) subblobref() *blobref.BlobRef {
if cp.SubBlobRef == nil && cp.SubBlobRefString != "" {
cp.SubBlobRef = blobref.Parse(cp.SubBlobRefString)
}
return cp.SubBlobRef
}
func stringFromMixedArray(parts []interface{}) string {
buf := new(bytes.Buffer)
for _, part := range parts {