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
/////////////////////////////////////////////////////////////////////////////// 
// 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 __OdGsFilerV100Impl_H__
#define __OdGsFilerV100Impl_H__
 
#include "TD_PackPush.h"
#include "Ge/GeMatrix3d.h"
#include "Ge/GeExtents3d.h"
#include "DbBaseDatabase.h"
#include "GsFiler.h"
#include "OdStack.h"
#include "RxObjectImpl.h"
 
 
// Database linker
class OdGsFilerDbLinker : public OdRxObject
{
public:
  OdGsFilerDbLinker() { }
  virtual ~OdGsFilerDbLinker() { }
public:
  // Get database hash
  virtual OdBinaryData getDbHash(const OdDbBaseDatabase *pDb) const;
 
  // Transform database handle
  virtual OdUInt64 stubToDbHandle(OdDbStub *pStub) const = 0;
  virtual OdDbStub *handleToDbStub(OdUInt64 nHandle) const = 0;
 
  // Util methods
  virtual OdDbBaseDatabase *getDatabase() const = 0;
  virtual OdDbBaseDatabase *getDatabase(OdDbStub *pStub) const = 0;
};
 
typedef OdSmartPtr<OdGsFilerDbLinker> OdGsFilerDbLinkerPtr;
 
 
 
#define STL_USING_MAP
#define STL_USING_SET
#include "OdaSTL.h"
 
// Implement substitutor
struct GS_TOOLKIT_EXPORT OdGsFiler_SubstitutorImpl : public OdRxObject, public OdGsFiler::Substitutor
{
  template<OdUInt32 nBytes> struct DataTyp
  {
    OdUInt8 m_data[nBytes];
    static int compare(const DataTyp &t1, const DataTyp &t2)
    {
      for (OdUInt32 nb = 0; nb < nBytes; nb++)
      {
        if (t1.m_data[nb] != t2.m_data[nb])
          return int(t1.m_data[nb]) - int(t2.m_data[nb]);
      }
      return 0;
    }
    bool operator ==(const DataTyp &t2) const { return compare(*this, t2) == 0; }
    bool operator !=(const DataTyp &t2) const { return compare(*this, t2) != 0; }
    bool operator <(const DataTyp &t2) const { return compare(*this, t2) < 0; }
    bool operator <=(const DataTyp &t2) const { return compare(*this, t2) <= 0; }
    bool operator >(const DataTyp &t2) const { return compare(*this, t2) > 0; }
    bool operator >=(const DataTyp &t2) const { return compare(*this, t2) >= 0; }
 
    operator const void*() const { return this; }
  };
  struct VoidsSet
  {
    void *m_pVoid;
    OdGsFiler::SubstitutionActuator *m_pAct;
  };
  struct VoidArry : public VoidsSet
  {
    OdInt32 m_nVoids;
    VoidArry()
      : m_nVoids(0)
    {
      m_pVoid = NULL;
      m_pAct = NULL;
    }
    ~VoidArry() { clear(); }
    VoidsSet *getSet() { return (VoidsSet*)m_pVoid; }
    VoidsSet *at(OdInt32 n) {
      if (m_nVoids == 1)
        return this;
      return getSet() + n;
    }
    bool contains(void *pVoid);
    void add(void *pVoid, OdGsFiler::SubstitutionActuator *pAct);
    void kill(void *pVoid);
    void clear();
  };
 
  struct AbstractTyp
  {
    void *m_pContainer;
    AbstractTyp() : m_pContainer(NULL) { }
  };
  typedef std::map<OdUInt32, AbstractTyp> RegsMap;
  typedef std::map<OdUInt32, AbstractTyp> SubstsMap;
  RegsMap m_regs;
  SubstsMap m_substs;
 
  template<OdUInt32 nBytes> struct Procs
  {
    typedef OdGsFiler_SubstitutorImpl::DataTyp<nBytes> ProcTyp;
    typedef std::map<ProcTyp, ProcTyp> RegMap;
    typedef std::map<ProcTyp, VoidArry> SubstMap;
    static void makeSubst(void *pPlace, const void *pSubstitution)
    {
      *(ProcTyp*)(pPlace) = *(const ProcTyp*)(pSubstitution);
    }
    static void runSubst(void *pPlace, const void *pSubstitution, OdGsFiler::SubstitutionActuator *pActuator)
    {
      ODA_ASSERT(pActuator);
      pActuator->applySubstitution(pPlace, pSubstitution, makeSubst);
    }
    static void subst(OdGsFiler_SubstitutorImpl &impl, const void *pValue, void *pPlace, OdGsFiler::SubstitutionActuator *pAct, const void *pSubstitution, bool bClear)
    {
      if (pPlace && pSubstitution)
      {
        runSubst(pPlace, pSubstitution, pAct);
        return;
      }
      if (pValue)
      {
        if (pPlace)
        {
          RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer;
          OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue);
          if (itReg != pRegMap->end())
          {
            runSubst(pPlace, itReg->second, pAct);
            if (bClear)
              pRegMap->erase(itReg);
          }
        }
        else if (pSubstitution)
        {
          SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer;
          OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(*(const ProcTyp*)pValue);
          if (itSub != pSubMap->end())
          {
            for (OdInt32 n = 0; n < itSub->second.m_nVoids; n++)
              runSubst(itSub->second.at(n)->m_pVoid, pSubstitution, itSub->second.at(n)->m_pAct);
            if (bClear)
              pSubMap->erase(itSub);
          }
        }
        else
        {
          RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer;
          SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer;
          if (pRegMap && pSubMap)
          {
            OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue);
            OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(*(const ProcTyp*)pValue);
            if ((itReg != pRegMap->end()) && (itSub != pSubMap->end()))
            {
              for (OdInt32 n = 0; n < itSub->second.m_nVoids; n++)
                runSubst(itSub->second.at(n)->m_pVoid, itReg->second, itSub->second.at(n)->m_pAct);
            }
            if (bClear)
            {
              if (itReg != pRegMap->end())
                pRegMap->erase(itReg);
              if (itSub != pSubMap->end())
                pSubMap->erase(itSub);
            }
          }
          else if (bClear)
          {
            if (pRegMap)
            {
              OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue);
              if (itReg != pRegMap->end())
                pRegMap->erase(itReg);
            }
            if (pSubMap)
            {
              OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(*(const ProcTyp*)pValue);
              if (itSub != pSubMap->end())
                pSubMap->erase(itSub);
            }
          }
        }
        return;
      }
      RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer;
      SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer;
      if (pRegMap && pSubMap)
      {
        OD_TYPENAME RegMap::iterator itReg = pRegMap->begin();
        while (itReg != pRegMap->end())
        {
          OD_TYPENAME SubstMap::iterator itSub = pSubMap->find(itReg->first);
          if (itSub != pSubMap->end())
          {
            for (OdInt32 n = 0; n < itSub->second.m_nVoids; n++)
              runSubst(itSub->second.at(n)->m_pVoid, itReg->second, itSub->second.at(n)->m_pAct);
          }
          itReg++;
        }
      }
      if (bClear)
      {
        if (pRegMap) { delete pRegMap; impl.m_regs[nBytes].m_pContainer = NULL; }
        if (pSubMap) { delete pSubMap; impl.m_substs[nBytes].m_pContainer = NULL; }
      }
    }
    static void reg(OdGsFiler_SubstitutorImpl &impl, const void *pValue, const void *pSubstitution, bool bRegister, bool bImmediate)
    {
      if (bRegister)
      {
        OdGsFiler_SubstitutorImpl::AbstractTyp &cont = impl.m_regs[nBytes];
        if (!cont.m_pContainer)
          cont.m_pContainer = new RegMap;
        RegMap &pMap = *(RegMap*)cont.m_pContainer;
        pMap[*(const ProcTyp*)pValue] = *(const ProcTyp*)pSubstitution;
      }
      if (bImmediate)
        subst(impl, pValue, NULL, NULL, pSubstitution, false);
    }
    static void req(OdGsFiler_SubstitutorImpl &impl, void *pPlace, OdGsFiler::SubstitutionActuator *pAct, const void *pValue, bool bRegister, bool bImmediate)
    {
      if (bRegister)
      {
        if (bImmediate)
        {
          RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer;
          if (pRegMap)
          {
            OD_TYPENAME RegMap::iterator itReg = pRegMap->find(*(const ProcTyp*)pValue);
            if (itReg != pRegMap->end())
            {
              runSubst(pPlace, itReg->second, pAct);
              return;
            }
          }
        }
        OdGsFiler_SubstitutorImpl::AbstractTyp &cont = impl.m_substs[nBytes];
        if (!cont.m_pContainer)
          cont.m_pContainer = new SubstMap;
        SubstMap &pMap = *(SubstMap*)cont.m_pContainer;
        pMap[*(const ProcTyp*)pValue].add(pPlace, pAct);
      }
      else if (bImmediate)
        subst(impl, pValue, pPlace, pAct, NULL, false);
    }
    static void clear(OdGsFiler_SubstitutorImpl &impl, const void *pValue)
    {
      RegMap *pRegMap = (RegMap*)impl.m_regs[nBytes].m_pContainer;
      SubstMap *pSubMap = (SubstMap*)impl.m_substs[nBytes].m_pContainer;
      if (pValue)
      {
        if (pRegMap)
        {
          OD_TYPENAME RegMap::iterator it = pRegMap->find(*(const ProcTyp*)pValue);
          if (it != pRegMap->end())
            pRegMap->erase(it);
        }
        if (pSubMap)
        {
          OD_TYPENAME SubstMap::iterator it = pSubMap->find(*(const ProcTyp*)pValue);
          if (it != pSubMap->end())
            pSubMap->erase(it);
        }
      }
      else
      {
        if (pRegMap) { delete pRegMap; impl.m_regs[nBytes].m_pContainer = NULL; }
        if (pSubMap) { delete pSubMap; impl.m_substs[nBytes].m_pContainer = NULL; }
      }
    }
  };
 
  static OdGsFiler::SubstitutionActuator g_defActuator;
  static struct OdRxObjectSubstitutionActuator : public OdGsFiler::SubstitutionActuator
  {
    OdRxObjectSubstitutionActuator() { }
    virtual void applySubstitution(void *pPlace, const void *pValue, SetPtrFunc pSetFunc)
    {
      OdGsFiler::SubstitutionActuator::applySubstitution(pPlace, pValue, pSetFunc);
      if (pPlace)
        (*reinterpret_cast<OdRxObjectPtr*>(pPlace))->addRef();
    }
  } g_rxObjectActuator;
 
  // Register known substitution
  virtual void registerSubstitution(const void *pValue, const void *pSubstitution, OdUInt32 size = sizeof(OdIntPtr), bool bRegister = true, bool bImmediate = false);
  // Register substitution request
  virtual void requestSubstitution(void *pPlace, const void *pValue, OdUInt32 size = sizeof(OdIntPtr), bool bRegister = true, bool bImmediate = true);
  // Register substitution request for smart pointer
  virtual void requestSubstitution(OdBaseObjectPtr *pPlace, const void *pValue, bool bRegister = true, bool bImmediate = true);
  // Register substitution with non-default behavior
  virtual void requestSubstitution(void *pPlace, OdGsFiler::SubstitutionActuator *pActuator, const void *pValue, OdUInt32 size = sizeof(OdIntPtr), bool bRegister = true, bool bImmediate = true);
  // Clear substitutions
  virtual void clearSubstitutions(const void *pValue = NULL, OdUInt32 size = 0);
  // Run substitutions
  virtual void runSubstitutions(const void *pValue = NULL, OdUInt32 size = 0, bool bClear = true);
#undef REG_FUNCCALL
  ~OdGsFiler_SubstitutorImpl() { clearSubstitutions(); }
};
 
 
// Implement V1 version filer
class GS_TOOLKIT_EXPORT OdGsFilerV100Impl : public OdGsFiler {
protected:
  enum Flags {
    kOpenedForWrite = (1 << 0),
 
    kLastFlag = kOpenedForWrite
  };
protected:
  mutable OdStreamBufPtr  m_pStream;
  OdGsFilerDbLinkerPtr    m_pLinker;
  OdUInt64                m_nSectionsToWrite;
  OdUInt64                m_nSectionsToRead;
  OdUInt32                m_nFlags;
  OdUInt32                m_nVersion;
  mutable Section         m_nCurSection;
  mutable OdUInt32        m_nCurSectionSize;
  struct WrSectionData {
    OdGsFiler::Section  m_type;
    OdUInt64            m_begin;
    WrSectionData()
      : m_type(OdGsFiler::kEOFSection)
      , m_begin(0)
    { }
    WrSectionData(OdGsFiler::Section section, OdUInt32 tell)
      : m_type(section)
      , m_begin(tell)
    { }
  };
  OdStack<WrSectionData> m_sectionStack;
  mutable OdSmartPtr<OdGsFiler_SubstitutorImpl> m_subst;
  typedef std::map<OdString, OdRxObjectPtr> ArbDataMap;
  ArbDataMap m_arbData;
  typedef std::set<const void *> RegPtrsSet;
  RegPtrsSet m_regPtrs;
protected:
  bool isWriting() const { return GETBIT(m_nFlags, kOpenedForWrite); }
  void setWriting(bool bSet) { SETBIT(m_nFlags, kOpenedForWrite, bSet); }
 
  void assertWr() const { if (!isWriting()) throw OdError(eNotOpenForWrite); }
  void assertRd() const { if (isWriting()) throw OdError(eNotOpenForRead); }
public:
  OdGsFilerV100Impl()
    : m_nSectionsToWrite(OdUInt64(-1))
    , m_nSectionsToRead(OdUInt64(-1))
    , m_nFlags(0)
    , m_nVersion(kV2)
    , m_nCurSection(kEOFSection)
    , m_nCurSectionSize(0)
  {
    m_subst = OdRxObjectImpl<OdGsFiler_SubstitutorImpl>::createObject();
  }
  ~OdGsFilerV100Impl()
  {
  }
 
  OdUInt32 headerTestChunk() const;
  bool rdHeaderSection();
  void wrHeaderSection();
 
  virtual bool setStream(OdStreamBuf *pStream, bool bWrite = false);
  virtual OdStreamBufPtr getStream() const;
 
  virtual void setDatabase(const OdDbBaseDatabase *pDb);
  virtual OdDbBaseDatabase *getDatabase() const;
 
  virtual void setVersion(OdUInt32 nVersion);
  virtual OdUInt32 version() const;
 
  virtual void wrDbHash(const OdDbBaseDatabase *pDb);
  virtual bool checkDbHash(const OdDbBaseDatabase *pDb);
 
  virtual void setWriteSections(OdUInt64 nSections);
  virtual void setWriteSection(Section section, bool bSet);
  virtual bool isWriteSection(Section section) const;
 
  virtual void setReadSections(OdUInt64 nSections);
  virtual void setReadSection(Section section, bool bSet);
  virtual bool isReadSection(Section section) const;
 
  virtual void wrSectionBegin(Section section);
  virtual void wrSectionEnd(Section section);
  virtual void wrEOFSection();
 
  virtual Section rdSection() const;
  virtual Section curSection() const;
  virtual void skipSection() const;
  virtual void rdBackSection() const;
  virtual bool checkEOF() const;
 
  virtual Substitutor *subst() const;
  virtual void makeSubstitutions(bool bClear = true) const;
  virtual OdRxObjectPtr getSubstitutor() const;
  virtual void setSubstitutor(OdRxObject *pSubst);
 
  virtual void setArbitraryData(const OdChar *pName, OdRxObject *pObject);
  virtual OdRxObjectPtr getArbitraryData(const OdChar *pName) const;
  virtual bool hasArbitraryData(const OdChar *pName) const;
  virtual void clearArbitraryData();
 
  virtual void registerPtr(const void *pPtr);
  virtual void unregisterPtr(const void *pPtr);
  virtual bool isPtrRegistered(const void *pPtr) const;
  virtual void clearRegisteredPtrs();
 
  virtual void wrHandle(OdDbStub *pHandle);
  virtual OdDbStub *rdHandle() const;
 
  virtual void wrClass(OdRxObject *pObj);
  virtual OdRxObjectPtr rdClass() const;
 
  virtual void wrRawData(const void *pData, OdUInt32 nDataSize);
  virtual void rdRawData(void *pData, OdUInt32 nDataSize) const;
};
 
#include "TD_PackPop.h"
 
#endif // __OdGsFilerV100Impl_H__