golang.org/x/exp@v0.0.0-20240506185415-9bf2ced13842/mmap/mmap_other.go (about) 1 // Copyright 2015 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build !linux && !windows && !darwin 6 7 // Package mmap provides a way to memory-map a file. 8 package mmap 9 10 import ( 11 "fmt" 12 "os" 13 ) 14 15 // ReaderAt reads a memory-mapped file. 16 // 17 // Like any io.ReaderAt, clients can execute parallel ReadAt calls, but it is 18 // not safe to call Close and reading methods concurrently. 19 type ReaderAt struct { 20 f *os.File 21 len int 22 } 23 24 // Close closes the reader. 25 func (r *ReaderAt) Close() error { 26 return r.f.Close() 27 } 28 29 // Len returns the length of the underlying memory-mapped file. 30 func (r *ReaderAt) Len() int { 31 return r.len 32 } 33 34 // At returns the byte at index i. 35 func (r *ReaderAt) At(i int) byte { 36 if i < 0 || r.len <= i { 37 panic("index out of range") 38 } 39 var b [1]byte 40 r.ReadAt(b[:], int64(i)) 41 return b[0] 42 } 43 44 // ReadAt implements the io.ReaderAt interface. 45 func (r *ReaderAt) ReadAt(p []byte, off int64) (int, error) { 46 return r.f.ReadAt(p, off) 47 } 48 49 // Open memory-maps the named file for reading. 50 func Open(filename string) (*ReaderAt, error) { 51 f, err := os.Open(filename) 52 if err != nil { 53 return nil, err 54 } 55 fi, err := f.Stat() 56 if err != nil { 57 f.Close() 58 return nil, err 59 } 60 61 size := fi.Size() 62 if size < 0 { 63 f.Close() 64 return nil, fmt.Errorf("mmap: file %q has negative size", filename) 65 } 66 if size != int64(int(size)) { 67 f.Close() 68 return nil, fmt.Errorf("mmap: file %q is too large", filename) 69 } 70 71 return &ReaderAt{ 72 f: f, 73 len: int(fi.Size()), 74 }, nil 75 }