1 /** 2 * D-LevelDB Slice 3 * 4 * Pointer Slice 5 * 6 * Copyright: Copyright © 2013 Byron Heads 7 * License: <a href="http://www.boost.org/LICENSE_1_0.txt">Boost License 1.0</a>. 8 * Authors: Byron Heads 9 */ 10 /* Copyright © 2013 Byron Heads 11 * Distributed under the Boost Software License, Version 1.0. 12 * (See accompanying file LICENSE_1_0.txt or copy at 13 * http://www.boost.org/LICENSE_1_0.txt) 14 */ 15 module leveldb.slice; 16 17 private: 18 import leveldb.exceptions; 19 import deimos.leveldb.leveldb : leveldb_free; 20 import std.traits : isBasicType, isArray, isPointer, ForeachType; 21 22 23 package: 24 25 template isPrimitive(T) 26 { 27 static if(isBasicType!T || (isArray!T && isBasicType!(ForeachType!T))) { 28 enum isPrimitive = true; 29 } else { 30 enum isPrimitive = false; 31 } 32 } 33 34 /** 35 * Holds a pointer returned from leveldb, or passed to leveldb. 36 * 37 * Leveldb memory is freed on destruction. 38 */ 39 struct Slice 40 { 41 private: 42 void* _ptr; // the pointer 43 size_t len; // the size of the data block 44 bool free = false; // should this block be freed by leveldb_free 45 46 this(void* p, size_t l, bool f = false) 47 { 48 debug { 49 import std.stdio; 50 writeln("length: ", l); 51 } 52 _ptr = p; 53 len = l; 54 free = f; 55 } 56 57 public: 58 59 /// Calles free on leveldb raw memory 60 ~this() 61 { 62 if(free) { 63 leveldb_free(_ptr); 64 } 65 } 66 67 68 /// length or size of slice 69 @property 70 size_t size() inout pure nothrow 71 { 72 return len; 73 } 74 75 /// Get slice pointer 76 @property 77 const(char)* cptr() inout pure nothrow 78 { 79 return cast(const(char)*)_ptr; 80 } 81 82 @property 83 inout(T) ptr(T)() inout pure nothrow 84 if(isPointer!T) 85 { 86 return cast(inout(T))_ptr; 87 } 88 89 /// Test is slice is valid 90 @property 91 bool ok() inout pure nothrow 92 { 93 return _ptr !is null; 94 } 95 96 /// Get slice as a data type 97 alias to = as; 98 @property 99 auto as(T)() 100 if(isPrimitive!T) 101 { 102 static if(isArray!T) { 103 return cast(T)(_ptr[0..size]).dup; 104 } else { 105 return *cast(T*)_ptr; 106 } 107 } 108 109 /// Slice casting 110 inout(T) opCast(T)() inout 111 { 112 return as!T; 113 } 114 115 // helper 116 auto static make(T)(T t) 117 if(isPrimitive!T) 118 out(slice){ 119 static if(isArray!T) { 120 assert(slice._ptr == t.ptr); 121 } else { 122 assert(slice._ptr == &t); 123 assert(slice.as!T == t); 124 } 125 } body { 126 debug { 127 import std.stdio; 128 writeln("T: ", T.stringof, " t: ", t); 129 } 130 static if(isArray!T) { 131 return Slice(cast(void*)t.ptr, t.length * (ForeachType!T).sizeof); 132 } else { 133 return Slice(cast(void*)&t, T.sizeof); 134 } 135 } 136 137 // helper 138 auto static make(T)(T t, size_t size, bool free = false) if(isPointer!T) { 139 debug { 140 import std.stdio; 141 writeln("T", T.stringof, " size: ", size, " free: ", free); 142 } 143 return Slice(cast(void*)t, size, free); 144 } 145 } 146