Gray C++ Libraries  0.0.2
A set of C++ libraries for MSVC, GNU on Windows, WinCE, Linux
cStream.h
Go to the documentation of this file.
1 //
4 //
5 
6 #ifndef _INC_cStream_H
7 #define _INC_cStream_H
8 #ifndef NO_PRAGMA_ONCE
9 #pragma once
10 #endif
11 
12 #include "StrT.h"
13 #include "cStreamProgress.h"
14 #include "cTimeSys.h"
15 #include "cMem.h"
16 #include "cHeap.h"
17 #include "HResult.h"
18 #include "cUnitTestDecl.h"
19 
20 namespace Gray
21 {
22 #ifdef _WIN32
23 #define FILE_EOL STR_CRLF
24 #else
25 #define FILE_EOL STR_NL
26 #endif
27 
28  class cStreamInput;
29 
31  {
34 
35  public:
38 
39  public:
40  cStreamStat() noexcept
41  : m_nCount(0)
42  , m_tLast(cTimeSys::k_CLEAR)
43  {
44  }
45  void ResetStat() noexcept
46  {
47  m_nCount = 0;
48  m_tLast.InitTime();
49  }
50  void UpdateStat(size_t n) noexcept
51  {
52  m_nCount += n;
53  m_tLast.InitTimeNow();
54  }
55  void Add(const cStreamStat& n) noexcept
56  {
57  m_nCount += n.m_nCount;
58  if (n.m_tLast.get_TimeSys() > m_tLast.get_TimeSys())
59  {
60  m_tLast = n.m_tLast;
61  }
62  }
63  };
64 
66  {
69 
70  public:
73 
74  public:
75  void Add(const cStreamStats& n)
76  {
77  m_StatOut.Add(n.m_StatOut);
78  m_StatInp.Add(n.m_StatInp);
79  }
80  };
81 
83  {
86 
87  public:
88  static const BYTE k_SIZE_MASK = 0x80;
89  static const size_t k_FILE_BLOCK_SIZE = (32 * 1024);
90 
91  public:
92  virtual ~cStreamBase()
93  {
94  }
96  {
105  UNREFERENCED_PARAMETER(iOffset);
106  UNREFERENCED_PARAMETER(eSeekOrigin);
107  return (STREAM_SEEKRET_t)E_NOTIMPL; // It doesn't work on this type of stream!
108  }
109 
110  void SeekToBegin()
111  {
113  Seek(0, SEEK_Set);
114  }
116  {
118  return((STREAM_POS_t)Seek(0, SEEK_End));
119  }
120 
121  virtual STREAM_POS_t GetPosition() const;
122  virtual STREAM_POS_t GetLength() const;
123  };
124 
126  {
132 
133  public:
134  cStreamOutput() noexcept
135  {
136  }
137  virtual ~cStreamOutput()
138  {
139  }
140 
141  virtual HRESULT WriteX(const void* pData, size_t nDataSize) // = 0;
142  {
147  ASSERT(0); // should never get called. (should always be overloaded)
148  UNREFERENCED_PARAMETER(pData);
149  UNREFERENCED_PARAMETER(nDataSize);
150  return HRESULT_WIN32_C(ERROR_WRITE_FAULT);
151  }
152 
153  HRESULT WriteT(const void* pVal, size_t nDataSize)
154  {
157  HRESULT hRes = WriteX(pVal, nDataSize);
158  if (SUCCEEDED(hRes) && hRes != (HRESULT)nDataSize)
159  return HRESULT_WIN32_C(ERROR_WRITE_FAULT); // STG_WRITEFAULT
160  return hRes;
161  }
162 
163  // Support the base types directly.
164  template< typename TYPE >
166 
167  HRESULT WriteSize(size_t nSize);
169  {
171  return WriteSize(nHashCode);
172  }
173 
174  HRESULT WriteN(const void* pBuffer, size_t nSize)
175  {
179  HRESULT hRes = WriteSize(nSize);
180  if (FAILED(hRes))
181  return hRes;
182  if (nSize == 0)
183  return S_OK;
184  return WriteT(pBuffer, nSize);
185  }
186 
187  template< typename _CH >
188  HRESULT WriteStringN(const _CH* pszStr)
189  {
192  return WriteN(pszStr, (pszStr == nullptr) ? 0 : (StrT::Len(pszStr) * sizeof(_CH)));
193  }
194  template< typename _CH >
195  HRESULT WriteCharRepeat(_CH nChar, int nCount = 1)
196  {
199  ASSERT(nCount >= 0);
200  _CH szTmp[2];
201  szTmp[0] = nChar;
202  szTmp[1] = '\0';
203  for (; nCount-- > 0;)
204  {
205  HRESULT hRes = WriteString(szTmp);
206  if (FAILED(hRes))
207  return hRes;
208  }
209  return S_OK;
210  }
211 
212  virtual HRESULT WriteString(const char* pszStr)
213  {
219  if (pszStr == nullptr)
220  return 0; // write nothing = S_OK.
221  StrLen_t iLen = StrT::Len(pszStr);
222  return WriteT(pszStr, iLen * sizeof(char));
223  }
224  virtual HRESULT WriteString(const wchar_t* pszStr)
225  {
231  if (pszStr == nullptr)
232  return 0; // write nothing = S_OK.
233  StrLen_t iLen = StrT::Len(pszStr);
234  HRESULT hRes = WriteT(pszStr, iLen * sizeof(wchar_t));
235  if (FAILED(hRes))
236  return hRes;
237  return(hRes / sizeof(wchar_t));
238  }
239 
240  StrLen_t VPrintf(const char* pszFormat, va_list args)
241  {
245  ASSERT(pszFormat != nullptr);
246  char szTemp[StrT::k_LEN_MAX];
247  StrLen_t iLenRet = StrT::vsprintfN(szTemp, STRMAX(szTemp), pszFormat, args);
248  UNREFERENCED_PARAMETER(iLenRet);
249  return WriteString(szTemp);
250  }
251  StrLen_t VPrintf(const wchar_t* pszFormat, va_list args)
252  {
256  ASSERT(pszFormat != nullptr);
257  wchar_t szTemp[StrT::k_LEN_MAX];
258  StrLen_t iLenRet = StrT::vsprintfN(szTemp, STRMAX(szTemp), pszFormat, args);
259  UNREFERENCED_PARAMETER(iLenRet);
260  return WriteString(szTemp);
261  }
262  StrLen_t _cdecl Printf(const char* pszFormat, ...)
263  {
269  ASSERT(pszFormat != nullptr);
270  va_list vargs;
271  va_start(vargs, pszFormat);
272  StrLen_t iLenRet = VPrintf(pszFormat, vargs);
273  va_end(vargs);
274  return iLenRet;
275  }
276  StrLen_t _cdecl Printf(const wchar_t* pszFormat, ...)
277  {
282  ASSERT(pszFormat != nullptr);
283  va_list vargs;
284  va_start(vargs, pszFormat);
285  StrLen_t iLenRet = VPrintf(pszFormat, vargs);
286  va_end(vargs);
287  return iLenRet;
288  }
289 
291  HRESULT WriteStream(cStreamInput& sInp, STREAM_POS_t nSizeMax = k_FILE_BLOCK_SIZE, IStreamProgressCallback* pProgress = nullptr, TIMESYSD_t nTimeout = 0);
292 
293  virtual HRESULT FlushX()
294  {
296  return S_OK;
297  }
298  };
299 
300  // Write all my types bool, char, int, float, double, _int64. (short, long, signed, unsigned)
301 #define CTYPE_DEF(a,_TYPE,c,d,e,f,g,h) template<> inline HRESULT cStreamOutput::WriteT<_TYPE>( _TYPE val ) { return WriteT(&val,sizeof(val)); }
302 #include "cTypes.tbl"
303 #undef CTYPE_DEF
304 
306  {
310  public:
311  cStreamInput() noexcept
312  {
313  }
314  virtual ~cStreamInput()
315  {
316  }
317 
318  virtual size_t SetSeekSizeMin(size_t nSizeMin = k_FILE_BLOCK_SIZE)
319  {
324 
325  UNREFERENCED_PARAMETER(nSizeMin);
326  ASSERT(false); // Must implement this ?
327  return 0; // Previous commit size.
328  }
329 
330  virtual HRESULT ReadX(OUT void* pData, size_t nDataSize)
331  {
340  UNREFERENCED_PARAMETER(pData);
341  UNREFERENCED_PARAMETER(nDataSize);
342  return 0;
343  }
344 
345  HRESULT ReadAll(OUT cHeapBlock& block, size_t nSizeExtra = 0)
346  {
350  STREAM_POS_t nLengthStream = this->GetLength();
351  size_t nLengthAlloc = (size_t)nLengthStream;
352  if (!block.Alloc(nLengthAlloc + nSizeExtra))
353  return E_OUTOFMEMORY;
354  return ReadT(block.get_Data(), nLengthAlloc); // must get all.
355  }
356 
357  virtual HRESULT ReadStringLine(OUT char* pszBuffer, StrLen_t iSizeMax);
358  virtual HRESULT ReadStringLine(OUT wchar_t* pszBuffer, StrLen_t iSizeMax);
359 
360  // Support the base types directly.
361  HRESULT ReadT(OUT void* pVal, size_t nSize)
362  {
366 
367  HRESULT hRes = ReadX(pVal, nSize);
368  if (SUCCEEDED(hRes) && hRes != (HRESULT)nSize)
369  {
370  return HRESULT_WIN32_C(ERROR_IO_INCOMPLETE); // maybe HRESULT_WIN32_C(ERROR_HANDLE_EOF) ?
371  }
372  return hRes;
373  }
374  template< typename TYPE >
375  HRESULT ReadT(OUT TYPE& val);
376 
377  template< typename TYPE >
378  HRESULT ReadTN(OUT TYPE& val)
379  {
381  HRESULT hRes = ReadT(val);
382  if (FAILED(hRes))
383  return hRes;
384  val = cMemT::NtoH(val);
385  return hRes;
386  }
387 
388  HRESULT ReadSize(OUT size_t& nSize);
389 
390  template< typename TYPE >
392  {
393  // cast size_t to some other type.
394  size_t nSize = 0;
395  HRESULT hRes = ReadSize(nSize);
396  n = (TYPE)nSize;
397  return hRes;
398  }
399 
400  HRESULT ReadHashCode(OUT UINT32& nHashCode)
401  {
402  return ReadSizeT<UINT32>(nHashCode);
403  }
404 #ifdef USE_INT64
405  HRESULT ReadHashCode(OUT UINT64& nHashCode)
406  {
407  return ReadSizeT<UINT64>(nHashCode);
408  }
409 #endif
410  HRESULT ReadN(OUT BYTE* pBuffer, size_t nSizeMax)
411  {
414  size_t nSize;
415  HRESULT hRes = ReadSize(nSize);
416  if (FAILED(hRes))
417  return hRes;
418  if (nSize > nSizeMax)
419  {
420  // ASSERT(0);
421  return HRESULT_WIN32_C(ERROR_FILE_CORRUPT); // corrupt data.
422  }
423  return ReadT(pBuffer, nSize);
424  }
425 
426  template< typename _CH >
427  HRESULT ReadStringN(OUT _CH* pszStr, StrLen_t iSizeMax)
428  {
435 
436  HRESULT hResRead = ReadN((BYTE*)pszStr, (size_t)(iSizeMax - 1) * sizeof(_CH));
437  if (FAILED(hResRead))
438  return hResRead;
439  StrLen_t nSizeRead = hResRead / sizeof(_CH);
440  ASSERT(nSizeRead < iSizeMax);
441  pszStr[nSizeRead] = '\0';
442  return nSizeRead + 1;
443  }
444 
445  virtual HRESULT ReadPeek(void* pData, size_t nDataSize);
446  };
447 
448  // Read all my types bool, char, int, float, double, _int64. (short, long, signed, unsigned)
449 #define CTYPE_DEF(a,_TYPE,c,d,e,f,g,h) template<> inline HRESULT cStreamInput::ReadT<_TYPE>( OUT _TYPE& rval ) { return ReadT(&rval,sizeof(rval)); }
450 #include "cTypes.tbl"
451 #undef CTYPE_DEF
452 
454  : public cStreamInput
455  , public cStreamOutput
456  {
463 
464  public:
466  virtual STREAM_SEEKRET_t Seek(STREAM_OFFSET_t iOffset, SEEK_ORIGIN_TYPE eSeekOrigin = SEEK_Set) override
467  {
468  return cStreamInput::Seek(iOffset, eSeekOrigin);
469  }
470  virtual STREAM_POS_t GetPosition() const override
471  {
472  return cStreamInput::GetPosition();
473  }
474  virtual STREAM_POS_t GetLength() const override
475  {
476  return cStreamInput::GetLength();
477  }
478  void SeekToBegin()
479  {
481  }
483  {
484  return cStreamInput::SeekToEnd();
485  }
486 
488  };
489 
491  {
494 
495  public:
499 
500  protected:
502  {
503  // Roll back to m_lPosStart
504  ASSERT(isTransactionActive());
505  STREAM_SEEKRET_t lPosRet = m_pInp->Seek(m_lPosStart, SEEK_Set);
506  if (lPosRet == m_lPosStart)
507  return S_OK;
508  ASSERT(lPosRet == m_lPosStart);
509  return HResult::GetDef((HRESULT)lPosRet, HRESULT_WIN32_C(ERROR_READ_FAULT));
510  }
511 
512  public:
514  : m_pInp(pInp)
515  {
516  ASSERT(m_pInp != nullptr);
517  m_lPosStart = m_pInp->GetPosition();
518  ASSERT(m_lPosStart >= 0 && m_lPosStart <= (STREAM_SEEKRET_t)cHeap::k_ALLOC_MAX);
519  m_nSeekSizeMinPrev = m_pInp->SetSeekSizeMin(0); // Don't use AutoReadCommit inside cStreamTransaction.
520  ASSERT(m_nSeekSizeMinPrev >= 0 && m_nSeekSizeMinPrev <= cHeap::k_ALLOC_MAX);
521  ASSERT(isTransactionActive());
522  }
524  {
526  if (m_pInp == nullptr)
527  return;
528  if (isTransactionActive()) // We failed ! didn't call SetTransactionComplete or SetTransactionFailed()
529  {
530  TransactionRollback();
531  }
532  // Restore commit ability
533  m_pInp->SetSeekSizeMin(m_nSeekSizeMinPrev); // Complete. we can now commit reads. e.g. toss data we have declared read.
534  }
535 
536  bool isTransactionActive() const
537  {
539  return m_lPosStart != ((STREAM_SEEKRET_t)-1);
540  }
542  {
544  ASSERT(isTransactionActive());
545  m_lPosStart = ((STREAM_SEEKRET_t)-1);
546  ASSERT(!isTransactionActive());
547  }
548  void SetTransactionCompleteN(size_t nSize)
549  {
550  // I got a partial success. I used some of the data. maybe not all.
551  ASSERT(isTransactionActive());
552  m_lPosStart += nSize; // roll back to here.
553  }
555  {
558  if (m_pInp == nullptr)
559  return;
560  m_pInp = nullptr;
561  }
563  {
566  ASSERT(isTransactionActive());
567  }
568  };
569 
571  {
574 
575  public:
576  virtual HRESULT WriteX(const void* pData, size_t nDataSize) override // = 0;
577  {
579  UNREFERENCED_PARAMETER(pData);
580  return (HRESULT)nDataSize;
581  }
582  };
583 };
584 
585 #endif // _INC_cStream_H
#define GRAYCORE_LINK
Definition: GrayCore.h:47
#define SUCCEEDED(x)
Definition: HResult.h:29
#define HRESULT_WIN32_C(x)
a constant LSTATUS/error_status_t with no check, unlike HRESULT_FROM_WIN32()
Definition: HResult.h:79
#define FAILED(x)
Definition: HResult.h:30
#define STRMAX(x)
Get Max size of static string space. minus the '\0' terminator character.
Definition: StrConst.h:33
#define TYPE
Definition: StrT.cpp:38
#define UNREFERENCED_PARAMETER(P)
< _WIN32 type thing. get rid of stupid warning.
Definition: SysTypes.h:299
INT32 HRESULT
_WIN32 style error codes. INT32
Definition: SysTypes.h:465
#define ASSERT(exp)
Definition: cDebugAssert.h:87
#define UNITTEST_FRIEND(n)
Define this in the class body to be unit tested. Allow the unit test to access private/protected stuf...
Definition: cUnitTestDecl.h:17
static HRESULT GetDef(HRESULT hRes, HRESULT hResDef=E_FAIL) noexcept
Definition: HResult.h:232
Definition: cHeap.h:156
Definition: cStream.h:83
void SeekToBegin()
Definition: cStream.h:110
virtual STREAM_POS_t GetLength() const
Definition: cStream.cpp:20
virtual STREAM_POS_t GetPosition() const
Definition: cStream.cpp:12
virtual STREAM_SEEKRET_t Seek(STREAM_OFFSET_t iOffset, SEEK_ORIGIN_TYPE eSeekOrigin=SEEK_Set)
Definition: cStream.h:95
STREAM_POS_t SeekToEnd()
Definition: cStream.h:115
virtual ~cStreamBase()
Definition: cStream.h:92
Definition: cStream.h:306
HRESULT ReadHashCode(OUT UINT64 &nHashCode)
Definition: cStream.h:405
HRESULT ReadStringN(OUT _CH *pszStr, StrLen_t iSizeMax)
Definition: cStream.h:427
virtual ~cStreamInput()
Definition: cStream.h:314
cStreamInput() noexcept
Definition: cStream.h:311
HRESULT ReadTN(OUT TYPE &val)
Definition: cStream.h:378
HRESULT ReadN(OUT BYTE *pBuffer, size_t nSizeMax)
Definition: cStream.h:410
HRESULT ReadT(OUT void *pVal, size_t nSize)
Definition: cStream.h:361
HRESULT ReadHashCode(OUT UINT32 &nHashCode)
Definition: cStream.h:400
HRESULT ReadT(OUT TYPE &val)
virtual size_t SetSeekSizeMin(size_t nSizeMin=k_FILE_BLOCK_SIZE)
Definition: cStream.h:318
HRESULT ReadAll(OUT cHeapBlock &block, size_t nSizeExtra=0)
Definition: cStream.h:345
HRESULT ReadSizeT(OUT TYPE &n)
Definition: cStream.h:391
virtual HRESULT ReadX(OUT void *pData, size_t nDataSize)
Definition: cStream.h:330
Definition: cStream.h:571
virtual HRESULT WriteX(const void *pData, size_t nDataSize) override
Definition: cStream.h:576
Definition: cStream.h:126
virtual ~cStreamOutput()
Definition: cStream.h:137
HRESULT WriteHashCode(HASHCODE_t nHashCode)
Definition: cStream.h:168
virtual HRESULT WriteString(const char *pszStr)
Definition: cStream.h:212
virtual HRESULT FlushX()
Definition: cStream.h:293
HRESULT WriteStringN(const _CH *pszStr)
Definition: cStream.h:188
StrLen_t _cdecl Printf(const char *pszFormat,...)
Definition: cStream.h:262
StrLen_t VPrintf(const char *pszFormat, va_list args)
Definition: cStream.h:240
HRESULT WriteT(const void *pVal, size_t nDataSize)
Definition: cStream.h:153
virtual HRESULT WriteX(const void *pData, size_t nDataSize)
Definition: cStream.h:141
HRESULT WriteT(TYPE val)
HRESULT WriteCharRepeat(_CH nChar, int nCount=1)
Definition: cStream.h:195
HRESULT WriteN(const void *pBuffer, size_t nSize)
Definition: cStream.h:174
StrLen_t VPrintf(const wchar_t *pszFormat, va_list args)
Definition: cStream.h:251
StrLen_t _cdecl Printf(const wchar_t *pszFormat,...)
Definition: cStream.h:276
cStreamOutput() noexcept
Definition: cStream.h:134
virtual HRESULT WriteString(const wchar_t *pszStr)
Definition: cStream.h:224
Definition: cStream.h:31
void ResetStat() noexcept
Definition: cStream.h:45
void UpdateStat(size_t n) noexcept
Definition: cStream.h:50
cStreamStat() noexcept
Definition: cStream.h:40
cTimeSys m_tLast
When did i last move data?
Definition: cStream.h:37
void Add(const cStreamStat &n) noexcept
Definition: cStream.h:55
STREAM_POS_t m_nCount
Keep arbitrary stats on how much i move (bytes).
Definition: cStream.h:36
Definition: cStream.h:66
cStreamStat m_StatInp
Definition: cStream.h:72
void Add(const cStreamStats &n)
Definition: cStream.h:75
cStreamStat m_StatOut
Definition: cStream.h:71
Definition: cStream.h:491
void SetTransactionComplete()
Definition: cStream.h:541
void SetTransactionRollback()
Definition: cStream.h:562
void SetTransactionCompleteN(size_t nSize)
Definition: cStream.h:548
void SetTransactionFailed()
Definition: cStream.h:554
cStreamInput * m_pInp
Pull transaction data from this stream.
Definition: cStream.h:496
HRESULT TransactionRollback()
Definition: cStream.h:501
size_t m_nSeekSizeMinPrev
Previous value. Maybe nested transactions !
Definition: cStream.h:498
cStreamTransaction(cStreamInput *pInp)
Definition: cStream.h:513
bool isTransactionActive() const
Definition: cStream.h:536
~cStreamTransaction()
Definition: cStream.h:523
STREAM_SEEKRET_t m_lPosStart
Definition: cStream.h:497
Definition: cStream.h:456
virtual STREAM_POS_t GetLength() const override
Definition: cStream.h:474
void SeekToBegin()
Definition: cStream.h:478
STREAM_POS_t SeekToEnd()
Definition: cStream.h:482
virtual STREAM_POS_t GetPosition() const override
Definition: cStream.h:470
virtual STREAM_SEEKRET_t Seek(STREAM_OFFSET_t iOffset, SEEK_ORIGIN_TYPE eSeekOrigin=SEEK_Set) override
Disambiguate Seek for cStreamBase to cStreamInput for stupid compiler.
Definition: cStream.h:466
Definition: cTimeSys.h:93
void InitTime(TIMESYS_t t=k_CLEAR) noexcept
Definition: cTimeSys.h:152
void InitTimeNow() noexcept
Definition: cTimeSys.h:156
TIMESYS_t get_TimeSys() const noexcept
Definition: cTimeSys.h:147
< The main namespace for all Core functions.
Definition: GrayCore.cpp:14
LONG_PTR STREAM_OFFSET_t
Might be 64 or 32 bit. TODO SET USE_FILE_POS64.
Definition: cOSHandle.h:52
int StrLen_t
the length of a string in chars (bytes for UTF8, wchar_t for UNICODE). or offset in characters....
Definition: StrConst.h:32
LONG_PTR STREAM_SEEKRET_t
return from Seek()
Definition: cOSHandle.h:53
INT32 TIMESYSD_t
Time delta. signed milli-Seconds Span. cTimeSys::k_DMAX, cTimeSys::k_INF = MAILSLOT_WAIT_FOREVER.
Definition: cTimeSys.h:28
UINT_PTR HASHCODE_t
could hold a pointer converted to a number? maybe 64 or 32 bit ? same as size_t.
Definition: GrayCore.h:116
ULONG_PTR STREAM_POS_t
NOT same as FILE_SIZE_t in 32 bit. Why not ?
Definition: cOSHandle.h:54
SEEK_ORIGIN_TYPE
Definition: cOSHandle.h:34
@ SEEK_End
SEEK_END = FILE_END = STREAM_SEEK_END = 2 = relative to the end of the file.
Definition: cOSHandle.h:41
@ SEEK_Set
SEEK_SET = FILE_BEGIN = STREAM_SEEK_SET = 0 = relative to the start of the file.
Definition: cOSHandle.h:39
class __DECL_IMPORT cStreamInput
Definition: cString.h:26
Definition: cStreamProgress.h:168
static const StrLen_t k_LEN_MAX
arbitrary max size for Format() etc. NOTE: _MSC_VER says stack frame should be at least 16384
Definition: StrT.h:75
static StrLen_t vsprintfN(OUT TYPE *pszOut, StrLen_t iLenOutMax, const TYPE *pszFormat, va_list vlist)
static StrLen_t Len(const TYPE *pszStr) noexcept
static const size_t k_ALLOC_MAX
256 * 64K = (arbitrary) largest reasonable single malloc.
Definition: cHeap.h:45
static TYPE NtoH(TYPE nVal) noexcept
Definition: cMem.h:502