![]() |
pl-nk v0.4.5
Plonk|Plink|Plank are a set of cross-platform C/C++ frameworks for audio software development
|
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