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 count, uint width, BufferDecoder decoder) 00087 { 00088 count *= width; 00089 void[] tmp = new void [count]; 00090 *x = tmp [0 .. decoder (tmp, count) / width]; 00091 } 00092 } 00093 00094 00095 /******************************************************************************* 00096 00097 *******************************************************************************/ 00098 00099 class NativeAllocator : SimpleAllocator 00100 { 00101 private bool aliased; 00102 00103 /*********************************************************************** 00104 00105 ***********************************************************************/ 00106 00107 this (bool aliased = true) 00108 { 00109 this.aliased = aliased; 00110 } 00111 00112 /*********************************************************************** 00113 00114 ***********************************************************************/ 00115 00116 bool isMutable (void* x) 00117 { 00118 return !aliased; 00119 } 00120 00121 /*********************************************************************** 00122 00123 ***********************************************************************/ 00124 00125 void allocate (void[]* x, uint count, uint width, BufferDecoder decoder) 00126 { 00127 void[] tmp = *x; 00128 count *= width; 00129 tmp.length = count; 00130 *x = tmp [0 .. decoder (tmp, count) / width]; 00131 } 00132 } 00133 00134 00135 /******************************************************************************* 00136 00137 *******************************************************************************/ 00138 00139 class BufferAllocator : SimpleAllocator 00140 { 00141 private BufferDecoder raw; 00142 private uint width; 00143 00144 /*********************************************************************** 00145 00146 ***********************************************************************/ 00147 00148 this (int width = 0) 00149 { 00150 this.width = width; 00151 } 00152 00153 /*********************************************************************** 00154 00155 ***********************************************************************/ 00156 00157 void reset () 00158 { 00159 IBuffer buffer = reader.getBuffer; 00160 00161 // ensure there's enough room for another record 00162 if (buffer.writable < width) 00163 buffer.compress (); 00164 } 00165 00166 /*********************************************************************** 00167 00168 ***********************************************************************/ 00169 00170 void bind (IReader reader) 00171 { 00172 raw = &(cast(Reader) reader).read; 00173 super.bind (reader); 00174 } 00175 00176 /*********************************************************************** 00177 00178 ***********************************************************************/ 00179 00180 bool isMutable (void* x) 00181 { 00182 void[] content = reader.getBuffer.getContent; 00183 return (x < content || x >= &content[length]); 00184 } 00185 00186 /*********************************************************************** 00187 00188 ***********************************************************************/ 00189 00190 void allocate (void[]* x, uint count, uint width, BufferDecoder decoder) 00191 { 00192 if (decoder == raw) 00193 *x = reader.getBuffer.get (count * width) [0..length / width]; 00194 else 00195 super.allocate (x, count, width, decoder); 00196 } 00197 } 00198 00199 00200 /******************************************************************************* 00201 00202 *******************************************************************************/ 00203 00204 class SliceAllocator : HeapSlice, IArrayAllocator 00205 { 00206 private IReader reader; 00207 00208 /*********************************************************************** 00209 00210 ***********************************************************************/ 00211 00212 this (int width) 00213 { 00214 super (width); 00215 } 00216 00217 /*********************************************************************** 00218 00219 ***********************************************************************/ 00220 00221 void reset () 00222 { 00223 super.reset (); 00224 } 00225 00226 /*********************************************************************** 00227 00228 ***********************************************************************/ 00229 00230 void bind (IReader reader) 00231 { 00232 this.reader = reader; 00233 } 00234 00235 /*********************************************************************** 00236 00237 ***********************************************************************/ 00238 00239 bool isMutable (void* x) 00240 { 00241 return false; 00242 } 00243 00244 /*********************************************************************** 00245 00246 ***********************************************************************/ 00247 00248 void allocate (void[]* x, uint count, uint width, BufferDecoder decoder) 00249 { 00250 count *= width; 00251 expand (count); 00252 void[] tmp = slice (count); 00253 *x = tmp [0 .. decoder (tmp, count) / width]; 00254 } 00255 } 00256 00257 00258 /******************************************************************************* 00259 00260 *******************************************************************************/ 00261 00262 class ReuseAllocator : SliceAllocator 00263 { 00264 private uint count; 00265 00266 /*********************************************************************** 00267 00268 ***********************************************************************/ 00269 00270 this (int width) 00271 { 00272 super (width); 00273 } 00274 00275 /*********************************************************************** 00276 00277 ***********************************************************************/ 00278 00279 void allocate (void[]* x, uint count, uint width, BufferDecoder decoder) 00280 { 00281 super.reset (); 00282 super.allocate (x, count, width, decoder); 00283 } 00284 00285 } 00286 00287