You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

119 lines
2.5 KiB

  1. // Copyright 2018 Google LLC
  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 elf
  15. import (
  16. "io"
  17. "os"
  18. )
  19. // errorReader returns error from all operations.
  20. type errorReader struct {
  21. error
  22. }
  23. func (r errorReader) Read(p []byte) (n int, err error) {
  24. return 0, r.error
  25. }
  26. func (r errorReader) ReadAt(p []byte, off int64) (n int, err error) {
  27. return 0, r.error
  28. }
  29. func (r errorReader) Seek(offset int64, whence int) (int64, error) {
  30. return 0, r.error
  31. }
  32. func (r errorReader) Close() error {
  33. return r.error
  34. }
  35. // readSeekerFromReader converts an io.Reader into an io.ReadSeeker.
  36. // In general Seek may not be efficient, but it is optimized for
  37. // common cases such as seeking to the end to find the length of the
  38. // data.
  39. type readSeekerFromReader struct {
  40. reset func() (io.Reader, error)
  41. r io.Reader
  42. size int64
  43. offset int64
  44. }
  45. func (r *readSeekerFromReader) start() {
  46. x, err := r.reset()
  47. if err != nil {
  48. r.r = errorReader{err}
  49. } else {
  50. r.r = x
  51. }
  52. r.offset = 0
  53. }
  54. func (r *readSeekerFromReader) Read(p []byte) (n int, err error) {
  55. if r.r == nil {
  56. r.start()
  57. }
  58. n, err = r.r.Read(p)
  59. r.offset += int64(n)
  60. return n, err
  61. }
  62. func (r *readSeekerFromReader) Seek(offset int64, whence int) (int64, error) {
  63. var newOffset int64
  64. switch whence {
  65. case seekStart:
  66. newOffset = offset
  67. case seekCurrent:
  68. newOffset = r.offset + offset
  69. case seekEnd:
  70. newOffset = r.size + offset
  71. default:
  72. return 0, os.ErrInvalid
  73. }
  74. switch {
  75. case newOffset == r.offset:
  76. return newOffset, nil
  77. case newOffset < 0, newOffset > r.size:
  78. return 0, os.ErrInvalid
  79. case newOffset == 0:
  80. r.r = nil
  81. case newOffset == r.size:
  82. r.r = errorReader{io.EOF}
  83. default:
  84. if newOffset < r.offset {
  85. // Restart at the beginning.
  86. r.start()
  87. }
  88. // Read until we reach offset.
  89. var buf [512]byte
  90. for r.offset < newOffset {
  91. b := buf[:]
  92. if newOffset-r.offset < int64(len(buf)) {
  93. b = buf[:newOffset-r.offset]
  94. }
  95. if _, err := r.Read(b); err != nil {
  96. return 0, err
  97. }
  98. }
  99. }
  100. r.offset = newOffset
  101. return r.offset, nil
  102. }