mirror of
https://github.com/ncruces/go-sqlite3.git
synced 2026-01-12 05:59:14 +00:00
Refactor.
This commit is contained in:
20
vfs.go
20
vfs.go
@@ -133,6 +133,9 @@ func vfsDelete(ctx context.Context, mod api.Module, pVfs, zPath, syncDir uint32)
|
||||
}
|
||||
|
||||
func vfsAccess(ctx context.Context, mod api.Module, pVfs, zPath, flags, pResOut uint32) uint32 {
|
||||
// Consider using [syscall.Access] for [ACCESS_READWRITE]/[ACCESS_READ]
|
||||
// (as the Unix VFS does).
|
||||
|
||||
path := getString(mod.Memory(), zPath, _MAX_PATHNAME)
|
||||
fi, err := os.Stat(path)
|
||||
|
||||
@@ -192,11 +195,11 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zName, pFile, flags, pOu
|
||||
return uint32(CANTOPEN)
|
||||
}
|
||||
|
||||
id, err := vfsGetFileID(file)
|
||||
id, err := vfsGetOpenFileID(file)
|
||||
if err != nil {
|
||||
return uint32(CANTOPEN)
|
||||
}
|
||||
vfsSetFileData(mod, pFile, id, _NO_LOCK)
|
||||
vfsFilePtr{mod, pFile}.SetID(id).SetLock(_NO_LOCK)
|
||||
|
||||
if pOutFlags == 0 {
|
||||
return _OK
|
||||
@@ -208,7 +211,8 @@ func vfsOpen(ctx context.Context, mod api.Module, pVfs, zName, pFile, flags, pOu
|
||||
}
|
||||
|
||||
func vfsClose(ctx context.Context, mod api.Module, pFile uint32) uint32 {
|
||||
err := vfsReleaseFile(mod, pFile)
|
||||
id := vfsFilePtr{mod, pFile}.ID()
|
||||
err := vfsReleaseOpenFile(id)
|
||||
if err != nil {
|
||||
return uint32(IOERR_CLOSE)
|
||||
}
|
||||
@@ -221,7 +225,7 @@ func vfsRead(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOfs
|
||||
panic(rangeErr)
|
||||
}
|
||||
|
||||
file := vfsGetOSFile(mod, pFile)
|
||||
file := vfsFilePtr{mod, pFile}.OSFile()
|
||||
n, err := file.ReadAt(mem, int64(iOfst))
|
||||
if n == int(iAmt) {
|
||||
return _OK
|
||||
@@ -241,7 +245,7 @@ func vfsWrite(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOf
|
||||
panic(rangeErr)
|
||||
}
|
||||
|
||||
file := vfsGetOSFile(mod, pFile)
|
||||
file := vfsFilePtr{mod, pFile}.OSFile()
|
||||
_, err := file.WriteAt(mem, int64(iOfst))
|
||||
if err != nil {
|
||||
return uint32(IOERR_WRITE)
|
||||
@@ -250,7 +254,7 @@ func vfsWrite(ctx context.Context, mod api.Module, pFile, zBuf, iAmt uint32, iOf
|
||||
}
|
||||
|
||||
func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64) uint32 {
|
||||
file := vfsGetOSFile(mod, pFile)
|
||||
file := vfsFilePtr{mod, pFile}.OSFile()
|
||||
err := file.Truncate(int64(nByte))
|
||||
if err != nil {
|
||||
return uint32(IOERR_TRUNCATE)
|
||||
@@ -259,7 +263,7 @@ func vfsTruncate(ctx context.Context, mod api.Module, pFile uint32, nByte uint64
|
||||
}
|
||||
|
||||
func vfsSync(ctx context.Context, mod api.Module, pFile, flags uint32) uint32 {
|
||||
file := vfsGetOSFile(mod, pFile)
|
||||
file := vfsFilePtr{mod, pFile}.OSFile()
|
||||
err := file.Sync()
|
||||
if err != nil {
|
||||
return uint32(IOERR_FSYNC)
|
||||
@@ -270,7 +274,7 @@ func vfsSync(ctx context.Context, mod api.Module, pFile, flags uint32) uint32 {
|
||||
func vfsFileSize(ctx context.Context, mod api.Module, pFile, pSize uint32) uint32 {
|
||||
// This uses [file.Seek] because we don't care about the offset for reading/writing.
|
||||
// But consider using [file.Stat] instead (as other VFSes do).
|
||||
file := vfsGetOSFile(mod, pFile)
|
||||
file := vfsFilePtr{mod, pFile}.OSFile()
|
||||
off, err := file.Seek(0, io.SeekEnd)
|
||||
if err != nil {
|
||||
return uint32(IOERR_SEEK)
|
||||
|
||||
65
vfs_files.go
65
vfs_files.go
@@ -15,18 +15,18 @@ type vfsOpenFile struct {
|
||||
}
|
||||
|
||||
var (
|
||||
vfsMutex sync.Mutex
|
||||
vfsOpenFiles []*vfsOpenFile
|
||||
vfsOpenFiles []*vfsOpenFile
|
||||
vfsOpenFilesMtx sync.Mutex
|
||||
)
|
||||
|
||||
func vfsGetFileID(file *os.File) (uint32, error) {
|
||||
func vfsGetOpenFileID(file *os.File) (uint32, error) {
|
||||
fi, err := file.Stat()
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
vfsMutex.Lock()
|
||||
defer vfsMutex.Unlock()
|
||||
vfsOpenFilesMtx.Lock()
|
||||
defer vfsOpenFilesMtx.Unlock()
|
||||
|
||||
// Reuse an already opened file.
|
||||
for id, of := range vfsOpenFiles {
|
||||
@@ -62,14 +62,9 @@ func vfsGetFileID(file *os.File) (uint32, error) {
|
||||
return uint32(id), nil
|
||||
}
|
||||
|
||||
func vfsReleaseFile(mod api.Module, pFile uint32) error {
|
||||
id, ok := mod.Memory().ReadUint32Le(pFile + ptrSize)
|
||||
if !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
|
||||
vfsMutex.Lock()
|
||||
defer vfsMutex.Unlock()
|
||||
func vfsReleaseOpenFile(id uint32) error {
|
||||
vfsOpenFilesMtx.Lock()
|
||||
defer vfsOpenFilesMtx.Unlock()
|
||||
|
||||
of := vfsOpenFiles[id]
|
||||
if of.nref--; of.nref > 0 {
|
||||
@@ -80,32 +75,46 @@ func vfsReleaseFile(mod api.Module, pFile uint32) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func vfsGetOSFile(mod api.Module, pFile uint32) *os.File {
|
||||
id, ok := mod.Memory().ReadUint32Le(pFile + ptrSize)
|
||||
if !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
type vfsFilePtr struct {
|
||||
api.Module
|
||||
ptr uint32
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) OSFile() *os.File {
|
||||
id := p.ID()
|
||||
vfsOpenFilesMtx.Lock()
|
||||
defer vfsOpenFilesMtx.Unlock()
|
||||
return vfsOpenFiles[id].file
|
||||
}
|
||||
|
||||
func vfsGetFileData(mod api.Module, pFile uint32) (id, lock uint32) {
|
||||
var ok bool
|
||||
if id, ok = mod.Memory().ReadUint32Le(pFile + ptrSize); !ok {
|
||||
func (p vfsFilePtr) ID() uint32 {
|
||||
id, ok := p.Memory().ReadUint32Le(p.ptr + ptrSize)
|
||||
if !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
if lock, ok = mod.Memory().ReadUint32Le(pFile + 2*ptrSize); !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
return
|
||||
return id
|
||||
}
|
||||
|
||||
func vfsSetFileData(mod api.Module, pFile, id, lock uint32) {
|
||||
if ok := mod.Memory().WriteUint32Le(pFile+ptrSize, id); !ok {
|
||||
func (p vfsFilePtr) Lock() uint32 {
|
||||
lk, ok := p.Memory().ReadUint32Le(p.ptr + 2*ptrSize)
|
||||
if !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
if ok := mod.Memory().WriteUint32Le(pFile+2*ptrSize, lock); !ok {
|
||||
return lk
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) SetID(id uint32) vfsFilePtr {
|
||||
if ok := p.Memory().WriteUint32Le(p.ptr+ptrSize, id); !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func (p vfsFilePtr) SetLock(lock uint32) vfsFilePtr {
|
||||
if ok := p.Memory().WriteUint32Le(p.ptr+2*ptrSize, lock); !ok {
|
||||
panic(rangeErr)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
const (
|
||||
|
||||
Reference in New Issue
Block a user