00001 /******************************************************************************* 00002 00003 @file Writer.d 00004 00005 00006 Copyright (C) 2004 Kris Bell 00007 00008 This software is provided 'as-is', without any express or implied 00009 warranty. In no event will the authors be held liable for damages 00010 of any kind arising from the use of this software. 00011 00012 Permission is hereby granted to anyone to use this software for any 00013 purpose, including commercial applications, and to alter it and/or 00014 redistribute it freely, subject to the following restrictions: 00015 00016 1. The origin of this software must not be misrepresented; you must 00017 not claim that you wrote the original software. If you use this 00018 software in a product, an acknowledgment within documentation of 00019 said product would be appreciated but is not required. 00020 00021 2. Altered source versions must be plainly marked as such, and must 00022 not be misrepresented as being the original software. 00023 00024 3. This notice may not be removed or altered from any distribution 00025 of the source. 00026 00027 00028 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00029 00030 00031 @version Initial version, March 2004 00032 @author Kris 00033 00034 *******************************************************************************/ 00035 00036 module mango.io.Writer; 00037 00038 public import mango.io.AbstractWriter; 00039 00040 /******************************************************************************* 00041 00042 Binary data Writer. Writers provide the means to append formatted 00043 data to an IBuffer, and expose a convenient method of handling a 00044 variety of data types. In addition to writing native types such 00045 as integer and char[], writers also process any class which has 00046 implemented the IWritable interface (one method). 00047 00048 See AbstractWriter for usage examples. 00049 00050 *******************************************************************************/ 00051 00052 class Writer : AbstractWriter 00053 { 00054 typedef void function (void* dst, uint count) Mutator; 00055 00056 /*********************************************************************** 00057 00058 Construct a Writer upon the provided IBuffer. All formatted 00059 ouput will be appended to this buffer. 00060 00061 ***********************************************************************/ 00062 00063 this (IBuffer buffer) 00064 { 00065 super (buffer); 00066 00067 numeric.int1 = 00068 numeric.int8 = 00069 numeric.int8u = 00070 numeric.int16 = 00071 numeric.int16u = 00072 numeric.int32 = 00073 numeric.int32u = 00074 numeric.int64 = 00075 numeric.int64u = 00076 numeric.float32 = 00077 numeric.float64 = 00078 numeric.float80 = 00079 string.char8 = 00080 string.char16 = 00081 string.char32 = &write; 00082 } 00083 00084 /*********************************************************************** 00085 00086 Construct a Writer on the buffer associated with the given 00087 conduit. 00088 00089 ***********************************************************************/ 00090 00091 this (IConduit conduit) 00092 { 00093 this (conduit.createBuffer); 00094 } 00095 00096 /*********************************************************************** 00097 00098 ***********************************************************************/ 00099 00100 override char[] toString() 00101 { 00102 return "binary writer"; 00103 } 00104 00105 /*********************************************************************** 00106 00107 ***********************************************************************/ 00108 00109 final void write (void* src, uint count) 00110 { 00111 static void mutate (void* dst, uint count) 00112 { 00113 } 00114 00115 write (src, count, ~0, &mutate); 00116 } 00117 00118 /*********************************************************************** 00119 00120 ***********************************************************************/ 00121 00122 final void write (void* src, uint count, uint mask, Mutator mutate) 00123 { 00124 while (count) 00125 { 00126 // write as much space as there is available in the buffer 00127 uint available = buffer.writable() & mask; 00128 00129 // cap bytes written 00130 if (available > count) 00131 available = count; 00132 00133 // copy them over and adjust output 00134 mutate (buffer.put(src, available), available); 00135 00136 // bump counters; flush if we used all buffer space 00137 src += available; 00138 if (count -= available) 00139 if (buffer.getConduit) 00140 buffer.flush (); 00141 else 00142 if (! buffer.grow (count)) 00143 throw ovf; 00144 } 00145 } 00146 }