mirror of https://github.com/perkeep/perkeep.git
schema/filereader: support zero regions, start of subfile support
This commit is contained in:
parent
6a74ef1e80
commit
319a12f982
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue