mirror of
https://github.com/octoleo/syncthing.git
synced 2024-11-19 03:25:16 +00:00
131 lines
2.5 KiB
Go
131 lines
2.5 KiB
Go
|
// Copyright 2014 The lldb Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style
|
||
|
// license that can be found in the LICENSE file.
|
||
|
|
||
|
package lldb
|
||
|
|
||
|
import (
|
||
|
"io"
|
||
|
"os"
|
||
|
|
||
|
"github.com/cznic/mathutil"
|
||
|
)
|
||
|
|
||
|
var _ Filer = (*OSFiler)(nil)
|
||
|
|
||
|
// OSFile is an os.File like minimal set of methods allowing to construct a
|
||
|
// Filer.
|
||
|
type OSFile interface {
|
||
|
Name() string
|
||
|
Stat() (fi os.FileInfo, err error)
|
||
|
Sync() (err error)
|
||
|
Truncate(size int64) (err error)
|
||
|
io.Closer
|
||
|
io.Reader
|
||
|
io.ReaderAt
|
||
|
io.Seeker
|
||
|
io.Writer
|
||
|
io.WriterAt
|
||
|
}
|
||
|
|
||
|
// OSFiler is like a SimpleFileFiler but based on an OSFile.
|
||
|
type OSFiler struct {
|
||
|
f OSFile
|
||
|
nest int
|
||
|
size int64 // not set if < 0
|
||
|
}
|
||
|
|
||
|
// NewOSFiler returns a Filer from an OSFile. This Filer is like the
|
||
|
// SimpleFileFiler, it does not implement the transaction related methods.
|
||
|
func NewOSFiler(f OSFile) (r *OSFiler) {
|
||
|
return &OSFiler{
|
||
|
f: f,
|
||
|
size: -1,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// BeginUpdate implements Filer.
|
||
|
func (f *OSFiler) BeginUpdate() (err error) {
|
||
|
f.nest++
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Close implements Filer.
|
||
|
func (f *OSFiler) Close() (err error) {
|
||
|
if f.nest != 0 {
|
||
|
return &ErrPERM{(f.Name() + ":Close")}
|
||
|
}
|
||
|
|
||
|
return f.f.Close()
|
||
|
}
|
||
|
|
||
|
// EndUpdate implements Filer.
|
||
|
func (f *OSFiler) EndUpdate() (err error) {
|
||
|
if f.nest == 0 {
|
||
|
return &ErrPERM{(f.Name() + ":EndUpdate")}
|
||
|
}
|
||
|
|
||
|
f.nest--
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Name implements Filer.
|
||
|
func (f *OSFiler) Name() string {
|
||
|
return f.f.Name()
|
||
|
}
|
||
|
|
||
|
// PunchHole implements Filer.
|
||
|
func (f *OSFiler) PunchHole(off, size int64) (err error) {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// ReadAt implements Filer.
|
||
|
func (f *OSFiler) ReadAt(b []byte, off int64) (n int, err error) {
|
||
|
return f.f.ReadAt(b, off)
|
||
|
}
|
||
|
|
||
|
// Rollback implements Filer.
|
||
|
func (f *OSFiler) Rollback() (err error) { return }
|
||
|
|
||
|
// Size implements Filer.
|
||
|
func (f *OSFiler) Size() (n int64, err error) {
|
||
|
if f.size < 0 { // boot
|
||
|
fi, err := f.f.Stat()
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
|
||
|
f.size = fi.Size()
|
||
|
}
|
||
|
return f.size, nil
|
||
|
}
|
||
|
|
||
|
// Sync implements Filer.
|
||
|
func (f *OSFiler) Sync() (err error) {
|
||
|
return f.f.Sync()
|
||
|
}
|
||
|
|
||
|
// Truncate implements Filer.
|
||
|
func (f *OSFiler) Truncate(size int64) (err error) {
|
||
|
if size < 0 {
|
||
|
return &ErrINVAL{"Truncate size", size}
|
||
|
}
|
||
|
|
||
|
f.size = size
|
||
|
return f.f.Truncate(size)
|
||
|
}
|
||
|
|
||
|
// WriteAt implements Filer.
|
||
|
func (f *OSFiler) WriteAt(b []byte, off int64) (n int, err error) {
|
||
|
if f.size < 0 { // boot
|
||
|
fi, err := os.Stat(f.f.Name())
|
||
|
if err != nil {
|
||
|
return 0, err
|
||
|
}
|
||
|
|
||
|
f.size = fi.Size()
|
||
|
}
|
||
|
f.size = mathutil.MaxInt64(f.size, int64(len(b))+off)
|
||
|
return f.f.WriteAt(b, off)
|
||
|
}
|