CFx SDK Documentation  2023 SP0
MemFileStreamImpl.h
Go to the documentation of this file.
1 // Copyright (C) 2002-2017, Open Design Alliance (the "Alliance").
3 // All rights reserved.
4 //
5 // This software and its documentation and related materials are owned by
6 // the Alliance. The software may only be incorporated into application
7 // programs owned by members of the Alliance, subject to a signed
8 // Membership Agreement and Supplemental Software License Agreement with the
9 // Alliance. The structure and organization of this software are the valuable
10 // trade secrets of the Alliance and its suppliers. The software is also
11 // protected by copyright law and international treaty provisions. Application
12 // programs incorporating this software must include the following statement
13 // with their copyright notices:
14 //
15 // This application incorporates Teigha(R) software pursuant to a license
16 // agreement with Open Design Alliance.
17 // Teigha(R) Copyright (C) 2002-2017 by Open Design Alliance.
18 // All rights reserved.
19 //
20 // By use of this software, its documentation or related materials, you
21 // acknowledge and accept the above terms.
23 
24 // MemFileStreamImpl.h : implementation for the OdMemFileStreamImpl class.
25 //
27 
28 #if !defined(_MEMORYFILESTREAMIMPL_H_INCLUDED_)
29 #define _MEMORYFILESTREAMIMPL_H_INCLUDED_
30 
31 #include "RxObjectImpl.h"
32 #include "MemoryStream.h"
33 #include "OdAlloc.h"
34 
35 #ifdef OD_HAVE_UNISTD_FILE
36 #include <unistd.h>
37 #endif
38 
39 #ifdef OD_HAVE_WINDOWS_STORAGE_FILE
40 #include <windows.storage.h>
41 #endif
42 
43 #ifdef OD_HAVE_WRL_FILE
44 #include <wrl/client.h>
45 #include <wrl/wrappers/corewrappers.h>
46 #endif
47 
48 //DD:EXPORT_ON
49 
53 namespace TmpFileHelper
54 {
55 #define TEMPFILE_PREFIX "tx$"
56 
60  static OdString getTempFile(OdDbBaseHostAppServices* pHostAppServices, const OdAnsiString& prefix = TEMPFILE_PREFIX)
61  {
62  OdString tmpDir = pHostAppServices->getTempPath();
63 #if defined(_WINRT)
64  GUID result;
65  if (CoCreateGuid(&result) < 0)
66  return OdString::kEmpty;
67  tmpDir = tmpDir.format(L"%ls%llx%x%x.tmp", tmpDir.c_str(), result.Data1, result.Data2, result.Data3);
68 
69 #elif defined(_WIN32) // Win 32 + 64 bit
70  OdChar tmpFile[MAX_PATH];
71  ::GetTempFileName(tmpDir.c_str(), !prefix.isEmpty() ? OdString(prefix).c_str() : L"tmp", 0, tmpFile);
72  if (odStrLen(tmpFile))
73  tmpDir = OdString(tmpFile, (int)odStrLen(tmpFile));
74 #else
75  char tmpFile[4096]; // sufficient for Win, Linux, Mac
76  tmpFile[0] = 0;
77 
78  OdAnsiCharArray dstBuf;
79  int lenStr = tmpDir.getLength();
80  dstBuf.reserve(lenStr * 4); // UTF-8 can use up to 4 bytes per character
81  OdCharMapper::unicodeToUtf8(tmpDir.c_str(), lenStr, dstBuf);
82  strcat(tmpFile, (const char*)dstBuf.asArrayPtr());
83 
84  strcat(tmpFile, !prefix.isEmpty() ? prefix.c_str() : "tmp");
85 #ifdef OD_HAVE_MKSTEMPS_FUNC
86  strcat(tmpFile, "XXXXXX.tmp");
87  int fileDescriptor = mkstemps(tmpFile, 4);
88 #else
89  strcat(tmpFile, "XXXXXX");
90  int fileDescriptor = mkstemp(tmpFile);
91 #endif
92  if (fileDescriptor == -1)
93  {
94  tmpFile[0] = 0;
95  }
96  else
97  close(fileDescriptor);
98  // Convert Utf8 back to Unicode
99  OdAnsiString ansiTmpFile(tmpFile);
100  OdCharArray buf;
101  OdCharMapper::utf8ToUnicode(ansiTmpFile.c_str(), ansiTmpFile.getLength(), buf);
102  tmpDir = OdString(buf.getPtr(), buf.size() - 1);
103 #endif
104  return tmpDir;
105  }
106 
107 } // namespace
108 
109 /*
110 same as OdMemoryStreamImpl, except that it uses a much larger PageSize, and a filled page
111 is swapped to an automatically created + associated temporary disk file;
112 the page data is then deleted, and if accessed, swapped-in from file again before accessing;
113 the PAGE's size should be at least 512 kB
114 */
115 
121 class PAGE
122 {
123 public:
131 };
132 
138 
139 
145 template <class TBase = OdMemFileStreamDummyBase>
146 class OdMemFileStreamImpl : public TBase
147 {
148  friend class OdMemoryStream;
149 
150  OdUInt64 m_numPages;
151  PAGE* m_pFirstPage;
152  PAGE* m_pCurrPage;
153  PAGE* m_pLastPage;
154 
160  class PageSwitcher
161  {
162  // the *singleton* data buffer
163 
165  PAGE* m_activePage;
166  OdString m_sTmpFileName;
167  OdStreamBufPtr m_pTmpFile;
168  OdDbBaseHostAppServices* m_pHostAppServices;
169 
173  bool releaseDiskFile(bool deleteIt)
174  {
175  m_pTmpFile = NULL;
176  if (deleteIt && !m_sTmpFileName.isEmpty()) {
177 #ifdef OD_HAVE_REMOVE_FUNC
178  remove(m_sTmpFileName);
179 #else
180  DeleteFile(OdString(m_sTmpFileName).c_str());
181 #endif
182  }
183  m_sTmpFileName.empty();
184  m_activePage = 0;
185  return true;
186  };
187 
188  public:
192  PageSwitcher()
193  : m_activePage(NULL)
194  {
195  };
196 
200  ~PageSwitcher()
201  {
202  setBufferSize(0);
203  releaseDiskFile(true);
204  };
205 
206  void setAppServices(OdDbBaseHostAppServices* pHostAppServices)
207  {
208  m_pHostAppServices = pHostAppServices;
209  }
210 
216  inline void setBufferSize(OdUInt32 pageSize) { m_dataBuffer.resize(pageSize); };
217 
223  inline OdUInt8* dataBuffer(PAGE* pPage) { return m_dataBuffer.asArrayPtr();};
224 
230  inline OdUInt32 dataSize(PAGE* pPage) { return m_dataBuffer.length(); };
231 
235  inline PAGE* activePage() const { return m_activePage; };
236 
242  inline void setActivePage(PAGE* pPage) { m_activePage = pPage; };
243 
250  inline bool isActivePage(PAGE* pPage) const { return (pPage == m_activePage); };
251 
258  inline bool isModified(PAGE* pPage) const { return pPage->m_modified; };
259 
266  inline void setModified(PAGE* pPage, bool modified) { pPage->m_modified = modified; };
267 
274  inline bool isSaved(PAGE* pPage) const { return pPage->m_savedToFile; };
275 
282  inline void setSaved(PAGE* pPage, bool saved) { pPage->m_savedToFile = saved; };
283 
289  inline OdUInt64 filePosition(PAGE* pPage) const { return pPage->m_nFilePos; };
290 
297  inline void setFilePosition(PAGE* pPage, OdUInt64 seekPos) { pPage->m_nFilePos = seekPos; };
298 
304  void initializePage(PAGE* pPage)
305  {
306  ODA_ASSERT(pPage);
307  pPage->m_pPrevPage = 0;
308  pPage->m_pNextPage = 0;
309  pPage->m_data = dataBuffer(pPage);
310  setModified(pPage, false);
311  setSaved(pPage, false);
312  setFilePosition(pPage, 0);
313  };
314 
318  OdStreamBufPtr& diskFile()
319  {
320  if (!m_pTmpFile.isNull())
321  return m_pTmpFile;
322 
323  // determine temporary filename
324  if (m_pHostAppServices)
325  {
326  m_sTmpFileName = TmpFileHelper::getTempFile(m_pHostAppServices);
327  m_pTmpFile = odrxSystemServices()->createFile(m_sTmpFileName,
331  ODA_ASSERT(!m_pTmpFile.isNull());
332  return m_pTmpFile;
333  }
334  else
335  throw OdError(eNullObjectPointer);
336  };
337 
344  bool savePage(PAGE* pPage)
345  {
346  if (pPage && isSaved(pPage) && !isModified(pPage)) // no need to save here
347  return true;
348 
349  if (!pPage || diskFile().isNull())
350  return false;
351 
352  if (isSaved(pPage))
353  {
354  diskFile()->seek(filePosition(pPage), OdDb::kSeekFromStart);
355  }
356  else
357  {
358  diskFile()->seek(0, OdDb::kSeekFromEnd);
359  setFilePosition(pPage, diskFile()->tell());
360  }
361  diskFile()->putBytes(dataBuffer(pPage), dataSize(pPage));
362 
363  setModified(pPage, false);
364  setSaved(pPage, true);
365  return true;
366  };
367 
374  bool loadPage(PAGE* pPage)
375  {
376  if (!pPage)
377  return false;
378  if (isActivePage(pPage) && !isModified(pPage)) // no need to (re-)load here
379  return true;
380 
381  if (isSaved(pPage) && !diskFile().isNull())
382  {
383  diskFile()->seek(filePosition(pPage), OdDb::kSeekFromStart);
384  diskFile()->getBytes(dataBuffer(pPage), dataSize(pPage));
385  }
386 
387  setModified(pPage, false);
388  setActivePage(pPage);
389  return true;
390  };
391 
397  bool ensurePage(PAGE* pPage)
398  {
399  ODA_ASSERT(pPage);
400  return isActivePage(pPage) ? true : switchToPage(pPage);
401  };
402 
410  bool switchToPage(PAGE* pPage)
411  {
412  ODA_ASSERT(pPage);
413  if (isActivePage(pPage))
414  return true;
415  savePage(activePage());
416  return loadPage(pPage);
417  };
418 
424  bool rewind(PAGE* pPage)
425  {
426  ODA_ASSERT(pPage);
427  // 'pPage' is loaded at next read/write access
428  return isActivePage(pPage) ? true : savePage(activePage());
429  }
430 
436  bool truncate(PAGE* pPage)
437  {
438  ODA_ASSERT(pPage);
439  bool wasSaved = isSaved(pPage);
440  setModified(pPage, false);
441  setSaved(pPage, false);
442  if (!wasSaved || diskFile().isNull())
443  {
444  return true;
445  }
446 
447  diskFile()->seek(filePosition(pPage), OdDb::kSeekFromStart);
448  diskFile()->truncate();
449  return true;
450  };
451  }; // class PageSwitcher
452 
453  PageSwitcher m_pageSwitcher;
454 
458  OdMemFileStreamImpl& operator= (const OdMemFileStreamImpl&) {return *this;}
459 
460 protected:
464 
468  inline PageSwitcher& pageSwitcher() { return m_pageSwitcher; };
469 
473  inline OdUInt64 allocated() const { return m_numPages * m_nPageDataSize; }
474  inline OdUInt64 curPageNo() const { return (m_nCurPos / m_nPageDataSize); }
476  inline OdUInt32 leftInCurPage() const { return (m_pCurrPage ? m_nPageDataSize - posInCurPage() : 0); }
477 
481  void addPage();
482 
486  void seekNextPage(bool bCreateNew = false);
487 
491  inline void seekPrevPage()
492  {
493  if(m_pCurrPage->m_pPrevPage)
494  {
495  m_nCurPos -= posInCurPage();
497  m_pCurrPage = m_pCurrPage->m_pPrevPage;
498  pageSwitcher().switchToPage(m_pCurrPage);
499  }
500  else
501  throw OdError(eEndOfFile);
502  }
503 
504  inline OdUInt8* currPos() { return m_pCurrPage->m_data + posInCurPage(); }
505  inline const OdUInt8* currPos() const { return m_pCurrPage->m_data + posInCurPage(); }
506 
507 public:
508  OdMemFileStreamImpl(OdUInt32 nPageDataSize = 0x00200000) // 2MB
509  : m_numPages(0)
510  , m_pFirstPage(0)
511  , m_pCurrPage(0)
512  , m_pLastPage(0)
513  , m_nCurPos(0)
514  , m_nEndPos(0)
515  , m_nPageDataSize(0)
516  {
517  setPageDataSize(nPageDataSize);
518  setAppServices(0);
519  }
520 
521  void setAppServices(OdDbBaseHostAppServices* pHostAppServices)
522  {
523  pageSwitcher().setAppServices(pHostAppServices);
524  }
525 
530 
536  void setPageDataSize(OdUInt32 nPageSize)
537  {
538  m_nPageDataSize = nPageSize;
539  pageSwitcher().setBufferSize(nPageSize);
540  }
541 
545  void reserve(OdUInt64 nSize)
546  {
547  while(nSize > allocated())
548  addPage();
549  }
550 
555  {
556  return m_nEndPos;
557  }
558 
566 
571  {
572  return m_nCurPos;
573  }
574 
579  bool isEof()
580  {
581  return (m_nCurPos>=m_nEndPos);
582  }
583 
588  OdUInt8 getByte();
589 
597  void getBytes(void* buffer, OdUInt32 nLen);
598 
605  void putByte(OdUInt8 val);
606 
614  void putBytes(const void* buffer, OdUInt32 nLen);
615 
616  //void copyDataTo(TBase* pDest, OdUInt32 nSrcStart = 0, OdUInt32 nSrcEnd = 0)
617  //{
618  // TBase::copyDataTo(pDest, nSrcStart, nSrcEnd);
619  //}
620 
624  void rewind()
625  {
626  m_nCurPos = 0;
627  m_pCurrPage = m_pFirstPage;
628  if(m_pCurrPage)
629  {
630  pageSwitcher().rewind(m_pCurrPage);
631  }
632  }
633 
637  void truncate()
638  {
639  if(m_pCurrPage)
640  {
641  pageSwitcher().truncate(m_pCurrPage);
642  PAGE* pNext, *pCurr = m_pCurrPage->m_pNextPage;
643  m_pCurrPage->m_pNextPage = 0;
644  m_pLastPage = m_pCurrPage;
646  while(pCurr)
647  {
648  pNext = pCurr->m_pNextPage;
649  pCurr->m_data = 0;
650  if (pageSwitcher().activePage() == pCurr)
651  {
652  pageSwitcher().setActivePage(0);
653  }
654  ::odrxFree(pCurr);
655  --m_numPages;
656  pCurr = pNext;
657  }
658  }
659  }
660 
665 };
666 
668 
669 template <class TBase>
671 {
672  PAGE* pNext, *pCurr = m_pFirstPage;
673  while(pCurr)
674  {
675  pNext = pCurr->m_pNextPage;
676  pCurr->m_data = 0;
677  if (pageSwitcher().activePage() == pCurr)
678  {
679  int t=0;
680  }
681  ::odrxFree(pCurr);
682  pCurr = pNext;
683  }
684  m_pFirstPage = 0;
685 }
686 
687 template <class TBase>
689 {
690  PAGE* pPage = (PAGE*)::odrxAlloc(sizeof(PAGE));
691  if (!pPage)
692  throw OdError(eOutOfMemory);
693 
694  pageSwitcher().initializePage(pPage);
695 
696  pPage->m_pPrevPage = m_pLastPage;
697  if(m_pLastPage)
698  {
699  m_pLastPage->m_pNextPage = pPage;
700  if(!m_pCurrPage)
701  {
702  m_pCurrPage = pPage;
703  pageSwitcher().switchToPage(m_pCurrPage);
704  }
705  pPage->m_nPageStartAddr = pPage->m_pPrevPage->m_nPageStartAddr + m_nPageDataSize;
706  }
707  else
708  {
709  m_pFirstPage = m_pCurrPage = pPage;
710  pPage->m_nPageStartAddr = 0;
711  pageSwitcher().switchToPage(m_pCurrPage);
712  }
713  m_pLastPage = pPage;
714  ++m_numPages;
715 }
716 
717 template <class TBase>
719 {
720  if(bCreateNew)
721  {
722  if(!m_pCurrPage)
723  {
724  addPage();
725  return;
726  }
727  if(!m_pCurrPage->m_pNextPage)
728  addPage();
729  }
730  if(m_pCurrPage->m_pNextPage)
731  {
732  m_pCurrPage = m_pCurrPage->m_pNextPage;
733  m_nCurPos += leftInCurPage();
734  pageSwitcher().switchToPage(m_pCurrPage);
735  }
736  else
737  throw OdError(eEndOfFile);
738 }
739 
740 template <class TBase>
742 {
743  OdUInt64 nNewPos;
744  switch(from)
745  {
746  case OdDb::kSeekFromEnd:
747  nNewPos = m_nEndPos + offset;
748  break;
750  nNewPos = m_nCurPos + offset;
751  break;
753  if(!offset)
754  {
755  rewind();
756  return 0;
757  }
758  nNewPos = offset;
759  break;
760  default:
761  throw OdError(eInvalidInput);
762  break;
763  };
764 
765  if(nNewPos != m_nCurPos)
766  {
767  if (nNewPos > m_nEndPos)
768  throw OdError( eEndOfFile );
769 
770  OdInt64 nFromEnd = m_nEndPos - nNewPos;
771 
772  bool bForward = false;
773  bool bBack = false;
774  if (m_pCurrPage)
775  {
776  if (nNewPos >= m_pCurrPage->m_nPageStartAddr)
777  {
778  bForward = true;
779  }
780  else
781  {
782  bBack = true;
783  }
784  }
785 
786  if (nFromEnd == 0)
787  {
788  m_pCurrPage = m_pLastPage;
789  bForward = true;
790  }
791  else if (bForward)
792  {
793  if (nFromEnd < ((OdInt64)nNewPos - (OdInt64)m_pCurrPage->m_nPageStartAddr))
794  {
795  m_pCurrPage = m_pLastPage;
796  bForward = false;
797  }
798  }
799  else if (bBack)
800  {
801  if (nNewPos < (m_pCurrPage->m_nPageStartAddr - nNewPos))
802  {
803  m_pCurrPage = m_pFirstPage;
804  bForward = true;
805  }
806  }
807  else
808  {
809  if (nNewPos <= (OdUInt64)nFromEnd)
810  {
811  m_pCurrPage = m_pFirstPage;
812  bForward = true;
813  }
814  else
815  {
816  m_pCurrPage = m_pLastPage;
817  }
818  }
819 
820  m_nCurPos = nNewPos;
821  if (bForward)
822  {
823  nNewPos = nNewPos / m_nPageDataSize * m_nPageDataSize ;
824  while(m_pCurrPage && m_pCurrPage->m_nPageStartAddr < nNewPos)
825  {
826  m_pCurrPage = m_pCurrPage->m_pNextPage;
827  }
828  }
829  else
830  {
831  while(m_pCurrPage->m_nPageStartAddr > m_nCurPos)
832  {
833  m_pCurrPage = m_pCurrPage->m_pPrevPage;
834  }
835  }
836  pageSwitcher().switchToPage(m_pCurrPage);
837  }
838  return m_nCurPos;
839 }
840 
841 template <class TBase>
843 {
844  OdUInt8 ret;
845  if(m_nCurPos < m_nEndPos)
846  {
847  pageSwitcher().ensurePage(m_pCurrPage);
848  OdUInt32 nPosInPage = posInCurPage();
849  ret = m_pCurrPage->m_data[nPosInPage];
850  ++m_nCurPos;
851  if ((nPosInPage + 1) == m_nPageDataSize)
852  m_pCurrPage = m_pCurrPage->m_pNextPage;
853  }
854  else
855  {
856  throw OdError(eEndOfFile);
857  }
858  return ret;
859 }
860 
861 template <class TBase>
863 {
864  if (nLen==0)
865  return;
866 
867  OdUInt64 nNewPos = m_nCurPos + nLen;
868  if(nNewPos <= m_nEndPos)
869  {
870  OdUInt8* pDest = (OdUInt8*)buffer;
871  OdUInt32 nToCopy = odmin(leftInCurPage(), nLen);
872  if(nToCopy)
873  {
874  pageSwitcher().ensurePage(m_pCurrPage);
875  ::memcpy(pDest, currPos(), nToCopy);
876  pDest += nToCopy;
877  nLen -= nToCopy;
878  }
879  while(nLen)
880  {
881  seekNextPage();
882  nToCopy = odmin(m_nPageDataSize, nLen);
883  ::memcpy(pDest, m_pCurrPage->m_data, nToCopy);
884  pDest += nToCopy;
885  nLen -= nToCopy;
886  }
887  m_nCurPos = nNewPos;
888  if(m_nCurPos && (m_nCurPos % m_nPageDataSize)==0)
889  m_pCurrPage = m_pCurrPage->m_pNextPage;
890  }
891  else
892  {
893  throw OdError(eEndOfFile);
894  }
895 }
896 
897 template <class TBase>
899 {
900  if(!m_pCurrPage)
901  {
902  seekNextPage(true);
903  }
904  pageSwitcher().ensurePage(m_pCurrPage);
905  pageSwitcher().setModified(m_pCurrPage, true);
906  OdUInt64 nPosInPage = posInCurPage();
907  m_pCurrPage->m_data[nPosInPage] = val;
908  ++m_nCurPos;
909  m_nEndPos = odmax(m_nCurPos, m_nEndPos);
910  if ((nPosInPage + 1) == m_nPageDataSize)
911  {
912  m_pCurrPage = m_pCurrPage->m_pNextPage;
913  }
914 }
915 
916 template <class TBase>
918 {
919  if (nLen == 0)
920  {
921  return;
922  }
923  const OdUInt8* pSrc = (const OdUInt8*)buffer;
924  OdUInt32 nToCopy = odmin(leftInCurPage(), nLen);
925  if(nToCopy)
926  {
927  pageSwitcher().ensurePage(m_pCurrPage);
928  pageSwitcher().setModified(m_pCurrPage, true);
929  ::memcpy(currPos(), pSrc, nToCopy);
930  pSrc += nToCopy;
931  nLen -= nToCopy;
932  }
933  while(nLen)
934  {
935  seekNextPage(true);
936  pageSwitcher().setModified(m_pCurrPage, true);
937  nToCopy = odmin(m_nPageDataSize, nLen);
938  ::memcpy(m_pCurrPage->m_data, pSrc, nToCopy);
939  pSrc += nToCopy;
940  nLen -= nToCopy;
941  }
942  m_nCurPos += nToCopy;
943  if(m_nCurPos && (m_nCurPos % m_nPageDataSize)==0)
944  {
945  m_pCurrPage = m_pCurrPage->m_pNextPage;
946  }
947  m_nEndPos = odmax(m_nCurPos, m_nEndPos);
948 }
949 
950 //DD:EXPORT_OFF
951 
952 #endif // !defined(_MEMORYFILESTREAMIMPL_H_INCLUDED_)
953 
#define ODA_ASSERT(exp)
Definition: DebugStuff.h:49
true
Definition: DimVarDefs.h:2046
#define NULL
Definition: GsProperties.h:177
#define TEMPFILE_PREFIX
ALLOCDLL_EXPORT void * odrxAlloc(size_t nBytes)
ALLOCDLL_EXPORT void odrxFree(void *pMemBlock)
#define odStrLen(str)
Definition: OdPlatform.h:240
#define odmin(X, Y)
Definition: OdPlatform.h:34
#define MAX_PATH
Definition: OdPlatform.h:72
#define odmax(X, Y)
Definition: OdPlatform.h:35
unsigned int OdUInt32
unsigned char OdUInt8
wchar_t OdChar
OdString OdString
Definition: OdString.h:1224
FIRSTDLL_EXPORT OdRxSystemServices * odrxSystemServices()
size_type length() const
Definition: OdArray.h:1054
size_type size() const
Definition: OdArray.h:893
const T * getPtr() const
Definition: OdArray.h:1102
void reserve(size_type reserveLength)
Definition: OdArray.h:920
const T * asArrayPtr() const
Definition: OdArray.h:1094
void resize(size_type logicalLength, const T &value)
Definition: OdArray.h:834
bool isNull() const
Definition: BaseObjectPtr.h:70
static void unicodeToUtf8(const OdChar *srcBuf, int srcSize, OdAnsiCharArray &dstBuf)
static void utf8ToUnicode(const char *srcBuf, int srcSize, OdCharArray &dstBuf)
virtual OdString getTempPath() const
Definition: Int64.h:43
OdUInt64 seek(OdInt64 offset, OdDb::FilerSeekType whence)
void reserve(OdUInt64 nSize)
void putByte(OdUInt8 val)
void putBytes(const void *buffer, OdUInt32 nLen)
void setPageDataSize(OdUInt32 nPageSize)
OdUInt32 leftInCurPage() const
OdUInt64 curPageNo() const
void getBytes(void *buffer, OdUInt32 nLen)
void seekNextPage(bool bCreateNew=false)
void setAppServices(OdDbBaseHostAppServices *pHostAppServices)
OdUInt64 allocated() const
const OdUInt8 * currPos() const
OdUInt32 posInCurPage() const
OdMemFileStreamImpl(OdUInt32 nPageDataSize=0x00200000)
OdUInt32 pageDataSize() const
PageSwitcher & pageSwitcher()
virtual OdStreamBufPtr createFile(const OdString &filename, Oda::FileAccessMode accessMode=Oda::kFileRead, Oda::FileShareMode shareMode=Oda::kShareDenyNo, Oda::FileCreationDisposition creationDisposition=Oda::kOpenExisting)
const OdChar * c_str() const
Definition: OdString.h:200
void empty()
bool isEmpty() const
Definition: OdString.h:141
OdString & format(const OdChar *formatString,...)
FIRSTDLL_EXPORT_STATIC static const OdString kEmpty
Definition: OdString.h:98
int getLength() const
Definition: OdString.h:130
bool m_savedToFile
PAGE * m_pNextPage
OdUInt64 m_nFilePos
bool m_modified
PAGE * m_pPrevPage
OdUInt8 * m_data
OdUInt64 m_nPageStartAddr
GLuint buffer
Definition: gles2_ext.h:178
GLintptr offset
Definition: gles2_ext.h:183
FilerSeekType
Definition: OdStreamBuf.h:49
@ kSeekFromCurrent
Definition: OdStreamBuf.h:51
@ kSeekFromStart
Definition: OdStreamBuf.h:50
@ kSeekFromEnd
Definition: OdStreamBuf.h:52
@ kShareDenyReadWrite
@ kCreateAlways
@ kFileWrite