1 /**
2  * ae.sys.datamm
3  *
4  * License:
5  *   This Source Code Form is subject to the terms of
6  *   the Mozilla Public License, v. 2.0. If a copy of
7  *   the MPL was not distributed with this file, You
8  *   can obtain one at http://mozilla.org/MPL/2.0/.
9  *
10  * Authors:
11  *   Vladimir Panteleev <ae@cy.md>
12  */
13 
14 module ae.sys.datamm;
15 
16 import std.mmfile;
17 import std.typecons;
18 debug import std.stdio;
19 
20 import ae.sys.data;
21 
22 alias MmMode = MmFile.Mode; /// Convenience alias.
23 
24 // ************************************************************************
25 
26 /// `DataWrapper` implementation encapsulating a memory-mapped file.
27 /// When the last reference is released, the file is unmapped.
28 class MappedDataWrapper : DataWrapper
29 {
30 	typeof(scoped!MmFile(null)) mmFile; /// The `MmFile` object.
31 	void[] mappedData; /// View of the mapped file data.
32 
33 	this(string name, MmMode mode, size_t from, size_t to)
34 	{
35 		mmFile = scoped!MmFile(name, mode, 0, null);
36 		mappedData = (from || to) ? mmFile.Scoped_payload[from..(to ? to : mmFile.length)] : mmFile.Scoped_payload[];
37 
38 		debug(DATA_REFCOUNT) writefln("? -> %s [%s..%s]: Created MappedDataWrapper", cast(void*)this, contents.ptr, contents.ptr + contents.length);
39 	} ///
40 
41 	debug(DATA_REFCOUNT)
42 	~this()
43 	{
44 		writefln("? -> %s: Deleted MappedDataWrapper", cast(void*)this);
45 	}
46 
47 	override @property inout(void)[] contents() inout { return mappedData; } ///
48 	override @property size_t size() const { return mappedData.length; } ///
49 	override void setSize(size_t newSize) { assert(false, "Can't resize MappedDataWrapper"); } ///
50 	override @property size_t capacity() const { return mappedData.length; } ///
51 }
52 
53 /// Returns a `Data` viewing a mapped file.
54 auto mapFile(string name, MmMode mode, size_t from = 0, size_t to = 0)
55 {
56 	auto wrapper = unmanagedNew!MappedDataWrapper(name, mode, from, to);
57 	return Data(wrapper, mode != MmMode.read);
58 }