reader.go 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  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. package storage
  15. import (
  16. "fmt"
  17. "hash/crc32"
  18. "io"
  19. )
  20. var crc32cTable = crc32.MakeTable(crc32.Castagnoli)
  21. // Reader reads a Cloud Storage object.
  22. // It implements io.Reader.
  23. type Reader struct {
  24. body io.ReadCloser
  25. remain, size int64
  26. contentType string
  27. checkCRC bool // should we check the CRC?
  28. wantCRC uint32 // the CRC32c value the server sent in the header
  29. gotCRC uint32 // running crc
  30. }
  31. // Close closes the Reader. It must be called when done reading.
  32. func (r *Reader) Close() error {
  33. return r.body.Close()
  34. }
  35. func (r *Reader) Read(p []byte) (int, error) {
  36. n, err := r.body.Read(p)
  37. if r.remain != -1 {
  38. r.remain -= int64(n)
  39. }
  40. if r.checkCRC {
  41. r.gotCRC = crc32.Update(r.gotCRC, crc32cTable, p[:n])
  42. // Check CRC here. It would be natural to check it in Close, but
  43. // everybody defers Close on the assumption that it doesn't return
  44. // anything worth looking at.
  45. if r.remain == 0 && r.gotCRC != r.wantCRC {
  46. return n, fmt.Errorf("storage: bad CRC on read: got %d, want %d",
  47. r.gotCRC, r.wantCRC)
  48. }
  49. }
  50. return n, err
  51. }
  52. // Size returns the size of the object in bytes.
  53. // The returned value is always the same and is not affected by
  54. // calls to Read or Close.
  55. func (r *Reader) Size() int64 {
  56. return r.size
  57. }
  58. // Remain returns the number of bytes left to read, or -1 if unknown.
  59. func (r *Reader) Remain() int64 {
  60. return r.remain
  61. }
  62. // ContentType returns the content type of the object.
  63. func (r *Reader) ContentType() string {
  64. return r.contentType
  65. }