-
Notifications
You must be signed in to change notification settings - Fork 102
/
Copy pathmmap_windows.go
72 lines (63 loc) · 1.8 KB
/
mmap_windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//go:build windows && !appengine
// +build windows,!appengine
package maxminddb
import (
"errors"
"os"
"unsafe"
"golang.org/x/sys/windows"
)
// mmap maps a file into memory and returns a byte slice.
func mmap(fd int, length int) ([]byte, error) {
// Create a file mapping
handle, err := windows.CreateFileMapping(
windows.Handle(fd),
nil,
windows.PAGE_READONLY,
0,
0,
nil,
)
if err != nil {
return nil, os.NewSyscallError("CreateFileMapping", err)
}
defer windows.CloseHandle(handle)
// Map the file into memory
addrUintptr, err := windows.MapViewOfFile(
handle,
windows.FILE_MAP_READ,
0,
0,
0,
)
if err != nil {
return nil, os.NewSyscallError("MapViewOfFile", err)
}
// When there's not enough address space for the whole file (e.g. large
// files on 32-bit systems), MapViewOfFile may return a partial mapping.
// Query the region size and fail on partial mappings.
var info windows.MemoryBasicInformation
if err := windows.VirtualQuery(addrUintptr, &info, unsafe.Sizeof(info)); err != nil {
_ = windows.UnmapViewOfFile(addrUintptr)
return nil, os.NewSyscallError("VirtualQuery", err)
}
if info.RegionSize < uintptr(length) {
_ = windows.UnmapViewOfFile(addrUintptr)
return nil, errors.New("file too large")
}
// Workaround for unsafeptr check in go vet, see
// https://github.com/golang/go/issues/58625
addr := *(*unsafe.Pointer)(unsafe.Pointer(&addrUintptr))
return unsafe.Slice((*byte)(addr), length), nil
}
// munmap unmaps a memory-mapped file and releases associated resources.
func munmap(b []byte) error {
// Convert slice to base address and length
data := unsafe.SliceData(b)
addr := uintptr(unsafe.Pointer(data))
// Unmap the memory
if err := windows.UnmapViewOfFile(addr); err != nil {
return os.NewSyscallError("UnmapViewOfFile", err)
}
return nil
}