D wrapper for raw data located in unmanaged memory.
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



Wrappers for raw data located in unmanaged memory.

Using the Data class will only place a small object in managed memory, keeping the actual data in unmanaged memory. A proxy class (DataBlock) is used to safely allow multiple references to the same block of unmanaged memory. When the DataBlock object is destroyed (either manually or by the garbage collector when there are no remaining Data references), the unmanaged memory is deallocated.

This has the following advantage over using managed memory:

  • Faster allocation and deallocation, since memory is requested from the OS directly as whole pages
  • Greatly reduced chance of memory leaks due to stray pointers
  • Overall improved GC performance due to reduced size of managed heap
  • Memory is immediately returned to the OS when data is deallocated
On the other hand, using Data has the following disadvantages:
  • This module is designed to store raw data which does not have any pointers. Storing objects containing pointers to managed memory is unsupported.
  • Accessing the contents of the Data object involves two levels of indirection. (This can be reduced to one level of indirection in future versions.)
  • Small objects may be stored inefficiently, as the module requests entire pages of memory from the OS. Considering allocating one large object and use slices (Data instances) for individual objects.
Future directions (TODO):
  • Cache Data.block.contents to reduce the level of indirection to 1
  • Port to D2
  • Templatize and enforce non-aliased types only
  • The Data class should be a struct

Vladimir Panteleev vladimir@thecybershadow.net

Public Domain

class Data;
The Data class represents a slice of a block of raw data. (The data itself is represented by a DataBlock class.) The Data class implements array-like operators and properties to allow comfortable usage of unmanaged memory.

this(void[] data);
Create new instance with a copy of the given data.

Data dup();
Create new instance with a copy of the referenced data.

this(size_t size = 0, size_t capacity = 0);
Create a new instance with given size/capacity. capacity defaults to size.

void clear();
Empty the Data instance. Does not actually destroy referenced data.

Be careful with assignments! Since Data is a class (reference type), assigning a Data to a Data will copy a reference to the DataBlock reference, so a .clear on one reference will affect both. To create a shallow copy, use the [] operator: a = b[];

void deleteContents();
Force immediate deallocation of referenced unmanaged data.

Unsafe! Use only when you know that you hold the only reference to the data.

Data opCat(void[] data);
Data opCat(Data data);
Data opCat_r(void[] data);
Create a new Data object containing a concatenation of this instance's contents and data.

Data opCatAssign(void[] data);
Data opCatAssign(Data data);
Data opCatAssign(ubyte value);
Append data to the current instance, in-place if possible. Note that unlike opCat (a ~ b), opCatAssign (a ~= b) will preallocate.

Following "legacy" D behavior, this will stomp on available memory in the same DataBlock that happens to be after this Data's end - that is, if you append to a slice of Data, the appended data will overwrite whatever was after the current instance's slice.

Data splice(size_t pos, void[] data);
Inserts data at pos. Will preallocate, like opCatAssign.

Data opSlice();
Duplicates the current instance, but does not actually copy the data.

Data opSlice(size_t x, size_t y);
Return a new Data object representing a slice of the current object's memory. Does not actually copy the data.

void[] contents();
Return the actual memory referenced by this instance.

This class has been designed to be "safe" for all cases when "contents" isn't accessed directly. Thus, direct access to "contents" should be avoided when possible.

Notes on working with contents directly:

  • Concatenations (the ~ operator, not appends) will work as expected, but the result will always be allocated in managed memory (use Data classes to avoid this)
  • Appends ( ~= ) to contents will cause undefined behavior - you should use Data classes instead
  • Be sure to keep the Data reference reachable by the GC - otherwise contents can become a dangling pointer!
void* ptr();
Return a pointer to the beginning of referenced data.

size_t length();
Return the length of referenced data.

void length(size_t value);
Resize, in-place when possible.

Data readData(string filename);
Read a file directly into a new Data block.

Page generated by Ddoc.