1package azblob
2
3import (
4	"os"
5	"reflect"
6	"syscall"
7	"unsafe"
8)
9
10type mmf []byte
11
12func newMMF(file *os.File, writable bool, offset int64, length int) (mmf, error) {
13	prot, access := uint32(syscall.PAGE_READONLY), uint32(syscall.FILE_MAP_READ) // Assume read-only
14	if writable {
15		prot, access = uint32(syscall.PAGE_READWRITE), uint32(syscall.FILE_MAP_WRITE)
16	}
17	hMMF, errno := syscall.CreateFileMapping(syscall.Handle(file.Fd()), nil, prot, uint32(int64(length)>>32), uint32(int64(length)&0xffffffff), nil)
18	if hMMF == 0 {
19		return nil, os.NewSyscallError("CreateFileMapping", errno)
20	}
21	defer syscall.CloseHandle(hMMF)
22	addr, errno := syscall.MapViewOfFile(hMMF, access, uint32(offset>>32), uint32(offset&0xffffffff), uintptr(length))
23	m := mmf{}
24	h := (*reflect.SliceHeader)(unsafe.Pointer(&m))
25	h.Data = addr
26	h.Len = length
27	h.Cap = h.Len
28	return m, nil
29}
30
31func (m *mmf) unmap() {
32	addr := uintptr(unsafe.Pointer(&(([]byte)(*m)[0])))
33	*m = mmf{}
34	err := syscall.UnmapViewOfFile(addr)
35	if err != nil {
36		panic("if we are unable to unmap the memory-mapped file, there is serious concern for memory corruption")
37	}
38}
39