1// Copyright 2016 Google Inc. All Rights Reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package storage 16 17import ( 18 "fmt" 19 "hash/crc32" 20 "io" 21) 22 23var crc32cTable = crc32.MakeTable(crc32.Castagnoli) 24 25// Reader reads a Cloud Storage object. 26// It implements io.Reader. 27type Reader struct { 28 body io.ReadCloser 29 remain, size int64 30 contentType string 31 cacheControl string 32 checkCRC bool // should we check the CRC? 33 wantCRC uint32 // the CRC32c value the server sent in the header 34 gotCRC uint32 // running crc 35} 36 37// Close closes the Reader. It must be called when done reading. 38func (r *Reader) Close() error { 39 return r.body.Close() 40} 41 42func (r *Reader) Read(p []byte) (int, error) { 43 n, err := r.body.Read(p) 44 if r.remain != -1 { 45 r.remain -= int64(n) 46 } 47 if r.checkCRC { 48 r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n]) 49 // Check CRC here. It would be natural to check it in Close, but 50 // everybody defers Close on the assumption that it doesn't return 51 // anything worth looking at. 52 if r.remain == 0 && r.gotCRC != r.wantCRC { 53 return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d", 54 r.gotCRC, r.wantCRC) 55 } 56 } 57 return n, err 58} 59 60// Size returns the size of the object in bytes. 61// The returned value is always the same and is not affected by 62// calls to Read or Close. 63func (r *Reader) Size() int64 { 64 return r.size 65} 66 67// Remain returns the number of bytes left to read, or -1 if unknown. 68func (r *Reader) Remain() int64 { 69 return r.remain 70} 71 72// ContentType returns the content type of the object. 73func (r *Reader) ContentType() string { 74 return r.contentType 75} 76 77// CacheControl returns the cache control of the object. 78func (r *Reader) CacheControl() string { 79 return r.cacheControl 80} 81