00001 /******************************************************************************* 00002 00003 @file ArrayAllocator.d 00004 00005 Copyright (c) 2004 Kris Bell 00006 00007 This software is provided 'as-is', without any express or implied 00008 warranty. In no event will the authors be held liable for damages 00009 of any kind arising from the use of this software. 00010 00011 Permission is hereby granted to anyone to use this software for any 00012 purpose, including commercial applications, and to alter it and/or 00013 redistribute it freely, subject to the following restrictions: 00014 00015 1. The origin of this software must not be misrepresented; you must 00016 not claim that you wrote the original software. If you use this 00017 software in a product, an acknowledgment within documentation of 00018 said product would be appreciated but is not required. 00019 00020 2. Altered source versions must be plainly marked as such, and must 00021 not be misrepresented as being the original software. 00022 00023 3. This notice may not be removed or altered from any distribution 00024 of the source. 00025 00026 4. Derivative works are permitted, but they must carry this notice 00027 in full and credit the original source. 00028 00029 00030 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00031 00032 00033 @version Initial version, October 2004 00034 @author Kris 00035 00036 00037 *******************************************************************************/ 00038 00039 module mango.io.ArrayAllocator; 00040 00041 private import mango.io.Reader; 00042 00043 private import mango.utils.HeapSlice; 00044 00045 private import mango.io.model.IBuffer, 00046 mango.io.model.IReader; 00047 00048 /******************************************************************************* 00049 00050 *******************************************************************************/ 00051 00052 class SimpleAllocator : IArrayAllocator 00053 { 00054 private IReader reader; 00055 00056 /*********************************************************************** 00057 00058 ***********************************************************************/ 00059 00060 void reset () 00061 { 00062 } 00063 00064 /*********************************************************************** 00065 00066 ***********************************************************************/ 00067 00068 void bind (IReader reader) 00069 { 00070 this.reader = reader; 00071 } 00072 00073 /*********************************************************************** 00074 00075 ***********************************************************************/ 00076 00077 bool isMutable (void* x) 00078 { 00079 return true; 00080 } 00081 00082 /*********************************************************************** 00083 00084 ***********************************************************************/ 00085 00086 void allocate (void[]* x, uint bytes, uint width, uint type, IBuffer.Converter decoder) 00087 { 00088 void[] tmp = new void [bytes]; 00089 *x = tmp [0 .. decoder (tmp, bytes, type) / width]; 00090 } 00091 } 00092 00093 00094 /******************************************************************************* 00095 00096 *******************************************************************************/ 00097 00098 class NativeAllocator : SimpleAllocator 00099 { 00100 private bool aliased; 00101 00102 /*********************************************************************** 00103 00104 ***********************************************************************/ 00105 00106 this (bool aliased = true) 00107 { 00108 this.aliased = aliased; 00109 } 00110 00111 /*********************************************************************** 00112 00113 ***********************************************************************/ 00114 00115 bool isMutable (void* x) 00116 { 00117 return cast(bool) !aliased; 00118 } 00119 00120 /*********************************************************************** 00121 00122 ***********************************************************************/ 00123 00124 void allocate (void[]* x, uint bytes, uint width, uint type, IBuffer.Converter decoder) 00125 { 00126 void[] tmp = *x; 00127 tmp.length = bytes; 00128 *x = tmp [0 .. decoder (tmp, bytes, type) / width]; 00129 } 00130 } 00131 00132 00133 /******************************************************************************* 00134 00135 *******************************************************************************/ 00136 00137 class BufferAllocator : SimpleAllocator 00138 { 00139 private IBuffer.Converter raw; 00140 private uint width; 00141 00142 /*********************************************************************** 00143 00144 ***********************************************************************/ 00145 00146 this (int width = 0) 00147 { 00148 this.width = width; 00149 } 00150 00151 /*********************************************************************** 00152 00153 ***********************************************************************/ 00154 00155 void reset () 00156 { 00157 IBuffer buffer = reader.getBuffer; 00158 00159 // ensure there's enough room for another record 00160 if (buffer.writable < width) 00161 buffer.compress (); 00162 } 00163 00164 /*********************************************************************** 00165 00166 ***********************************************************************/ 00167 00168 void bind (IReader reader) 00169 { 00170 raw = &(cast(Reader) reader).read; 00171 super.bind (reader); 00172 } 00173 00174 /*********************************************************************** 00175 00176 ***********************************************************************/ 00177 00178 bool isMutable (void* x) 00179 { 00180 void[] content = reader.getBuffer.getContent; 00181 return cast(bool) (x < content || x >= (content.ptr + content.length)); 00182 } 00183 00184 /*********************************************************************** 00185 00186 ***********************************************************************/ 00187 00188 void allocate (void[]* x, uint bytes, uint width, uint type, IBuffer.Converter decoder) 00189 { 00190 if (decoder == raw) 00191 *x = reader.getBuffer.get (bytes) [0..length / width]; 00192 else 00193 super.allocate (x, bytes, width, type, decoder); 00194 } 00195 } 00196 00197 00198 /******************************************************************************* 00199 00200 *******************************************************************************/ 00201 00202 class SliceAllocator : HeapSlice, IArrayAllocator 00203 { 00204 private IReader reader; 00205 00206 /*********************************************************************** 00207 00208 ***********************************************************************/ 00209 00210 this (int width) 00211 { 00212 super (width); 00213 } 00214 00215 /*********************************************************************** 00216 00217 ***********************************************************************/ 00218 00219 void reset () 00220 { 00221 super.reset (); 00222 } 00223 00224 /*********************************************************************** 00225 00226 ***********************************************************************/ 00227 00228 void bind (IReader reader) 00229 { 00230 this.reader = reader; 00231 } 00232 00233 /*********************************************************************** 00234 00235 ***********************************************************************/ 00236 00237 bool isMutable (void* x) 00238 { 00239 return false; 00240 } 00241 00242 /*********************************************************************** 00243 00244 ***********************************************************************/ 00245 00246 void allocate (void[]* x, uint bytes, uint width, uint type, IBuffer.Converter decoder) 00247 { 00248 expand (bytes); 00249 void[] tmp = slice (bytes); 00250 *x = tmp [0 .. decoder (tmp, bytes, type) / width]; 00251 } 00252 } 00253 00254 00255 /******************************************************************************* 00256 00257 *******************************************************************************/ 00258 00259 class ReuseAllocator : SliceAllocator 00260 { 00261 private uint bytes; 00262 00263 /*********************************************************************** 00264 00265 ***********************************************************************/ 00266 00267 this (int width) 00268 { 00269 super (width); 00270 } 00271 00272 /*********************************************************************** 00273 00274 ***********************************************************************/ 00275 00276 void allocate (void[]* x, uint bytes, uint width, uint type, IBuffer.Converter decoder) 00277 { 00278 super.reset (); 00279 super.allocate (x, bytes, width, type, decoder); 00280 } 00281 00282 } 00283 00284