Copyright 2016 Google LLC Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

package storage

import (
	
	
	

	
	raw 
)
CopierFrom creates a Copier that can copy src to dst. You can immediately call Run on the returned Copier, or you can configure it first. For Requester Pays buckets, the user project of dst is billed, unless it is empty, in which case the user project of src is billed.
func ( *ObjectHandle) ( *ObjectHandle) *Copier {
	return &Copier{dst: , src: }
}
A Copier copies a source object to a destination.
ObjectAttrs are optional attributes to set on the destination object. Any attributes must be initialized before any calls on the Copier. Nil or zero-valued attributes are ignored.
RewriteToken can be set before calling Run to resume a copy operation. After Run returns a non-nil error, RewriteToken will have been updated to contain the value needed to resume the copy.
ProgressFunc can be used to monitor the progress of a multi-RPC copy operation. If ProgressFunc is not nil and copying requires multiple calls to the underlying service (see https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite), then ProgressFunc will be invoked after each call with the number of bytes of content copied so far and the total size in bytes of the source object. ProgressFunc is intended to make upload progress available to the application. For example, the implementation of ProgressFunc may update a progress bar in the application's UI, or log the result of float64(copiedBytes)/float64(totalBytes). ProgressFunc should return quickly without blocking.
	ProgressFunc func(copiedBytes, totalBytes uint64)
The Cloud KMS key, in the form projects/P/locations/L/keyRings/R/cryptoKeys/K, that will be used to encrypt the object. Overrides the object's KMSKeyName, if any. Providing both a DestinationKMSKeyName and a customer-supplied encryption key (via ObjectHandle.Key) on the destination object will result in an error when Run is called.
Run performs the copy.
func ( *Copier) ( context.Context) ( *ObjectAttrs,  error) {
	 = trace.StartSpan(, "cloud.google.com/go/storage.Copier.Run")
	defer func() { trace.EndSpan(, ) }()

	if  := .src.validate();  != nil {
		return nil, 
	}
	if  := .dst.validate();  != nil {
		return nil, 
	}
	if .DestinationKMSKeyName != "" && .dst.encryptionKey != nil {
		return nil, errors.New("storage: cannot use DestinationKMSKeyName with a customer-supplied encryption key")
Convert destination attributes to raw form, omitting the bucket. If the bucket is included but name or content-type aren't, the service returns a 400 with "Required" as the only message. Omitting the bucket does not cause any problems.
	 := .ObjectAttrs.toRawObject("")
	for {
		,  := .callRewrite(, )
		if  != nil {
			return nil, 
		}
		if .ProgressFunc != nil {
			.ProgressFunc(uint64(.TotalBytesRewritten), uint64(.ObjectSize))
		}
		if .Done { // Finished successfully.
			return newObject(.Resource), nil
		}
	}
}

func ( *Copier) ( context.Context,  *raw.Object) (*raw.RewriteResponse, error) {
	 := .dst.c.raw.Objects.Rewrite(.src.bucket, .src.object, .dst.bucket, .dst.object, )

	.Context().Projection("full")
	if .RewriteToken != "" {
		.RewriteToken(.RewriteToken)
	}
	if .DestinationKMSKeyName != "" {
		.DestinationKmsKeyName(.DestinationKMSKeyName)
	}
	if .PredefinedACL != "" {
		.DestinationPredefinedAcl(.PredefinedACL)
	}
	if  := applyConds("Copy destination", .dst.gen, .dst.conds, );  != nil {
		return nil, 
	}
	if .dst.userProject != "" {
		.UserProject(.dst.userProject)
	} else if .src.userProject != "" {
		.UserProject(.src.userProject)
	}
	if  := applySourceConds(.src.gen, .src.conds, );  != nil {
		return nil, 
	}
	if  := setEncryptionHeaders(.Header(), .dst.encryptionKey, false);  != nil {
		return nil, 
	}
	if  := setEncryptionHeaders(.Header(), .src.encryptionKey, true);  != nil {
		return nil, 
	}
	var  *raw.RewriteResponse
	var  error
	setClientHeader(.Header())
	 = runWithRetry(, func() error { ,  = .Do(); return  })
	if  != nil {
		return nil, 
	}
	.RewriteToken = .RewriteToken
	return , nil
}
ComposerFrom creates a Composer that can compose srcs into dst. You can immediately call Run on the returned Composer, or you can configure it first. The encryption key for the destination object will be used to decrypt all source objects and encrypt the destination object. It is an error to specify an encryption key for any of the source objects.
func ( *ObjectHandle) ( ...*ObjectHandle) *Composer {
	return &Composer{dst: , srcs: }
}
A Composer composes source objects into a destination object. For Requester Pays buckets, the user project of dst is billed.
ObjectAttrs are optional attributes to set on the destination object. Any attributes must be initialized before any calls on the Composer. Nil or zero-valued attributes are ignored.
SendCRC specifies whether to transmit a CRC32C field. It should be set to true in addition to setting the Composer's CRC32C field, because zero is a valid CRC and normally a zero would not be transmitted. If a CRC32C is sent, and the data in the destination object does not match the checksum, the compose will be rejected.
Run performs the compose operation.
func ( *Composer) ( context.Context) ( *ObjectAttrs,  error) {
	 = trace.StartSpan(, "cloud.google.com/go/storage.Composer.Run")
	defer func() { trace.EndSpan(, ) }()

	if  := .dst.validate();  != nil {
		return nil, 
	}
	if len(.srcs) == 0 {
		return nil, errors.New("storage: at least one source object must be specified")
	}

Compose requires a non-empty Destination, so we always set it, even if the caller-provided ObjectAttrs is the zero value.
	.Destination = .ObjectAttrs.toRawObject(.dst.bucket)
	if .SendCRC32C {
		.Destination.Crc32c = encodeUint32(.ObjectAttrs.CRC32C)
	}
	for ,  := range .srcs {
		if  := .validate();  != nil {
			return nil, 
		}
		if .bucket != .dst.bucket {
			return nil, fmt.Errorf("storage: all source objects must be in bucket %q, found %q", .dst.bucket, .bucket)
		}
		if .encryptionKey != nil {
			return nil, fmt.Errorf("storage: compose source %s.%s must not have encryption key", .bucket, .object)
		}
		 := &raw.ComposeRequestSourceObjects{
			Name: .object,
		}
		if  := applyConds("ComposeFrom source", .gen, .conds, composeSourceObj{});  != nil {
			return nil, 
		}
		.SourceObjects = append(.SourceObjects, )
	}

	 := .dst.c.raw.Objects.Compose(.dst.bucket, .dst.object, ).Context()
	if  := applyConds("ComposeFrom destination", .dst.gen, .dst.conds, );  != nil {
		return nil, 
	}
	if .dst.userProject != "" {
		.UserProject(.dst.userProject)
	}
	if .PredefinedACL != "" {
		.DestinationPredefinedAcl(.PredefinedACL)
	}
	if  := setEncryptionHeaders(.Header(), .dst.encryptionKey, false);  != nil {
		return nil, 
	}
	var  *raw.Object
	setClientHeader(.Header())
	 = runWithRetry(, func() error { ,  = .Do(); return  })
	if  != nil {
		return nil, 
	}
	return newObject(), nil