191 atomic.AddInt64(&f.at, int64(n)) |
204 atomic.AddInt64(&f.at, int64(n)) |
192 return |
205 return |
193 } |
206 } |
194 |
207 |
195 func (f *File) ReadAt(b []byte, off int64) (n int, err error) { |
208 func (f *File) ReadAt(b []byte, off int64) (n int, err error) { |
|
209 prev := atomic.LoadInt64(&f.at) |
196 atomic.StoreInt64(&f.at, off) |
210 atomic.StoreInt64(&f.at, off) |
197 return f.Read(b) |
211 n, err = f.Read(b) |
|
212 atomic.StoreInt64(&f.at, prev) |
|
213 return |
198 } |
214 } |
199 |
215 |
200 func (f *File) Truncate(size int64) error { |
216 func (f *File) Truncate(size int64) error { |
201 if f.closed == true { |
217 if f.closed == true { |
202 return ErrFileClosed |
218 return ErrFileClosed |
205 return &os.PathError{Op: "truncate", Path: f.fileData.name, Err: errors.New("file handle is read only")} |
221 return &os.PathError{Op: "truncate", Path: f.fileData.name, Err: errors.New("file handle is read only")} |
206 } |
222 } |
207 if size < 0 { |
223 if size < 0 { |
208 return ErrOutOfRange |
224 return ErrOutOfRange |
209 } |
225 } |
|
226 f.fileData.Lock() |
|
227 defer f.fileData.Unlock() |
210 if size > int64(len(f.fileData.data)) { |
228 if size > int64(len(f.fileData.data)) { |
211 diff := size - int64(len(f.fileData.data)) |
229 diff := size - int64(len(f.fileData.data)) |
212 f.fileData.data = append(f.fileData.data, bytes.Repeat([]byte{00}, int(diff))...) |
230 f.fileData.data = append(f.fileData.data, bytes.Repeat([]byte{00}, int(diff))...) |
213 } else { |
231 } else { |
214 f.fileData.data = f.fileData.data[0:size] |
232 f.fileData.data = f.fileData.data[0:size] |
220 func (f *File) Seek(offset int64, whence int) (int64, error) { |
238 func (f *File) Seek(offset int64, whence int) (int64, error) { |
221 if f.closed == true { |
239 if f.closed == true { |
222 return 0, ErrFileClosed |
240 return 0, ErrFileClosed |
223 } |
241 } |
224 switch whence { |
242 switch whence { |
225 case 0: |
243 case io.SeekStart: |
226 atomic.StoreInt64(&f.at, offset) |
244 atomic.StoreInt64(&f.at, offset) |
227 case 1: |
245 case io.SeekCurrent: |
228 atomic.AddInt64(&f.at, int64(offset)) |
246 atomic.AddInt64(&f.at, offset) |
229 case 2: |
247 case io.SeekEnd: |
230 atomic.StoreInt64(&f.at, int64(len(f.fileData.data))+offset) |
248 atomic.StoreInt64(&f.at, int64(len(f.fileData.data))+offset) |
231 } |
249 } |
232 return f.at, nil |
250 return f.at, nil |
233 } |
251 } |
234 |
252 |
235 func (f *File) Write(b []byte) (n int, err error) { |
253 func (f *File) Write(b []byte) (n int, err error) { |
|
254 if f.closed == true { |
|
255 return 0, ErrFileClosed |
|
256 } |
236 if f.readOnly { |
257 if f.readOnly { |
237 return 0, &os.PathError{Op: "write", Path: f.fileData.name, Err: errors.New("file handle is read only")} |
258 return 0, &os.PathError{Op: "write", Path: f.fileData.name, Err: errors.New("file handle is read only")} |
238 } |
259 } |
239 n = len(b) |
260 n = len(b) |
240 cur := atomic.LoadInt64(&f.at) |
261 cur := atomic.LoadInt64(&f.at) |
244 var tail []byte |
265 var tail []byte |
245 if n+int(cur) < len(f.fileData.data) { |
266 if n+int(cur) < len(f.fileData.data) { |
246 tail = f.fileData.data[n+int(cur):] |
267 tail = f.fileData.data[n+int(cur):] |
247 } |
268 } |
248 if diff > 0 { |
269 if diff > 0 { |
249 f.fileData.data = append(bytes.Repeat([]byte{00}, int(diff)), b...) |
270 f.fileData.data = append(f.fileData.data, append(bytes.Repeat([]byte{00}, int(diff)), b...)...) |
250 f.fileData.data = append(f.fileData.data, tail...) |
271 f.fileData.data = append(f.fileData.data, tail...) |
251 } else { |
272 } else { |
252 f.fileData.data = append(f.fileData.data[:cur], b...) |
273 f.fileData.data = append(f.fileData.data[:cur], b...) |
253 f.fileData.data = append(f.fileData.data, tail...) |
274 f.fileData.data = append(f.fileData.data, tail...) |
254 } |
275 } |
255 setModTime(f.fileData, time.Now()) |
276 setModTime(f.fileData, time.Now()) |
256 |
277 |
257 atomic.StoreInt64(&f.at, int64(len(f.fileData.data))) |
278 atomic.AddInt64(&f.at, int64(n)) |
258 return |
279 return |
259 } |
280 } |
260 |
281 |
261 func (f *File) WriteAt(b []byte, off int64) (n int, err error) { |
282 func (f *File) WriteAt(b []byte, off int64) (n int, err error) { |
262 atomic.StoreInt64(&f.at, off) |
283 atomic.StoreInt64(&f.at, off) |