Browse code

pkg/ioutils: fix multireader SEEK_CUR branch

Before getReaderForOffset returned always nil and wrong offset.

Signed-off-by: Alexander Morozov <lk4d4@docker.com>

Alexander Morozov authored on 2016/09/03 03:09:55
Showing 2 changed files
... ...
@@ -97,27 +97,24 @@ func (r *multiReadSeeker) Seek(offset int64, whence int) (int64, error) {
97 97
 }
98 98
 
99 99
 func (r *multiReadSeeker) getReaderForOffset(offset int64) (io.ReadSeeker, int64, error) {
100
-	var rdr io.ReadSeeker
101
-	var rdrOffset int64
102 100
 
103
-	for i, rdr := range r.readers {
104
-		offsetTo, err := r.getOffsetToReader(rdr)
101
+	var offsetTo int64
102
+
103
+	for _, rdr := range r.readers {
104
+		size, err := getReadSeekerSize(rdr)
105 105
 		if err != nil {
106 106
 			return nil, -1, err
107 107
 		}
108
-		if offsetTo > offset {
109
-			rdr = r.readers[i-1]
110
-			rdrOffset = offsetTo - offset
111
-			break
108
+		if offsetTo+size > offset {
109
+			return rdr, offset - offsetTo, nil
112 110
 		}
113
-
114 111
 		if rdr == r.readers[len(r.readers)-1] {
115
-			rdrOffset = offsetTo + offset
116
-			break
112
+			return rdr, offsetTo + offset, nil
117 113
 		}
114
+		offsetTo += size
118 115
 	}
119 116
 
120
-	return rdr, rdrOffset, nil
117
+	return nil, 0, nil
121 118
 }
122 119
 
123 120
 func (r *multiReadSeeker) getCurOffset() (int64, error) {
... ...
@@ -147,3 +147,44 @@ func TestMultiReadSeekerNegativeSeek(t *testing.T) {
147 147
 		t.Fatalf("expected %q to be %q", string(buf), expected)
148 148
 	}
149 149
 }
150
+
151
+func TestMultiReadSeekerCurAfterSet(t *testing.T) {
152
+	str := "hello world"
153
+	s1 := strings.NewReader(str + " 1")
154
+	s2 := strings.NewReader(str + " 2")
155
+	s3 := strings.NewReader(str + " 3")
156
+	mr := MultiReadSeeker(s1, s2, s3)
157
+
158
+	mid := int64(s1.Len() + s2.Len()/2)
159
+
160
+	size, err := mr.Seek(mid, os.SEEK_SET)
161
+	if err != nil {
162
+		t.Fatal(err)
163
+	}
164
+	if size != mid {
165
+		t.Fatalf("reader size does not match, got %d, expected %d", size, mid)
166
+	}
167
+
168
+	size, err = mr.Seek(3, os.SEEK_CUR)
169
+	if err != nil {
170
+		t.Fatal(err)
171
+	}
172
+	if size != mid+3 {
173
+		t.Fatalf("reader size does not match, got %d, expected %d", size, mid+3)
174
+	}
175
+	size, err = mr.Seek(5, os.SEEK_CUR)
176
+	if err != nil {
177
+		t.Fatal(err)
178
+	}
179
+	if size != mid+8 {
180
+		t.Fatalf("reader size does not match, got %d, expected %d", size, mid+8)
181
+	}
182
+
183
+	size, err = mr.Seek(10, os.SEEK_CUR)
184
+	if err != nil {
185
+		t.Fatal(err)
186
+	}
187
+	if size != mid+18 {
188
+		t.Fatalf("reader size does not match, got %d, expected %d", size, mid+18)
189
+	}
190
+}