pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
plonk_BinaryFile.h
00001 /*
00002  -------------------------------------------------------------------------------
00003  This file is part of the Plink, Plonk, Plank libraries
00004   by Martin Robinson
00005  
00006  http://code.google.com/p/pl-nk/
00007  
00008  Copyright University of the West of England, Bristol 2011-14
00009  All rights reserved.
00010  
00011  Redistribution and use in source and binary forms, with or without
00012  modification, are permitted provided that the following conditions are met:
00013  
00014  * Redistributions of source code must retain the above copyright
00015    notice, this list of conditions and the following disclaimer.
00016  * Redistributions in binary form must reproduce the above copyright
00017    notice, this list of conditions and the following disclaimer in the
00018    documentation and/or other materials provided with the distribution.
00019  * Neither the name of University of the West of England, Bristol nor 
00020    the names of its contributors may be used to endorse or promote products
00021    derived from this software without specific prior written permission.
00022  
00023  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
00024  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00025  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 
00026  DISCLAIMED. IN NO EVENT SHALL UNIVERSITY OF THE WEST OF ENGLAND, BRISTOL BE 
00027  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
00028  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 
00029  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00030  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 
00031  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 
00032  OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
00033  
00034  This software makes use of third party libraries. For more information see:
00035  doc/license.txt included in the distribution.
00036  -------------------------------------------------------------------------------
00037  */
00038 
00039 #ifndef PLONK_BINARYFILE_H
00040 #define PLONK_BINARYFILE_H
00041 
00042 #include "../core/plonk_CoreForwardDeclarations.h"
00043 #include "plonk_FilesForwardDeclarations.h"
00044 #include "../core/plonk_SmartPointer.h"
00045 #include "../core/plonk_WeakPointer.h"
00046 #include "../core/plonk_SmartPointerContainer.h"
00047 #include "../containers/plonk_Text.h"
00048 
00049 class BinaryFileInternal : public SmartPointer
00050 {
00051 public:
00052     BinaryFileInternal() throw();
00053     BinaryFileInternal (Text const& path, 
00054                         const bool writable = false, 
00055                         const bool clearContents = false,
00056                         const bool bigEndian = false) throw();
00057     BinaryFileInternal (ByteArray const& bytes,
00058                         const bool writable = false) throw();
00059     BinaryFileInternal (FilePathArray const& fileArray, const int multiMode, const bool bigEndian) throw();
00060     BinaryFileInternal (BinaryFileQueue const& fileQueue, const bool bigEndian) throw();
00061     BinaryFileInternal (FilePathQueue const& fileQueue, const bool bigEndian) throw();
00062 
00063     explicit BinaryFileInternal (PlankFileRef fileRef) throw();
00064 
00065     ~BinaryFileInternal();
00066     
00067     void disownPeer (PlankFileRef fileRef) throw();
00068     
00069     static bool setupBytes (PlankFileRef p, ByteArray const& bytes, const bool writable) throw();
00070     static bool setupMulti (PlankFileRef p, FilePathArray const& fileArray, const int multiMode, const bool bigEndian, IntVariable* indexRef = 0) throw();
00071     static bool setupMulti (PlankFileRef p, BinaryFileQueue const& fileQueue, const bool bigEndian) throw();
00072     static bool setupMulti (PlankFileRef p, FilePathQueue const& fileQueue, const bool bigEndian) throw();
00073 
00074     static PlankResult dynamicMemoryOpenCallback (PlankFileRef p);
00075     static PlankResult dynamicMemoryCloseCallback (PlankFileRef p);
00076     static PlankResult dynamicMemoryClearCallback (PlankFileRef p);
00077     static PlankResult dynamicMemoryGetStatusCallback (PlankFileRef p, int type, int* status);
00078     static PlankResult dynamicMemoryReadCallback (PlankFileRef p, PlankP ptr, int maximumBytes, int* bytesReadOut);
00079     static PlankResult dynamicMemoryWriteCallback (PlankFileRef p, const void* data, const int maximumBytes);
00080     static PlankResult dynamicMemorySetPositionCallback (PlankFileRef p, PlankLL offset, int code);
00081     static PlankResult dynamicMemoryGetPositionCallback (PlankFileRef p, PlankLL* position);
00082     
00083     LongLong getPosition() const throw();
00084     void setPosition (const LongLong position) throw();
00085     
00086     void setEof() throw();
00087     bool isEof() const throw();
00088     
00089     bool isBigEndian() const throw();
00090     bool isLittleEndian() const throw();
00091     bool isNativeEndian() const throw();
00092     bool canRead() const throw();
00093     bool canWrite() const throw();
00094 
00095     int read (void* data, const int maximumBytes) throw();
00096     void read (char& value) throw();
00097         void read (short& value) throw();
00098     void read (int& value) throw();
00099     void read (Int24& value) throw();
00100     void read (LongLong& value) throw();
00101     void read (unsigned char& value) throw();
00102     void read (unsigned short& value) throw();
00103     void read (unsigned int& value) throw();
00104     void read (UnsignedLongLong& value) throw();
00105         void read (float& value) throw();
00106         void read (double& value) throw();
00107     
00108     template<class NumericalType>
00109     int read (NumericalArray<NumericalType>& array) throw();
00110     
00111     void write (void* data, const int maximumBytes) throw();
00112         void write (const char value) throw();
00113         void write (const short value) throw();
00114     void write (const int value) throw();
00115     void write (const Int24 value) throw();
00116     void write (const LongLong value) throw();
00117     void write (const unsigned char value) throw();
00118     void write (const unsigned short value) throw();
00119     void write (const unsigned int value) throw();
00120     void write (const UnsignedLongLong value) throw();
00121         void write (const float value) throw();
00122         void write (const double value) throw();
00123         
00124     template<class NumericalType>
00125     void write (NumericalArray<NumericalType> const& array) throw();
00126 
00127     ResultCode copy (BinaryFileInternal* source, const LongLong size) throw();
00128     
00129     friend class JSON;
00130     
00131     //private:
00132     inline PlankFileRef getPeerRef() { return static_cast<PlankFileRef> (&peer); }
00133     inline const PlankFileRef getPeerRef() const { return const_cast<const PlankFileRef> (&peer); }
00134     
00135 private:
00136     PlankFile peer;
00137 };
00138 
00139 template<class NumericalType>
00140 int BinaryFileInternal::read (NumericalArray<NumericalType>& array) throw()
00141 {
00142     int bytesRead;
00143     plonk_assert (array.length() > 0);
00144     
00145     ResultCode result = pl_File_Read (getPeerRef(), 
00146                                       reinterpret_cast<void*> (array.getArray()), 
00147                                       sizeof (NumericalType) * array.length()
00148                                       &bytesRead);
00149     
00150     plonk_assert (result == PlankResult_OK || result == PlankResult_FileEOF); 
00151     
00152     if (sizeof (NumericalType) > 1 && !isNativeEndian())
00153         Endian::swap (array);
00154     
00155 #ifndef PLONK_DEBUG
00156     (void)result;
00157 #endif    
00158     
00159     return bytesRead;
00160 }
00161 
00162 template<class NumericalType>
00163 void BinaryFileInternal::write (NumericalArray<NumericalType> const& array) throw()
00164 {
00165     const int length = array.length();
00166     
00167     if (length > 0)
00168     {        
00169         if (isNativeEndian() || (sizeof(NumericalType) == 1))
00170         {
00171             ResultCode result = pl_File_Write (getPeerRef(), 
00172                                                reinterpret_cast<const void*> (array.getArray()), 
00173                                                sizeof (NumericalType) * length);
00174             
00175             plonk_assert (result == PlankResult_OK);
00176             
00177 #ifndef PLONK_DEBUG
00178             (void)result;
00179 #endif
00180         }
00181         else
00182         {
00183             const NumericalType* rawArray = array.getArray();
00184             
00185             for (int i = 0; i < length; ++i)
00186                 write (rawArray[i]);
00187         }        
00188     }
00189 }
00190 
00191 
00195 class BinaryFile : public SmartPointerContainer<BinaryFileInternal>
00196 {
00197 public:
00198     typedef BinaryFileInternal                      Internal;
00199     typedef SmartPointerContainer<Internal>         Base;
00200     typedef WeakPointerContainer<BinaryFile>        Weak;
00201     
00202     enum MultiFileTypes
00203     {
00204         MultiFileUnknown = PLANKMULITFILE_MODE_UNKNOWN,
00205         MultiFileArraySequenceOnce = PLANKMULITFILE_MODE_ARRAYSEQUENCEONCE,
00206         MultiFileArraySequenceLoop = PLANKMULITFILE_MODE_ARRAYSEQUENCELOOP,
00207         MultiFileArrayRandom = PLANKMULITFILE_MODE_ARRAYRANDOM,
00208         MultiFileArrayRandomNoRepeat = PLANKMULITFILE_MODE_ARRAYRANDOMNOREPEAT,
00209         MultiFileArrayIndexRef = PLANKMULITFILE_MODE_ARRAYINDEXREF,
00210         MultiFileQueue = PLANKMULITFILE_MODE_QUEUE,
00211         MultiFileCustom = PLANKMULITFILE_MODE_CUSTOM
00212     };
00213     
00216     BinaryFile() throw()
00217     :   Base (new Internal())
00218     {
00219     }
00220     
00227         BinaryFile (Text const& path, const bool bigEndian = PLANK_BIGENDIAN) throw()
00228         :       Base (new Internal (path, false, false, bigEndian))
00229         {
00230         }
00231     
00244     BinaryFile (Text const& path, const bool writable, const bool clearContents, const bool bigEndian = PLANK_BIGENDIAN) throw()
00245         :       Base (new Internal (path, writable, clearContents, bigEndian))
00246         {
00247         }        
00248     
00255     BinaryFile (const char* path, const bool bigEndian = PLANK_BIGENDIAN) throw()
00256         :       Base (new Internal (path, false, false, bigEndian))
00257         {
00258         }
00259         
00272     BinaryFile (const char* path, const bool writable, const bool clearContents, const bool bigEndian = PLANK_BIGENDIAN) throw()
00273         :       Base (new Internal (path, writable, clearContents, bigEndian))
00274         {
00275         }
00276     
00278     BinaryFile (ByteArray const& bytes, const bool writable = false) throw()
00279         :       Base (new Internal (bytes, writable))
00280     {
00281     }
00282     
00285     BinaryFile (FilePathArray const& fileArray, const int multiMode, const bool bigEndian = PLANK_BIGENDIAN) throw()
00286     :   Base (new Internal (fileArray, multiMode, bigEndian))
00287     {
00288     }
00289     
00290     BinaryFile (BinaryFileQueue const& fileQueue, const bool bigEndian = PLANK_BIGENDIAN) throw()
00291     :   Base (new Internal (fileQueue, bigEndian))
00292     {
00293     }
00294 
00296     explicit BinaryFile (Internal* internalToUse) throw() 
00297         :       Base (internalToUse)
00298         {
00299         }
00300     
00302     explicit BinaryFile (PlankFileRef fileRef) throw()
00303         :       Base (new Internal (fileRef))
00304         {
00305         }
00306 
00309     BinaryFile (BinaryFile const& copy) throw()
00310     :   Base (static_cast<Base const&> (copy))
00311     {
00312     }
00313     
00315     BinaryFile& operator= (BinaryFile const& other) throw()
00316         {
00317                 if (this != &other)
00318             this->setInternal (other.getInternal());
00319         
00320         return *this;
00321         }
00322         
00326     static BinaryFile fromWeak (Weak const& weak) throw()
00327     {
00328         return weak.fromWeak();
00329     }    
00330         
00332     inline LongLong getPosition() throw()
00333     {
00334         return getInternal()->getPosition();
00335     }
00336     
00339     inline void setPosition (const LongLong position) throw()
00340     {
00341         getInternal()->setPosition (position);
00342     }
00343 
00345     inline void setEof() throw()
00346     {
00347         getInternal()->setEof();
00348     }    
00349     
00351         inline bool isEof() const throw()
00352         {
00353                 return getInternal()->isEof();
00354         }
00355     
00356     inline bool canRead() const throw()
00357     {
00358         return getInternal()->canRead();
00359     }
00360 
00361     inline bool canWrite() const throw()
00362     {
00363         return getInternal()->canWrite();
00364     }
00365 
00370     template<class ValueType>
00371     inline ValueType read() throw()
00372     {
00373         ValueType value;
00374         getInternal()->read (value);
00375         return value;
00376     }    
00377     
00382     template<class ValueType>
00383     void read (ValueType& value) throw()
00384     {
00385         getInternal()->read (value);
00386     }    
00387     
00388     template<class NumericalType>
00389     int read (NumericalArray<NumericalType>& array) throw()
00390     {
00391         return getInternal()->read (array);
00392     }
00393     
00394     template<class NumericalType>
00395     void write (NumericalArray<NumericalType> const& array) throw()
00396     {
00397         return getInternal()->write (array);
00398     }
00399     
00400     void disownPeer (PlankFileRef otherFile) throw()
00401     {
00402         getInternal()->disownPeer (otherFile);
00403     }
00404 
00409     template<class ValueType>
00410     void write (const ValueType value) throw()
00411     {
00412         getInternal()->write (value);
00413     }
00414     
00415     ResultCode copy (BinaryFile const& source, const LongLong size = 0) throw()
00416     {
00417         return getInternal()->copy (source.getInternal(), size);
00418     }
00419                 
00423     static inline int chunkID (const char* const fourCharCode) throw()
00424     {
00425         plonk_assert (Text (fourCharCode).length() == 4);
00426         return pl_FourCharCode (fourCharCode);
00427     }
00428     
00429     PLONK_OBJECTARROWOPERATOR(BinaryFile);
00430 
00431 };
00432 
00433 
00434 
00435 #endif // PLONK_BINARYFILE_H
 All Classes Functions Typedefs Enumerations Enumerator Properties