2011-05-26 23:46:27 +00:00
|
|
|
/*
|
|
|
|
Copyright 2011 Google Inc.
|
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
you may not use this file except in compliance with the License.
|
|
|
|
You may obtain a copy of the License at
|
|
|
|
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
See the License for the specific language governing permissions and
|
|
|
|
limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
package schema
|
|
|
|
|
|
|
|
import (
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
"encoding/json"
|
|
|
|
"errors"
|
2011-05-26 23:46:27 +00:00
|
|
|
"fmt"
|
2011-06-06 20:30:54 +00:00
|
|
|
"io"
|
2011-05-31 17:20:28 +00:00
|
|
|
"log"
|
2011-05-26 23:46:27 +00:00
|
|
|
"os"
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
"camlistore.org/pkg/blobref"
|
2011-05-26 23:46:27 +00:00
|
|
|
)
|
|
|
|
|
2011-05-31 17:35:45 +00:00
|
|
|
var _ = log.Printf
|
|
|
|
|
2011-06-10 01:28:07 +00:00
|
|
|
const closedIndex = -1
|
2011-07-02 16:09:50 +00:00
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
var errClosed = errors.New("filereader is closed")
|
2011-06-10 01:28:07 +00:00
|
|
|
|
2011-07-17 15:50:55 +00:00
|
|
|
// A DirReader reads the entries of a "directory" schema blob's
|
|
|
|
// referenced "static-set" blob.
|
|
|
|
type DirReader struct {
|
|
|
|
fetcher blobref.SeekFetcher
|
|
|
|
ss *Superset
|
|
|
|
|
|
|
|
staticSet []*blobref.BlobRef
|
|
|
|
current int
|
|
|
|
}
|
|
|
|
|
2011-07-19 02:06:56 +00:00
|
|
|
// NewDirReader creates a new directory reader and prepares to
|
2011-07-17 15:50:55 +00:00
|
|
|
// fetch the static-set entries
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func NewDirReader(fetcher blobref.SeekFetcher, dirBlobRef *blobref.BlobRef) (*DirReader, error) {
|
2011-07-17 15:50:55 +00:00
|
|
|
ss := new(Superset)
|
|
|
|
err := ss.setFromBlobRef(fetcher, dirBlobRef)
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if ss.Type != "directory" {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: expected \"directory\" schema blob for %s, got %q", dirBlobRef, ss.Type)
|
|
|
|
}
|
|
|
|
dr, err := ss.NewDirReader(fetcher)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: creating DirReader for %s: %v", dirBlobRef, err)
|
|
|
|
}
|
|
|
|
dr.current = 0
|
|
|
|
return dr, nil
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (ss *Superset) NewDirReader(fetcher blobref.SeekFetcher) (*DirReader, error) {
|
2011-07-17 15:50:55 +00:00
|
|
|
if ss.Type != "directory" {
|
|
|
|
return nil, fmt.Errorf("Superset not of type \"directory\"")
|
|
|
|
}
|
|
|
|
return &DirReader{fetcher: fetcher, ss: ss}, nil
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (ss *Superset) setFromBlobRef(fetcher blobref.SeekFetcher, blobRef *blobref.BlobRef) error {
|
2011-07-17 15:50:55 +00:00
|
|
|
if blobRef == nil {
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
return errors.New("schema/filereader: blobref was nil")
|
2011-07-17 15:50:55 +00:00
|
|
|
}
|
|
|
|
ss.BlobRef = blobRef
|
|
|
|
rsc, _, err := fetcher.Fetch(blobRef)
|
|
|
|
if err != nil {
|
|
|
|
return fmt.Errorf("schema/filereader: fetching schema blob %s: %v", blobRef, err)
|
|
|
|
}
|
|
|
|
if err = json.NewDecoder(rsc).Decode(ss); err != nil {
|
|
|
|
return fmt.Errorf("schema/filereader: decoding schema blob %s: %v", blobRef, err)
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// StaticSet returns the whole of the static set members of that directory
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (dr *DirReader) StaticSet() ([]*blobref.BlobRef, error) {
|
2011-07-17 15:50:55 +00:00
|
|
|
if dr.staticSet != nil {
|
|
|
|
return dr.staticSet, nil
|
|
|
|
}
|
|
|
|
staticSetBlobref := blobref.Parse(dr.ss.Entries)
|
|
|
|
if staticSetBlobref == nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: Invalid blobref\n")
|
|
|
|
}
|
|
|
|
rsc, _, err := dr.fetcher.Fetch(staticSetBlobref)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: fetching schema blob %s: %v", staticSetBlobref, err)
|
|
|
|
}
|
|
|
|
ss := new(Superset)
|
|
|
|
if err = json.NewDecoder(rsc).Decode(ss); err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: decoding schema blob %s: %v", staticSetBlobref, err)
|
|
|
|
}
|
|
|
|
if ss.Type != "static-set" {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: expected \"static-set\" schema blob for %s, got %q", staticSetBlobref, ss.Type)
|
|
|
|
}
|
|
|
|
for _, s := range ss.Members {
|
|
|
|
member := blobref.Parse(s)
|
|
|
|
if member == nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: invalid (static-set member) blobref\n")
|
|
|
|
}
|
|
|
|
dr.staticSet = append(dr.staticSet, member)
|
|
|
|
}
|
|
|
|
return dr.staticSet, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Readdir implements the Directory interface.
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (dr *DirReader) Readdir(n int) (entries []DirectoryEntry, err error) {
|
2011-07-17 15:50:55 +00:00
|
|
|
sts, err := dr.StaticSet()
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: can't get StaticSet: %v\n", err)
|
|
|
|
}
|
|
|
|
up := dr.current + n
|
|
|
|
if n <= 0 {
|
|
|
|
dr.current = 0
|
|
|
|
up = len(sts)
|
|
|
|
} else {
|
|
|
|
if n > (len(sts) - dr.current) {
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
err = io.EOF
|
2011-07-17 15:50:55 +00:00
|
|
|
up = len(sts)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, entryBref := range sts[dr.current:up] {
|
|
|
|
entry, err := NewDirectoryEntryFromBlobRef(dr.fetcher, entryBref)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: can't create dirEntry: %v\n", err)
|
|
|
|
}
|
|
|
|
entries = append(entries, entry)
|
|
|
|
}
|
|
|
|
return entries, err
|
|
|
|
}
|
|
|
|
|
2011-05-26 23:46:27 +00:00
|
|
|
type FileReader struct {
|
2011-06-04 15:56:03 +00:00
|
|
|
fetcher blobref.SeekFetcher
|
2011-05-26 23:46:27 +00:00
|
|
|
ss *Superset
|
2011-05-31 17:35:45 +00:00
|
|
|
|
2011-06-10 01:28:07 +00:00
|
|
|
ci int // index into contentparts, or -1 on closed
|
2011-06-06 20:30:54 +00:00
|
|
|
ccon uint64 // bytes into current chunk already consumed
|
|
|
|
remain int64 // bytes remaining
|
2012-08-24 01:44:03 +00:00
|
|
|
size int64 // total number of bytes
|
2011-06-06 20:30:54 +00:00
|
|
|
|
|
|
|
cr blobref.ReadSeekCloser // cached reader (for blobref chunks)
|
2011-06-06 15:50:20 +00:00
|
|
|
crbr *blobref.BlobRef // the blobref that cr is for
|
2011-06-06 20:30:54 +00:00
|
|
|
|
2011-09-08 00:51:29 +00:00
|
|
|
csubfr *FileReader // cached sub blobref reader (for subBlobRef chunks)
|
|
|
|
ccp *BytesPart // the content part that csubfr is cached for
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
|
2011-09-08 00:51:29 +00:00
|
|
|
// TODO(bradfitz): make this take a blobref.FetcherAt instead?
|
|
|
|
// TODO(bradfitz): rename this into bytes reader? but for now it's still
|
|
|
|
// named FileReader, but can also read a "bytes" schema.
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func NewFileReader(fetcher blobref.SeekFetcher, fileBlobRef *blobref.BlobRef) (*FileReader, error) {
|
2011-06-06 20:30:54 +00:00
|
|
|
if fileBlobRef == nil {
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
return nil, errors.New("schema/filereader: NewFileReader blobref was nil")
|
2011-06-06 20:30:54 +00:00
|
|
|
}
|
2011-05-31 17:20:28 +00:00
|
|
|
ss := new(Superset)
|
|
|
|
rsc, _, err := fetcher.Fetch(fileBlobRef)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: fetching file schema blob: %v", err)
|
|
|
|
}
|
|
|
|
if err = json.NewDecoder(rsc).Decode(ss); err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: decoding file schema blob: %v", err)
|
|
|
|
}
|
2011-09-08 00:51:29 +00:00
|
|
|
if ss.Type != "file" && ss.Type != "bytes" {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: expected \"file\" or \"bytes\" schema blob, got %q", ss.Type)
|
2011-05-31 17:20:28 +00:00
|
|
|
}
|
2011-07-13 08:52:37 +00:00
|
|
|
fr, err := ss.NewFileReader(fetcher)
|
|
|
|
if err != nil {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: creating FileReader for %s: %v", fileBlobRef, err)
|
|
|
|
}
|
|
|
|
return fr, nil
|
2011-05-31 17:20:28 +00:00
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (ss *Superset) NewFileReader(fetcher blobref.SeekFetcher) (*FileReader, error) {
|
2011-09-08 00:51:29 +00:00
|
|
|
if ss.Type != "file" && ss.Type != "bytes" {
|
|
|
|
return nil, fmt.Errorf("schema/filereader: Superset not of type \"file\" or \"bytes\"")
|
2011-07-13 08:52:37 +00:00
|
|
|
}
|
2012-08-24 01:44:03 +00:00
|
|
|
size := int64(ss.SumPartsSize())
|
|
|
|
return &FileReader{
|
|
|
|
fetcher: fetcher,
|
|
|
|
ss: ss,
|
|
|
|
size: size,
|
|
|
|
remain: size,
|
|
|
|
}, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Size returns the size of the file in bytes.
|
|
|
|
func (fr *FileReader) Size() int64 {
|
|
|
|
return fr.size
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
|
2011-05-31 17:20:28 +00:00
|
|
|
// FileSchema returns the reader's schema superset. Don't mutate it.
|
|
|
|
func (fr *FileReader) FileSchema() *Superset {
|
|
|
|
return fr.ss
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (fr *FileReader) Close() error {
|
2011-06-10 01:28:07 +00:00
|
|
|
if fr.ci == closedIndex {
|
|
|
|
return errClosed
|
|
|
|
}
|
|
|
|
fr.closeOpenBlobs()
|
|
|
|
fr.ci = closedIndex
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2011-06-06 20:30:54 +00:00
|
|
|
func (fr *FileReader) Skip(skipBytes uint64) uint64 {
|
2011-06-10 01:28:07 +00:00
|
|
|
if fr.ci == closedIndex {
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2011-06-06 20:30:54 +00:00
|
|
|
wantedSkipped := skipBytes
|
|
|
|
|
2011-09-08 00:51:29 +00:00
|
|
|
for skipBytes != 0 && fr.ci < len(fr.ss.Parts) {
|
|
|
|
cp := fr.ss.Parts[fr.ci]
|
2011-05-26 23:46:27 +00:00
|
|
|
thisChunkSkippable := cp.Size - fr.ccon
|
|
|
|
toSkip := minu64(skipBytes, thisChunkSkippable)
|
|
|
|
fr.ccon += toSkip
|
2011-06-06 15:50:20 +00:00
|
|
|
fr.remain -= int64(toSkip)
|
2011-05-26 23:46:27 +00:00
|
|
|
if fr.ccon == cp.Size {
|
|
|
|
fr.ci++
|
|
|
|
fr.ccon = 0
|
|
|
|
}
|
|
|
|
skipBytes -= toSkip
|
|
|
|
}
|
2011-06-06 20:30:54 +00:00
|
|
|
|
|
|
|
return wantedSkipped - skipBytes
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
|
2011-05-31 17:35:45 +00:00
|
|
|
func (fr *FileReader) closeOpenBlobs() {
|
|
|
|
if fr.cr != nil {
|
|
|
|
fr.cr.Close()
|
|
|
|
fr.cr = nil
|
|
|
|
fr.crbr = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (fr *FileReader) readerFor(br *blobref.BlobRef, seekTo int64) (r io.Reader, err error) {
|
2011-05-31 17:35:45 +00:00
|
|
|
if fr.crbr == br {
|
|
|
|
return fr.cr, nil
|
|
|
|
}
|
|
|
|
fr.closeOpenBlobs()
|
2011-06-06 20:30:54 +00:00
|
|
|
var rsc blobref.ReadSeekCloser
|
2011-06-06 18:31:45 +00:00
|
|
|
if br != nil {
|
|
|
|
rsc, _, err = fr.fetcher.Fetch(br)
|
|
|
|
if err != nil {
|
|
|
|
return
|
|
|
|
}
|
2011-06-06 20:30:54 +00:00
|
|
|
|
|
|
|
_, serr := rsc.Seek(int64(seekTo), os.SEEK_SET)
|
|
|
|
if serr != nil {
|
|
|
|
return nil, fmt.Errorf("schema: FileReader.Read seek error on blob %s: %v", br, serr)
|
|
|
|
}
|
|
|
|
|
2011-06-06 18:31:45 +00:00
|
|
|
} else {
|
2012-08-24 01:44:03 +00:00
|
|
|
rsc = zeroReader{}
|
2011-05-31 17:35:45 +00:00
|
|
|
}
|
|
|
|
fr.crbr = br
|
|
|
|
fr.cr = rsc
|
|
|
|
return rsc, nil
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (fr *FileReader) subBlobRefReader(cp *BytesPart) (io.Reader, error) {
|
2011-06-06 20:30:54 +00:00
|
|
|
if fr.ccp == cp {
|
|
|
|
return fr.csubfr, nil
|
|
|
|
}
|
2011-09-08 00:51:29 +00:00
|
|
|
subfr, err := NewFileReader(fr.fetcher, cp.BytesRef)
|
2011-06-06 20:30:54 +00:00
|
|
|
if err == nil {
|
|
|
|
subfr.Skip(cp.Offset)
|
|
|
|
fr.csubfr = subfr
|
|
|
|
fr.ccp = cp
|
|
|
|
}
|
|
|
|
return subfr, err
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (fr *FileReader) currentPart() (*BytesPart, error) {
|
2011-05-26 23:46:27 +00:00
|
|
|
for {
|
2011-09-08 00:51:29 +00:00
|
|
|
if fr.ci >= len(fr.ss.Parts) {
|
2011-05-31 17:35:45 +00:00
|
|
|
fr.closeOpenBlobs()
|
2011-06-06 15:50:20 +00:00
|
|
|
if fr.remain > 0 {
|
2011-06-06 20:30:54 +00:00
|
|
|
return nil, fmt.Errorf("schema: declared file schema size was larger than sum of content parts")
|
2011-06-06 15:50:20 +00:00
|
|
|
}
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
return nil, io.EOF
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
2011-09-08 00:51:29 +00:00
|
|
|
cp := fr.ss.Parts[fr.ci]
|
2011-05-26 23:46:27 +00:00
|
|
|
thisChunkReadable := cp.Size - fr.ccon
|
|
|
|
if thisChunkReadable == 0 {
|
|
|
|
fr.ci++
|
|
|
|
fr.ccon = 0
|
|
|
|
continue
|
|
|
|
}
|
2011-06-06 20:30:54 +00:00
|
|
|
return cp, nil
|
|
|
|
}
|
|
|
|
panic("unreachable")
|
|
|
|
}
|
|
|
|
|
2012-08-24 01:44:03 +00:00
|
|
|
var _ interface {
|
|
|
|
io.ReaderAt
|
|
|
|
io.Reader
|
|
|
|
io.Closer
|
|
|
|
} = (*FileReader)(nil)
|
|
|
|
|
|
|
|
func (fr *FileReader) ReadAt(p []byte, offset int64) (n int, err error) {
|
|
|
|
if offset < 0 {
|
|
|
|
return 0, errors.New("schema/filereader: negative offset")
|
|
|
|
}
|
|
|
|
if offset >= fr.Size() {
|
|
|
|
return 0, io.EOF
|
|
|
|
}
|
|
|
|
want := len(p)
|
|
|
|
for len(p) > 0 && err == nil {
|
|
|
|
panic("TODO: finish implementing")
|
|
|
|
r := fr.readerForOffset(offset)
|
|
|
|
var n1 int
|
|
|
|
n1, err = r.Read(p)
|
|
|
|
p = p[n1:]
|
|
|
|
if err == io.EOF {
|
|
|
|
err = nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if n == want && err == io.EOF {
|
|
|
|
// ReaderAt permits either way, but I like this way.
|
|
|
|
err = nil
|
|
|
|
}
|
|
|
|
if n < want && err == nil {
|
|
|
|
err = io.ErrUnexpectedEOF
|
|
|
|
}
|
|
|
|
return n, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func (fr *FileReader) readerForOffset(off int64) io.Reader {
|
|
|
|
panic("TODO(bradfitz): implement")
|
|
|
|
}
|
|
|
|
|
Update from r60 to [almost] Go 1.
A lot is still broken, but most stuff at least compiles now.
The directory tree has been rearranged now too. Go libraries are now
under "pkg". Fully qualified, they are e.g. "camlistore.org/pkg/jsonsign".
The go tool cannot yet fetch from arbitrary domains, but discussion is
happening now on which mechanism to use to allow that.
For now, put the camlistore root under $GOPATH/src. Typically $GOPATH
is $HOME, so Camlistore should be at $HOME/src/camlistore.org.
Then you can:
$ go build ./server/camlistored
... etc
The build.pl script is currently disabled. It'll be resurrected at
some point, but with a very different role (helping create a fake
GOPATH and running the go build command, if things are installed at
the wrong place, and/or running fileembed generators).
Many things are certainly broken.
Many things are disabled. (MySQL, all indexing, etc).
Many things need to be moved into
camlistore.org/third_party/{code.google.com,github.com} and updated
from their r60 to Go 1 versions, where applicable.
The GoMySQL stuff should be updated to use database/sql and the ziutek
library implementing database/sql/driver.
Help wanted.
Change-Id: If71217dc5c8f0e70dbe46e9504ca5131c6eeacde
2012-02-19 05:53:06 +00:00
|
|
|
func (fr *FileReader) Read(p []byte) (n int, err error) {
|
2011-06-10 01:28:07 +00:00
|
|
|
if fr.ci == closedIndex {
|
|
|
|
return 0, errClosed
|
|
|
|
}
|
|
|
|
|
2011-06-06 20:30:54 +00:00
|
|
|
cp, err := fr.currentPart()
|
|
|
|
if err != nil {
|
|
|
|
return 0, err
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
|
2011-06-06 15:50:20 +00:00
|
|
|
if cp.Size == 0 {
|
|
|
|
return 0, fmt.Errorf("blobref content part contained illegal size 0")
|
|
|
|
}
|
|
|
|
|
2011-06-08 00:00:21 +00:00
|
|
|
br := cp.BlobRef
|
2011-09-08 00:51:29 +00:00
|
|
|
sbr := cp.BytesRef
|
2011-06-06 18:31:45 +00:00
|
|
|
if br != nil && sbr != nil {
|
|
|
|
return 0, fmt.Errorf("content part index %d has both blobRef and subFileBlobRef", fr.ci)
|
|
|
|
}
|
2011-05-31 17:35:45 +00:00
|
|
|
|
2011-06-06 20:30:54 +00:00
|
|
|
var r io.Reader
|
2011-05-26 23:46:27 +00:00
|
|
|
|
2011-06-06 20:30:54 +00:00
|
|
|
if sbr != nil {
|
|
|
|
r, err = fr.subBlobRefReader(cp)
|
|
|
|
if err != nil {
|
|
|
|
return 0, fmt.Errorf("schema: FileReader.Read error fetching sub file %s: %v", sbr, err)
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
seekTo := cp.Offset + fr.ccon
|
|
|
|
r, err = fr.readerFor(br, int64(seekTo))
|
|
|
|
if err != nil {
|
|
|
|
return 0, fmt.Errorf("schema: FileReader.Read error fetching blob %s: %v", br, err)
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
readSize := cp.Size - fr.ccon
|
2011-06-06 20:30:54 +00:00
|
|
|
if readSize < uint64(len(p)) {
|
|
|
|
p = p[:int(readSize)]
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
|
2011-06-06 20:30:54 +00:00
|
|
|
n, err = r.Read(p)
|
2011-06-06 15:50:20 +00:00
|
|
|
fr.ccon += uint64(n)
|
|
|
|
fr.remain -= int64(n)
|
|
|
|
if fr.remain < 0 {
|
|
|
|
err = fmt.Errorf("schema: file schema was invalid; content parts sum to over declared size")
|
2011-05-26 23:46:27 +00:00
|
|
|
}
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
func minu64(a, b uint64) uint64 {
|
|
|
|
if a < b {
|
|
|
|
return a
|
|
|
|
}
|
|
|
|
return b
|
|
|
|
}
|
2011-06-06 18:31:45 +00:00
|
|
|
|
2012-08-24 01:44:03 +00:00
|
|
|
// zeroReader is a ReadSeekCloser that always reads zero bytes.
|
2011-06-06 20:30:54 +00:00
|
|
|
type zeroReader struct{}
|
2011-06-06 18:31:45 +00:00
|
|
|
|
2012-08-24 01:44:03 +00:00
|
|
|
func (zeroReader) Read(p []byte) (int, error) {
|
2011-06-06 18:31:45 +00:00
|
|
|
for i := range p {
|
|
|
|
p[i] = 0
|
|
|
|
}
|
|
|
|
return len(p), nil
|
|
|
|
}
|
|
|
|
|
2012-08-24 01:44:03 +00:00
|
|
|
func (zeroReader) Close() error {
|
2011-06-06 18:31:45 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2012-08-24 01:44:03 +00:00
|
|
|
func (zeroReader) Seek(offset int64, whence int) (newFilePos int64, err error) {
|
2011-06-06 18:31:45 +00:00
|
|
|
// Caller is ignoring our newFilePos return value.
|
|
|
|
return 0, nil
|
|
|
|
}
|