1 /****************************************************************************** 2 3 Collection of common utilities built on top of (de)serializer 4 5 Copyright: 6 Copyright (c) 2009-2016 dunnhumby Germany GmbH. 7 All rights reserved. 8 9 License: 10 Boost Software License Version 1.0. See LICENSE_BOOST.txt for details. 11 Alternatively, this file may be distributed under the terms of the Tango 12 3-Clause BSD License (see LICENSE_BSD.txt for details). 13 14 *******************************************************************************/ 15 16 module ocean.util.serialize.contiguous.Util; 17 18 19 import ocean.util.serialize.contiguous.Contiguous; 20 import ocean.util.serialize.contiguous.Serializer; 21 import ocean.util.serialize.contiguous.Deserializer; 22 23 import ocean.meta.types.Qualifiers; 24 import ocean.core.Test; 25 26 /******************************************************************************* 27 28 Copies struct data to other chunk and adjusts all internal pointers 29 to reference new buffer. 30 31 Params: 32 src = source struct (must be already contiguous) 33 dst = target struct chunk to copy data to. Will grow if current 34 length is smaller than src.data.length 35 36 Returns: 37 `dst` by value 38 39 Throws: 40 DeserializationException if src is not well-formed 41 42 /******************************************************************************/ 43 44 public Contiguous!(S) copy(S) ( in Contiguous!(S) src, ref Contiguous!(S) dst ) 45 { 46 // We have to cast away `const` here since the `ptr` 47 // method does not support it. We are not modifying 48 // anything so we do not break the `in` promise of 49 // the function signature. 50 if ((cast(Contiguous!(S)) src).ptr is null) 51 { 52 dst.reset(); 53 } 54 else 55 { 56 Deserializer.deserialize(src.data, dst); 57 } 58 59 return dst; 60 } 61 62 /******************************************************************************* 63 64 Deep copies any struct to its contiguous representation. Effectively does 65 serialization and deserialization in one go. 66 67 Params: 68 src = any struct instance 69 dst = contiguous struct to be filled with same values as src 70 71 Returns: 72 `dst` by value 73 74 *******************************************************************************/ 75 76 public Contiguous!(S) copy(S) ( ref const S src, ref Contiguous!(S) dst ) 77 { 78 Serializer.serialize(src, dst.data); 79 dst = Deserializer.deserialize!(S)(dst.data); 80 return dst; 81 } 82 83 unittest 84 { 85 struct Test 86 { 87 int[] arr; 88 } 89 90 Test t; t.arr = [ 1, 2, 3 ]; 91 92 Contiguous!(Test) one, two; 93 94 copy(t, one); 95 96 test!("==")(one.ptr.arr, t.arr); 97 one.enforceIntegrity(); 98 99 copy(one, two); 100 101 test!("==")(two.ptr.arr, t.arr); 102 two.enforceIntegrity(); 103 104 one.reset(); 105 test!("is")(one.ptr, null); 106 test!("!is")(two.ptr, null); 107 108 copy(one, two); 109 test!("is")(two.ptr, null); 110 } 111 112 unittest 113 { 114 struct Test 115 { 116 int[] arr; 117 } 118 119 const(Test) t = Test([ 1, 2, 3 ]); 120 Contiguous!(Test) dst; 121 copy(t, dst); 122 test!("==")(dst.ptr.arr, t.arr); 123 } 124 125 /******************************************************************************* 126 127 Simple wrapper on top of (de)serializer which allows to deep copy 128 a given struct by storing all indirections in contiguous buffer. Most 129 commonly used in tests - performance-critical applications should store 130 `Contiguous!(S)` instead and copy it as it is much faster. 131 132 Params: 133 dst = resizable buffer used to serialize `src` 134 src = struct to copy 135 136 Returns: 137 new struct instance stored in `dst` cast to S 138 139 *******************************************************************************/ 140 141 public S deepCopy (S) ( ref S src, ref void[] dst ) 142 { 143 Serializer.serialize(src, dst); 144 return *Deserializer.deserialize!(S)(dst).ptr; 145 } 146 147 /******************************************************************************* 148 149 Ditto, but allocates new buffer each time called 150 151 *******************************************************************************/ 152 153 public S deepCopy (S) ( ref S src ) 154 { 155 void[] empty; 156 return deepCopy(src, empty); 157 } 158 159 /// 160 unittest 161 { 162 struct Test 163 { 164 int[] arr; 165 } 166 167 auto s1 = Test([ 1, 2, 3 ]); 168 auto s2 = deepCopy(s1); 169 170 test!("==")(s1.arr, s2.arr); 171 test!("!is")(s1.arr.ptr, s2.arr.ptr); 172 }