Add Read/Write to the MMap interface
This commit is contained in:
parent
944e036611
commit
5b46d990a2
@ -53,6 +53,9 @@ type MMap interface {
|
|||||||
FileSystemName() string
|
FileSystemName() string
|
||||||
Stat() (fs.FileInfo, error)
|
Stat() (fs.FileInfo, error)
|
||||||
Flush() error
|
Flush() error
|
||||||
|
Seek(offset int64, whence int) (ret int64, err error)
|
||||||
|
Read(b []byte) (n int, err error)
|
||||||
|
Write(b []byte) (n int, err error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type AccessFlags int
|
type AccessFlags int
|
||||||
@ -106,9 +109,11 @@ func truncate_or_unlink(ans *os.File, size uint64) (err error) {
|
|||||||
|
|
||||||
const NUM_BYTES_FOR_SIZE = 4
|
const NUM_BYTES_FOR_SIZE = 4
|
||||||
|
|
||||||
|
var ErrRegionTooSmall = errors.New("mmaped region too small")
|
||||||
|
|
||||||
func WriteWithSize(self MMap, b []byte, at int) error {
|
func WriteWithSize(self MMap, b []byte, at int) error {
|
||||||
if len(self.Slice()) < at+len(b)+NUM_BYTES_FOR_SIZE {
|
if len(self.Slice()) < at+len(b)+NUM_BYTES_FOR_SIZE {
|
||||||
return io.ErrShortBuffer
|
return ErrRegionTooSmall
|
||||||
}
|
}
|
||||||
binary.BigEndian.PutUint32(self.Slice()[at:], uint32(len(b)))
|
binary.BigEndian.PutUint32(self.Slice()[at:], uint32(len(b)))
|
||||||
copy(self.Slice()[at+NUM_BYTES_FOR_SIZE:], b)
|
copy(self.Slice()[at+NUM_BYTES_FOR_SIZE:], b)
|
||||||
@ -118,12 +123,12 @@ func WriteWithSize(self MMap, b []byte, at int) error {
|
|||||||
func ReadWithSize(self MMap, at int) ([]byte, error) {
|
func ReadWithSize(self MMap, at int) ([]byte, error) {
|
||||||
s := self.Slice()[at:]
|
s := self.Slice()[at:]
|
||||||
if len(s) < NUM_BYTES_FOR_SIZE {
|
if len(s) < NUM_BYTES_FOR_SIZE {
|
||||||
return nil, io.ErrShortBuffer
|
return nil, ErrRegionTooSmall
|
||||||
}
|
}
|
||||||
size := int(binary.BigEndian.Uint32(self.Slice()[at : at+NUM_BYTES_FOR_SIZE]))
|
size := int(binary.BigEndian.Uint32(self.Slice()[at : at+NUM_BYTES_FOR_SIZE]))
|
||||||
s = s[NUM_BYTES_FOR_SIZE:]
|
s = s[NUM_BYTES_FOR_SIZE:]
|
||||||
if len(s) < size {
|
if len(s) < size {
|
||||||
return nil, io.ErrShortBuffer
|
return nil, ErrRegionTooSmall
|
||||||
}
|
}
|
||||||
return s[:size], nil
|
return s[:size], nil
|
||||||
}
|
}
|
||||||
@ -158,6 +163,41 @@ func ReadWithSizeAndUnlink(name string, file_callback ...func(fs.FileInfo) error
|
|||||||
return ans, nil
|
return ans, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func Read(self MMap, b []byte) (n int, err error) {
|
||||||
|
pos, _ := self.Seek(0, io.SeekCurrent)
|
||||||
|
if pos < 0 {
|
||||||
|
pos = 0
|
||||||
|
}
|
||||||
|
s := self.Slice()
|
||||||
|
sz := int64(len(s))
|
||||||
|
if pos >= sz {
|
||||||
|
return 0, io.EOF
|
||||||
|
}
|
||||||
|
n = copy(b, s[pos:])
|
||||||
|
self.Seek(int64(n), io.SeekCurrent)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func Write(self MMap, b []byte) (n int, err error) {
|
||||||
|
if len(b) == 0 {
|
||||||
|
return 0, nil
|
||||||
|
}
|
||||||
|
pos, _ := self.Seek(0, io.SeekCurrent)
|
||||||
|
if pos < 0 {
|
||||||
|
pos = 0
|
||||||
|
}
|
||||||
|
s := self.Slice()
|
||||||
|
if pos >= int64(len(s)) {
|
||||||
|
return 0, io.ErrShortWrite
|
||||||
|
}
|
||||||
|
n = copy(s[pos:], b)
|
||||||
|
self.Seek(int64(n), io.SeekCurrent)
|
||||||
|
if n < len(b) {
|
||||||
|
return n, io.ErrShortWrite
|
||||||
|
}
|
||||||
|
return n, nil
|
||||||
|
}
|
||||||
|
|
||||||
func test_integration_with_python(args []string) (rc int, err error) {
|
func test_integration_with_python(args []string) (rc int, err error) {
|
||||||
switch args[0] {
|
switch args[0] {
|
||||||
default:
|
default:
|
||||||
|
|||||||
@ -7,6 +7,7 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -21,6 +22,7 @@ var _ = fmt.Print
|
|||||||
|
|
||||||
type file_based_mmap struct {
|
type file_based_mmap struct {
|
||||||
f *os.File
|
f *os.File
|
||||||
|
pos int64
|
||||||
region []byte
|
region []byte
|
||||||
unlinked bool
|
unlinked bool
|
||||||
special_name string
|
special_name string
|
||||||
@ -42,6 +44,26 @@ func file_mmap(f *os.File, size uint64, access AccessFlags, truncate bool, speci
|
|||||||
return &file_based_mmap{f: f, region: region, special_name: special_name}, nil
|
return &file_based_mmap{f: f, region: region, special_name: special_name}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *file_based_mmap) Seek(offset int64, whence int) (ret int64, err error) {
|
||||||
|
switch whence {
|
||||||
|
case io.SeekStart:
|
||||||
|
self.pos = offset
|
||||||
|
case os.SEEK_END:
|
||||||
|
self.pos = int64(len(self.region)) + offset
|
||||||
|
case os.SEEK_CUR:
|
||||||
|
self.pos += offset
|
||||||
|
}
|
||||||
|
return self.pos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *file_based_mmap) Read(b []byte) (n int, err error) {
|
||||||
|
return Read(self, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *file_based_mmap) Write(b []byte) (n int, err error) {
|
||||||
|
return Write(self, b)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *file_based_mmap) Stat() (fs.FileInfo, error) {
|
func (self *file_based_mmap) Stat() (fs.FileInfo, error) {
|
||||||
return self.f.Stat()
|
return self.f.Stat()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,6 +6,7 @@ package shm
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io"
|
||||||
"io/fs"
|
"io/fs"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
@ -65,6 +66,7 @@ func shm_open(name string, flags, perm int) (ans *os.File, err error) {
|
|||||||
|
|
||||||
type syscall_based_mmap struct {
|
type syscall_based_mmap struct {
|
||||||
f *os.File
|
f *os.File
|
||||||
|
pos int64
|
||||||
region []byte
|
region []byte
|
||||||
unlinked bool
|
unlinked bool
|
||||||
}
|
}
|
||||||
@ -117,6 +119,26 @@ func (self *syscall_based_mmap) Unlink() (err error) {
|
|||||||
return shm_unlink(self.Name())
|
return shm_unlink(self.Name())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *syscall_based_mmap) Seek(offset int64, whence int) (ret int64, err error) {
|
||||||
|
switch whence {
|
||||||
|
case io.SeekStart:
|
||||||
|
self.pos = offset
|
||||||
|
case os.SEEK_END:
|
||||||
|
self.pos = int64(len(self.region)) + offset
|
||||||
|
case os.SEEK_CUR:
|
||||||
|
self.pos += offset
|
||||||
|
}
|
||||||
|
return self.pos, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *syscall_based_mmap) Read(b []byte) (n int, err error) {
|
||||||
|
return Read(self, b)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self *syscall_based_mmap) Write(b []byte) (n int, err error) {
|
||||||
|
return Write(self, b)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *syscall_based_mmap) IsFileSystemBacked() bool { return false }
|
func (self *syscall_based_mmap) IsFileSystemBacked() bool { return false }
|
||||||
func (self *syscall_based_mmap) FileSystemName() string { return "" }
|
func (self *syscall_based_mmap) FileSystemName() string { return "" }
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user