summaryrefslogtreecommitdiffstats
path: root/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/manual_test_program.go56
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_other.go76
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_test.go34
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_unix.go117
-rw-r--r--dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_windows.go123
5 files changed, 406 insertions, 0 deletions
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/manual_test_program.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/manual_test_program.go
new file mode 100644
index 0000000..a1ab17b
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/manual_test_program.go
@@ -0,0 +1,56 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build ignore
+// +build ignore
+
+//
+// This build tag means that "go build" does not build this file. Use "go run
+// manual_test_program.go" to run it.
+//
+// You will also need to change "debug = false" to "debug = true" in mmap_*.go.
+
+package main
+
+import (
+ "log"
+ "math/rand"
+ "time"
+
+ "golang.org/x/exp/mmap"
+)
+
+var garbage []byte
+
+func main() {
+ const filename = "manual_test_program.go"
+
+ for _, explicitClose := range []bool{false, true} {
+ r, err := mmap.Open(filename)
+ if err != nil {
+ log.Fatalf("Open: %v", err)
+ }
+ if explicitClose {
+ r.Close()
+ } else {
+ // Leak the *mmap.ReaderAt returned by mmap.Open. The finalizer
+ // should pick it up, if finalizers run at all.
+ }
+ }
+
+ println("Finished all explicit Close calls.")
+ println("Creating and collecting garbage.")
+ println("Look for two munmap log messages.")
+ println("Hit Ctrl-C to exit.")
+
+ rng := rand.New(rand.NewSource(1))
+ now := time.Now()
+ for {
+ garbage = make([]byte, rng.Intn(1<<20))
+ if time.Since(now) > 1*time.Second {
+ now = time.Now()
+ print(".")
+ }
+ }
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_other.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_other.go
new file mode 100644
index 0000000..1e7b948
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_other.go
@@ -0,0 +1,76 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !linux && !windows && !darwin
+// +build !linux,!windows,!darwin
+
+// Package mmap provides a way to memory-map a file.
+package mmap
+
+import (
+ "fmt"
+ "os"
+)
+
+// ReaderAt reads a memory-mapped file.
+//
+// Like any io.ReaderAt, clients can execute parallel ReadAt calls, but it is
+// not safe to call Close and reading methods concurrently.
+type ReaderAt struct {
+ f *os.File
+ len int
+}
+
+// Close closes the reader.
+func (r *ReaderAt) Close() error {
+ return r.f.Close()
+}
+
+// Len returns the length of the underlying memory-mapped file.
+func (r *ReaderAt) Len() int {
+ return r.len
+}
+
+// At returns the byte at index i.
+func (r *ReaderAt) At(i int) byte {
+ if i < 0 || r.len <= i {
+ panic("index out of range")
+ }
+ var b [1]byte
+ r.ReadAt(b[:], int64(i))
+ return b[0]
+}
+
+// ReadAt implements the io.ReaderAt interface.
+func (r *ReaderAt) ReadAt(p []byte, off int64) (int, error) {
+ return r.f.ReadAt(p, off)
+}
+
+// Open memory-maps the named file for reading.
+func Open(filename string) (*ReaderAt, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ fi, err := f.Stat()
+ if err != nil {
+ f.Close()
+ return nil, err
+ }
+
+ size := fi.Size()
+ if size < 0 {
+ f.Close()
+ return nil, fmt.Errorf("mmap: file %q has negative size", filename)
+ }
+ if size != int64(int(size)) {
+ f.Close()
+ return nil, fmt.Errorf("mmap: file %q is too large", filename)
+ }
+
+ return &ReaderAt{
+ f: f,
+ len: int(fi.Size()),
+ }, nil
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_test.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_test.go
new file mode 100644
index 0000000..797fc5f
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_test.go
@@ -0,0 +1,34 @@
+// Copyright 2015 The Go 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 mmap
+
+import (
+ "bytes"
+ "io"
+ "io/ioutil"
+ "testing"
+)
+
+func TestOpen(t *testing.T) {
+ const filename = "mmap_test.go"
+ r, err := Open(filename)
+ if err != nil {
+ t.Fatalf("Open: %v", err)
+ }
+ got := make([]byte, r.Len())
+ if _, err := r.ReadAt(got, 0); err != nil && err != io.EOF {
+ t.Fatalf("ReadAt: %v", err)
+ }
+ want, err := ioutil.ReadFile(filename)
+ if err != nil {
+ t.Fatalf("ioutil.ReadFile: %v", err)
+ }
+ if len(got) != len(want) {
+ t.Fatalf("got %d bytes, want %d", len(got), len(want))
+ }
+ if !bytes.Equal(got, want) {
+ t.Fatalf("\ngot %q\nwant %q", string(got), string(want))
+ }
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_unix.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_unix.go
new file mode 100644
index 0000000..ae12499
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_unix.go
@@ -0,0 +1,117 @@
+// Copyright 2015 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux || darwin
+// +build linux darwin
+
+// Package mmap provides a way to memory-map a file.
+package mmap
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "syscall"
+)
+
+// debug is whether to print debugging messages for manual testing.
+//
+// The runtime.SetFinalizer documentation says that, "The finalizer for x is
+// scheduled to run at some arbitrary time after x becomes unreachable. There
+// is no guarantee that finalizers will run before a program exits", so we
+// cannot automatically test that the finalizer runs. Instead, set this to true
+// when running the manual test.
+const debug = false
+
+// ReaderAt reads a memory-mapped file.
+//
+// Like any io.ReaderAt, clients can execute parallel ReadAt calls, but it is
+// not safe to call Close and reading methods concurrently.
+type ReaderAt struct {
+ data []byte
+}
+
+// Close closes the reader.
+func (r *ReaderAt) Close() error {
+ if r.data == nil {
+ return nil
+ }
+ data := r.data
+ r.data = nil
+ if debug {
+ var p *byte
+ if len(data) != 0 {
+ p = &data[0]
+ }
+ println("munmap", r, p)
+ }
+ runtime.SetFinalizer(r, nil)
+ return syscall.Munmap(data)
+}
+
+// Len returns the length of the underlying memory-mapped file.
+func (r *ReaderAt) Len() int {
+ return len(r.data)
+}
+
+// At returns the byte at index i.
+func (r *ReaderAt) At(i int) byte {
+ return r.data[i]
+}
+
+// ReadAt implements the io.ReaderAt interface.
+func (r *ReaderAt) ReadAt(p []byte, off int64) (int, error) {
+ if r.data == nil {
+ return 0, errors.New("mmap: closed")
+ }
+ if off < 0 || int64(len(r.data)) < off {
+ return 0, fmt.Errorf("mmap: invalid ReadAt offset %d", off)
+ }
+ n := copy(p, r.data[off:])
+ if n < len(p) {
+ return n, io.EOF
+ }
+ return n, nil
+}
+
+// Open memory-maps the named file for reading.
+func Open(filename string) (*ReaderAt, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ fi, err := f.Stat()
+ if err != nil {
+ return nil, err
+ }
+
+ size := fi.Size()
+ if size == 0 {
+ return &ReaderAt{}, nil
+ }
+ if size < 0 {
+ return nil, fmt.Errorf("mmap: file %q has negative size", filename)
+ }
+ if size != int64(int(size)) {
+ return nil, fmt.Errorf("mmap: file %q is too large", filename)
+ }
+
+ data, err := syscall.Mmap(int(f.Fd()), 0, int(size), syscall.PROT_READ, syscall.MAP_SHARED)
+ if err != nil {
+ return nil, err
+ }
+ r := &ReaderAt{data}
+ if debug {
+ var p *byte
+ if len(data) != 0 {
+ p = &data[0]
+ }
+ println("mmap", r, p)
+ }
+ runtime.SetFinalizer(r, (*ReaderAt).Close)
+ return r, nil
+}
diff --git a/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_windows.go b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_windows.go
new file mode 100644
index 0000000..d898828
--- /dev/null
+++ b/dependencies/pkg/mod/golang.org/x/exp@v0.0.0-20220613132600-b0d781184e0d/mmap/mmap_windows.go
@@ -0,0 +1,123 @@
+// Copyright 2015 The Go 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 mmap provides a way to memory-map a file.
+package mmap
+
+import (
+ "errors"
+ "fmt"
+ "io"
+ "os"
+ "runtime"
+ "syscall"
+ "unsafe"
+)
+
+// debug is whether to print debugging messages for manual testing.
+//
+// The runtime.SetFinalizer documentation says that, "The finalizer for x is
+// scheduled to run at some arbitrary time after x becomes unreachable. There
+// is no guarantee that finalizers will run before a program exits", so we
+// cannot automatically test that the finalizer runs. Instead, set this to true
+// when running the manual test.
+const debug = false
+
+// ReaderAt reads a memory-mapped file.
+//
+// Like any io.ReaderAt, clients can execute parallel ReadAt calls, but it is
+// not safe to call Close and reading methods concurrently.
+type ReaderAt struct {
+ data []byte
+}
+
+// Close closes the reader.
+func (r *ReaderAt) Close() error {
+ if r.data == nil {
+ return nil
+ }
+ data := r.data
+ r.data = nil
+ if debug {
+ var p *byte
+ if len(data) != 0 {
+ p = &data[0]
+ }
+ println("munmap", r, p)
+ }
+ runtime.SetFinalizer(r, nil)
+ return syscall.UnmapViewOfFile(uintptr(unsafe.Pointer(&data[0])))
+}
+
+// Len returns the length of the underlying memory-mapped file.
+func (r *ReaderAt) Len() int {
+ return len(r.data)
+}
+
+// At returns the byte at index i.
+func (r *ReaderAt) At(i int) byte {
+ return r.data[i]
+}
+
+// ReadAt implements the io.ReaderAt interface.
+func (r *ReaderAt) ReadAt(p []byte, off int64) (int, error) {
+ if r.data == nil {
+ return 0, errors.New("mmap: closed")
+ }
+ if off < 0 || int64(len(r.data)) < off {
+ return 0, fmt.Errorf("mmap: invalid ReadAt offset %d", off)
+ }
+ n := copy(p, r.data[off:])
+ if n < len(p) {
+ return n, io.EOF
+ }
+ return n, nil
+}
+
+// Open memory-maps the named file for reading.
+func Open(filename string) (*ReaderAt, error) {
+ f, err := os.Open(filename)
+ if err != nil {
+ return nil, err
+ }
+ defer f.Close()
+ fi, err := f.Stat()
+ if err != nil {
+ return nil, err
+ }
+
+ size := fi.Size()
+ if size == 0 {
+ return &ReaderAt{}, nil
+ }
+ if size < 0 {
+ return nil, fmt.Errorf("mmap: file %q has negative size", filename)
+ }
+ if size != int64(int(size)) {
+ return nil, fmt.Errorf("mmap: file %q is too large", filename)
+ }
+
+ low, high := uint32(size), uint32(size>>32)
+ fmap, err := syscall.CreateFileMapping(syscall.Handle(f.Fd()), nil, syscall.PAGE_READONLY, high, low, nil)
+ if err != nil {
+ return nil, err
+ }
+ defer syscall.CloseHandle(fmap)
+ ptr, err := syscall.MapViewOfFile(fmap, syscall.FILE_MAP_READ, 0, 0, uintptr(size))
+ if err != nil {
+ return nil, err
+ }
+ data := unsafe.Slice((*byte)(unsafe.Pointer(ptr)), size)
+
+ r := &ReaderAt{data: data}
+ if debug {
+ var p *byte
+ if len(data) != 0 {
+ p = &data[0]
+ }
+ println("mmap", r, p)
+ }
+ runtime.SetFinalizer(r, (*ReaderAt).Close)
+ return r, nil
+}