diff options
Diffstat (limited to 'vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go')
-rw-r--r-- | vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go | 157 |
1 files changed, 0 insertions, 157 deletions
diff --git a/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go b/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go deleted file mode 100644 index 39493df99..000000000 --- a/vendor/github.com/ncruces/go-sqlite3/vfs/cksm.go +++ /dev/null @@ -1,157 +0,0 @@ -package vfs - -import ( - "bytes" - "context" - _ "embed" - "encoding/binary" - "strconv" - - "github.com/tetratelabs/wazero/api" - - "github.com/ncruces/go-sqlite3/internal/util" - "github.com/ncruces/go-sqlite3/util/sql3util" -) - -func cksmWrapFile(name *Filename, flags OpenFlag, file File) File { - // Checksum only main databases and WALs. - if flags&(OPEN_MAIN_DB|OPEN_WAL) == 0 { - return file - } - - cksm := cksmFile{File: file} - - if flags&OPEN_WAL != 0 { - main, _ := name.DatabaseFile().(cksmFile) - cksm.cksmFlags = main.cksmFlags - } else { - cksm.cksmFlags = new(cksmFlags) - cksm.isDB = true - } - - return cksm -} - -type cksmFile struct { - File - *cksmFlags - isDB bool -} - -type cksmFlags struct { - computeCksm bool - verifyCksm bool - inCkpt bool - pageSize int -} - -func (c cksmFile) ReadAt(p []byte, off int64) (n int, err error) { - n, err = c.File.ReadAt(p, off) - - // SQLite is reading the header of a database file. - if c.isDB && off == 0 && len(p) >= 100 && - bytes.HasPrefix(p, []byte("SQLite format 3\000")) { - c.init(p) - } - - // Verify checksums. - if c.verifyCksm && !c.inCkpt && len(p) == c.pageSize { - cksm1 := cksmCompute(p[:len(p)-8]) - cksm2 := *(*[8]byte)(p[len(p)-8:]) - if cksm1 != cksm2 { - return 0, _IOERR_DATA - } - } - return n, err -} - -func (c cksmFile) WriteAt(p []byte, off int64) (n int, err error) { - // SQLite is writing the first page of a database file. - if c.isDB && off == 0 && len(p) >= 100 && - bytes.HasPrefix(p, []byte("SQLite format 3\000")) { - c.init(p) - } - - // Compute checksums. - if c.computeCksm && !c.inCkpt && len(p) == c.pageSize { - *(*[8]byte)(p[len(p)-8:]) = cksmCompute(p[:len(p)-8]) - } - - return c.File.WriteAt(p, off) -} - -func (c cksmFile) Pragma(name string, value string) (string, error) { - switch name { - case "checksum_verification": - b, ok := sql3util.ParseBool(value) - if ok { - c.verifyCksm = b && c.computeCksm - } - if !c.verifyCksm { - return "0", nil - } - return "1", nil - - case "page_size": - if c.computeCksm { - // Do not allow page size changes on a checksum database. - return strconv.Itoa(c.pageSize), nil - } - } - return "", _NOTFOUND -} - -func (c cksmFile) DeviceCharacteristics() DeviceCharacteristic { - ret := c.File.DeviceCharacteristics() - if c.verifyCksm { - ret &^= IOCAP_SUBPAGE_READ - } - return ret -} - -func (c cksmFile) fileControl(ctx context.Context, mod api.Module, op _FcntlOpcode, pArg ptr_t) _ErrorCode { - switch op { - case _FCNTL_CKPT_START: - c.inCkpt = true - case _FCNTL_CKPT_DONE: - c.inCkpt = false - } - if rc := vfsFileControlImpl(ctx, mod, c, op, pArg); rc != _NOTFOUND { - return rc - } - return vfsFileControlImpl(ctx, mod, c.File, op, pArg) -} - -func (f *cksmFlags) init(header []byte) { - f.pageSize = 256 * int(binary.LittleEndian.Uint16(header[16:18])) - if r := header[20] == 8; r != f.computeCksm { - f.computeCksm = r - f.verifyCksm = r - } -} - -func cksmCompute(a []byte) (cksm [8]byte) { - var s1, s2 uint32 - for len(a) >= 8 { - s1 += binary.LittleEndian.Uint32(a[0:4]) + s2 - s2 += binary.LittleEndian.Uint32(a[4:8]) + s1 - a = a[8:] - } - if len(a) != 0 { - panic(util.AssertErr()) - } - binary.LittleEndian.PutUint32(cksm[0:4], s1) - binary.LittleEndian.PutUint32(cksm[4:8], s2) - return -} - -func (c cksmFile) SharedMemory() SharedMemory { - if f, ok := c.File.(FileSharedMemory); ok { - return f.SharedMemory() - } - return nil -} - -func (c cksmFile) Unwrap() File { - return c.File -} |