src/stream/ZStream.h

00001 /*  @(#) $Id: ZStream.h,v 1.32 2006/07/23 21:58:20 agreen Exp $ */
00002 
00003 /* ------------------------------------------------------------
00004 Copyright (c) 2000 Andrew Green and Learning in Motion, Inc.
00005 http://www.zoolib.org
00006 
00007 Permission is hereby granted, free of charge, to any person obtaining a copy
00008 of this software and associated documentation files (the "Software"), to deal
00009 in the Software without restriction, including without limitation the rights
00010 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
00011 copies of the Software, and to permit persons to whom the Software is
00012 furnished to do so, subject to the following conditions:
00013 
00014 The above copyright notice and this permission notice shall be included in
00015 all copies or substantial portions of the Software.
00016 
00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
00020 COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
00021 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
00022 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00023 ------------------------------------------------------------ */
00024 
00025 #ifndef __ZStream__
00026 #define __ZStream__ 1
00027 #include "zconfig.h"
00028 
00029 #include "ZTypes.h"
00030 #include <stdexcept> // For std::range_error
00031 #include <string>
00032 
00033 class ZStreamR;
00034 class ZStreamW;
00035 
00038 void sCopyReadToWrite(const ZStreamR& iStreamR, const ZStreamW& iStreamW, uint64 iCount,
00039                                                 uint64* oCountRead, uint64* oCountWritten);
00040 
00041 // =================================================================================================
00042 #pragma mark -
00043 #pragma mark * ZStreamR
00044 
00046 
00047 class ZStreamR
00048         {
00049 protected:      //@{
00054         ZStreamR() {}
00055         ~ZStreamR() {}
00056         ZStreamR(const ZStreamR&) {}
00057         ZStreamR& operator=(const ZStreamR&) { return *this; }
00059 
00060 public:
00061         class ExEndOfStream;
00062         static void sThrowEndOfStream();
00063         //@{
00067         void Read(void* iDest, size_t iCount) const;
00068         void Read(void* iDest, size_t iCount, size_t* oCountRead) const;
00070 
00071         //@{
00075         void CopyAllTo(const ZStreamW& iStreamW) const;
00076         void CopyAllTo(const ZStreamW& iStreamW, uint64* oCountRead, uint64* oCountWritten) const;
00077 
00078         void CopyTo(const ZStreamW& iStreamW, uint64 iCount) const;
00079         void CopyTo(const ZStreamW& iStreamW, uint64 iCount,
00080                 uint64* oCountRead, uint64* oCountWritten) const;
00082 
00083         //@{
00087         void Skip(uint64 iCount) const;
00088         void Skip(uint64 iCount, uint64* oCountSkipped) const;
00089         void SkipAll() const;
00090         void SkipAll(uint64* oCountSkipped) const;
00092 
00093         //@{
00097         int8 ReadInt8() const;
00098         int16 ReadInt16() const;
00099         int32 ReadInt32() const;
00100         int64 ReadInt64() const;
00101         float ReadFloat() const;
00102         double ReadDouble() const;
00103 
00104         int16 ReadInt16LE() const;
00105         int32 ReadInt32LE() const;
00106         int64 ReadInt64LE() const;
00107         float ReadFloatLE() const;
00108         double ReadDoubleLE() const;
00109 
00110         bool ReadBool() const;
00111 
00112         uint8 ReadUInt8() const { return uint8(this->ReadInt8()); }
00113         uint16 ReadUInt16() const { return uint16(this->ReadInt16()); }
00114         uint32 ReadUInt32() const { return uint32(this->ReadInt32()); }
00115         uint64 ReadUInt64() const { return uint64(this->ReadInt64()); }
00116 
00117         uint16 ReadUInt16LE() const { return uint16(this->ReadInt16LE()); }
00118         uint32 ReadUInt32LE() const { return uint32(this->ReadInt32LE()); }
00119         uint64 ReadUInt64LE() const { return uint64(this->ReadInt64LE()); }
00121 
00122         //@{
00126         bool ReadByte(uint8& oResult) const;
00127         bool ReadChar(char& oResult) const;
00129 
00130         //@{
00133         std::string ReadString(size_t iSize) const;
00134         bool ReadString(size_t iSize, std::string& oString) const;
00136 
00137         //@{
00140         size_t CountReadable() const;
00142 
00143         //@{
00147         virtual void Imp_Read(void* iDest, size_t iCount, size_t* oCountRead) = 0;
00149 
00150         //@{
00155         virtual size_t Imp_CountReadable();
00156 
00157         virtual void Imp_CopyToDispatch(const ZStreamW& iStreamW, uint64 iCount,
00158                 uint64* oCountRead, uint64* oCountWritten);
00159 
00160         virtual void Imp_CopyTo(const ZStreamW& iStreamW, uint64 iCount,
00161                 uint64* oCountRead, uint64* oCountWritten);
00162 
00163         virtual void Imp_Skip(uint64 iCount, uint64* oCountSkipped);
00165 
00166 protected:
00167         static uint64 sDiffPosR(uint64 iSize, uint64 iPos)
00168                 { return iSize > iPos ? iSize - iPos : 0; }
00169 
00170         static size_t sClampedR(uint64 iCount)
00171                 {
00172                 if (sizeof(size_t) < sizeof(uint64))
00173                         return size_t(std::min(iCount, uint64(size_t(-1))));
00174                 else
00175                         return iCount;
00176                 }
00177         };
00178 
00180 inline void ZStreamR::Read(void* iDest, size_t iCount, size_t* oCountRead) const
00181         { const_cast<ZStreamR*>(this)->Imp_Read(iDest, iCount, oCountRead); }
00182 
00184 inline void ZStreamR::Skip(uint64 iCount, uint64* oCountSkipped) const
00185         { const_cast<ZStreamR*>(this)->Imp_Skip(iCount, oCountSkipped); }
00186 
00188 inline void ZStreamR::SkipAll() const
00189         { this->SkipAll(nil); }
00190 
00192 inline size_t ZStreamR::CountReadable() const
00193         { return const_cast<ZStreamR*>(this)->Imp_CountReadable(); }
00194 
00195 // =================================================================================================
00196 #pragma mark -
00197 #pragma mark * ZStreamR::ExEndOfStream
00198 
00199 class ZStreamR::ExEndOfStream : public std::range_error
00200         {
00201 public:
00202         ExEndOfStream();
00203         };
00204 
00205 // =================================================================================================
00206 #pragma mark -
00207 #pragma mark * ZStreamU
00208 
00210 
00211 class ZStreamU : public ZStreamR
00212         {
00213 public:
00214         void Unread() const;
00215 
00216         virtual void Imp_Unread() = 0;
00217         };
00218 
00221 inline void ZStreamU::Unread() const
00222         { const_cast<ZStreamU*>(this)->Imp_Unread(); }
00223 
00224 // =================================================================================================
00225 #pragma mark -
00226 #pragma mark * ZStreamRPos
00227 
00229 
00230 class ZStreamRPos : public ZStreamU
00231         {
00232 public:
00233         ZStreamRPos();
00234         //@{
00237         virtual size_t Imp_CountReadable();
00238         virtual void Imp_Skip(uint64 iCount, uint64* oCountSkipped);
00240 
00241         //@{
00244         virtual void Imp_Unread();
00246 
00247         //@{
00250         uint64 GetPosition() const;
00251         void SetPosition(uint64 iPosition) const;
00252 
00253         uint64 GetSize() const;
00255 
00256         //@{
00259         virtual uint64 Imp_GetPosition() = 0;
00260         virtual void Imp_SetPosition(uint64 iPosition) = 0;
00261 
00262         virtual uint64 Imp_GetSize() = 0;
00264         };
00265 
00267 inline uint64 ZStreamRPos::GetPosition() const
00268         { return const_cast<ZStreamRPos*>(this)->Imp_GetPosition(); }
00269 
00271 inline void ZStreamRPos::SetPosition(uint64 iPosition) const
00272         { const_cast<ZStreamRPos*>(this)->Imp_SetPosition(iPosition); }
00273 
00275 inline uint64 ZStreamRPos::GetSize() const
00276         { return const_cast<ZStreamRPos*>(this)->Imp_GetSize(); }
00277 
00278 // =================================================================================================
00279 #pragma mark -
00280 #pragma mark * ZStreamW
00281 
00283 
00284 class ZStreamW
00285         {
00286 protected:      //@{
00291         ZStreamW() {}
00292         ~ZStreamW() {}
00293         ZStreamW(const ZStreamW&) {}
00294         ZStreamW& operator=(const ZStreamW&) { return *this; }
00296 
00297 public:
00298         class ExEndOfStream;
00299         static void sThrowEndOfStream();
00300         //@{
00304         void Write(const void* iSource, size_t iCount) const;
00305         void Write(const void* iSource, size_t iCount, size_t* oCountWritten) const;
00307 
00308         //@{
00312         void CopyAllFrom(const ZStreamR& iStreamR) const;
00313         void CopyAllFrom(const ZStreamR& iStreamR, uint64* oCountRead, uint64* oCountWritten) const;
00314 
00315         void CopyFrom(const ZStreamR& iStreamR, uint64 iCount) const;
00316         void CopyFrom(const ZStreamR& iStreamR, uint64 iCount,
00317                 uint64* oCountRead, uint64* oCountWritten) const;
00319 
00320         //@{
00324         void WriteInt8(int8 iVal) const;
00325         void WriteInt16(int16 iVal) const;
00326         void WriteInt32(int32 iVal) const;
00327         void WriteInt64(int64 iVal) const;
00328         void WriteFloat(float iVal) const;
00329         void WriteDouble(double iVal) const;
00330 
00331         void WriteInt16LE(int16 iVal) const;
00332         void WriteInt32LE(int32 iVal) const;
00333         void WriteInt64LE(int64 iVal) const;
00334         void WriteFloatLE(float iVal) const;
00335         void WriteDoubleLE(double iVal) const;
00336 
00337         void WriteBool(bool iVal) const;
00338 
00339         void WriteUInt8(uint8 iVal) const { this->WriteInt8(int8(iVal)); }
00340         void WriteUInt16(uint16 iVal) const { this->WriteInt16(int16(iVal)); }
00341         void WriteUInt32(uint32 iVal) const { this->WriteInt32(int32(iVal)); }
00342         void WriteUInt64(uint64 iVal) const { this->WriteInt64(int64(iVal)); }
00343 
00344         void WriteUInt16LE(uint16 iVal) const { this->WriteInt16LE(int16(iVal)); }
00345         void WriteUInt32LE(uint32 iVal) const { this->WriteInt32LE(int32(iVal)); }
00346         void WriteUInt64LE(uint64 iVal) const { this->WriteInt64LE(int64(iVal)); }
00347 
00348         void WriteString(const char* iString) const;
00349         void WriteString(const std::string& iString) const;
00350 
00351         size_t Writef(const char* iString, ...) const;
00353 
00354         //@{
00358         bool WriteByte(uint8 iVal) const;
00360 
00361         //@{
00364         void Flush() const;
00366 
00367         //@{
00371         virtual void Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten) = 0;
00373 
00374         //@{
00379         virtual void Imp_CopyFromDispatch(const ZStreamR& iStreamR, uint64 iCount,
00380                 uint64* oCountRead, uint64* oCountWritten);
00381 
00382         virtual void Imp_CopyFrom(const ZStreamR& iStreamR, uint64 iCount,
00383                 uint64* oCountRead, uint64* oCountWritten);
00384 
00385         virtual void Imp_Flush();
00387 
00388 protected:
00389         static uint64 sDiffPosW(uint64 iSize, uint64 iPos)
00390                 { return iSize > iPos ? iSize - iPos : 0; }
00391         static size_t sClampedW(uint64 iCount)
00392                 {
00393                 if (sizeof(size_t) < sizeof(uint64))
00394                         return size_t(std::min(iCount, uint64(size_t(-1))));
00395                 else
00396                         return iCount;
00397                 }
00398         };
00399 
00400 // =================================================================================================
00401 #pragma mark -
00402 #pragma mark * ZStreamW::ExEndOfStream
00403 
00404 class ZStreamW::ExEndOfStream : public std::range_error
00405         {
00406 public:
00407         ExEndOfStream();
00408         };
00409 
00410 // =================================================================================================
00411 #pragma mark -
00412 #pragma mark * ZStreamWPos
00413 
00415 
00416 class ZStreamWPos : public ZStreamW
00417         {
00418 public:
00419         class ExBadSize;
00420         static void sThrowBadSize();
00421         //@{
00424         uint64 GetPosition() const;
00425         void SetPosition(uint64 iPosition) const;
00426 
00427         uint64 GetSize() const;
00428         void SetSize(uint64 iSize) const;
00429 
00430         void Truncate() const;
00432 
00433         //@{
00437         virtual uint64 Imp_GetPosition() = 0;
00438         virtual void Imp_SetPosition(uint64 iPosition) = 0;
00439 
00440         virtual uint64 Imp_GetSize() = 0;
00441         virtual void Imp_SetSize(uint64 iSize) = 0;
00443 
00444         //@{
00447         virtual void Imp_Truncate();
00449         };
00450 
00452 inline uint64 ZStreamWPos::GetPosition() const
00453         { return const_cast<ZStreamWPos*>(this)->Imp_GetPosition(); }
00454 
00457 inline void ZStreamWPos::SetPosition(uint64 iPosition) const
00458         { const_cast<ZStreamWPos*>(this)->Imp_SetPosition(iPosition); }
00459 
00461 inline uint64 ZStreamWPos::GetSize() const
00462         { return const_cast<ZStreamWPos*>(this)->Imp_GetSize(); }
00463 
00466 inline void ZStreamWPos::SetSize(uint64 iSize) const
00467         { return const_cast<ZStreamWPos*>(this)->Imp_SetSize(iSize); }
00468 
00470 inline void ZStreamWPos::Truncate() const
00471         { return const_cast<ZStreamWPos*>(this)->Imp_Truncate(); }
00472 
00473 // =================================================================================================
00474 #pragma mark -
00475 #pragma mark * ZStreamWPos::ExBadSize
00476 
00477 class ZStreamWPos::ExBadSize : public std::range_error
00478         {
00479 public:
00480         ExBadSize();
00481         };
00482 
00483 // =================================================================================================
00484 #pragma mark -
00485 #pragma mark * ZStreamRWPos
00486 
00488 
00489 class ZStreamRWPos : public ZStreamRPos, public ZStreamWPos
00490         {
00491 protected:      //@{
00494         ZStreamRWPos() {}
00495         ~ZStreamRWPos() {}
00496         ZStreamRWPos(const ZStreamRWPos&) {}
00497         ZStreamRWPos& operator=(const ZStreamRWPos&) { return *this; }
00499 
00500 public: //@{
00504         uint64 GetPosition() const;
00505         void SetPosition(uint64 iPosition) const;
00506 
00507         uint64 GetSize() const;
00508 
00509         virtual uint64 Imp_GetPosition() = 0;
00510         virtual void Imp_SetPosition(uint64 iPosition) = 0;
00511 
00512         virtual uint64 Imp_GetSize() = 0;
00514 
00515         //@{
00519         virtual void Imp_SetSize(uint64 iSize) = 0;
00521         };
00522 
00523 inline uint64 ZStreamRWPos::GetPosition() const
00524         { return const_cast<ZStreamRWPos*>(this)->Imp_GetPosition(); }
00525 
00526 inline void ZStreamRWPos::SetPosition(uint64 iPosition) const
00527         { const_cast<ZStreamRWPos*>(this)->Imp_SetPosition(iPosition); }
00528 
00529 inline uint64 ZStreamRWPos::GetSize() const
00530         { return const_cast<ZStreamRWPos*>(this)->Imp_GetSize(); }
00531 
00532 // =================================================================================================
00533 #pragma mark -
00534 #pragma mark * ZStreamU_Unreader
00535 
00537 
00538 class ZStreamU_Unreader : public ZStreamU
00539         {
00540 public:
00541         ZStreamU_Unreader(const ZStreamR& iStreamSource);
00542 
00543 // From ZStreamR
00544         virtual void Imp_Read(void* iDest, size_t iCount, size_t* oCountRead);
00545 
00546 // From ZStreamU
00547         virtual void Imp_Unread();
00548 
00549 private:
00550         const ZStreamR& fStreamSource;
00551         enum { eStateFresh, eStateNormal, eStateUnread, eStateHitEnd } fState;
00552         char fChar;
00553         };
00554 
00555 // =================================================================================================
00556 #pragma mark -
00557 #pragma mark * ZStreamR_Null
00558 
00560 
00561 class ZStreamR_Null : public ZStreamR
00562         {
00563 public:
00564         ZStreamR_Null();
00565         ~ZStreamR_Null();
00566 
00567 // From ZStreamR
00568         virtual void Imp_Read(void* iDest, size_t iCount, size_t* oCountRead);
00569 
00570         virtual void Imp_CopyToDispatch(const ZStreamW& iStreamW, uint64 iCount,
00571                 uint64* oCountRead, uint64* oCountWritten);
00572 
00573         virtual void Imp_CopyTo(const ZStreamW& iStreamW, uint64 iCount,
00574                 uint64* oCountRead, uint64* oCountWritten);
00575 
00576         virtual void Imp_Skip(uint64 iCount, uint64* oCountSkipped);
00577         };
00578 
00579 // =================================================================================================
00580 #pragma mark -
00581 #pragma mark * ZStreamRPos_Null
00582 
00584 
00585 class ZStreamRPos_Null : public ZStreamRPos
00586         {
00587 public:
00588         ZStreamRPos_Null();
00589         ~ZStreamRPos_Null();
00590 
00591 // From ZStreamR via ZStreamRPos
00592         virtual void Imp_Read(void* iDest, size_t iCount, size_t* oCountRead);
00593 
00594         virtual void Imp_CopyToDispatch(const ZStreamW& iStreamW, uint64 iCount,
00595                 uint64* oCountRead, uint64* oCountWritten);
00596 
00597         virtual void Imp_CopyTo(const ZStreamW& iStreamW, uint64 iCount,
00598                 uint64* oCountRead, uint64* oCountWritten);
00599 
00600         virtual void Imp_Skip(uint64 iCount, uint64* oCountSkipped);
00601 
00602 // From ZStreamRPos
00603         virtual uint64 Imp_GetPosition();
00604         virtual void Imp_SetPosition(uint64 iPosition);
00605 
00606         virtual uint64 Imp_GetSize();
00607 
00608 private:
00609         uint64 fPosition;
00610         };
00611 
00612 // =================================================================================================
00613 #pragma mark -
00614 #pragma mark * ZStreamW_Null
00615 
00617 
00618 class ZStreamW_Null : public ZStreamW
00619         {
00620 public:
00621         ZStreamW_Null();
00622         ~ZStreamW_Null();
00623 
00624 // From ZStreamW
00625         virtual void Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten);
00626 
00627         virtual void Imp_CopyFromDispatch(const ZStreamR& iStreamR, uint64 iCount,
00628                 uint64* oCountRead, uint64* oCountWritten);
00629 
00630         virtual void Imp_CopyFrom(const ZStreamR& iStreamR, uint64 iCount,
00631                 uint64* oCountRead, uint64* oCountWritten);
00632 
00633 // Our protocol
00634         void Internal_CopyFrom(const ZStreamR& iStreamR, uint64 iCount,
00635                 uint64* oCountRead, uint64* oCountWritten);
00636         };
00637 
00638 // =================================================================================================
00639 #pragma mark -
00640 #pragma mark * ZStreamWPos_Null
00641 
00643 
00644 class ZStreamWPos_Null : public ZStreamWPos
00645         {
00646 public:
00647         ZStreamWPos_Null();
00648         ~ZStreamWPos_Null();
00649 
00650 // From ZStreamW
00651         virtual void Imp_Write(const void* iSource, size_t iCount, size_t* oCountWritten);
00652 
00653         virtual void Imp_CopyFromDispatch(const ZStreamR& iStreamR, uint64 iCount,
00654                 uint64* oCountRead, uint64* oCountWritten);
00655 
00656         virtual void Imp_CopyFrom(const ZStreamR& iStreamR, uint64 iCount,
00657                 uint64* oCountRead, uint64* oCountWritten);
00658 
00659 // From ZStreamWPos
00660         virtual uint64 Imp_GetPosition();
00661         virtual void Imp_SetPosition(uint64 iPosition);
00662 
00663         virtual uint64 Imp_GetSize();
00664         virtual void Imp_SetSize(uint64 iSize);
00665 
00666 // Our protocol
00667         void Internal_CopyFrom(const ZStreamR& iStreamR, uint64 iCount,
00668                 uint64* oCountRead, uint64* oCountWritten);
00669 
00670 private:
00671         uint64 fPosition;
00672         uint64 fSize;
00673         };
00674 
00675 #endif // __ZStream__

Generated on Thu Jul 26 11:21:53 2007 for ZooLib by  doxygen 1.4.7