00001 /******************************************************************************* 00002 00003 @file CompositeWriter.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 00027 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 00028 00029 00030 @version Initial version, March 2004 00031 @author Kris 00032 00033 00034 *******************************************************************************/ 00035 00036 module mango.io.CompositeWriter; 00037 00038 private import mango.io.Exception; 00039 00040 public import mango.io.model.IBuffer, 00041 mango.io.model.IWriter; 00042 00043 00044 /******************************************************************************* 00045 00046 CompositeWriter brackets the writing of a data set, providing a 00047 basic framework that can be extended to support commit semantics. 00048 00049 The approach leverages the exisiting IWritable interface which, 00050 when implemented, exposes a class that writes a related set of 00051 data. For instance: 00052 00053 @code 00054 class Foo : IWritable 00055 { 00056 int x, 00057 y; 00058 char[] text; 00059 00060 void write (IWriter writer) 00061 { 00062 writer.put(x).put(y).put(text); 00063 } 00064 } 00065 @endcode 00066 00067 In the above example, we set up a class that implements IWritable 00068 (via the write() method). The class may write whatever it chooses, 00069 and may also invoke the write() method of other IWritable classes. 00070 Thus, the initial IWritable has control over a potential writable 00071 cluster, all of which is bracketed within the CompositeWriter. 00072 CompositeWriter could be extended to support commit and rollback 00073 semantics with little effort. 00074 00075 This particular CompositeWriter simply flushes the output buffer 00076 after a data-set has been written to it (option). In general usage 00077 this will be measurably more efficient than using a FlushBuffer. 00078 00079 Here's an expanded example of how this is intended to operate: 00080 00081 @code 00082 // define a serializable class (via interfaces) 00083 class Wumpus : IReadable, IWritable 00084 { 00085 private int x = 11, 00086 y = 112, 00087 z = 1024; 00088 00089 void write(IWriter writer) 00090 { 00091 writer.put(x).put(y).put(z); 00092 } 00093 00094 void read(IReader reader) 00095 { 00096 reader.get(x).get(y).get(z); 00097 } 00098 } 00099 00100 // construct a Wumpus 00101 Wumpus wumpus = new Wumpus(); 00102 00103 // open a file for IO 00104 FileConduit fc = new FileConduit ("random.bin", FileStyle.ReadWriteCreate); 00105 00106 // construct composite reader & writer upon the file, with binary IO 00107 CompositeWriter cw = new CompositeWriter (new Writer(fc)); 00108 CompositeReader cr = new CompositeReader (new Reader(fc)); 00109 00110 // write the Wumpus (and flush it) 00111 cw.put (wumpus); 00112 00113 // rewind to file start 00114 fc.seek (0); 00115 00116 // read Wumpus back again 00117 cr.get (wumpus); 00118 @endcode 00119 00120 *******************************************************************************/ 00121 00122 class CompositeWriter 00123 { 00124 private IWriter writer; 00125 00126 /*********************************************************************** 00127 00128 Construct a CompositeWriter with the provided IWriter. 00129 00130 ***********************************************************************/ 00131 00132 this (IWriter writer) 00133 in { 00134 assert (writer); 00135 } 00136 body 00137 { 00138 this.writer = writer; 00139 } 00140 00141 /*********************************************************************** 00142 00143 Write the source 00144 00145 ***********************************************************************/ 00146 00147 CompositeWriter put (IWritable source) 00148 in { 00149 assert (source); 00150 } 00151 body 00152 { 00153 // write the contents 00154 source.write (writer); 00155 return this; 00156 } 00157 00158 /*********************************************************************** 00159 00160 Flush the output 00161 00162 ***********************************************************************/ 00163 00164 void flush () 00165 { 00166 // flush data-set to conduit 00167 writer.flush (); 00168 } 00169 } 00170