diff options
| -rw-r--r-- | account.go | 89 | ||||
| -rw-r--r-- | backend.go | 10 | ||||
| -rw-r--r-- | bulk.go | 56 | ||||
| -rw-r--r-- | capabilities.go | 16 | ||||
| -rw-r--r-- | capabilities/package.go | 14 | ||||
| -rw-r--r-- | container.go | 95 | ||||
| -rw-r--r-- | container_iterator.go | 62 | ||||
| -rw-r--r-- | doc.go | 10 | ||||
| -rw-r--r-- | download.go | 20 | ||||
| -rw-r--r-- | errors.go | 38 | ||||
| -rw-r--r-- | field_metadata.go | 14 | ||||
| -rw-r--r-- | field_string.go | 22 | ||||
| -rw-r--r-- | field_time.go | 60 | ||||
| -rw-r--r-- | field_uint64.go | 34 | ||||
| -rw-r--r-- | generated.go | 128 | ||||
| -rw-r--r-- | generated.go.in | 22 | ||||
| -rw-r--r-- | gopherschwift/package.go | 11 | ||||
| -rw-r--r-- | headers.go | 64 | ||||
| -rw-r--r-- | iterator.go | 6 | ||||
| -rw-r--r-- | largeobject.go | 256 | ||||
| -rw-r--r-- | object.go | 209 | ||||
| -rw-r--r-- | object_iterator.go | 70 | ||||
| -rw-r--r-- | request.go | 17 | ||||
| -rw-r--r-- | tests/largeobject_test.go | 2 | ||||
| -rw-r--r-- | tests/shared_test.go | 1 | ||||
| -rw-r--r-- | version.go | 2 |
26 files changed, 659 insertions, 669 deletions
@@ -25,9 +25,9 @@ import ( "regexp" ) -//Account represents a Swift account. Instances are usually obtained by -//connecting to a backend (see package-level documentation), or by traversing -//upwards from a container with Container.Account(). +// Account represents a Swift account. Instances are usually obtained by +// connecting to a backend (see package-level documentation), or by traversing +// upwards from a container with Container.Account(). type Account struct { backend Backend //URL parts @@ -38,16 +38,16 @@ type Account struct { caps *Capabilities } -//IsEqualTo returns true if both Account instances refer to the same account. +// IsEqualTo returns true if both Account instances refer to the same account. func (a *Account) IsEqualTo(other *Account) bool { return other.baseURL == a.baseURL && other.name == a.name } var endpointURLRegexp = regexp.MustCompile(`^(.*/)v1/(.*)/$`) -//InitializeAccount takes something that implements the Backend interface, and -//returns the Account instance corresponding to the account/project that this -//backend is connected to. +// InitializeAccount takes something that implements the Backend interface, and +// returns the Account instance corresponding to the account/project that this +// backend is connected to. func InitializeAccount(backend Backend) (*Account, error) { match := endpointURLRegexp.FindStringSubmatch(backend.EndpointURL()) if match == nil { @@ -60,13 +60,13 @@ func InitializeAccount(backend Backend) (*Account, error) { }, nil } -//SwitchAccount returns a handle to a different account on the same server. Note -//that you need reseller permissions to access accounts other than that where -//you originally authenticated. This method does not check whether the account -//actually exists. +// SwitchAccount returns a handle to a different account on the same server. Note +// that you need reseller permissions to access accounts other than that where +// you originally authenticated. This method does not check whether the account +// actually exists. // -//The account name is usually the Keystone project ID with an additional "AUTH_" -//prefix. +// The account name is usually the Keystone project ID with an additional "AUTH_" +// prefix. func (a *Account) SwitchAccount(accountName string) *Account { newEndpointURL := a.baseURL + "v1/" + accountName + "/" return &Account{ @@ -76,25 +76,25 @@ func (a *Account) SwitchAccount(accountName string) *Account { } } -//Name returns the name of the account (usually the prefix "AUTH_" followed by -//the Keystone project ID). +// Name returns the name of the account (usually the prefix "AUTH_" followed by +// the Keystone project ID). func (a *Account) Name() string { return a.name } -//Backend returns the backend which is used to make requests against this -//account. +// Backend returns the backend which is used to make requests against this +// account. func (a *Account) Backend() Backend { return a.backend } -//Headers returns the AccountHeaders for this account. If the AccountHeaders -//has not been cached yet, a HEAD request is issued on the account. +// Headers returns the AccountHeaders for this account. If the AccountHeaders +// has not been cached yet, a HEAD request is issued on the account. // -//This operation fails with http.StatusNotFound if the account does not exist. +// This operation fails with http.StatusNotFound if the account does not exist. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (a *Account) Headers() (AccountHeaders, error) { if a.headers != nil { return *a.headers, nil @@ -117,19 +117,19 @@ func (a *Account) Headers() (AccountHeaders, error) { return *a.headers, nil } -//Invalidate clears the internal cache of this Account instance. The next call -//to Headers() on this instance will issue a HEAD request on the account. +// Invalidate clears the internal cache of this Account instance. The next call +// to Headers() on this instance will issue a HEAD request on the account. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (a *Account) Invalidate() { a.headers = nil } -//Update updates the account using a POST request. The headers in the headers -//attribute take precedence over those in opts.Headers. +// Update updates the account using a POST request. The headers in the headers +// attribute take precedence over those in opts.Headers. // -//A successful POST request implies Invalidate() since it may change metadata. +// A successful POST request implies Invalidate() since it may change metadata. func (a *Account) Update(headers AccountHeaders, opts *RequestOptions) error { _, err := Request{ Method: "POST", @@ -142,10 +142,10 @@ func (a *Account) Update(headers AccountHeaders, opts *RequestOptions) error { return err } -//Create creates the account using a PUT request. This operation is only -//available to reseller admins, not to regular users. +// Create creates the account using a PUT request. This operation is only +// available to reseller admins, not to regular users. // -//A successful PUT request implies Invalidate() since it may change metadata. +// A successful PUT request implies Invalidate() since it may change metadata. func (a *Account) Create(opts *RequestOptions) error { _, err := Request{ Method: "PUT", @@ -159,34 +159,33 @@ func (a *Account) Create(opts *RequestOptions) error { return err } -//Containers returns a ContainerIterator that lists the containers in this -//account. The most common use case is: +// Containers returns a ContainerIterator that lists the containers in this +// account. The most common use case is: // // containers, err := account.Containers().Collect() // -//You can extend this by configuring the iterator before collecting the results: +// You can extend this by configuring the iterator before collecting the results: // // iter := account.Containers() // iter.Prefix = "test-" // containers, err := iter.Collect() // -//Or you can use a different iteration method: +// Or you can use a different iteration method: // // err := account.Containers().ForeachDetailed(func (ci ContainerInfo) error { // log.Printf("container %s contains %d objects!\n", // ci.Container.Name(), ci.ObjectCount) // }) -// func (a *Account) Containers() *ContainerIterator { return &ContainerIterator{Account: a} } -//Capabilities queries the GET /info endpoint of the Swift server providing -//this account. Capabilities are cached, so the GET request will only be sent -//once during the first call to this method. +// Capabilities queries the GET /info endpoint of the Swift server providing +// this account. Capabilities are cached, so the GET request will only be sent +// once during the first call to this method. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (a *Account) Capabilities() (Capabilities, error) { if a.caps != nil { return *a.caps, nil @@ -207,9 +206,9 @@ func (a *Account) Capabilities() (Capabilities, error) { return caps, nil } -//RawCapabilities queries the GET /info endpoint of the Swift server providing -//this account, and returns the response body. Unlike Account.Capabilities, -//this method does not employ any caching. +// RawCapabilities queries the GET /info endpoint of the Swift server providing +// this account, and returns the response body. Unlike Account.Capabilities, +// this method does not employ any caching. func (a *Account) RawCapabilities() ([]byte, error) { //This method is the only one in Schwift that bypasses struct Request since //the request URL is not below the endpoint URL. @@ -22,9 +22,9 @@ import ( "net/http" ) -//Backend is the interface between Schwift and the libraries providing -//authentication for it. Each instance of Backend represents a particular Swift -//account. +// Backend is the interface between Schwift and the libraries providing +// authentication for it. Each instance of Backend represents a particular Swift +// account. type Backend interface { //EndpointURL returns the endpoint URL from the Keystone catalog for the //Swift account that this backend operates on. It should look like @@ -43,6 +43,6 @@ type Backend interface { Do(req *http.Request) (*http.Response, error) } -//DefaultUserAgent is the User-Agent string that Backend implementations should -//use if the user does not provide their own User-Agent string. +// DefaultUserAgent is the User-Agent string that Backend implementations should +// use if the user does not provide their own User-Agent string. const DefaultUserAgent = "schwift/" + Version @@ -30,7 +30,7 @@ import ( "github.com/majewsky/schwift/capabilities" ) -//BulkUploadFormat enumerates possible archive formats for Container.BulkUpload(). +// BulkUploadFormat enumerates possible archive formats for Container.BulkUpload(). type BulkUploadFormat string const ( @@ -42,11 +42,11 @@ const ( BulkUploadTarBzip2 BulkUploadFormat = "tar.bz2" ) -//BulkUpload extracts an archive (which may contain multiple files) into a -//Swift account. The path of each file in the archive is appended to the -//uploadPath to form the FullName() of the resulting Object. +// BulkUpload extracts an archive (which may contain multiple files) into a +// Swift account. The path of each file in the archive is appended to the +// uploadPath to form the FullName() of the resulting Object. // -//For example, when uploading an archive that contains the file "a/b/c": +// For example, when uploading an archive that contains the file "a/b/c": // // //This uploads the file into the container "a" as object "b/c". // account.BulkUpload("", format, contents, nil) @@ -55,15 +55,15 @@ const ( // //This uploads the file into the container "foo" as object "bar/baz/a/b/c". // account.BulkUpload("foo/bar/baz", format, contents, nil) // -//The first return value indicates the number of files that have been created -//on the server side. This may be lower than the number of files in the archive -//if some files could not be saved individually (e.g. because a quota was -//exceeded in the middle of the archive extraction). +// The first return value indicates the number of files that have been created +// on the server side. This may be lower than the number of files in the archive +// if some files could not be saved individually (e.g. because a quota was +// exceeded in the middle of the archive extraction). // -//If not nil, the error return value is *usually* an instance of BulkError. +// If not nil, the error return value is *usually* an instance of BulkError. // -//This operation returns (0, ErrNotSupported) if the server does not support -//bulk-uploading. +// This operation returns (0, ErrNotSupported) if the server does not support +// bulk-uploading. func (a *Account) BulkUpload(uploadPath string, format BulkUploadFormat, contents io.Reader, opts *RequestOptions) (int, error) { caps, err := a.Capabilities() if err != nil { @@ -115,18 +115,18 @@ func makeBulkObjectError(fullName string, statusCode int) BulkObjectError { } } -//BulkDelete deletes a large number of objects (and containers) at once. -//Containers are queued at the end of the deletion, so a container can be -//deleted in the same call in which all objects in it are deleted. +// BulkDelete deletes a large number of objects (and containers) at once. +// Containers are queued at the end of the deletion, so a container can be +// deleted in the same call in which all objects in it are deleted. // -//For example, to delete all objects in a container: +// For example, to delete all objects in a container: // // var container *schwift.Container // // objects, err := container.Objects().Collect() // numDeleted, numNotFound, err := container.Account().BulkDelete(objects, nil, nil) // -//To also delete the container: +// To also delete the container: // // var container *schwift.Container // @@ -134,14 +134,14 @@ func makeBulkObjectError(fullName string, statusCode int) BulkObjectError { // numDeleted, numNotFound, err := container.Account().BulkDelete( // objects, []*schwift.Container{container}, nil) // -//If the server does not support bulk-deletion, this function falls back to -//deleting each object and container individually, and aggregates the result. +// If the server does not support bulk-deletion, this function falls back to +// deleting each object and container individually, and aggregates the result. // -//If not nil, the error return value is *usually* an instance of BulkError. +// If not nil, the error return value is *usually* an instance of BulkError. // -//The objects may be located in multiple containers, but they and the -//containers must all be located in the given account. (Otherwise, -//ErrAccountMismatch is returned.) +// The objects may be located in multiple containers, but they and the +// containers must all be located in the given account. (Otherwise, +// ErrAccountMismatch is returned.) func (a *Account) BulkDelete(objects []*Object, containers []*Container, opts *RequestOptions) (numDeleted int, numNotFound int, deleteError error) { //validate that all given objects are in this account for _, obj := range objects { @@ -200,8 +200,8 @@ func (a *Account) BulkDelete(objects []*Object, containers []*Container, opts *R return numDeleted, numNotFound, nil } -//Implementation of BulkDelete() for servers that *do not* support bulk -//deletion. +// Implementation of BulkDelete() for servers that *do not* support bulk +// deletion. func (a *Account) bulkDeleteSingle(objects []*Object, containers []*Container, opts *RequestOptions) (int, int, error) { var ( numDeleted = 0 @@ -256,9 +256,9 @@ func (a *Account) bulkDeleteSingle(objects []*Object, containers []*Container, o } } -//Implementation of BulkDelete() for servers that *do* support bulk deletion. -//This function is called *after* chunking, so `len(names) <= -//account.Capabilities.BulkDelete.MaximumDeletesPerRequest`. +// Implementation of BulkDelete() for servers that *do* support bulk deletion. +// This function is called *after* chunking, so `len(names) <= +// account.Capabilities.BulkDelete.MaximumDeletesPerRequest`. func (a *Account) bulkDelete(names []string, opts *RequestOptions) (int, int, error) { req := Request{ Method: "DELETE", diff --git a/capabilities.go b/capabilities.go index 69d6183..62290d9 100644 --- a/capabilities.go +++ b/capabilities.go @@ -18,14 +18,14 @@ package schwift -//Capabilities describes a subset of the capabilities that Swift can report -//under its /info endpoint. This struct is obtained through the -//Account.Capabilities() method. To query capabilities not represented in this -//struct, see Account.QueryCapabilities(). +// Capabilities describes a subset of the capabilities that Swift can report +// under its /info endpoint. This struct is obtained through the +// Account.Capabilities() method. To query capabilities not represented in this +// struct, see Account.QueryCapabilities(). // -//All direct members of struct Capabilities, except for "Swift", are pointers. -//If any of these is nil, it indicates that the middleware corresponding to -//that field is not available on this server. +// All direct members of struct Capabilities, except for "Swift", are pointers. +// If any of these is nil, it indicates that the middleware corresponding to +// that field is not available on this server. type Capabilities struct { BulkDelete *struct { MaximumDeletesPerRequest uint `json:"max_deletes_per_request"` @@ -82,7 +82,7 @@ type Capabilities struct { } `json:"tempurl"` } -//StoragePolicySpec is a subtype that appears in struct Capabilities. +// StoragePolicySpec is a subtype that appears in struct Capabilities. type StoragePolicySpec struct { Name string `json:"name"` Aliases string `json:"aliases"` diff --git a/capabilities/package.go b/capabilities/package.go index 021f28b..3d1e5a3 100644 --- a/capabilities/package.go +++ b/capabilities/package.go @@ -16,14 +16,14 @@ * ******************************************************************************/ -//Package capabilities contains feature switches that Schwift's unit tests can -//set to exercise certain fallback code paths in Schwift that they could not -//trigger otherwise. +// Package capabilities contains feature switches that Schwift's unit tests can +// set to exercise certain fallback code paths in Schwift that they could not +// trigger otherwise. // -//THIS IS A PRIVATE MODULE. It is not covered by any forwards or backwards -//compatiblity and may be gone at a moment's notice. +// THIS IS A PRIVATE MODULE. It is not covered by any forwards or backwards +// compatiblity and may be gone at a moment's notice. package capabilities -//AllowBulkDelete can be set to false to force Schwift to act as if the server -//does not support bulk deletion. +// AllowBulkDelete can be set to false to force Schwift to act as if the server +// does not support bulk deletion. var AllowBulkDelete = true diff --git a/container.go b/container.go index de85f62..476a704 100644 --- a/container.go +++ b/container.go @@ -22,9 +22,9 @@ import ( "net/http" ) -//Container represents a Swift container. Instances are usually obtained by -//traversing downwards from an account with Account.Container() or -//Account.Containers(), or upwards from an object with Object.Container(). +// Container represents a Swift container. Instances are usually obtained by +// traversing downwards from an account with Account.Container() or +// Account.Containers(), or upwards from an object with Object.Container(). type Container struct { a *Account name string @@ -32,34 +32,34 @@ type Container struct { headers *ContainerHeaders } -//IsEqualTo returns true if both Container instances refer to the same container. +// IsEqualTo returns true if both Container instances refer to the same container. func (c *Container) IsEqualTo(other *Container) bool { return other.name == c.name && other.a.IsEqualTo(c.a) } -//Container returns a handle to the container with the given name within this -//account. This function does not issue any HTTP requests, and therefore cannot -//ensure that the container exists. Use the Exists() function to check for the -//container's existence, or chain this function with the EnsureExists() -//function like so: +// Container returns a handle to the container with the given name within this +// account. This function does not issue any HTTP requests, and therefore cannot +// ensure that the container exists. Use the Exists() function to check for the +// container's existence, or chain this function with the EnsureExists() +// function like so: // // container, err := account.Container("documents").EnsureExists() func (a *Account) Container(name string) *Container { return &Container{a: a, name: name} } -//Account returns a handle to the account this container is stored in. +// Account returns a handle to the account this container is stored in. func (c *Container) Account() *Account { return c.a } -//Name returns the container name. +// Name returns the container name. func (c *Container) Name() string { return c.name } -//Exists checks if this container exists, potentially by issuing a HEAD request -//if no Headers() have been cached yet. +// Exists checks if this container exists, potentially by issuing a HEAD request +// if no Headers() have been cached yet. func (c *Container) Exists() (bool, error) { _, err := c.Headers() if Is(err, http.StatusNotFound) { @@ -70,13 +70,13 @@ func (c *Container) Exists() (bool, error) { return true, nil } -//Headers returns the ContainerHeaders for this container. If the ContainerHeaders -//has not been cached yet, a HEAD request is issued on the container. +// Headers returns the ContainerHeaders for this container. If the ContainerHeaders +// has not been cached yet, a HEAD request is issued on the container. // -//This operation fails with http.StatusNotFound if the container does not exist. +// This operation fails with http.StatusNotFound if the container does not exist. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (c *Container) Headers() (ContainerHeaders, error) { if c.headers != nil { return *c.headers, nil @@ -100,12 +100,12 @@ func (c *Container) Headers() (ContainerHeaders, error) { return *c.headers, nil } -//Update updates the container using a POST request. To add URL parameters, pass -//a non-nil *RequestOptions. +// Update updates the container using a POST request. To add URL parameters, pass +// a non-nil *RequestOptions. // -//If you are not sure whether the container exists, use Create() instead. +// If you are not sure whether the container exists, use Create() instead. // -//A successful POST request implies Invalidate() since it may change metadata. +// A successful POST request implies Invalidate() since it may change metadata. func (c *Container) Update(headers ContainerHeaders, opts *RequestOptions) error { _, err := Request{ Method: "POST", @@ -119,12 +119,12 @@ func (c *Container) Update(headers ContainerHeaders, opts *RequestOptions) error return err } -//Create creates the container using a PUT request. To add URL parameters, pass -//a non-nil *RequestOptions. +// Create creates the container using a PUT request. To add URL parameters, pass +// a non-nil *RequestOptions. // -//This function can be used regardless of whether the container exists or not. +// This function can be used regardless of whether the container exists or not. // -//A successful PUT request implies Invalidate() since it may change metadata. +// A successful PUT request implies Invalidate() since it may change metadata. func (c *Container) Create(opts *RequestOptions) error { _, err := Request{ Method: "PUT", @@ -139,14 +139,14 @@ func (c *Container) Create(opts *RequestOptions) error { return err } -//Delete deletes the container using a DELETE request. To add URL parameters, -//pass a non-nil *RequestOptions. +// Delete deletes the container using a DELETE request. To add URL parameters, +// pass a non-nil *RequestOptions. // -//This operation fails with http.StatusConflict if the container is not empty. +// This operation fails with http.StatusConflict if the container is not empty. // -//This operation fails with http.StatusNotFound if the container does not exist. +// This operation fails with http.StatusNotFound if the container does not exist. // -//A successful DELETE request implies Invalidate(). +// A successful DELETE request implies Invalidate(). func (c *Container) Delete(opts *RequestOptions) error { _, err := Request{ Method: "DELETE", @@ -160,20 +160,20 @@ func (c *Container) Delete(opts *RequestOptions) error { return err } -//Invalidate clears the internal cache of this Container instance. The next call -//to Headers() on this instance will issue a HEAD request on the container. +// Invalidate clears the internal cache of this Container instance. The next call +// to Headers() on this instance will issue a HEAD request on the container. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (c *Container) Invalidate() { c.headers = nil } -//EnsureExists issues a PUT request on this container. -//If the container does not exist yet, it will be created by this call. -//If the container exists already, this call does not change it. -//This function returns the same container again, because its intended use is -//with freshly constructed Container instances like so: +// EnsureExists issues a PUT request on this container. +// If the container does not exist yet, it will be created by this call. +// If the container exists already, this call does not change it. +// This function returns the same container again, because its intended use is +// with freshly constructed Container instances like so: // // container, err := account.Container("documents").EnsureExists() func (c *Container) EnsureExists() (*Container, error) { @@ -186,31 +186,30 @@ func (c *Container) EnsureExists() (*Container, error) { return c, err } -//Objects returns an ObjectIterator that lists the objects in this -//container. The most common use case is: +// Objects returns an ObjectIterator that lists the objects in this +// container. The most common use case is: // // objects, err := container.Objects().Collect() // -//You can extend this by configuring the iterator before collecting the results: +// You can extend this by configuring the iterator before collecting the results: // // iter := container.Objects() // iter.Prefix = "test-" // objects, err := iter.Collect() // -//Or you can use a different iteration method: +// Or you can use a different iteration method: // // err := container.Objects().ForeachDetailed(func (info ObjectInfo) error { // log.Printf("object %s is %d bytes large!\n", // info.Object.Name(), info.SizeBytes) // }) -// func (c *Container) Objects() *ObjectIterator { return &ObjectIterator{Container: c} } -//URL returns the canonical URL for this container on the server. This is -//particularly useful when the ReadACL on the account or container is set to -//allow anonymous read access. +// URL returns the canonical URL for this container on the server. This is +// particularly useful when the ReadACL on the account or container is set to +// allow anonymous read access. func (c *Container) URL() (string, error) { return Request{ ContainerName: c.name, diff --git a/container_iterator.go b/container_iterator.go index 73722e3..6dd75c2 100644 --- a/container_iterator.go +++ b/container_iterator.go @@ -23,10 +23,10 @@ import ( "time" ) -//ContainerInfo is a result type returned by ContainerIterator for detailed -//container listings. The metadata in this type is a subset of Container.Headers(), -//but since it is returned as part of the detailed container listing, it can be -//obtained without making additional HEAD requests on the container(s). +// ContainerInfo is a result type returned by ContainerIterator for detailed +// container listings. The metadata in this type is a subset of Container.Headers(), +// but since it is returned as part of the detailed container listing, it can be +// obtained without making additional HEAD requests on the container(s). type ContainerInfo struct { Container *Container ObjectCount uint64 @@ -34,8 +34,8 @@ type ContainerInfo struct { LastModified time.Time } -//ContainerIterator iterates over the accounts in a container. It is typically -//constructed with the Account.Containers() method. For example: +// ContainerIterator iterates over the accounts in a container. It is typically +// constructed with the Account.Containers() method. For example: // // //either this... // iter := account.Containers() @@ -48,17 +48,17 @@ type ContainerInfo struct { // Prefix: "test-", // }.Collect() // -//When listing containers via a GET request on the account, you can choose to -//receive container names only (via the methods without the "Detailed" suffix), -//or container names plus some basic metadata fields (via the methods with the -//"Detailed" suffix). See struct ContainerInfo for which metadata is returned. +// When listing containers via a GET request on the account, you can choose to +// receive container names only (via the methods without the "Detailed" suffix), +// or container names plus some basic metadata fields (via the methods with the +// "Detailed" suffix). See struct ContainerInfo for which metadata is returned. // -//To obtain any other metadata, you can call Container.Headers() on the result -//container, but this will issue a separate HEAD request for each container. +// To obtain any other metadata, you can call Container.Headers() on the result +// container, but this will issue a separate HEAD request for each container. // -//Use the "Detailed" methods only when you use the extra metadata in struct -//ContainerInfo; detailed GET requests are more expensive than simple ones that -//return only container names. +// Use the "Detailed" methods only when you use the extra metadata in struct +// ContainerInfo; detailed GET requests are more expensive than simple ones that +// return only container names. type ContainerIterator struct { Account *Account //When Prefix is set, only containers whose name starts with this string are @@ -77,15 +77,15 @@ func (i *ContainerIterator) getBase() *iteratorBase { return i.base } -//NextPage queries Swift for the next page of container names. If limit is -//>= 0, not more than that many container names will be returned at once. Note -//that the server also has a limit for how many containers to list in one -//request; the lower limit wins. +// NextPage queries Swift for the next page of container names. If limit is +// >= 0, not more than that many container names will be returned at once. Note +// that the server also has a limit for how many containers to list in one +// request; the lower limit wins. // -//The end of the container listing is reached when an empty list is returned. +// The end of the container listing is reached when an empty list is returned. // -//This method offers maximal flexibility, but most users will prefer the -//simpler interfaces offered by Collect() and Foreach(). +// This method offers maximal flexibility, but most users will prefer the +// simpler interfaces offered by Collect() and Foreach(). func (i *ContainerIterator) NextPage(limit int) ([]*Container, error) { names, err := i.getBase().nextPage(limit) if err != nil { @@ -99,7 +99,7 @@ func (i *ContainerIterator) NextPage(limit int) ([]*Container, error) { return result, nil } -//NextPageDetailed is like NextPage, but includes basic metadata. +// NextPageDetailed is like NextPage, but includes basic metadata. func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error) { b := i.getBase() @@ -134,9 +134,9 @@ func (i *ContainerIterator) NextPageDetailed(limit int) ([]ContainerInfo, error) return result, nil } -//Foreach lists the container names matching this iterator and calls the -//callback once for every container. Iteration is aborted when a GET request fails, -//or when the callback returns a non-nil error. +// Foreach lists the container names matching this iterator and calls the +// callback once for every container. Iteration is aborted when a GET request fails, +// or when the callback returns a non-nil error. func (i *ContainerIterator) Foreach(callback func(*Container) error) error { for { containers, err := i.NextPage(-1) @@ -155,7 +155,7 @@ func (i *ContainerIterator) Foreach(callback func(*Container) error) error { } } -//ForeachDetailed is like Foreach, but includes basic metadata. +// ForeachDetailed is like Foreach, but includes basic metadata. func (i *ContainerIterator) ForeachDetailed(callback func(ContainerInfo) error) error { for { infos, err := i.NextPageDetailed(-1) @@ -174,9 +174,9 @@ func (i *ContainerIterator) ForeachDetailed(callback func(ContainerInfo) error) } } -//Collect lists all container names matching this iterator. For large sets of -//containers that cannot be retrieved at once, Collect handles paging behind -//the scenes. The return value is always the complete set of containers. +// Collect lists all container names matching this iterator. For large sets of +// containers that cannot be retrieved at once, Collect handles paging behind +// the scenes. The return value is always the complete set of containers. func (i *ContainerIterator) Collect() ([]*Container, error) { var result []*Container for { @@ -191,7 +191,7 @@ func (i *ContainerIterator) Collect() ([]*Container, error) { } } -//CollectDetailed is like Collect, but includes basic metadata. +// CollectDetailed is like Collect, but includes basic metadata. func (i *ContainerIterator) CollectDetailed() ([]ContainerInfo, error) { var result []ContainerInfo for { @@ -17,11 +17,10 @@ ******************************************************************************/ /* - Package schwift is a client library for OpenStack Swift (https://github.com/openstack/swift, https://openstack.org). -Authentication with Gophercloud +# Authentication with Gophercloud Schwift does not implement authentication (neither Keystone nor Swift v1), but can be plugged into any library that does. The most common choice is @@ -62,14 +61,14 @@ For example, to download an object's contents into a string: text, err := account.Container("foo").Object("bar.txt").Download(nil).AsString() -Authentication with a different OpenStack library +# Authentication with a different OpenStack library If you use a different Go library to handle Keystone/Swift authentication, take the client object that it provides and wrap it into something that implements the schwift.Backend interface. Then use schwift.InitializeAccount() to obtain a schwift.Account. -Caching +# Caching When a GET or HEAD request is sent by an Account, Container or Object instance, the headers associated with that thing will be stored in that instance and not @@ -86,7 +85,7 @@ caches on any Account, Container or Object instance. Some methods that modify the instance on the server call Invalidate() automatically, e.g. Object.Upload(), Update() or Delete(). This will be indicated in the method's documentation. -Error handling +# Error handling When a method on an Account, Container or Object instance makes a HTTP request to Swift and Swift returns an unexpected status code, a @@ -107,6 +106,5 @@ The documentation for a method may indicate certain common error conditions that can be detected this way by stating that "This method fails with http.StatusXXX if ...". Because of the wide variety of failure modes in Swift, this information is not guaranteed to be exhaustive. - */ package schwift diff --git a/download.go b/download.go index dfd9a07..130df91 100644 --- a/download.go +++ b/download.go @@ -23,9 +23,9 @@ import ( "io/ioutil" ) -//DownloadedObject is returned by Object.Download(). It wraps the io.ReadCloser -//from http.Response.Body with convenience methods for collecting the contents -//into a byte slice or string. +// DownloadedObject is returned by Object.Download(). It wraps the io.ReadCloser +// from http.Response.Body with convenience methods for collecting the contents +// into a byte slice or string. // // var obj *swift.Object // @@ -38,9 +38,9 @@ import ( // //Do this instead: // str, err := obj.Download(nil).AsString() // -//Since all methods on DownloadedObject are irreversible, the idiomatic way of -//using DownloadedObject is to call one of its members immediately, without -//storing the DownloadedObject instance in a variable first. +// Since all methods on DownloadedObject are irreversible, the idiomatic way of +// using DownloadedObject is to call one of its members immediately, without +// storing the DownloadedObject instance in a variable first. // // var obj *swift.Object // @@ -55,13 +55,13 @@ type DownloadedObject struct { err error } -//AsReadCloser returns an io.ReadCloser containing the contents of the -//downloaded object. +// AsReadCloser returns an io.ReadCloser containing the contents of the +// downloaded object. func (o DownloadedObject) AsReadCloser() (io.ReadCloser, error) { return o.r, o.err } -//AsByteSlice collects the contents of this downloaded object into a byte slice. +// AsByteSlice collects the contents of this downloaded object into a byte slice. func (o DownloadedObject) AsByteSlice() ([]byte, error) { if o.err != nil { return nil, o.err @@ -74,7 +74,7 @@ func (o DownloadedObject) AsByteSlice() ([]byte, error) { return slice, closeErr } -//AsString collects the contents of this downloaded object into a string. +// AsString collects the contents of this downloaded object into a string. func (o DownloadedObject) AsString() (string, error) { slice, err := o.AsByteSlice() return string(slice), err @@ -56,16 +56,16 @@ var ( ErrSegmentInvalid = errors.New("segment invalid or incompatible with large object strategy") ) -//UnexpectedStatusCodeError is generated when a request to Swift does not yield -//a response with the expected successful status code. The actual status code -//can be checked with the Is() function; see documentation over there. +// UnexpectedStatusCodeError is generated when a request to Swift does not yield +// a response with the expected successful status code. The actual status code +// can be checked with the Is() function; see documentation over there. type UnexpectedStatusCodeError struct { ExpectedStatusCodes []int ActualResponse *http.Response ResponseBody []byte } -//Error implements the builtin/error interface. +// Error implements the builtin/error interface. func (e UnexpectedStatusCodeError) Error() string { codeStrs := make([]string, len(e.ExpectedStatusCodes)) for idx, code := range e.ExpectedStatusCodes { @@ -81,15 +81,15 @@ func (e UnexpectedStatusCodeError) Error() string { return msg } -//BulkObjectError is the error message for a single object in a bulk operation. -//It is not generated individually, only as part of BulkError. +// BulkObjectError is the error message for a single object in a bulk operation. +// It is not generated individually, only as part of BulkError. type BulkObjectError struct { ContainerName string ObjectName string StatusCode int } -//Error implements the builtin/error interface. +// Error implements the builtin/error interface. func (e BulkObjectError) Error() string { return fmt.Sprintf("%s/%s: %d %s", e.ContainerName, e.ObjectName, @@ -97,10 +97,10 @@ func (e BulkObjectError) Error() string { ) } -//BulkError is returned by Account.BulkUpload() when the archive was -//uploaded and unpacked successfully, but some (or all) objects could not be -//saved in Swift; and by Account.BulkDelete() when not all requested objects -//could be deleted. +// BulkError is returned by Account.BulkUpload() when the archive was +// uploaded and unpacked successfully, but some (or all) objects could not be +// saved in Swift; and by Account.BulkDelete() when not all requested objects +// could be deleted. type BulkError struct { //StatusCode contains the overall HTTP status code of the operation. StatusCode int @@ -112,8 +112,8 @@ type BulkError struct { ObjectErrors []BulkObjectError } -//Error implements the builtin/error interface. To fit into one line, it -//condenses the ObjectErrors into a count. +// Error implements the builtin/error interface. To fit into one line, it +// condenses the ObjectErrors into a count. func (e BulkError) Error() string { result := fmt.Sprintf("%d %s", e.StatusCode, http.StatusText(e.StatusCode)) if e.OverallError != "" { @@ -125,8 +125,8 @@ func (e BulkError) Error() string { return result } -//Is checks if the given error is an UnexpectedStatusCodeError for that status -//code. For example: +// Is checks if the given error is an UnexpectedStatusCodeError for that status +// code. For example: // // err := container.Delete(nil) // if err != nil { @@ -139,7 +139,7 @@ func (e BulkError) Error() string { // } // } // -//It is safe to pass a nil error, in which case Is() always returns false. +// It is safe to pass a nil error, in which case Is() always returns false. func Is(err error, code int) bool { if e, ok := err.(UnexpectedStatusCodeError); ok { return e.ActualResponse.StatusCode == code @@ -147,14 +147,14 @@ func Is(err error, code int) bool { return false } -//MalformedHeaderError is generated when a response from Swift contains a -//malformed header. +// MalformedHeaderError is generated when a response from Swift contains a +// malformed header. type MalformedHeaderError struct { Key string ParseError error } -//Error implements the builtin/error interface. +// Error implements the builtin/error interface. func (e MalformedHeaderError) Error() string { return "Bad header " + e.Key + ": " + e.ParseError.Error() } diff --git a/field_metadata.go b/field_metadata.go index 90993d4..447f293 100644 --- a/field_metadata.go +++ b/field_metadata.go @@ -18,9 +18,9 @@ package schwift -//FieldMetadata is a helper type that provides safe access to the metadata headers -//in a headers instance. It cannot be directly constructed, but each headers -//type has a method "Metadata" returning this type. For example: +// FieldMetadata is a helper type that provides safe access to the metadata headers +// in a headers instance. It cannot be directly constructed, but each headers +// type has a method "Metadata" returning this type. For example: // // hdr := NewObjectHeaders() // //the following two statements are equivalent @@ -31,22 +31,22 @@ type FieldMetadata struct { k string } -//Clear works like Headers.Clear(), but prepends the metadata prefix to the key. +// Clear works like Headers.Clear(), but prepends the metadata prefix to the key. func (m FieldMetadata) Clear(key string) { m.h.Clear(m.k + key) } -//Del works like Headers.Del(), but prepends the metadata prefix to the key. +// Del works like Headers.Del(), but prepends the metadata prefix to the key. func (m FieldMetadata) Del(key string) { m.h.Del(m.k + key) } -//Get works like Headers.Get(), but prepends the metadata prefix to the key. +// Get works like Headers.Get(), but prepends the metadata prefix to the key. func (m FieldMetadata) Get(key string) string { return m.h.Get(m.k + key) } -//Set works like Headers.Set(), but prepends the metadata prefix to the key. +// Set works like Headers.Set(), but prepends the metadata prefix to the key. func (m FieldMetadata) Set(key, value string) { m.h.Set(m.k+key, value) } diff --git a/field_string.go b/field_string.go index e0007e9..8621a69 100644 --- a/field_string.go +++ b/field_string.go @@ -18,9 +18,9 @@ package schwift -//FieldString is a helper type that provides type-safe access to a Swift header key -//whose value is a string. It cannot be directly constructed, but methods on -//the Headers types return this type. For example: +// FieldString is a helper type that provides type-safe access to a Swift header key +// whose value is a string. It cannot be directly constructed, but methods on +// the Headers types return this type. For example: // // hdr := NewAccountHeaders() // //the following two statements are equivalent: @@ -31,30 +31,30 @@ type FieldString struct { k string } -//Exists checks whether there is a value for this header. +// Exists checks whether there is a value for this header. func (f FieldString) Exists() bool { return f.h.Get(f.k) != "" } -//Get returns the value for this header, or the empty string if there is no value. +// Get returns the value for this header, or the empty string if there is no value. func (f FieldString) Get() string { return f.h.Get(f.k) } -//Set writes a new value for this header into the corresponding headers -//instance. +// Set writes a new value for this header into the corresponding headers +// instance. func (f FieldString) Set(value string) { f.h.Set(f.k, value) } -//Del removes this key from the original headers instance, so that the -//key will remain unchanged on the server during Update(). +// Del removes this key from the original headers instance, so that the +// key will remain unchanged on the server during Update(). func (f FieldString) Del() { f.h.Del(f.k) } -//Clear sets this key to an empty string in the original headers -//instance, so that the key will be removed on the server during Update(). +// Clear sets this key to an empty string in the original headers +// instance, so that the key will be removed on the server during Update(). func (f FieldString) Clear() { f.h.Clear(f.k) } diff --git a/field_time.go b/field_time.go index d6ec447..e5fe8cc 100644 --- a/field_time.go +++ b/field_time.go @@ -24,13 +24,13 @@ import ( "time" ) -//FieldHTTPTimeReadonly is a helper type that provides type-safe access to a -//readonly Swift header whose value is a HTTP timestamp like this: +// FieldHTTPTimeReadonly is a helper type that provides type-safe access to a +// readonly Swift header whose value is a HTTP timestamp like this: // // Mon, 02 Jan 2006 15:04:05 GMT // -//It cannot be directly constructed, but methods on the Headers types return -//this type. For example: +// It cannot be directly constructed, but methods on the Headers types return +// this type. For example: // // //suppose you have: // hdr, err := obj.Headers() @@ -41,21 +41,21 @@ import ( // //or you can just: // time := hdr.UpdatedAt().Get() // -//Don't worry about the missing `err` in the last line. When the header fails -//to parse, Object.Headers() already returns the corresponding -//MalformedHeaderError. +// Don't worry about the missing `err` in the last line. When the header fails +// to parse, Object.Headers() already returns the corresponding +// MalformedHeaderError. type FieldHTTPTimeReadonly struct { h Headers k string } -//Exists checks whether there is a value for this header. +// Exists checks whether there is a value for this header. func (f FieldHTTPTimeReadonly) Exists() bool { return f.h.Get(f.k) != "" } -//Get returns the value for this header, or the zero value if there is no value -//(or if it is not a valid timestamp). +// Get returns the value for this header, or the zero value if there is no value +// (or if it is not a valid timestamp). func (f FieldHTTPTimeReadonly) Get() time.Time { t, err := http.ParseTime(f.h.Get(f.k)) if err != nil { @@ -78,9 +78,9 @@ func (f FieldHTTPTimeReadonly) validate() error { //////////////////////////////////////////////////////////////////////////////// -//FieldUnixTime is a helper type that provides type-safe access to a Swift -//header whose value is a UNIX timestamp. It cannot be directly constructed, -//but methods on the Headers types return this type. For example: +// FieldUnixTime is a helper type that provides type-safe access to a Swift +// header whose value is a UNIX timestamp. It cannot be directly constructed, +// but methods on the Headers types return this type. For example: // // //suppose you have: // hdr, err := obj.Headers() @@ -92,21 +92,21 @@ func (f FieldHTTPTimeReadonly) validate() error { // //or you can just: // time := hdr.ExpiresAt().Get() // -//Don't worry about the missing `err` in the last line. When the header fails -//to parse, Object.Headers() already returns the corresponding -//MalformedHeaderError. +// Don't worry about the missing `err` in the last line. When the header fails +// to parse, Object.Headers() already returns the corresponding +// MalformedHeaderError. type FieldUnixTime struct { h Headers k string } -//Exists checks whether there is a value for this header. +// Exists checks whether there is a value for this header. func (f FieldUnixTime) Exists() bool { return f.h.Get(f.k) != "" } -//Get returns the value for this header, or the zero value if there is no value -//(or if it is not a valid timestamp). +// Get returns the value for this header, or the zero value if there is no value +// (or if it is not a valid timestamp). func (f FieldUnixTime) Get() time.Time { v, err := strconv.ParseFloat(f.h.Get(f.k), 64) if err != nil { @@ -115,20 +115,20 @@ func (f FieldUnixTime) Get() time.Time { return time.Unix(0, int64(1e9*v)) } -//Set writes a new value for this header into the corresponding headers -//instance. +// Set writes a new value for this header into the corresponding headers +// instance. func (f FieldUnixTime) Set(value time.Time) { f.h.Set(f.k, strconv.FormatUint(uint64(value.UnixNano())/1e9, 10)) } -//Del removes this key from the original headers instance, so that the key will -//remain unchanged on the server during Update(). +// Del removes this key from the original headers instance, so that the key will +// remain unchanged on the server during Update(). func (f FieldUnixTime) Del() { f.h.Del(f.k) } -//Clear sets this key to an empty string in the original headers instance, so -//that the key will be removed on the server during Update(). +// Clear sets this key to an empty string in the original headers instance, so +// that the key will be removed on the server during Update(). func (f FieldUnixTime) Clear() { f.h.Clear(f.k) } @@ -147,20 +147,20 @@ func (f FieldUnixTime) validate() error { //////////////////////////////////////////////////////////////////////////////// -//FieldUnixTimeReadonly is a readonly variant of FieldUnixTime. It is used for -//fields that cannot be set by the client. +// FieldUnixTimeReadonly is a readonly variant of FieldUnixTime. It is used for +// fields that cannot be set by the client. type FieldUnixTimeReadonly struct { h Headers k string } -//Exists checks whether there is a value for this header. +// Exists checks whether there is a value for this header. func (f FieldUnixTimeReadonly) Exists() bool { return f.h.Get(f.k) != "" } -//Get returns the value for this header, or the zero value if there is no value -//(or if it is not a valid timestamp). +// Get returns the value for this header, or the zero value if there is no value +// (or if it is not a valid timestamp). func (f FieldUnixTimeReadonly) Get() time.Time { return FieldUnixTime{f.h, f.k}.Get() } diff --git a/field_uint64.go b/field_uint64.go index 2a542ae..d8e63a4 100644 --- a/field_uint64.go +++ b/field_uint64.go @@ -22,9 +22,9 @@ import ( "strconv" ) -//FieldUint64 is a helper type that provides type-safe access to a Swift header -//whose value is an unsigned integer. It cannot be directly constructed, but -//methods on the Headers types return this type. For example: +// FieldUint64 is a helper type that provides type-safe access to a Swift header +// whose value is an unsigned integer. It cannot be directly constructed, but +// methods on the Headers types return this type. For example: // // hdr := NewAccountHeaders() // //the following two statements are equivalent: @@ -35,13 +35,13 @@ type FieldUint64 struct { k string } -//Exists checks whether there is a value for this header. +// Exists checks whether there is a value for this header. func (f FieldUint64) Exists() bool { return f.h.Get(f.k) != "" } -//Get returns the value for this header, or 0 if there is no value (or if it is -//not a valid uint64). +// Get returns the value for this header, or 0 if there is no value (or if it is +// not a valid uint64). func (f FieldUint64) Get() uint64 { v, err := strconv.ParseUint(f.h.Get(f.k), 10, 64) if err != nil { @@ -50,20 +50,20 @@ func (f FieldUint64) Get() uint64 { return v } -//Set writes a new value for this header into the corresponding headers -//instance. +// Set writes a new value for this header into the corresponding headers +// instance. func (f FieldUint64) Set(value uint64) { f.h.Set(f.k, strconv.FormatUint(value, 10)) } -//Del removes this key from the original headers instance, so that the key will -//remain unchanged on the server during Update(). +// Del removes this key from the original headers instance, so that the key will +// remain unchanged on the server during Update(). func (f FieldUint64) Del() { f.h.Del(f.k) } -//Clear sets this key to an empty string in the original headers instance, so -//that the key will be removed on the server during Update(). +// Clear sets this key to an empty string in the original headers instance, so +// that the key will be removed on the server during Update(). func (f FieldUint64) Clear() { f.h.Clear(f.k) } @@ -82,20 +82,20 @@ func (f FieldUint64) validate() error { //////////////////////////////////////////////////////////////////////////////// -//FieldUint64Readonly is a readonly variant of FieldUint64. It is used for -//fields that cannot be set by the client. +// FieldUint64Readonly is a readonly variant of FieldUint64. It is used for +// fields that cannot be set by the client. type FieldUint64Readonly struct { h Headers k string } -//Exists checks whether there is a value for this header. +// Exists checks whether there is a value for this header. func (f FieldUint64Readonly) Exists() bool { return f.h.Get(f.k) != "" } -//Get returns the value for this header, or 0 if there is no value (or if it is -//not a valid uint64). +// Get returns the value for this header, or 0 if there is no value (or if it is +// not a valid uint64). func (f FieldUint64Readonly) Get() uint64 { return FieldUint64{f.h, f.k}.Get() } diff --git a/generated.go b/generated.go index abc4f90..e7ffcd9 100644 --- a/generated.go +++ b/generated.go @@ -8,25 +8,25 @@ package schwift -//AccountHeaders contains the headers for a schwift.Account instance. +// AccountHeaders contains the headers for a schwift.Account instance. // -//To read and write well-known headers, use the methods on this type. -//To read and write arbitary headers, use the methods on the Headers supertype. +// To read and write well-known headers, use the methods on this type. +// To read and write arbitary headers, use the methods on the Headers supertype. type AccountHeaders struct { Headers } -//NewAccountHeaders creates a new AccountHeaders instance. The return value -//will have the Headers attribute initialized to a non-nil map. +// NewAccountHeaders creates a new AccountHeaders instance. The return value +// will have the Headers attribute initialized to a non-nil map. func NewAccountHeaders() AccountHeaders { return AccountHeaders{make(Headers)} } -//Validate returns MalformedHeaderError if the value of any well-known header -//does not conform to its data type. This is called automatically by Schwift -//when preparing an AccountHeaders instance from a GET/HEAD response, so you -//usually do not need to do it yourself. You will get the validation error from -//the Account method doing the request, e.g. Headers(). +// Validate returns MalformedHeaderError if the value of any well-known header +// does not conform to its data type. This is called automatically by Schwift +// when preparing an AccountHeaders instance from a GET/HEAD response, so you +// usually do not need to do it yourself. You will get the validation error from +// the Account method doing the request, e.g. Headers(). func (h AccountHeaders) Validate() error { if err := h.BytesUsed().validate(); err != nil { return err @@ -55,65 +55,65 @@ func (h AccountHeaders) Validate() error { return evadeGolintComplaint1() } -//BytesUsed provides type-safe access to X-Account-Bytes-Used headers. +// BytesUsed provides type-safe access to X-Account-Bytes-Used headers. func (h AccountHeaders) BytesUsed() FieldUint64Readonly { return FieldUint64Readonly{h.Headers, "X-Account-Bytes-Used"} } -//ContainerCount provides type-safe access to X-Account-Container-Count headers. +// ContainerCount provides type-safe access to X-Account-Container-Count headers. func (h AccountHeaders) ContainerCount() FieldUint64Readonly { return FieldUint64Readonly{h.Headers, "X-Account-Container-Count"} } -//Metadata provides type-safe access to X-Account-Meta- headers. +// Metadata provides type-safe access to X-Account-Meta- headers. func (h AccountHeaders) Metadata() FieldMetadata { return FieldMetadata{h.Headers, "X-Account-Meta-"} } -//BytesUsedQuota provides type-safe access to X-Account-Meta-Quota-Bytes headers. +// BytesUsedQuota provides type-safe access to X-Account-Meta-Quota-Bytes headers. func (h AccountHeaders) BytesUsedQuota() FieldUint64 { return FieldUint64{h.Headers, "X-Account-Meta-Quota-Bytes"} } -//TempURLKey2 provides type-safe access to X-Account-Meta-Temp-URL-Key-2 headers. +// TempURLKey2 provides type-safe access to X-Account-Meta-Temp-URL-Key-2 headers. func (h AccountHeaders) TempURLKey2() FieldString { return FieldString{h.Headers, "X-Account-Meta-Temp-URL-Key-2"} } -//TempURLKey provides type-safe access to X-Account-Meta-Temp-URL-Key headers. +// TempURLKey provides type-safe access to X-Account-Meta-Temp-URL-Key headers. func (h AccountHeaders) TempURLKey() FieldString { return FieldString{h.Headers, "X-Account-Meta-Temp-URL-Key"} } -//ObjectCount provides type-safe access to X-Account-Object-Count headers. +// ObjectCount provides type-safe access to X-Account-Object-Count headers. func (h AccountHeaders) ObjectCount() FieldUint64Readonly { return FieldUint64Readonly{h.Headers, "X-Account-Object-Count"} } -//CreatedAt provides type-safe access to X-Timestamp headers. +// CreatedAt provides type-safe access to X-Timestamp headers. func (h AccountHeaders) CreatedAt() FieldUnixTimeReadonly { return FieldUnixTimeReadonly{h.Headers, "X-Timestamp"} } -//ContainerHeaders contains the headers for a schwift.Container instance. +// ContainerHeaders contains the headers for a schwift.Container instance. // -//To read and write well-known headers, use the methods on this type. -//To read and write arbitary headers, use the methods on the Headers supertype. +// To read and write well-known headers, use the methods on this type. +// To read and write arbitary headers, use the methods on the Headers supertype. type ContainerHeaders struct { Headers } -//NewContainerHeaders creates a new ContainerHeaders instance. The return value -//will have the Headers attribute initialized to a non-nil map. +// NewContainerHeaders creates a new ContainerHeaders instance. The return value +// will have the Headers attribute initialized to a non-nil map. func NewContainerHeaders() ContainerHeaders { return ContainerHeaders{make(Headers)} } -//Validate returns MalformedHeaderError if the value of any well-known header -//does not conform to its data type. This is called automatically by Schwift -//when preparing an ContainerHeaders instance from a GET/HEAD response, so you -//usually do not need to do it yourself. You will get the validation error from -//the Container method doing the request, e.g. Headers(). +// Validate returns MalformedHeaderError if the value of any well-known header +// does not conform to its data type. This is called automatically by Schwift +// when preparing an ContainerHeaders instance from a GET/HEAD response, so you +// usually do not need to do it yourself. You will get the validation error from +// the Container method doing the request, e.g. Headers(). func (h ContainerHeaders) Validate() error { if err := h.BytesUsed().validate(); err != nil { return err @@ -163,100 +163,100 @@ func (h ContainerHeaders) Validate() error { return evadeGolintComplaint1() } -//BytesUsed provides type-safe access to X-Container-Bytes-Used headers. +// BytesUsed provides type-safe access to X-Container-Bytes-Used headers. func (h ContainerHeaders) BytesUsed() FieldUint64Readonly { return FieldUint64Readonly{h.Headers, "X-Container-Bytes-Used"} } -//Metadata provides type-safe access to X-Container-Meta- headers. +// Metadata provides type-safe access to X-Container-Meta- headers. func (h ContainerHeaders) Metadata() FieldMetadata { return FieldMetadata{h.Headers, "X-Container-Meta-"} } -//BytesUsedQuota provides type-safe access to X-Container-Meta-Quota-Bytes headers. +// BytesUsedQuota provides type-safe access to X-Container-Meta-Quota-Bytes headers. func (h ContainerHeaders) BytesUsedQuota() FieldUint64 { return FieldUint64{h.Headers, "X-Container-Meta-Quota-Bytes"} } -//ObjectCountQuota provides type-safe access to X-Container-Meta-Quota-Count headers. +// ObjectCountQuota provides type-safe access to X-Container-Meta-Quota-Count headers. func (h ContainerHeaders) ObjectCountQuota() FieldUint64 { return FieldUint64{h.Headers, "X-Container-Meta-Quota-Count"} } -//TempURLKey2 provides type-safe access to X-Container-Meta-Temp-URL-Key-2 headers. +// TempURLKey2 provides type-safe access to X-Container-Meta-Temp-URL-Key-2 headers. func (h ContainerHeaders) TempURLKey2() FieldString { return FieldString{h.Headers, "X-Container-Meta-Temp-URL-Key-2"} } -//TempURLKey provides type-safe access to X-Container-Meta-Temp-URL-Key headers. +// TempURLKey provides type-safe access to X-Container-Meta-Temp-URL-Key headers. func (h ContainerHeaders) TempURLKey() FieldString { return FieldString{h.Headers, "X-Container-Meta-Temp-URL-Key"} } -//ObjectCount provides type-safe access to X-Container-Object-Count headers. +// ObjectCount provides type-safe access to X-Container-Object-Count headers. func (h ContainerHeaders) ObjectCount() FieldUint64Readonly { return FieldUint64Readonly{h.Headers, "X-Container-Object-Count"} } -//ReadACL provides type-safe access to X-Container-Read headers. +// ReadACL provides type-safe access to X-Container-Read headers. func (h ContainerHeaders) ReadACL() FieldString { return FieldString{h.Headers, "X-Container-Read"} } -//SyncKey provides type-safe access to X-Container-Sync-Key headers. +// SyncKey provides type-safe access to X-Container-Sync-Key headers. func (h ContainerHeaders) SyncKey() FieldString { return FieldString{h.Headers, "X-Container-Sync-Key"} } -//SyncTo provides type-safe access to X-Container-Sync-To headers. +// SyncTo provides type-safe access to X-Container-Sync-To headers. func (h ContainerHeaders) SyncTo() FieldString { return FieldString{h.Headers, "X-Container-Sync-To"} } -//WriteACL provides type-safe access to X-Container-Write headers. +// WriteACL provides type-safe access to X-Container-Write headers. func (h ContainerHeaders) WriteACL() FieldString { return FieldString{h.Headers, "X-Container-Write"} } -//HistoryLocation provides type-safe access to X-History-Location headers. +// HistoryLocation provides type-safe access to X-History-Location headers. func (h ContainerHeaders) HistoryLocation() FieldString { return FieldString{h.Headers, "X-History-Location"} } -//StoragePolicy provides type-safe access to X-Storage-Policy headers. +// StoragePolicy provides type-safe access to X-Storage-Policy headers. func (h ContainerHeaders) StoragePolicy() FieldString { return FieldString{h.Headers, "X-Storage-Policy"} } -//CreatedAt provides type-safe access to X-Timestamp headers. +// CreatedAt provides type-safe access to X-Timestamp headers. func (h ContainerHeaders) CreatedAt() FieldUnixTimeReadonly { return FieldUnixTimeReadonly{h.Headers, "X-Timestamp"} } -//VersionsLocation provides type-safe access to X-Versions-Location headers. +// VersionsLocation provides type-safe access to X-Versions-Location headers. func (h ContainerHeaders) VersionsLocation() FieldString { return FieldString{h.Headers, "X-Versions-Location"} } -//ObjectHeaders contains the headers for a schwift.Object instance. +// ObjectHeaders contains the headers for a schwift.Object instance. // -//To read and write well-known headers, use the methods on this type. -//To read and write arbitary headers, use the methods on the Headers supertype. +// To read and write well-known headers, use the methods on this type. +// To read and write arbitary headers, use the methods on the Headers supertype. type ObjectHeaders struct { Headers } -//NewObjectHeaders creates a new ObjectHeaders instance. The return value -//will have the Headers attribute initialized to a non-nil map. +// NewObjectHeaders creates a new ObjectHeaders instance. The return value +// will have the Headers attribute initialized to a non-nil map. func NewObjectHeaders() ObjectHeaders { return ObjectHeaders{make(Headers)} } -//Validate returns MalformedHeaderError if the value of any well-known header -//does not conform to its data type. This is called automatically by Schwift -//when preparing an ObjectHeaders instance from a GET/HEAD response, so you -//usually do not need to do it yourself. You will get the validation error from -//the Object method doing the request, e.g. Headers(). +// Validate returns MalformedHeaderError if the value of any well-known header +// does not conform to its data type. This is called automatically by Schwift +// when preparing an ObjectHeaders instance from a GET/HEAD response, so you +// usually do not need to do it yourself. You will get the validation error from +// the Object method doing the request, e.g. Headers(). func (h ObjectHeaders) Validate() error { if err := h.ContentDisposition().validate(); err != nil { return err @@ -294,57 +294,57 @@ func (h ObjectHeaders) Validate() error { return evadeGolintComplaint1() } -//ContentDisposition provides type-safe access to Content-Disposition headers. +// ContentDisposition provides type-safe access to Content-Disposition headers. func (h ObjectHeaders) ContentDisposition() FieldString { return FieldString{h.Headers, "Content-Disposition"} } -//ContentEncoding provides type-safe access to Content-Encoding headers. +// ContentEncoding provides type-safe access to Content-Encoding headers. func (h ObjectHeaders) ContentEncoding() FieldString { return FieldString{h.Headers, "Content-Encoding"} } -//SizeBytes provides type-safe access to Content-Length headers. +// SizeBytes provides type-safe access to Content-Length headers. func (h ObjectHeaders) SizeBytes() FieldUint64 { return FieldUint64{h.Headers, "Content-Length"} } -//ContentType provides type-safe access to Content-Type headers. +// ContentType provides type-safe access to Content-Type headers. func (h ObjectHeaders) ContentType() FieldString { return FieldString{h.Headers, "Content-Type"} } -//Etag provides type-safe access to Etag headers. +// Etag provides type-safe access to Etag headers. func (h ObjectHeaders) Etag() FieldString { return FieldString{h.Headers, "Etag"} } -//UpdatedAt provides type-safe access to Last-Modified headers. +// UpdatedAt provides type-safe access to Last-Modified headers. func (h ObjectHeaders) UpdatedAt() FieldHTTPTimeReadonly { return FieldHTTPTimeReadonly{h.Headers, "Last-Modified"} } -//ExpiresAt provides type-safe access to X-Delete-At headers. +// ExpiresAt provides type-safe access to X-Delete-At headers. func (h ObjectHeaders) ExpiresAt() FieldUnixTime { return FieldUnixTime{h.Headers, "X-Delete-At"} } -//Metadata provides type-safe access to X-Object-Meta- headers. +// Metadata provides type-safe access to X-Object-Meta- headers. func (h ObjectHeaders) Metadata() FieldMetadata { return FieldMetadata{h.Headers, "X-Object-Meta-"} } -//SymlinkTargetAccount provides type-safe access to X-Symlink-Target-Account headers. +// SymlinkTargetAccount provides type-safe access to X-Symlink-Target-Account headers. func (h ObjectHeaders) SymlinkTargetAccount() FieldString { return FieldString{h.Headers, "X-Symlink-Target-Account"} } -//SymlinkTarget provides type-safe access to X-Symlink-Target headers. +// SymlinkTarget provides type-safe access to X-Symlink-Target headers. func (h ObjectHeaders) SymlinkTarget() FieldString { return FieldString{h.Headers, "X-Symlink-Target"} } -//CreatedAt provides type-safe access to X-Timestamp headers. +// CreatedAt provides type-safe access to X-Timestamp headers. func (h ObjectHeaders) CreatedAt() FieldUnixTimeReadonly { return FieldUnixTimeReadonly{h.Headers, "X-Timestamp"} } diff --git a/generated.go.in b/generated.go.in index 2858bcb..3f4dcd4 100644 --- a/generated.go.in +++ b/generated.go.in @@ -59,25 +59,25 @@ package schwift {{- range $htype, $hmeta := . }} -//{{$htype}}Headers contains the headers for a schwift.{{$htype}} instance. +// {{$htype}}Headers contains the headers for a schwift.{{$htype}} instance. // -//To read and write well-known headers, use the methods on this type. -//To read and write arbitary headers, use the methods on the Headers supertype. +// To read and write well-known headers, use the methods on this type. +// To read and write arbitrary headers, use the methods on the Headers supertype. type {{$htype}}Headers struct { Headers } -//New{{$htype}}Headers creates a new {{$htype}}Headers instance. The return value -//will have the Headers attribute initialized to a non-nil map. +// New{{$htype}}Headers creates a new {{$htype}}Headers instance. The return value +// will have the Headers attribute initialized to a non-nil map. func New{{$htype}}Headers() {{$htype}}Headers { return {{$htype}}Headers{make(Headers)} } -//Validate returns MalformedHeaderError if the value of any well-known header -//does not conform to its data type. This is called automatically by Schwift -//when preparing an {{$htype}}Headers instance from a GET/HEAD response, so you -//usually do not need to do it yourself. You will get the validation error from -//the {{$htype}} method doing the request, e.g. Headers(). +// Validate returns MalformedHeaderError if the value of any well-known header +// does not conform to its data type. This is called automatically by Schwift +// when preparing an {{$htype}}Headers instance from a GET/HEAD response, so you +// usually do not need to do it yourself. You will get the validation error from +// the {{$htype}} method doing the request, e.g. Headers(). func (h {{$htype}}Headers) Validate() error { {{- range $field := $hmeta.Fields }} if err := h.{{$field.Attribute}}().validate(); err != nil { @@ -89,7 +89,7 @@ func (h {{$htype}}Headers) Validate() error { {{- range $field := $hmeta.Fields }} -//{{$field.Attribute}} provides type-safe access to {{$field.Header}} headers. +// {{$field.Attribute}} provides type-safe access to {{$field.Header}} headers. func (h {{$htype}}Headers) {{$field.Attribute}}() Field{{$field.Type}} { return Field{{$field.Type}}{h.Headers, "{{$field.Header}}"} } diff --git a/gopherschwift/package.go b/gopherschwift/package.go index 1d0d724..adeee83 100644 --- a/gopherschwift/package.go +++ b/gopherschwift/package.go @@ -17,7 +17,6 @@ ******************************************************************************/ /* - Package gopherschwift contains a Gophercloud backend for Schwift. If your application uses Gophercloud (https://github.com/gophercloud/gophercloud), @@ -37,7 +36,6 @@ so you only need to obtain a client token once using Gophercloud. For example: Using this schwift.Account instance, you have access to all of schwift's API. Refer to the documentation in the parent package for details. - */ package gopherschwift @@ -47,19 +45,20 @@ import ( "net/http" "github.com/gophercloud/gophercloud" + "github.com/majewsky/schwift" ) -//Options contains additional options that can be passed to Wrap(). +// Options contains additional options that can be passed to Wrap(). type Options struct { //If set, this User-Agent will be reported in HTTP requests instead of //schwift.DefaultUserAgent. UserAgent string } -//Wrap creates a schwift.Account that uses the given service client as its -//backend. The service client must refer to a Swift endpoint, i.e. it should -//have been created by openstack.NewObjectStorageV1(). +// Wrap creates a schwift.Account that uses the given service client as its +// backend. The service client must refer to a Swift endpoint, i.e. it should +// have been created by openstack.NewObjectStorageV1(). func Wrap(client *gophercloud.ServiceClient, opts *Options) (*schwift.Account, error) { b := &backend{ c: client, @@ -23,55 +23,54 @@ import ( "net/textproto" ) -//Headers represents a set of request headers or response headers. +// Headers represents a set of request headers or response headers. // -//Users will typically use one of the subtypes (AccountHeaders, -//ContainerHeaders, ObjectHeaders) instead, which provide type-safe access to -//well-known headers. The http.Header-like interface on this type can be used -//read and write arbitary headers. For example, the following calls are -//equivalent: +// Users will typically use one of the subtypes (AccountHeaders, +// ContainerHeaders, ObjectHeaders) instead, which provide type-safe access to +// well-known headers. The http.Header-like interface on this type can be used +// read and write arbitary headers. For example, the following calls are +// equivalent: // // h := make(AccountHeaders) // h.Headers.Set("X-Account-Meta-Quota-Bytes", "1048576") // h.BytesUsedQuota().Set(1048576) -// type Headers map[string]string -//Clear sets the value for the specified header to the empty string. When the -//Headers instance is then sent to the server with Update(), the server will -//delete the value for that header; cf. Del(). +// Clear sets the value for the specified header to the empty string. When the +// Headers instance is then sent to the server with Update(), the server will +// delete the value for that header; cf. Del(). func (h Headers) Clear(key string) { h[textproto.CanonicalMIMEHeaderKey(key)] = "" } -//Del deletes a key from the Headers instance. When the Headers instance is -//then sent to the server with Update(), a key which has been deleted with -//Del() will remain unchanged on the server. +// Del deletes a key from the Headers instance. When the Headers instance is +// then sent to the server with Update(), a key which has been deleted with +// Del() will remain unchanged on the server. // -//For most writable attributes, a key which has been deleted with Del() will -//remain unchanged on the server. To remove the key on the server, use Clear() -//instead. +// For most writable attributes, a key which has been deleted with Del() will +// remain unchanged on the server. To remove the key on the server, use Clear() +// instead. // -//For object metadata (but not other object attributes), deleting a key will -//cause that key to be deleted on the server. Del() is identical to Clear() in -//this case. +// For object metadata (but not other object attributes), deleting a key will +// cause that key to be deleted on the server. Del() is identical to Clear() in +// this case. func (h Headers) Del(key string) { delete(h, textproto.CanonicalMIMEHeaderKey(key)) } -//Get returns the value for the specified header. +// Get returns the value for the specified header. func (h Headers) Get(key string) string { return h[textproto.CanonicalMIMEHeaderKey(key)] } -//Set sets a new value for the specified header. Any existing value will be -//overwritten. +// Set sets a new value for the specified header. Any existing value will be +// overwritten. func (h Headers) Set(key, value string) { h[textproto.CanonicalMIMEHeaderKey(key)] = value } -//ToHTTP converts this Headers instance into the equivalent http.Header -//instance. The return value is guaranteed to be non-nil. +// ToHTTP converts this Headers instance into the equivalent http.Header +// instance. The return value is guaranteed to be non-nil. func (h Headers) ToHTTP() http.Header { dest := make(http.Header, len(h)) for k, v := range h { @@ -80,14 +79,13 @@ func (h Headers) ToHTTP() http.Header { return dest } -//ToOpts wraps this Headers instance into a RequestOpts instance, so that it -//can be passed to Schwift's various request methods. +// ToOpts wraps this Headers instance into a RequestOpts instance, so that it +// can be passed to Schwift's various request methods. // // hdr := NewObjectHeaders() // hdr.ContentType().Set("image/png") // hdr.Metadata().Set("color", "blue") // obj.Upload(content, nil, hdr.ToOpts()) -// func (h Headers) ToOpts() *RequestOptions { return &RequestOptions{Headers: h} } @@ -105,20 +103,20 @@ func headersFromHTTP(src http.Header) Headers { //////////////////////////////////////////////////////////////////////////////// // specialized accessors on Headers subtypes that are not autogenerated -//IsDynamicLargeObject returns true if this set of headers belongs to a Dynamic -//Large Object (DLO). +// IsDynamicLargeObject returns true if this set of headers belongs to a Dynamic +// Large Object (DLO). func (h ObjectHeaders) IsDynamicLargeObject() bool { return h.Headers.Get("X-Object-Manifest") != "" } -//IsStaticLargeObject returns true if this set of headers belongs to a Static -//Large Object (SLO). +// IsStaticLargeObject returns true if this set of headers belongs to a Static +// Large Object (SLO). func (h ObjectHeaders) IsStaticLargeObject() bool { return h.Headers.Get("X-Static-Large-Object") == "True" } -//IsLargeObject returns true if this set of headers belongs to a large object -//(either an SLO or a DLO). +// IsLargeObject returns true if this set of headers belongs to a large object +// (either an SLO or a DLO). func (h ObjectHeaders) IsLargeObject() bool { return h.IsDynamicLargeObject() || h.IsStaticLargeObject() } diff --git a/iterator.go b/iterator.go index 641e28d..6ae132b 100644 --- a/iterator.go +++ b/iterator.go @@ -25,8 +25,8 @@ import ( "strings" ) -//iteratorInterface allows iteratorBase to access public attributes of -//ContainerIterator/ObjectIterator. +// iteratorInterface allows iteratorBase to access public attributes of +// ContainerIterator/ObjectIterator. type iteratorInterface interface { getAccount() *Account getContainerName() string @@ -68,7 +68,7 @@ func (i ObjectIterator) putHeader(hdr http.Header) error { return nil } -//iteratorBase provides shared behavior for ContainerIterator and ObjectIterator. +// iteratorBase provides shared behavior for ContainerIterator and ObjectIterator. type iteratorBase struct { i iteratorInterface marker string diff --git a/largeobject.go b/largeobject.go index f58828c..637c024 100644 --- a/largeobject.go +++ b/largeobject.go @@ -40,21 +40,21 @@ import ( "github.com/jpillora/longestcommon" ) -//SegmentInfo describes a segment of a large object. +// SegmentInfo describes a segment of a large object. // -//For .RangeLength == 0, the segment consists of all the bytes in the backing -//object, after skipping the first .RangeOffset bytes. The default -//(.RangeOffset == 0) is to include the entire contents of the backing object. +// For .RangeLength == 0, the segment consists of all the bytes in the backing +// object, after skipping the first .RangeOffset bytes. The default +// (.RangeOffset == 0) is to include the entire contents of the backing object. // -//For .RangeLength > 0, the segment consists of that many bytes from the -//backing object, again after skipping the first .RangeOffset bytes. +// For .RangeLength > 0, the segment consists of that many bytes from the +// backing object, again after skipping the first .RangeOffset bytes. // -//However, for .RangeOffset < 0, the segment consists of .RangeLength many bytes -//from the *end* of the backing object. (The concrete value for .RangeOffset is -//disregarded.) .RangeLength must be non-zero in this case. +// However, for .RangeOffset < 0, the segment consists of .RangeLength many bytes +// from the *end* of the backing object. (The concrete value for .RangeOffset is +// disregarded.) .RangeLength must be non-zero in this case. // -//Sorry that specifying a range is that involved. I was just following orders ^W -//RFC 7233, section 3.1 here. +// Sorry that specifying a range is that involved. I was just following orders ^W +// RFC 7233, section 3.1 here. type SegmentInfo struct { Object *Object SizeBytes uint64 @@ -79,14 +79,14 @@ type sloSegmentInfo struct { DataBase64 string `json:"data,omitempty"` } -//LargeObjectStrategy enumerates segmenting strategies supported by Swift. +// LargeObjectStrategy enumerates segmenting strategies supported by Swift. type LargeObjectStrategy int -//A value of 0 for LargeObjectStrategy will instruct Schwift to choose a -//strategy itself. Right now, Schwift always chooses StaticLargeObject, but -//this behavior may change in future versions of Schwift, esp. if new -//strategies become available. The choice may also start to depend on the -//capabilities advertised by the server. +// A value of 0 for LargeObjectStrategy will instruct Schwift to choose a +// strategy itself. Right now, Schwift always chooses StaticLargeObject, but +// this behavior may change in future versions of Schwift, esp. if new +// strategies become available. The choice may also start to depend on the +// capabilities advertised by the server. const ( //StaticLargeObject is the default LargeObjectStrategy used by Schwift. StaticLargeObject LargeObjectStrategy = iota + 1 @@ -96,20 +96,20 @@ const ( DynamicLargeObject ) -//SegmentingOptions describes how an object is segmented. It is passed to -//Object.AsNewLargeObject(). +// SegmentingOptions describes how an object is segmented. It is passed to +// Object.AsNewLargeObject(). // -//If Strategy is not set, a reasonable strategy is chosen; see documentation on -//LargeObjectStrategy for details. +// If Strategy is not set, a reasonable strategy is chosen; see documentation on +// LargeObjectStrategy for details. // -//SegmentContainer must not be nil. A value of nil will cause Schwift to panic. -//If the SegmentContainer is not in the same account as the large object, -//ErrAccountMismatch will be returned by Schwift. +// SegmentContainer must not be nil. A value of nil will cause Schwift to panic. +// If the SegmentContainer is not in the same account as the large object, +// ErrAccountMismatch will be returned by Schwift. // -//If SegmentPrefix is empty, a reasonable default will be computed by -//Object.AsNewLargeObject(), using the format -//"<object-name>/<strategy>/<timestamp>", where strategy is either "slo" or -//"dlo". +// If SegmentPrefix is empty, a reasonable default will be computed by +// Object.AsNewLargeObject(), using the format +// "<object-name>/<strategy>/<timestamp>", where strategy is either "slo" or +// "dlo". type SegmentingOptions struct { Strategy LargeObjectStrategy SegmentContainer *Container @@ -118,13 +118,13 @@ type SegmentingOptions struct { //////////////////////////////////////////////////////////////////////////////// -//LargeObject is a wrapper for type Object that performs operations specific to -//large objects, i.e. those objects which are uploaded in segments rather than -//all at once. It can be constructed with the Object.AsLargeObject() and -//Object.AsNewLargeObject() methods. +// LargeObject is a wrapper for type Object that performs operations specific to +// large objects, i.e. those objects which are uploaded in segments rather than +// all at once. It can be constructed with the Object.AsLargeObject() and +// Object.AsNewLargeObject() methods. // -//The following example shows how to upload a large file from the filesystem to -//Swift (error handling elided for brevity): +// The following example shows how to upload a large file from the filesystem to +// Swift (error handling elided for brevity): // // file, err := os.Open(sourcePath) // segmentContainer, err := account.Container("segments").EnsureExists() @@ -140,14 +140,14 @@ type SegmentingOptions struct { // err = lo.Append(contents, 1<<30) // 1<30 bytes = 1 GiB per segment // err = lo.WriteManifest(nil) // -//Append() has a more low-level counterpart, AddSegment(). Both methods can be -//freely intermixed. AddSegment() is useful when you want to control the -//segments' metadata or use advanced features like range segments or data -//segments; see documentation over there. +// Append() has a more low-level counterpart, AddSegment(). Both methods can be +// freely intermixed. AddSegment() is useful when you want to control the +// segments' metadata or use advanced features like range segments or data +// segments; see documentation over there. // -//Writing to a large object must always be concluded by a call to -//WriteManifest() to link the new segments to the large object on the server -//side. +// Writing to a large object must always be concluded by a call to +// WriteManifest() to link the new segments to the large object on the server +// side. type LargeObject struct { object *Object segmentContainer *Container @@ -156,45 +156,45 @@ type LargeObject struct { segments []SegmentInfo } -//Object returns the location of this large object (where its manifest is stored). +// Object returns the location of this large object (where its manifest is stored). func (lo *LargeObject) Object() *Object { return lo.object } -//SegmentContainer returns the container in which this object's segments are -//stored. For static large objects, some segments may also be located in -//different containers. +// SegmentContainer returns the container in which this object's segments are +// stored. For static large objects, some segments may also be located in +// different containers. func (lo *LargeObject) SegmentContainer() *Container { return lo.segmentContainer } -//SegmentPrefix returns the prefix shared by the names of all segments of this -//object. For static large objects, some segments may not be located in this -//prefix. +// SegmentPrefix returns the prefix shared by the names of all segments of this +// object. For static large objects, some segments may not be located in this +// prefix. func (lo *LargeObject) SegmentPrefix() string { return lo.segmentPrefix } -//Strategy returns the LargeObjectStrategy used by this object. +// Strategy returns the LargeObjectStrategy used by this object. func (lo *LargeObject) Strategy() LargeObjectStrategy { return lo.strategy } -//Segments returns a list of all segments for this object, in order. +// Segments returns a list of all segments for this object, in order. func (lo *LargeObject) Segments() ([]SegmentInfo, error) { //NOTE: This method has an error return value because we might later switch //to loading segments lazily inside this method. return lo.segments, nil } -//SegmentObjects returns a list of all segment objects referenced by this large -//object. Note that, in general, +// SegmentObjects returns a list of all segment objects referenced by this large +// object. Note that, in general, // // len(lo.SegmentObjects()) <= len(lo.Segments()) // -//since one object may be backing multiple segments, and data segments are not -//backed by any object at all. No guarantee is made about the order in which -//objects appear in this list. +// since one object may be backing multiple segments, and data segments are not +// backed by any object at all. No guarantee is made about the order in which +// objects appear in this list. func (lo *LargeObject) SegmentObjects() []*Object { seen := make(map[string]bool) result := make([]*Object, 0, len(lo.segments)) @@ -211,9 +211,9 @@ func (lo *LargeObject) SegmentObjects() []*Object { return result } -//AsLargeObject opens an existing large object. If the given object does not -//exist, or if it is not a large object, ErrNotLarge will be returned. In this -//case, Object.AsNewLargeObject() needs to be used instead. +// AsLargeObject opens an existing large object. If the given object does not +// exist, or if it is not a large object, ErrNotLarge will be returned. In this +// case, Object.AsNewLargeObject() needs to be used instead. func (o *Object) AsLargeObject() (*LargeObject, error) { exists, err := o.Exists() if err != nil { @@ -401,14 +401,14 @@ func parseHTTPRange(str string) (offsetVal int64, lengthVal uint64, ok bool) { return int64(firstByte), lastByte - firstByte + 1, true } -//AsNewLargeObject opens an object as a large object. SegmentingOptions are -//always required, see the documentation on type SegmentingOptions for details. +// AsNewLargeObject opens an object as a large object. SegmentingOptions are +// always required, see the documentation on type SegmentingOptions for details. // -//This function can be used regardless of whether the object exists or not. -//If the object exists and is a large object, this function behaves like -//Object.AsLargeObject() followed by Truncate(), except that segmenting options -//are initialized from the method's SegmentingOptions argument rather than from -//the existing manifest. +// This function can be used regardless of whether the object exists or not. +// If the object exists and is a large object, this function behaves like +// Object.AsLargeObject() followed by Truncate(), except that segmenting options +// are initialized from the method's SegmentingOptions argument rather than from +// the existing manifest. func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOptions) (*LargeObject, error) { //we only need to load the existing large object if we want to do something //with the old segments @@ -463,8 +463,8 @@ func (o *Object) AsNewLargeObject(sopts SegmentingOptions, topts *TruncateOption return lo, nil } -//TruncateOptions contains options that can be passed to LargeObject.Truncate() -//and Object.AsNewLargeObject(). +// TruncateOptions contains options that can be passed to LargeObject.Truncate() +// and Object.AsNewLargeObject(). type TruncateOptions struct { //When truncating a large object's manifest, delete its segments. //This will cause Truncate() to call into BulkDelete(), so a BulkError may be @@ -473,9 +473,9 @@ type TruncateOptions struct { DeleteSegments bool } -//Truncate removes all segments from a large object's manifest. The manifest is -//not written by this call, so WriteManifest() usually needs to be called -//afterwards. +// Truncate removes all segments from a large object's manifest. The manifest is +// not written by this call, so WriteManifest() usually needs to be called +// afterwards. func (lo *LargeObject) Truncate(opts *TruncateOptions) error { _, _, err := lo.object.c.a.BulkDelete(lo.SegmentObjects(), nil, nil) if err == nil { @@ -484,33 +484,33 @@ func (lo *LargeObject) Truncate(opts *TruncateOptions) error { return err } -//NextSegmentObject suggests where to upload the next segment. +// NextSegmentObject suggests where to upload the next segment. // -//WARNING: This is a low-level function. Most callers will want to use -//Append(). You will only need to upload segments manually when you want to -//control the segments' metadata. +// WARNING: This is a low-level function. Most callers will want to use +// Append(). You will only need to upload segments manually when you want to +// control the segments' metadata. // -//If the name of the current final segment ends with a counter, that counter is -//incremented, otherwise a counter is appended to its name. When looking for a -//counter in an existing segment name, the regex /[0-9]+$/ is used. For example, -//given: +// If the name of the current final segment ends with a counter, that counter is +// incremented, otherwise a counter is appended to its name. When looking for a +// counter in an existing segment name, the regex /[0-9]+$/ is used. For example, +// given: // // segments := lo.segments() // lastSegmentName := segments[len(segments)-1].Name() // nextSegmentName := lo.NextSegmentObject().Name() // -//If lastSegmentName is "segments/archive/segment0001", then nextSegmentName is -//"segments/archive/segment0002". If lastSegmentName is -//"segments/archive/first", then nextSegmentName is -//"segments/archive/first0000000000000001". +// If lastSegmentName is "segments/archive/segment0001", then nextSegmentName is +// "segments/archive/segment0002". If lastSegmentName is +// "segments/archive/first", then nextSegmentName is +// "segments/archive/first0000000000000001". // -//However, the last segment's name will only be considered if it lies within -//lo.segmentContainer below lo.segmentPrefix. If that is not the case, the name -//of the last segment that does will be used instead. +// However, the last segment's name will only be considered if it lies within +// lo.segmentContainer below lo.segmentPrefix. If that is not the case, the name +// of the last segment that does will be used instead. // -//If there are no segments yet, or if all segments are located outside the -//lo.segmentContainer and lo.segmentPrefix, the first segment name is chosen as -//lo.segmentPrefix + "0000000000000001". +// If there are no segments yet, or if all segments are located outside the +// lo.segmentContainer and lo.segmentPrefix, the first segment name is chosen as +// lo.segmentPrefix + "0000000000000001". func (lo *LargeObject) NextSegmentObject() *Object { //find the name of the last-most segment that is within the designated //segment container and prefix @@ -540,9 +540,9 @@ func (lo *LargeObject) NextSegmentObject() *Object { var splitSegmentIndexRx = regexp.MustCompile(`^(.*?)([0-9]+$)`) var initialIndex = "0000000000000001" -//Given the object name of a previous large object segment, compute a suitable -//name for the next segment. See doc for LargeObject.NextSegmentObject() -//for how this works. +// Given the object name of a previous large object segment, compute a suitable +// name for the next segment. See doc for LargeObject.NextSegmentObject() +// for how this works. func nextSegmentName(segmentName string) string { match := splitSegmentIndexRx.FindStringSubmatch(segmentName) if match == nil { @@ -563,31 +563,31 @@ func nextSegmentName(segmentName string) string { return base + fmt.Sprintf(formatStr, idx+1) } -//AddSegment appends a segment to this object. The segment must already have -//been uploaded. +// AddSegment appends a segment to this object. The segment must already have +// been uploaded. // -//WARNING: This is a low-level function. Most callers will want to use -//Append(). You will only need to add segments manually when you want to -//control the segments' metadata, or when using advanced features such as -//range-limited segments or data segments. +// WARNING: This is a low-level function. Most callers will want to use +// Append(). You will only need to add segments manually when you want to +// control the segments' metadata, or when using advanced features such as +// range-limited segments or data segments. // -//This method returns ErrAccountMismatch if the segment is not located in a -//container in the same account. +// This method returns ErrAccountMismatch if the segment is not located in a +// container in the same account. // -//For dynamic large objects, this method returns ErrContainerMismatch if the -//segment is not located in the correct container below the correct prefix. +// For dynamic large objects, this method returns ErrContainerMismatch if the +// segment is not located in the correct container below the correct prefix. // -//This method returns ErrSegmentInvalid if: +// This method returns ErrSegmentInvalid if: // -//- a range is specified in the SegmentInfo, but it is invalid or the -//LargeObject is a dynamic large object (DLOs do not support ranges), or +// - a range is specified in the SegmentInfo, but it is invalid or the +// LargeObject is a dynamic large object (DLOs do not support ranges), or // -//- the SegmentInfo's Data attribute is set and any other attribute is also -//set (segments cannot be backed by objects and be data segments at the same -//time), or +// - the SegmentInfo's Data attribute is set and any other attribute is also +// set (segments cannot be backed by objects and be data segments at the same +// time), or // -//- the SegmentInfo's Data attribute is set, but the LargeObject is a dynamic -//large objects (DLOs do not support data segments). +// - the SegmentInfo's Data attribute is set, but the LargeObject is a dynamic +// large objects (DLOs do not support data segments). func (lo *LargeObject) AddSegment(segment SegmentInfo) error { if len(segment.Data) == 0 { //validate segments backed by objects @@ -636,13 +636,13 @@ func (lo *LargeObject) AddSegment(segment SegmentInfo) error { return nil } -//Append uploads the contents of the given io.Reader as segment objects of the -//given segment size. (The last segment will be shorter than the segment size -//unless the reader yields an exact multiple of the segment size.) The reader -//is consumed until EOF, or until an error occurs. +// Append uploads the contents of the given io.Reader as segment objects of the +// given segment size. (The last segment will be shorter than the segment size +// unless the reader yields an exact multiple of the segment size.) The reader +// is consumed until EOF, or until an error occurs. // -//If you do not have an io.Reader, but you have a []byte or string instance -//containing the data, wrap it in a *bytes.Reader instance like so: +// If you do not have an io.Reader, but you have a []byte or string instance +// containing the data, wrap it in a *bytes.Reader instance like so: // // var buffer []byte // lo.Append(bytes.NewReader(buffer), segmentSizeBytes) @@ -651,16 +651,16 @@ func (lo *LargeObject) AddSegment(segment SegmentInfo) error { // var buffer string // lo.Append(bytes.NewReader([]byte(buffer)), segmentSizeBytes) // -//If segmentSizeBytes is zero, Append() defaults to the maximum file size -//reported by Account.Capabilities(). +// If segmentSizeBytes is zero, Append() defaults to the maximum file size +// reported by Account.Capabilities(). // -//Calls to Append() and its low-level counterpart, AddSegment(), can be freely -//intermixed. AddSegment() is useful when you want to control the segments' -//metadata or use advanced features like range segments or data segments; see -//documentation over there. +// Calls to Append() and its low-level counterpart, AddSegment(), can be freely +// intermixed. AddSegment() is useful when you want to control the segments' +// metadata or use advanced features like range segments or data segments; see +// documentation over there. // -//This function uploads segment objects, so it may return any error that -//Object.Upload() returns, see documentation over there. +// This function uploads segment objects, so it may return any error that +// Object.Upload() returns, see documentation over there. func (lo *LargeObject) Append(contents io.Reader, segmentSizeBytes int64, opts *RequestOptions) error { if segmentSizeBytes < 0 { panic("segmentSizeBytes may not be negative") @@ -751,12 +751,12 @@ func (r *lengthAndEtagTrackingReader) Read(buf []byte) (int, error) { return n, err } -//WriteManifest creates this large object by writing a manifest to its -//location using a PUT request. +// WriteManifest creates this large object by writing a manifest to its +// location using a PUT request. // -//For dynamic large objects, this method does not generate a PUT request -//if the object already exists and has the correct manifest (i.e. -//SegmentContainer and SegmentPrefix have not been changed). +// For dynamic large objects, this method does not generate a PUT request +// if the object already exists and has the correct manifest (i.e. +// SegmentContainer and SegmentPrefix have not been changed). func (lo *LargeObject) WriteManifest(opts *RequestOptions) error { switch lo.strategy { case StaticLargeObject: @@ -33,9 +33,9 @@ import ( "time" ) -//Object represents a Swift object. Instances are usually obtained by -//traversing downwards from a container with Container.Object() or -//Container.Objects(). +// Object represents a Swift object. Instances are usually obtained by +// traversing downwards from a container with Container.Object() or +// Container.Objects(). type Object struct { c *Container name string @@ -44,27 +44,27 @@ type Object struct { symlinkHeaders *ObjectHeaders //from HEAD/GET with ?symlink=get } -//IsEqualTo returns true if both Object instances refer to the same object. +// IsEqualTo returns true if both Object instances refer to the same object. func (o *Object) IsEqualTo(other *Object) bool { return other.name == o.name && other.c.IsEqualTo(o.c) } -//Object returns a handle to the object with the given name within this -//container. This function does not issue any HTTP requests, and therefore cannot -//ensure that the object exists. Use the Exists() function to check for the -//object's existence. +// Object returns a handle to the object with the given name within this +// container. This function does not issue any HTTP requests, and therefore cannot +// ensure that the object exists. Use the Exists() function to check for the +// object's existence. func (c *Container) Object(name string) *Object { return &Object{c: c, name: name} } -//Container returns a handle to the container this object is stored in. +// Container returns a handle to the container this object is stored in. func (o *Object) Container() *Container { return o.c } -//Name returns the object name. This does not parse the name in any way; if you -//want only the basename portion of the object name, use package path from the -//standard library in conjunction with this function. For example: +// Name returns the object name. This does not parse the name in any way; if you +// want only the basename portion of the object name, use package path from the +// standard library in conjunction with this function. For example: // // obj := account.Container("docs").Object("2018-02-10/invoice.pdf") // obj.Name() //returns "2018-02-10/invoice.pdf" @@ -73,10 +73,10 @@ func (o *Object) Name() string { return o.name } -//FullName returns the container name and object name joined together with a -//slash. This identifier is used by Swift in several places (large object -//manifests, symlink targets, etc.) to refer to an object within an account. -//For example: +// FullName returns the container name and object name joined together with a +// slash. This identifier is used by Swift in several places (large object +// manifests, symlink targets, etc.) to refer to an object within an account. +// For example: // // obj := account.Container("docs").Object("2018-02-10/invoice.pdf") // obj.Name() //returns "2018-02-10/invoice.pdf" @@ -85,8 +85,8 @@ func (o *Object) FullName() string { return o.c.name + "/" + o.name } -//Exists checks if this object exists, potentially by issuing a HEAD request -//if no Headers() have been cached yet. +// Exists checks if this object exists, potentially by issuing a HEAD request +// if no Headers() have been cached yet. func (o *Object) Exists() (bool, error) { _, err := o.Headers() if Is(err, http.StatusNotFound) { @@ -97,16 +97,16 @@ func (o *Object) Exists() (bool, error) { return true, nil } -//Headers returns the ObjectHeaders for this object. If the ObjectHeaders -//has not been cached yet, a HEAD request is issued on the object. +// Headers returns the ObjectHeaders for this object. If the ObjectHeaders +// has not been cached yet, a HEAD request is issued on the object. // -//For symlinks, this operation returns the metadata for the target object. Use -//Object.SymlinkHeaders() to obtain the metadata for the symlink instead. +// For symlinks, this operation returns the metadata for the target object. Use +// Object.SymlinkHeaders() to obtain the metadata for the symlink instead. // -//This operation fails with http.StatusNotFound if the object does not exist. +// This operation fails with http.StatusNotFound if the object does not exist. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (o *Object) Headers() (ObjectHeaders, error) { if o.headers != nil { return *o.headers, nil @@ -139,12 +139,12 @@ func (o *Object) fetchHeaders(opts *RequestOptions) (*ObjectHeaders, error) { return &headers, headers.Validate() } -//Update updates the object's headers using a POST request. To add URL -//parameters, pass a non-nil *RequestOptions. +// Update updates the object's headers using a POST request. To add URL +// parameters, pass a non-nil *RequestOptions. // -//This operation fails with http.StatusNotFound if the object does not exist. +// This operation fails with http.StatusNotFound if the object does not exist. // -//A successful POST request implies Invalidate() since it may change metadata. +// A successful POST request implies Invalidate() since it may change metadata. func (o *Object) Update(headers ObjectHeaders, opts *RequestOptions) error { _, err := Request{ Method: "POST", @@ -159,17 +159,17 @@ func (o *Object) Update(headers ObjectHeaders, opts *RequestOptions) error { return err } -//UploadOptions invokes advanced behavior in the Object.Upload() method. +// UploadOptions invokes advanced behavior in the Object.Upload() method. type UploadOptions struct { //When overwriting a large object, delete its segments. This will cause //Upload() to call into BulkDelete(), so a BulkError may be returned. DeleteSegments bool } -//Upload creates the object using a PUT request. +// Upload creates the object using a PUT request. // -//If you do not have an io.Reader, but you have a []byte or string instance -//containing the object, wrap it in a *bytes.Reader instance like so: +// If you do not have an io.Reader, but you have a []byte or string instance +// containing the object, wrap it in a *bytes.Reader instance like so: // // var buffer []byte // o.Upload(bytes.NewReader(buffer), opts) @@ -178,29 +178,29 @@ type UploadOptions struct { // var buffer string // o.Upload(bytes.NewReader([]byte(buffer)), opts) // -//If you have neither an io.Reader nor a []byte or string, but you have a -//function that generates the object's content into an io.Writer, use -//UploadFromWriter instead. +// If you have neither an io.Reader nor a []byte or string, but you have a +// function that generates the object's content into an io.Writer, use +// UploadFromWriter instead. // -//If the object is very large and you want to upload it in segments, use -//LargeObject.Append() instead. See documentation on type LargeObject for -//details. +// If the object is very large and you want to upload it in segments, use +// LargeObject.Append() instead. See documentation on type LargeObject for +// details. // -//If content is a *bytes.Reader or a *bytes.Buffer instance, the Content-Length -//and Etag request headers will be computed automatically. Otherwise, it is -//highly recommended that the caller set these headers (if possible) to allow -//the server to check the integrity of the uploaded file. +// If content is a *bytes.Reader or a *bytes.Buffer instance, the Content-Length +// and Etag request headers will be computed automatically. Otherwise, it is +// highly recommended that the caller set these headers (if possible) to allow +// the server to check the integrity of the uploaded file. // -//If Etag and/or Content-Length is supplied and the content does not match -//these parameters, http.StatusUnprocessableEntity is returned. If Etag is not -//supplied and cannot be computed in advance, Upload() will compute the Etag as -//data is read from the io.Reader, and compare the result to the Etag returned -//by Swift, returning ErrChecksumMismatch in case of mismatch. The object will -//have been uploaded at that point, so you will usually want to Delete() it. +// If Etag and/or Content-Length is supplied and the content does not match +// these parameters, http.StatusUnprocessableEntity is returned. If Etag is not +// supplied and cannot be computed in advance, Upload() will compute the Etag as +// data is read from the io.Reader, and compare the result to the Etag returned +// by Swift, returning ErrChecksumMismatch in case of mismatch. The object will +// have been uploaded at that point, so you will usually want to Delete() it. // -//This function can be used regardless of whether the object exists or not. +// This function can be used regardless of whether the object exists or not. // -//A successful PUT request implies Invalidate() since it may change metadata. +// A successful PUT request implies Invalidate() since it may change metadata. func (o *Object) Upload(content io.Reader, opts *UploadOptions, ropts *RequestOptions) error { if opts == nil { opts = &UploadOptions{} @@ -325,9 +325,9 @@ func tryComputeEtag(content io.Reader, headers ObjectHeaders) { } } -//UploadFromWriter is a variant of Upload that can be used when the object's -//content is generated by some function or package that takes an io.Writer -//instead of supplying an io.Reader. For example: +// UploadFromWriter is a variant of Upload that can be used when the object's +// content is generated by some function or package that takes an io.Writer +// instead of supplying an io.Reader. For example: // // func greeting(target io.Writer, name string) error { // _, err := fmt.Fprintf(target, "Hello %s!\n", name) @@ -343,7 +343,7 @@ func tryComputeEtag(content io.Reader, headers ObjectHeaders) { // return err // }) // -//If you do not need an io.Writer, always use Upload instead. +// If you do not need an io.Writer, always use Upload instead. func (o *Object) UploadFromWriter(opts *UploadOptions, ropts *RequestOptions, callback func(io.Writer) error) error { reader, writer := io.Pipe() errChan := make(chan error) @@ -356,19 +356,19 @@ func (o *Object) UploadFromWriter(opts *UploadOptions, ropts *RequestOptions, ca return <-errChan } -//DeleteOptions invokes advanced behavior in the Object.Delete() method. +// DeleteOptions invokes advanced behavior in the Object.Delete() method. type DeleteOptions struct { //When deleting a large object, also delete its segments. This will cause //Delete() to call into BulkDelete(), so a BulkError may be returned. DeleteSegments bool } -//Delete deletes the object using a DELETE request. To add URL parameters, -//pass a non-nil *RequestOptions. +// Delete deletes the object using a DELETE request. To add URL parameters, +// pass a non-nil *RequestOptions. // -//This operation fails with http.StatusNotFound if the object does not exist. +// This operation fails with http.StatusNotFound if the object does not exist. // -//A successful DELETE request implies Invalidate(). +// A successful DELETE request implies Invalidate(). func (o *Object) Delete(opts *DeleteOptions, ropts *RequestOptions) error { if opts == nil { opts = &DeleteOptions{} @@ -408,20 +408,20 @@ func (o *Object) Delete(opts *DeleteOptions, ropts *RequestOptions) error { return err } -//Invalidate clears the internal cache of this Object instance. The next call -//to Headers() on this instance will issue a HEAD request on the object. +// Invalidate clears the internal cache of this Object instance. The next call +// to Headers() on this instance will issue a HEAD request on the object. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (o *Object) Invalidate() { o.headers = nil o.symlinkHeaders = nil } -//Download retrieves the object's contents using a GET request. This returns a -//helper object which allows you to select whether you want an io.ReadCloser -//for reading the object contents progressively, or whether you want the object -//contents collected into a byte slice or string. +// Download retrieves the object's contents using a GET request. This returns a +// helper object which allows you to select whether you want an io.ReadCloser +// for reading the object contents progressively, or whether you want the object +// contents collected into a byte slice or string. // // reader, err := object.Download(nil).AsReadCloser() // @@ -429,10 +429,10 @@ func (o *Object) Invalidate() { // // str, err := object.Download(nil).AsString() // -//See documentation on type DownloadedObject for details. +// See documentation on type DownloadedObject for details. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (o *Object) Download(opts *RequestOptions) DownloadedObject { resp, err := Request{ Method: "GET", @@ -457,7 +457,7 @@ func (o *Object) Download(opts *RequestOptions) DownloadedObject { return DownloadedObject{body, err} } -//CopyOptions invokes advanced behavior in the Object.Copy() method. +// CopyOptions invokes advanced behavior in the Object.Copy() method. type CopyOptions struct { //Copy only the object's content, not its metadata. New metadata can always //be supplied in the RequestOptions argument of Object.CopyTo(). @@ -466,10 +466,10 @@ type CopyOptions struct { ShallowCopySymlinks bool } -//CopyTo copies the object on the server side using a COPY request. +// CopyTo copies the object on the server side using a COPY request. // -//A successful COPY implies target.Invalidate() since it may change the -//target's metadata. +// A successful COPY implies target.Invalidate() since it may change the +// target's metadata. func (o *Object) CopyTo(target *Object, opts *CopyOptions, ropts *RequestOptions) error { ropts = cloneRequestOptions(ropts, nil) ropts.Headers.Set("Destination", target.FullName()) @@ -499,19 +499,19 @@ func (o *Object) CopyTo(target *Object, opts *CopyOptions, ropts *RequestOptions return err } -//SymlinkOptions invokes advanced behavior in the Object.SymlinkTo() method. +// SymlinkOptions invokes advanced behavior in the Object.SymlinkTo() method. type SymlinkOptions struct { //When overwriting a large object, delete its segments. This will cause //SymlinkTo() to call into BulkDelete(), so a BulkError may be returned. DeleteSegments bool } -//SymlinkTo creates the object as a symbolic link to another object using a PUT -//request. Like Object.Upload(), this method works regardless of whether the -//object already exists or not. Existing object contents will be overwritten by -//this operation. +// SymlinkTo creates the object as a symbolic link to another object using a PUT +// request. Like Object.Upload(), this method works regardless of whether the +// object already exists or not. Existing object contents will be overwritten by +// this operation. // -//A successful PUT request implies Invalidate() since it may change metadata. +// A successful PUT request implies Invalidate() since it may change metadata. func (o *Object) SymlinkTo(target *Object, opts *SymlinkOptions, ropts *RequestOptions) error { ropts = cloneRequestOptions(ropts, nil) ropts.Headers.Set("X-Symlink-Target", target.FullName()) @@ -534,24 +534,24 @@ func (o *Object) SymlinkTo(target *Object, opts *SymlinkOptions, ropts *RequestO return o.Upload(nil, uopts, ropts) } -//SymlinkHeaders is similar to Headers, but if the object is a symlink, it -//returns the metadata of the symlink rather than the metadata of the target. -//It also returns a reference to the target object. +// SymlinkHeaders is similar to Headers, but if the object is a symlink, it +// returns the metadata of the symlink rather than the metadata of the target. +// It also returns a reference to the target object. // -//If this object is not a symlink, Object.SymlinkHeaders() returns the same -//ObjectHeaders as Object.Headers(), and a nil target object. +// If this object is not a symlink, Object.SymlinkHeaders() returns the same +// ObjectHeaders as Object.Headers(), and a nil target object. // -//In a nutshell, if Object.Headers() is like os.Stat(), then -//Object.SymlinkHeaders() is like os.Lstat(). +// In a nutshell, if Object.Headers() is like os.Stat(), then +// Object.SymlinkHeaders() is like os.Lstat(). // -//If you do not know whether a given object is a symlink or not, it's a good -//idea to call Object.SymlinkHeaders() first: If the object turns out not to be -//a symlink, the cache for Object.Headers() has already been populated. +// If you do not know whether a given object is a symlink or not, it's a good +// idea to call Object.SymlinkHeaders() first: If the object turns out not to be +// a symlink, the cache for Object.Headers() has already been populated. // -//This operation fails with http.StatusNotFound if the object does not exist. +// This operation fails with http.StatusNotFound if the object does not exist. // -//WARNING: This method is not thread-safe. Calling it concurrently on the same -//object results in undefined behavior. +// WARNING: This method is not thread-safe. Calling it concurrently on the same +// object results in undefined behavior. func (o *Object) SymlinkHeaders() (headers ObjectHeaders, target *Object, err error) { if o.symlinkHeaders == nil { o.symlinkHeaders, err = o.fetchHeaders(&RequestOptions{ @@ -587,9 +587,9 @@ func (o *Object) SymlinkHeaders() (headers ObjectHeaders, target *Object, err er return *o.symlinkHeaders, target, nil } -//URL returns the canonical URL for the object on the server. This is -//particularly useful when the ReadACL on the account or container is set to -//allow anonymous read access. +// URL returns the canonical URL for the object on the server. This is +// particularly useful when the ReadACL on the account or container is set to +// allow anonymous read access. func (o *Object) URL() (string, error) { return Request{ ContainerName: o.c.name, @@ -597,14 +597,14 @@ func (o *Object) URL() (string, error) { }.URL(o.c.a.backend, nil) } -//TempURL is like Object.URL, but includes a token with a limited lifetime (as -//specified by the `expires` argument) that permits anonymous access to this -//object using the given HTTP method. This works only when the tempurl -//middleware is set up on the server, and if the given `key` matches one of the -//tempurl keys for this object's container or account. +// TempURL is like Object.URL, but includes a token with a limited lifetime (as +// specified by the `expires` argument) that permits anonymous access to this +// object using the given HTTP method. This works only when the tempurl +// middleware is set up on the server, and if the given `key` matches one of the +// tempurl keys for this object's container or account. // -//For example, if the ReadACL both on the account and container do not permit -//anonymous read access (which is the default behavior): +// For example, if the ReadACL both on the account and container do not permit +// anonymous read access (which is the default behavior): // // var o *schwift.Object // ... @@ -623,7 +623,6 @@ func (o *Object) URL() (string, error) { // url := o.TempURL(key, "GET", time.Now().Add(10 * time.Minute)) // resp, err := http.Get(url) // //This time, resp.StatusCode == 200 because the URL includes a token. -// func (o *Object) TempURL(key, method string, expires time.Time) (string, error) { urlStr, err := o.URL() if err != nil { diff --git a/object_iterator.go b/object_iterator.go index a94d7c9..dcb8443 100644 --- a/object_iterator.go +++ b/object_iterator.go @@ -24,10 +24,10 @@ import ( "time" ) -//ObjectInfo is a result type returned by ObjectIterator for detailed -//object listings. The metadata in this type is a subset of Object.Headers(), -//but since it is returned as part of the detailed object listing, it can be -//obtained without making additional HEAD requests on the object(s). +// ObjectInfo is a result type returned by ObjectIterator for detailed +// object listings. The metadata in this type is a subset of Object.Headers(), +// but since it is returned as part of the detailed object listing, it can be +// obtained without making additional HEAD requests on the object(s). type ObjectInfo struct { Object *Object SizeBytes uint64 @@ -43,8 +43,8 @@ type ObjectInfo struct { SubDirectory string } -//ObjectIterator iterates over the objects in a container. It is typically -//constructed with the Container.Objects() method. For example: +// ObjectIterator iterates over the objects in a container. It is typically +// constructed with the Container.Objects() method. For example: // // //either this... // iter := container.Objects() @@ -57,21 +57,21 @@ type ObjectInfo struct { // Prefix: "test-", // }.Collect() // -//When listing objects via a GET request on the container, you can choose to -//receive object names only (via the methods without the "Detailed" suffix), -//or object names plus some basic metadata fields (via the methods with the -//"Detailed" suffix). See struct ObjectInfo for which metadata is returned. +// When listing objects via a GET request on the container, you can choose to +// receive object names only (via the methods without the "Detailed" suffix), +// or object names plus some basic metadata fields (via the methods with the +// "Detailed" suffix). See struct ObjectInfo for which metadata is returned. // -//To obtain any other metadata, you can call Object.Headers() on the result -//object, but this will issue a separate HEAD request for each object. +// To obtain any other metadata, you can call Object.Headers() on the result +// object, but this will issue a separate HEAD request for each object. // -//Use the "Detailed" methods only when you use the extra metadata in struct -//ObjectInfo; detailed GET requests are more expensive than simple ones that -//return only object names. +// Use the "Detailed" methods only when you use the extra metadata in struct +// ObjectInfo; detailed GET requests are more expensive than simple ones that +// return only object names. // -//Note that, when Delimiter is set, instances of *Object that you receive from -//the iterator may refer to a pseudo-directory instead of an actual object, in -//which case Exists() will return false. +// Note that, when Delimiter is set, instances of *Object that you receive from +// the iterator may refer to a pseudo-directory instead of an actual object, in +// which case Exists() will return false. type ObjectIterator struct { Container *Container //When Prefix is set, only objects whose name starts with this string are @@ -94,15 +94,15 @@ func (i *ObjectIterator) getBase() *iteratorBase { return i.base } -//NextPage queries Swift for the next page of object names. If limit is -//>= 0, not more than that many object names will be returned at once. Note -//that the server also has a limit for how many objects to list in one -//request; the lower limit wins. +// NextPage queries Swift for the next page of object names. If limit is +// >= 0, not more than that many object names will be returned at once. Note +// that the server also has a limit for how many objects to list in one +// request; the lower limit wins. // -//The end of the object listing is reached when an empty list is returned. +// The end of the object listing is reached when an empty list is returned. // -//This method offers maximal flexibility, but most users will prefer the -//simpler interfaces offered by Collect() and Foreach(). +// This method offers maximal flexibility, but most users will prefer the +// simpler interfaces offered by Collect() and Foreach(). func (i *ObjectIterator) NextPage(limit int) ([]*Object, error) { names, err := i.getBase().nextPage(limit) if err != nil { @@ -116,10 +116,10 @@ func (i *ObjectIterator) NextPage(limit int) ([]*Object, error) { return result, nil } -//The symlink_path attribute looks like "/v1/AUTH_foo/containername/obje/ctna/me". +// The symlink_path attribute looks like "/v1/AUTH_foo/containername/obje/ctna/me". var symlinkPathRx = regexp.MustCompile(`^/v1/([^/]+)/([^/]+)/(.+)$`) -//NextPageDetailed is like NextPage, but includes basic metadata. +// NextPageDetailed is like NextPage, but includes basic metadata. func (i *ObjectIterator) NextPageDetailed(limit int) ([]ObjectInfo, error) { b := i.getBase() @@ -179,9 +179,9 @@ func (i *ObjectIterator) NextPageDetailed(limit int) ([]ObjectInfo, error) { return result, nil } -//Foreach lists the object names matching this iterator and calls the -//callback once for every object. Iteration is aborted when a GET request fails, -//or when the callback returns a non-nil error. +// Foreach lists the object names matching this iterator and calls the +// callback once for every object. Iteration is aborted when a GET request fails, +// or when the callback returns a non-nil error. func (i *ObjectIterator) Foreach(callback func(*Object) error) error { for { objects, err := i.NextPage(-1) @@ -200,7 +200,7 @@ func (i *ObjectIterator) Foreach(callback func(*Object) error) error { } } -//ForeachDetailed is like Foreach, but includes basic metadata. +// ForeachDetailed is like Foreach, but includes basic metadata. func (i *ObjectIterator) ForeachDetailed(callback func(ObjectInfo) error) error { for { infos, err := i.NextPageDetailed(-1) @@ -219,9 +219,9 @@ func (i *ObjectIterator) ForeachDetailed(callback func(ObjectInfo) error) error } } -//Collect lists all object names matching this iterator. For large sets of -//objects that cannot be retrieved at once, Collect handles paging behind -//the scenes. The return value is always the complete set of objects. +// Collect lists all object names matching this iterator. For large sets of +// objects that cannot be retrieved at once, Collect handles paging behind +// the scenes. The return value is always the complete set of objects. func (i *ObjectIterator) Collect() ([]*Object, error) { var result []*Object for { @@ -236,7 +236,7 @@ func (i *ObjectIterator) Collect() ([]*Object, error) { } } -//CollectDetailed is like Collect, but includes basic metadata. +// CollectDetailed is like Collect, but includes basic metadata. func (i *ObjectIterator) CollectDetailed() ([]ObjectInfo, error) { var result []ObjectInfo for { @@ -27,18 +27,17 @@ import ( "strings" ) -//RequestOptions is used to pass additional headers and values to a request. +// RequestOptions is used to pass additional headers and values to a request. // -//When preparing a RequestOptions instance with additional headers, the -//preferred way is to create an AccountHeaders, ContainerHeaders and -//ObjectHeaders instance and use the type-safe API on these types. Then use the -//ToOpts() method on that instance. For example: +// When preparing a RequestOptions instance with additional headers, the +// preferred way is to create an AccountHeaders, ContainerHeaders and +// ObjectHeaders instance and use the type-safe API on these types. Then use the +// ToOpts() method on that instance. For example: // // hdr := NewObjectHeaders() // hdr.ContentType().Set("image/png") // hdr.Metadata().Set("color", "blue") // opts := hdr.ToOpts() //type *schwift.RequestOptions -// type RequestOptions struct { Headers Headers Values url.Values @@ -65,7 +64,7 @@ func cloneRequestOptions(orig *RequestOptions, additional Headers) *RequestOptio return &result } -//Request contains the parameters that can be set in a request to the Swift API. +// Request contains the parameters that can be set in a request to the Swift API. type Request struct { Method string //"GET", "HEAD", "PUT", "POST" or "DELETE" ContainerName string //empty for requests on accounts @@ -80,7 +79,7 @@ type Request struct { DrainResponseBody bool } -//URL returns the full URL for this request. +// URL returns the full URL for this request. func (r Request) URL(backend Backend, values url.Values) (string, error) { uri, err := url.Parse(backend.EndpointURL()) if err != nil { @@ -107,7 +106,7 @@ func (r Request) URL(backend Backend, values url.Values) (string, error) { return uri.String(), nil } -//Do executes this request on the given Backend. +// Do executes this request on the given Backend. func (r Request) Do(backend Backend) (*http.Response, error) { //build URL var values url.Values diff --git a/tests/largeobject_test.go b/tests/largeobject_test.go index 1932741..b63ccd7 100644 --- a/tests/largeobject_test.go +++ b/tests/largeobject_test.go @@ -36,7 +36,6 @@ func foreachLargeObjectStrategy(action func(schwift.LargeObjectStrategy, string) func TestLargeObjectsBasic(t *testing.T) { testWithContainer(t, func(c *schwift.Container) { foreachLargeObjectStrategy(func(strategy schwift.LargeObjectStrategy, strategyStr string) { - obj := c.Object(strategyStr + "-largeobject") lo, err := obj.AsLargeObject() expectError(t, err, schwift.ErrNotLarge.Error()) @@ -135,7 +134,6 @@ func TestLargeObjectsBasic(t *testing.T) { Etag: etagOfString(segment4), }, }) - }) }) } diff --git a/tests/shared_test.go b/tests/shared_test.go index 36404bd..54934ff 100644 --- a/tests/shared_test.go +++ b/tests/shared_test.go @@ -30,6 +30,7 @@ import ( "github.com/gophercloud/gophercloud/openstack" "github.com/gophercloud/gophercloud/openstack/objectstorage/v1/swauth" "github.com/gophercloud/utils/openstack/clientconfig" + "github.com/majewsky/schwift" "github.com/majewsky/schwift/gopherschwift" ) @@ -18,5 +18,5 @@ package schwift -//Version contains the version number of Schwift. +// Version contains the version number of Schwift. const Version = "1.0.0" |
