zjf
2023-03-06 392b76515f40376b6d36f40a114850ef63650384
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
/////////////////////////////////////////////////////////////////////////////// 
// Copyright (C) 2002-2016, Open Design Alliance (the "Alliance"). 
// All rights reserved. 
// 
// This software and its documentation and related materials are owned by 
// the Alliance. The software may only be incorporated into application 
// programs owned by members of the Alliance, subject to a signed 
// Membership Agreement and Supplemental Software License Agreement with the
// Alliance. The structure and organization of this software are the valuable  
// trade secrets of the Alliance and its suppliers. The software is also 
// protected by copyright law and international treaty provisions. Application  
// programs incorporating this software must include the following statement 
// with their copyright notices:
//   
//   This application incorporates Teigha(R) software pursuant to a license 
//   agreement with Open Design Alliance.
//   Teigha(R) Copyright (C) 2002-2016 by Open Design Alliance. 
//   All rights reserved.
//
// By use of this software, its documentation or related materials, you 
// acknowledge and accept the above terms.
///////////////////////////////////////////////////////////////////////////////
 
#ifndef ODFILEBUF_DEFINED
#define ODFILEBUF_DEFINED
 
#include "TD_PackPush.h"
#include "OdaCommon.h"
 
#if defined(ODA_WINDOWS) && !defined(_WINRT)
 
#include "OdStreamBuf.h"
#include "RxObjectImpl.h"
#include "OdString.h"
#include "RxSystemServices.h"
 
class OdBaseFileBuf;
 
/** \remarks
  This template class is a specialization of the OdSmartPtr class for OdBaseFileBuf object pointers.
*/
typedef OdSmartPtr<OdBaseFileBuf> OdBaseFileBufPtr;
 
/** \details
  This class is the base file I/O class.
  \sa
  Source code provided.
  <group ExServices_Classes>
*/
class OdBaseFileBuf: public OdRxObjectImpl<OdStreamBuf>
{
private:
  bool m_bError;
protected:
  inline void enableErrorMode(bool bEnable = true)
  {
    m_bError = bEnable;
  }
 
  inline bool errorModeEnabled()
  {
    return m_bError;
  }
 
  inline void throwOdError(const OdError &pError)
  {
    enableErrorMode(true);
    throw pError;
  }
 
protected:
  HANDLE    m_hFile;
  OdString  m_sFileName;
  int       m_iFileShare;
  bool      m_bFileWritten;
 
  OdBaseFileBuf()
  {
    m_hFile = INVALID_HANDLE_VALUE;
    m_iFileShare = 0;
    m_bFileWritten = false;
    m_bError = false;
  }
 
public:
  /** \details
    Opens the specified file with this StreamBuf object.
    \param filename [in]  Filename.
    \param shareMode [in]  Share mode.
    \param accessMode [in]  Access mode.
    \param creationDisposition [in]  Creation disposition.
  */
  virtual void open(const OdString& filename,
    Oda::FileShareMode shareMode,
    Oda::FileAccessMode accessMode,
    Oda::FileCreationDisposition creationDisposition);
#ifndef TD_UNICODE
  virtual void open(const OdCharW* filename,
    Oda::FileShareMode shareMode,
    Oda::FileAccessMode accessMode,
    Oda::FileCreationDisposition creationDisposition);
#endif
 
  /** \details
    Closes the file opened by this StreamBuf object.
  */
  virtual void close();
 
  /** \details
    Returns the name of the file associated with this StreamBuf object.
  */
  virtual OdString fileName() { return m_sFileName; }
 
  /** \details
    Returns the share mode of this StreamBuf object.
  */
  virtual OdUInt32 getShareMode() { return OdUInt32(m_iFileShare); }
 
  /** \details
    Returns the length in bytes of the file associated with
    this StreamBuf object.
  */
  virtual OdUInt64 length();
 
  /** \details
    Moves the current position of the file pointer for
    this StreamBuf object to the specified location.
 
    \param offset [in]  Number of bytes.
    \param seekType [in]  Seek type.
 
    \remarks
    seekType must be one of the following:
 
    <table>
    Name                    Value       Description.
    OdDb::kSeekFromStart    SEEK_SET    Start of file.
    OdDb::kSeekFromCurrent  SEEK_CUR    Current position of file pointer.
    OdDb::kSeekFromEnd      SEEK_END    End of file.
    </table>
  */
  virtual OdUInt64 seek(OdInt64 offset, OdDb::FilerSeekType seekType);
 
  /** \details
    Returns the current position of the file pointer for
    this StreamBuf object.
  */
  virtual OdUInt64 tell();
 
  /** \details
    Returns true if and only if the current position of the file pointer for
    this StreamBuf object is at the end of file.
  */
  virtual bool isEof();
 
  /** \details
    Returns the byte at the current position of the file pointer
    for this StreamBuf object, and increments the pointer.
  */
  virtual OdUInt8 getByte();
 
  /** \details
    Returns the specified number of bytes, starting at the current position of the file pointer
    for this StreamBuf object, and increments the pointer by numBytes.
    \param buffer [in]  Character buffer.
    \param numBytes [in]  Number of bytes.
  */
  virtual void getBytes(void* buffer, OdUInt32 numBytes);
 
  /** \details
    Writes the byte to the current position of the file pointer
    for this StreamBuf object, and increments the pointer.
    \param value [in]  Byte to write.
  */
  virtual void putByte(OdUInt8 value);
 
  /** \details
    Writes the specified number of bytes, starting at the current position of the file pointer
    for this StreamBuf object, and increments the pointer by numBytes.
    \param buffer [in]  Character buffer.
    \param numBytes [in]  Number of bytes.
  */
  virtual void putBytes(const void* buffer, OdUInt32 numBytes);
 
  /** \details
    Sets the physical file size for the specified file associated with this 
    StreamBuf object to the current position of the file pointer.
  */
  virtual void truncate();
 
   /** \details
    Copies the specified bytes from this StreamBuf object to the specified StreamBuf object.
    \param pDestination [in]  Pointer to the StreamBuf object to receive the data.
    \param sourceStart [in]  Starting position of the file pointer of this StreamBuf object.
    \param sourceEnd [in]  Ending position of the file pointer of this StreamBuf object.
    \remarks
    Bytes are copied from sourceStart to sourceEnd inclusive.
   */
 virtual void copyDataTo(OdStreamBuf* pDestination, OdUInt64 sourceStart, OdUInt64 sourceEnd);
};
 
class OdRdFileBuf;
 
/** \remarks
  This template class is a specialization of the OdSmartPtr class for OdRdFileBuf object pointers.
*/
typedef OdSmartPtr<OdRdFileBuf> OdRdFileBufPtr;
 
/** \details
  This class implements file input.
  \sa
  Source code provided.
  <group ExServices_Classes>
*/
class OdRdFileBuf : public OdBaseFileBuf
{
  OdRdFileBuf(const OdRdFileBuf& source);
  OdRdFileBuf& operator = (const OdRdFileBuf& source);
 
protected:
  HANDLE      m_hFileMap;
  LPVOID      m_pFileMap;
  ULARGE_INTEGER  m_ulSize;
  ULARGE_INTEGER  m_ulPos;
 
  /*!DOM*/
  inline bool memBufferUsed() const { return m_pFileMap != 0; }
 
public:
  OdRdFileBuf(const OdString& filename)
  {
    m_hFileMap = INVALID_HANDLE_VALUE;
    m_pFileMap = NULL;
    m_ulSize.QuadPart = 0;
    m_ulPos.QuadPart = 0;
 
    open(filename);
  }
 
  /** \details
    \param filename [in]  Filename.
    \param shareMode [in]  Share mode.
    \param accessMode [in]  Access mode.
    \param creationDisposition [in]  Creation disposition.
    \remarks
    Opens filename if specified.
  */
  OdRdFileBuf(
    const OdString& filename,
    Oda::FileShareMode shareMode,
    Oda::FileAccessMode accessMode,
    Oda::FileCreationDisposition creationDisposition)
  {
    m_hFileMap = INVALID_HANDLE_VALUE;
    m_pFileMap = NULL;
    m_ulSize.QuadPart = 0;
    m_ulPos.QuadPart = 0;
 
    open(filename, shareMode, accessMode, creationDisposition);
  }
 
  OdRdFileBuf();
 
  ~OdRdFileBuf() { close(); }
 
  /** \param filename [in]  Filename.
    \param shareMode [in]  Share mode.
    \param accessMode [in]  Access mode.
    \param creationDisposition [in]  Creation disposition.
    \remarks
    Opens filename if specified.
  */
  static OdRdFileBufPtr createObject()
  {
    return OdRdFileBufPtr(new OdRdFileBuf(), kOdRxObjAttach);
  }
 
  static OdRdFileBufPtr createObject(
    const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyWrite,
    Oda::FileAccessMode accessMode = Oda::kFileRead,
    Oda::FileCreationDisposition creationDisposition = Oda::kOpenExisting)
  {
    return OdRdFileBufPtr(new OdRdFileBuf(filename, shareMode, accessMode, creationDisposition), kOdRxObjAttach);
  }
 
  virtual void open(const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyWrite,
    Oda::FileAccessMode accessMode = Oda::kFileRead,
    Oda::FileCreationDisposition creationDisposition = Oda::kOpenExisting);
#ifndef TD_UNICODE
  virtual void open(const OdCharW* filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyWrite,
    Oda::FileAccessMode accessMode = Oda::kFileRead,
    Oda::FileCreationDisposition creationDisposition = Oda::kOpenExisting);
#endif
 
  virtual void close();
 
  virtual OdUInt64 length();
  virtual OdUInt64 seek(OdInt64 offset, OdDb::FilerSeekType seekType);
  virtual OdUInt64 tell();
  virtual bool isEof();
  virtual OdUInt8 getByte();
  virtual void getBytes(void* buffer, OdUInt32 numBytes);
  virtual void putByte(OdUInt8 value);
  virtual void putBytes(const void* buffer, OdUInt32 numBytes);
  virtual void truncate();
 
  virtual void copyDataTo(OdStreamBuf* pDestination, OdUInt64 sourceStart, OdUInt64 sourceEnd);
};
 
#define WRITING_BUFFER_LENGTH 1024*8
class OdWrFileBuf;
 
/** \remarks
  This template class is a specialization of the OdSmartPtr class for OdWrFileBuf object pointers.
*/
typedef OdSmartPtr<OdWrFileBuf> OdWrFileBufPtr;
 
/** \details
  This class implements file output.
  \sa
  Source code provided.
  <group ExServices_Classes>
*/
class OdWrFileBuf : public OdBaseFileBuf
{
  OdWrFileBuf(const OdWrFileBuf& source);
  OdWrFileBuf& operator = (const OdWrFileBuf& source);
  OdUInt8 m_pBuffer[WRITING_BUFFER_LENGTH+1]; // +1 is to suppress /analyse false positive
  OdUInt32 m_nBufferedSize;
  inline void flush()
  {
    if ( m_nBufferedSize == 0 )
      return;
    OdBaseFileBuf::putBytes(m_pBuffer, m_nBufferedSize);
    m_nBufferedSize = 0;
  }
 
public:
 
  /** \details
    \param filename [in]  Filename.
    \param shareMode [in]  Share mode.
    \param accessMode [in]  Access mode.
    \param creationDisposition [in]  Creation disposition.
    \remarks
    Opens filename if specified.
  */
  OdWrFileBuf(const OdString& filename):m_nBufferedSize(0) { open(filename); }
  OdWrFileBuf(
    const OdString& filename,
    Oda::FileShareMode shareMode,
    Oda::FileAccessMode accessMode,
    Oda::FileCreationDisposition creationDisposition):m_nBufferedSize(0)
  {
    open(filename, shareMode, accessMode, creationDisposition);
  }
 
  OdWrFileBuf();
 
  ~OdWrFileBuf();
 
  /** \param filename [in]  Filename.
    \param shareMode [in]  Share mode.
    \param accessMode [in]  Access mode.
    \param creationDisposition [in]  Creation disposition.
    \remarks
    Opens filename if specified.
  */
  static OdWrFileBufPtr createObject()
  {
    return OdWrFileBufPtr(new OdWrFileBuf(), kOdRxObjAttach);
  }
  static OdWrFileBufPtr createObject(const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyNo,
    Oda::FileAccessMode accessMode = Oda::kFileWrite,
    Oda::FileCreationDisposition creationDisposition = Oda::kCreateAlways)
  {
    return OdWrFileBufPtr(new OdWrFileBuf(filename, shareMode, accessMode, creationDisposition), kOdRxObjAttach);
  }
 
  virtual void close();
  virtual OdUInt64 seek(OdInt64 offset, OdDb::FilerSeekType seekType);
  virtual void copyDataTo(OdStreamBuf* pDestination, OdUInt64 sourceStart, OdUInt64 sourceEnd);
  virtual OdUInt64 tell();
  virtual OdUInt64 length();
 
  virtual void putByte(OdUInt8 value);
  virtual void putBytes(const void* buffer, OdUInt32 numBytes);
  virtual OdUInt8 getByte();
  virtual void getBytes(void* buffer, OdUInt32 numBytes);
 
  virtual void open(const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyNo,
    Oda::FileAccessMode accessMode = Oda::kFileWrite,
    Oda::FileCreationDisposition creationDisposition = Oda::kCreateAlways);
#ifndef TD_UNICODE
  virtual void open(const OdCharW* filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyNo,
    Oda::FileAccessMode accessMode = Oda::kFileWrite,
    Oda::FileCreationDisposition creationDisposition = Oda::kCreateAlways);
#endif
};
 
#else // #ifdef WIN32
 
#include <stdio.h>
#include <memory>
#include "DbSystemServices.h"
#include "OdString.h"
#include "RxObjectImpl.h"
 
#define ERR_VAL ((OdUInt64)-1)
 
/** <group ExServices_Classes>
*/
class FileToRemoveOnClose
{
  char* fName;
public:
  void setFileName(const char* fileName)
  {
    free(fName);
    fName = (char*)malloc(strlen(fileName)+1);
    strcpy(fName, fileName);
  }
  FileToRemoveOnClose():fName(NULL){ }
  ~FileToRemoveOnClose()
  { 
    if ( fName && strlen(fName)>0 )
    {
#ifdef OD_HAVE_REMOVE_FUNC
      remove(fName);
#else
      DeleteFile(OdString(fName).c_str());
#endif
    }
    free(fName);
  }
};
 
class OdBaseFileBuf : public OdRxObjectImpl<OdStreamBuf>
{
  OdBaseFileBuf(const OdBaseFileBuf&);
  OdBaseFileBuf& operator = (const OdBaseFileBuf&);
  std::auto_ptr< FileToRemoveOnClose > m_pFtr;
 
public:
          OdBaseFileBuf();
  virtual ~OdBaseFileBuf(){ close(); };
 
  virtual void      open(
    const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyNo,
    Oda::FileAccessMode accessMode = Oda::FileAccessMode(Oda::kFileRead | Oda::kFileWrite),
    Oda::FileCreationDisposition creationDisposition = Oda::kOpenExisting);
 
         virtual void      close();
  inline virtual OdString  fileName()     { return m_FileName; }
         virtual OdUInt8   getByte();
         virtual void      getBytes(void* buffer, OdUInt32 numBytes);
         virtual void      putByte(OdUInt8 value);
         virtual void      putBytes(const void* buffer, OdUInt32 numBytes);
  inline virtual OdUInt64  length()       { return m_length; };
//         virtual OdUInt64  length();
  inline virtual OdUInt32  getShareMode() { return (OdUInt32)m_shMode; };
  inline virtual OdUInt64  tell()         { return m_position; };
  inline virtual bool      isEof()        { return (m_position >= m_length); };
         virtual OdUInt64  seek(OdInt64 offset, OdDb::FilerSeekType seekType);
         virtual void      truncate();
 
protected:
  FILE *              m_fp;
  OdString            m_FileName;
  OdUInt64            m_length;
  OdUInt64            m_position;
  Oda::FileShareMode  m_shMode;
  bool                m_prevWasRead;
 
  void Unlink(const char* fileName){ m_pFtr->setFileName(fileName); }
};
 
class OdWrFileBuf;
typedef OdSmartPtr<OdWrFileBuf> OdWrFileBufPtr;
 
class OdWrFileBuf : public OdBaseFileBuf
{
  OdWrFileBuf(const OdWrFileBuf& source);
  OdWrFileBuf& operator = (const OdWrFileBuf& source);
 
public:
  OdWrFileBuf(const OdString& filename) { open(filename); }
  OdWrFileBuf(const OdString& filename, Oda::FileShareMode shareMode) { open(filename, shareMode); }
  OdWrFileBuf(const OdString& filename, Oda::FileShareMode shareMode, Oda::FileAccessMode accessMode, Oda::FileCreationDisposition creationDisposition) 
  { 
    open(filename, shareMode, accessMode, creationDisposition); 
  }
  OdWrFileBuf(){};
  ~OdWrFileBuf(){ close(); };
 
  static OdWrFileBufPtr createObject()
  {
    return OdWrFileBufPtr(new OdWrFileBuf(), kOdRxObjAttach);
  }
  static OdWrFileBufPtr createObject(const OdString& filename, Oda::FileShareMode shareMode = Oda::kShareDenyNo)
  {
    return OdWrFileBufPtr(new OdWrFileBuf(filename, shareMode), kOdRxObjAttach);
  }
 
  virtual void open(const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyNo,
    Oda::FileAccessMode accessMode = Oda::kFileWrite,
    Oda::FileCreationDisposition creationDisposition = Oda::kCreateAlways);
};
 
 
#define NUM_BUFFERS 8
 
class OdRdFileBuf;
typedef OdSmartPtr<OdRdFileBuf> OdRdFileBufPtr;
 
class OdRdFileBuf : public OdBaseFileBuf
{
  OdRdFileBuf(const OdRdFileBuf&);
  OdRdFileBuf& operator = (const OdRdFileBuf&);
 
public:
  OdRdFileBuf(const OdString& filename) : m_Counter(0L) { init(); open(filename); }
  OdRdFileBuf(const OdString& filename, Oda::FileShareMode shareMode) : m_Counter(0L)
  {
    init();
    open(filename, shareMode);
  }
  OdRdFileBuf(const OdString& filename, Oda::FileShareMode shareMode, Oda::FileAccessMode accessMode, Oda::FileCreationDisposition creationDisposition) : m_Counter(0L)
  {
    init();
    open(filename, shareMode, accessMode, creationDisposition);
  }
  OdRdFileBuf();
  static OdRdFileBufPtr createObject()
  {
    return OdRdFileBufPtr(new OdRdFileBuf(), kOdRxObjAttach);
  }
  static OdRdFileBufPtr createObject(const OdString& filename, Oda::FileShareMode shareMode = Oda::kShareDenyNo)
  {
    return OdRdFileBufPtr(new OdRdFileBuf(filename, shareMode), kOdRxObjAttach);
  }
  ~OdRdFileBuf(){ close(); };
 
  virtual void open(
    const OdString& filename,
    Oda::FileShareMode shareMode = Oda::kShareDenyNo,
    Oda::FileAccessMode accessMode = Oda::kFileRead,
    Oda::FileCreationDisposition creationDisposition = Oda::kOpenExisting);
 
  virtual void close();
 
  virtual OdUInt64  seek(OdInt64 offset, OdDb::FilerSeekType seekType);
  virtual OdUInt64  tell();
  virtual bool      isEof();
  virtual OdUInt8   getByte();
  virtual void      getBytes(void* buffer, OdUInt32 numBytes);
  virtual void      putByte(OdUInt8 value) { ODA_FAIL();  throw OdError(eNotApplicable); };
  virtual void      putBytes(const void* buffer, OdUInt32 numBytes) { ODA_FAIL();  throw OdError(eNotApplicable); };
  virtual void      truncate();
 
protected:
  struct blockstru
  {
    OdUInt8*  buf;        /* this buffer */
    OdUInt64  startaddr;  /* address from which it came in the file */
    int       validbytes; /* number of valid bytes it holds */
    OdInt32   counter;    /* least recently used counter */
  };
 
  OdUInt64  m_PhysFilePos; /* where the file pointer is */
  OdUInt64  m_BufPos;      /* position from which buf was filled */
  int       m_BytesLeft;   /* bytes left in buf */
  int       m_BufBytes;    /* valid bytes read into buffer */
  OdUInt8*  m_pNextChar;   /* pointer to next char in buffer */
  OdUInt8*  m_pCurBuf;     /* pointer to the buffer currently being used */
  int       m_UsingBlock;  /* which block is currently in use */
  struct blockstru         /* the data being held */
            m_DataBlock[NUM_BUFFERS];
 
  static const int m_BufSize; /* size of each read buffer */
  static const int  m_PosMask; /* mask to allow position check */
  OdInt32    m_Counter;
 
  bool filbuf();
  void init();
};
 
#endif // #ifdef WIN32
#include "TD_PackPop.h"
#endif // ODFILEBUF_DEFINED