Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members | Related Pages

DeviceConduit.d

Go to the documentation of this file.
00001 /*******************************************************************************
00002 
00003         @file DeviceConduit.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; May 2005      
00034 
00035         @author         Kris 
00036 
00037 *******************************************************************************/
00038 
00039 module mango.io.DeviceConduit;
00040 
00041 private import  mango.sys.OS;
00042                 
00043 private import  mango.io.Buffer,
00044                 mango.io.Conduit,
00045                 mango.io.Exception;
00046 
00047 /*******************************************************************************
00048 
00049         Implements a means of reading and writing a file device. Conduits
00050         are the primary means of accessing external data, and are usually 
00051         routed through a Buffer. 
00052         
00053 *******************************************************************************/
00054 
00055 class DeviceConduit : Conduit
00056 {
00057         // expose conduit.copy() methods also
00058         alias Conduit.copy  copy;
00059         alias Conduit.read  read;
00060         alias Conduit.write write;
00061 
00062         /***********************************************************************
00063         
00064                 Construct a conduit with the given style and seek abilities. 
00065                 Conduits are either seekable or non-seekable.
00066 
00067         ***********************************************************************/
00068 
00069         this (ConduitStyle.Bits style, bool seekable)
00070         {
00071                 super (style, seekable);
00072         }
00073 
00074         /***********************************************************************
00075 
00076                 Create a FileConduit on the provided FileDevice. This is 
00077                 strictly for adapting existing devices such as Stdout and
00078                 friends.
00079         
00080         ***********************************************************************/
00081 
00082         this (FileDevice device)
00083         {
00084                 // say we're not seekable
00085                 super (device.style, false);
00086                 
00087                 // open the file
00088                 reopen (device);
00089         }    
00090 
00091         /***********************************************************************
00092                 
00093                 Callback to close the file. This is invoked from the Resource
00094                 base-class when the resource is being closed.
00095 
00096         ***********************************************************************/
00097 
00098         override void close ()
00099         {       
00100                 super.close ();
00101                 _close ();
00102         }    
00103                    
00104         /***********************************************************************
00105         
00106                 Make a reasonable attempt to clean up
00107 
00108         ***********************************************************************/
00109 
00110         ~this ()
00111         {
00112                 if (! isHalting)
00113                       _close ();
00114         }
00115                    
00116         /***********************************************************************
00117         
00118                 Return a preferred size for buffering conduit I/O
00119 
00120         ***********************************************************************/
00121 
00122         uint bufferSize ()
00123         {
00124                 return 1024 * 16;
00125         }
00126                      
00127         /***********************************************************************
00128 
00129                 Return the name of this device
00130 
00131         ***********************************************************************/
00132 
00133         protected char[] getName()
00134         {
00135                 return "<device>";
00136         }
00137 
00138 
00139         /***********************************************************************
00140 
00141                 Windows-specific code
00142         
00143         ***********************************************************************/
00144 
00145         version (Win32)
00146         {
00147                 protected HANDLE handle;
00148 
00149                 /***************************************************************
00150 
00151                         Throw an IOException noting the last error
00152 
00153                 ***************************************************************/
00154 
00155                 final void error ()
00156                 {
00157                         throw new IOException (getName() ~ ": " ~ OS.error);
00158                 }
00159 
00160                 /***************************************************************
00161 
00162                         Return the device handle
00163 
00164                 ***************************************************************/
00165 
00166                 package final HANDLE getHandle ()
00167                 {
00168                         return handle;
00169                 }
00170 
00171                 /***************************************************************
00172 
00173                         Gain access to the standard IO handles (console etc).
00174 
00175                 ***************************************************************/
00176 
00177                 protected void reopen (FileDevice device)
00178                 {
00179                         handle = cast(HANDLE) device.id;
00180                 }
00181 
00182                 /***************************************************************
00183 
00184                         Close the underlying file
00185 
00186                 ***************************************************************/
00187 
00188                 protected void _close ()
00189                 {
00190                         if (handle)
00191                             if (! CloseHandle (handle))
00192                                   error ();
00193                         handle = null;
00194                 }
00195 
00196                 /***************************************************************
00197 
00198                         Read a chunk of bytes from the file into the provided
00199                         array (typically that belonging to an IBuffer)
00200 
00201                 ***************************************************************/
00202 
00203                 protected override uint reader (void[] dst)
00204                 {
00205                         DWORD read;
00206                         void *p = dst;
00207 
00208                         if (! ReadFile (handle, p, dst.length, &read, null))
00209                               error ();
00210 
00211                         if (read == 0 && dst.length > 0)
00212                             return Eof;
00213                         return read;
00214                 }
00215 
00216                 /***************************************************************
00217 
00218                         Write a chunk of bytes to the file from the provided
00219                         array (typically that belonging to an IBuffer)
00220 
00221                 ***************************************************************/
00222 
00223                 protected override uint writer (void[] src)
00224                 {
00225                         DWORD written;
00226 
00227                         if (! WriteFile (handle, src, src.length, &written, null))
00228                               error ();
00229 
00230                         return written;
00231                 }
00232         }
00233 
00234 
00235         /***********************************************************************
00236 
00237                  Unix-specific code.
00238         
00239         ***********************************************************************/
00240 
00241         version (Posix)
00242         {
00243                 protected int handle = -1;
00244 
00245                 /***************************************************************
00246 
00247                         Throw an IOException noting the last error
00248 
00249                 ***************************************************************/
00250 
00251                 final void error ()
00252                 {
00253                         throw new IOException (getName() ~ ": " ~
00254                                                OS.error);
00255                 }
00256 
00257                 /***************************************************************
00258 
00259                         Return the device handle
00260 
00261                 ***************************************************************/
00262 
00263                 package final int getHandle ()
00264                 {
00265                         return handle;
00266                 }
00267 
00268                 /***************************************************************
00269 
00270                         Gain access to the standard IO handles (console etc).
00271 
00272                 ***************************************************************/
00273 
00274                 protected void reopen (FileDevice device)
00275                 {
00276                         handle = device.id;
00277                 }
00278 
00279                 /***************************************************************
00280 
00281                         Close the underlying file
00282 
00283                 ***************************************************************/
00284 
00285                 protected void _close ()
00286                 {
00287                         if (handle)
00288                             if (posix.close (handle) == -1)
00289                                 error ();
00290                         handle = 0;
00291                 }
00292 
00293                 /***************************************************************
00294 
00295                         Read a chunk of bytes from the file into the provided
00296                         array (typically that belonging to an IBuffer)
00297 
00298                 ***************************************************************/
00299 
00300                 protected override uint reader (void[] dst)
00301                 {
00302                         int read = posix.read (handle, dst, dst.length);
00303                         if (read == -1)
00304                             error ();
00305                         else
00306                            if (read == 0 && dst.length > 0)
00307                                return Eof;
00308                         return read;
00309                 }
00310 
00311                 /***************************************************************
00312 
00313                         Write a chunk of bytes to the file from the provided
00314                         array (typically that belonging to an IBuffer)
00315 
00316                 ***************************************************************/
00317 
00318                 protected override uint writer (void[] src)
00319                 {
00320                         int written = posix.write (handle, src, src.length);
00321                         if (written == -1)
00322                             error ();
00323                         return written;
00324                 }
00325         }
00326 }
00327 
00328 
00329 /*******************************************************************************
00330 
00331         Class used to wrap an existing file-oriented handle, such as Stdout
00332         and its cohorts.
00333 
00334 *******************************************************************************/
00335 
00336 class FileDevice 
00337 {
00338         private uint                    _id;
00339         private ConduitStyle.Bits       style;
00340 
00341         this (uint id, ConduitStyle.Bits style)
00342         {
00343                 this.style = style;
00344                 this._id = id;
00345         }
00346 
00347         int id()
00348         {
00349               return _id;  
00350         }
00351 }
00352 
00353 

Generated on Sat Dec 24 17:28:32 2005 for Mango by  doxygen 1.4.0