summaryrefslogtreecommitdiffstats
path: root/binfilter/inc/bf_svtools/filerec.hxx
blob: 6e662416fc26d47fa1ace81d7e4aa4fba0d451fd (plain)
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
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#ifndef _SFXFILEREC_HXX
#define _SFXFILEREC_HXX

#include <bf_svtools/bf_solar.h>

#include <tools/debug.hxx>

#include <tools/stream.hxx>

#include <bf_svtools/svarray.hxx>

namespace binfilter
{

//------------------------------------------------------------------------

#define SFX_REC_PRETAG_EXT              BYTE(0x00)  // Pre-Tag f"ur Extended-Records
#define SFX_REC_PRETAG_EOR              BYTE(0xFF)  // Pre-Tag f"ur End-Of-Records

#define SFX_REC_TYPE_NONE               BYTE(0x00)  // unbekannter Record-Typ
#define SFX_REC_TYPE_FIRST              BYTE(0x01)
#define SFX_REC_TYPE_SINGLE             BYTE(0x01)  // Single-Content-Record
#define SFX_REC_TYPE_FIXSIZE            BYTE(0x02)  // Fix-Size-Multi-Content-Record
#define SFX_REC_TYPE_VARSIZE_RELOC      BYTE(0x03)  // variable Rec-Size
#define SFX_REC_TYPE_VARSIZE            BYTE(0x04)  // alt (nicht verschiebbar)
#define SFX_REC_TYPE_MIXTAGS_RELOC      BYTE(0x07)  // Mixed Tag Content-Record
#define SFX_REC_TYPE_MIXTAGS            BYTE(0x08)  // alt (nicht verschiebbar)
#define SFX_REC_TYPE_LAST               BYTE(0x08)
#define SFX_REC_TYPE_MINI                   0x100   // Mini-Record
#define SFX_REC_TYPE_DRAWENG                0x400   // Drawing-Engine-Record
#define SFX_REC_TYPE_EOR                    0xF00   // End-Of-Records

//------------------------------------------------------------------------

#define SFX_REC_HEADERSIZE_MINI     4   // Gr"o\se des Mini-Record-Headers
#define SFX_REC_HEADERSIZE_SINGLE   4   // zzgl. HEADERSIZE_MINI => 8
#define SFX_REC_HEADERSIZE_MULTI    6   // zzgl. HEADERSIZE_SINGLE => 14

//------------------------------------------------------------------------

#ifndef DBG
#ifdef DBG_UTIL
#define DBG(x) x
#else
#define DBG(x)
#endif
#endif

//------------------------------------------------------------------------

class  SfxMiniRecordReader

/*  [Beschreibung]

    Mit Instanzen dieser Klasse kann ein einfacher Record aus einem Stream
    gelesen werden, der mit der Klasse <SfxRecordWriter> geschrieben wurde.

    Es ist auch m"oglich, den Record zu "uberspringen, ohne sein internes
    Format zu kennen.

    [Beispiel]

    {
        SfxMiniRecordReader aRecord( pStream );
        switch ( aRecord.GetTag() )
        {
            case MY_TAG_X:
                *aRecord >> aMember1;
                *aRecord >> aMember2;
                break;

            ...
        }
    }
*/

{
protected:
    SvStream*           _pStream;   //  <SvStream>, aus dem gelesen wird
    UINT32              _nEofRec;   //  Position direkt hinter dem Record
    bool            _bSkipped;  //  TRUE: der Record wurde explizit geskippt
    BYTE                _nPreTag;   //  aus dem Header gelesenes Pre-Tag

                        // Drei-Phasen-Ctor f"ur Subklassen
                        SfxMiniRecordReader() {}
   void                 Construct_Impl( SvStream *pStream, BYTE nTag )
                        {
                            _pStream = pStream;
                            _bSkipped = FALSE;
                            _nPreTag = nTag;
                        }
    inline bool     SetHeader_Impl( UINT32 nHeader );

                        // als ung"ultig markieren und zur"uck-seeken
    void                SetInvalid_Impl( UINT32 nRecordStartPos )
                        {
                            _nPreTag = SFX_REC_PRETAG_EOR;
                            _pStream->Seek( nRecordStartPos );
                        }

public:
                        SfxMiniRecordReader( SvStream *pStream, BYTE nTag );
    inline              ~SfxMiniRecordReader();

    inline BYTE         GetTag() const;
    inline bool     IsValid() const;

    inline SvStream&    operator*() const;

    inline void         Skip();

private:
                        // not implementend, not allowed
                        SfxMiniRecordReader( const SfxMiniRecordReader& );
    SfxMiniRecordReader& operator=(const SfxMiniRecordReader&);
};

//------------------------------------------------------------------------

class  SfxSingleRecordReader: public SfxMiniRecordReader

/*  [Beschreibung]

    Es ist auch m"oglich, den Record zu "uberspringen, ohne sein internes
    Format zu kennen.

    [Beispiel]

    {
        SfxSingleRecordReader aRecord( pStream );
        switch ( aRecord.GetTag() )
        {
            case MY_TAG_X:
                aRecord >> aMember1;
                if ( aRecord.HasVersion(2) )
                    *aRecord >> aMember2;
                break;

            ...
        }
    }
*/

{
protected:
    UINT16              _nRecordTag;    // Art des Gesamt-Inhalts
    BYTE                _nRecordVer;    // Version des Gesamt-Inhalts
    BYTE                _nRecordType;   // Record Type aus dem Header

                        // Drei-Phasen-Ctor f"ur Subklassen
                        SfxSingleRecordReader() {}
    void                Construct_Impl( SvStream *pStream )
                        {
                            SfxMiniRecordReader::Construct_Impl(
                                    pStream, SFX_REC_PRETAG_EXT );
                        }
    bool            FindHeader_Impl( UINT16 nTypes, UINT16 nTag );
    bool            ReadHeader_Impl( USHORT nTypes );

public:
                        SfxSingleRecordReader( SvStream *pStream, USHORT nTag );

    inline UINT16       GetTag() const;

    inline BYTE         GetVersion() const;
    inline bool     HasVersion( USHORT nVersion ) const;
};

//------------------------------------------------------------------------

class  SfxMultiRecordReader: public SfxSingleRecordReader

/*  [Beschreibung]

    Es ist auch m"oglich, den Record oder einzelne Contents zu "uberspringen,
    ohne das jeweilis interne Format zu kennen.

    [Beispiel]

    {
        SfxMultiRecordReader aRecord( pStream );
        for ( USHORT nRecNo = 0; aRecord.GetContent(); ++nRecNo )
        {
            switch ( aRecord.GetTag() )
            {
                case MY_TAG_X:
                    X *pObj = new X;
                    *aRecord >> pObj.>aMember1;
                    if ( aRecord.HasVersion(2) )
                        *aRecord >> pObj->aMember2;
                    Append( pObj );
                    break;

                ...
            }
        }
    }
*/

{
    UINT32              _nStartPos;     //  Start-Position des Records
    UINT32*             _pContentOfs;   //  Offsets der Startpositionen
    UINT32              _nContentSize;  //  Size jedes einzelnen / Tabellen-Pos
    UINT16              _nContentCount; //  Anzahl der Contents im Record
    UINT16              _nContentNo;    /*  der Index des aktuellen Contents
                                            enth"alt jeweils den Index des
                                            Contents, der beim n"achsten
                                            GetContent() geholt wird */
    UINT16              _nContentTag;   //  Art-Kennung des aktuellen Contents
    BYTE                _nContentVer;   //  Versions-Kennung des akt. Contents

    bool            ReadHeader_Impl();

public:
                        SfxMultiRecordReader( SvStream *pStream, UINT16 nTag );
                        ~SfxMultiRecordReader();

    bool            GetContent();
    inline UINT16       GetContentTag();
    inline BYTE         GetContentVersion() const;
    inline bool     HasContentVersion( USHORT nVersion ) const;

    inline UINT32       ContentCount() const;
};

//=========================================================================

inline SfxMiniRecordReader::~SfxMiniRecordReader()

/*  [Beschreibung]

    Der Dtor der Klasse <SfxMiniRecordReader> positioniert den Stream
    automatisch auf die Position direkt hinter dem Record, falls nicht
    <SfxMiniRecordReader::Skip()> bereits explizit gerufen wurde.
*/

{
    // noch nicht explizit ans Ende gesprungen?
    if ( !_bSkipped )
        Skip();
}

//-------------------------------------------------------------------------

inline void SfxMiniRecordReader::Skip()

/*  [Beschreibung]

    Mit dieser Methode wird der Stream direkt hinter das Ende des Records
    positioniert.
*/

{
    _pStream->Seek(_nEofRec);
    _bSkipped = TRUE;
}

//-------------------------------------------------------------------------

inline BYTE SfxMiniRecordReader::GetTag() const

/*  [Beschreibung]

    Liefert des aus dem Header gelesene Pre-Tag des Records. Dieses kann
    auch SFX_REC_PRETAG_EXT oder SFX_REC_PRETAG_EOR sein, im
    letzteren Fall ist am Stream der Fehlercode ERRCODE_IO_WRONGFORMAT
    gesetzt. SFX_REC_PRETAG_EXT ist g"ultig, da diese extended-Records
    nur eine Erweiterung des SfxMiniRecord darstellen.
*/

{
    return _nPreTag;
}

//-------------------------------------------------------------------------

inline bool SfxMiniRecordReader::IsValid() const

/*  [Beschreibung]

    Hiermit kann abgefragt werden, ob der Record erfolgreich aus dem
    Stream konstruiert werden konnte, der Header also f"ur diesen Record-Typ
    passend war.
*/

{
    return _nPreTag != SFX_REC_PRETAG_EOR;
}

//-------------------------------------------------------------------------

inline SvStream& SfxMiniRecordReader::operator*() const

/*  [Beschreibung]

    Dieser Operator liefert den Stream in dem der Record liegt.
    Die aktuelle Position des Streams mu\s innerhalb des Records liegen.
*/

{
    DBG_ASSERT( _pStream->Tell() < _nEofRec, "read behind record" );
    return *_pStream;
}

//=========================================================================

inline UINT16 SfxSingleRecordReader::GetTag() const

/*  [Beschreibung]

    Liefert des aus dem Header gelesene Tag f"ur den Gesamt-Record.
*/

{
    return _nRecordTag;
}

//-------------------------------------------------------------------------

inline BYTE SfxSingleRecordReader::GetVersion() const

/*  [Beschreibung]

    Liefert die Version des aus dem Stream gelesenen Records.
*/

{
    return _nRecordVer;
}

//-------------------------------------------------------------------------

inline bool SfxSingleRecordReader::HasVersion( USHORT nVersion ) const

/*  [Beschreibung]

    Stellt fest, ob der aus dem Stream gelese Record in der Version
    'nVersion' oder h"oher vorliegt.
*/

{
    return _nRecordVer >= nVersion;
}

//=========================================================================

inline UINT16 SfxMultiRecordReader::GetContentTag()

/*  [Beschreibung]

    Diese Methode liefert die Art-Kennung des zuletzt mit der Methode
    <SfxMultiRecordReder::GetContent()> ge"offneten Contents.
*/

{
    return _nContentTag;
}

//-------------------------------------------------------------------------

inline BYTE SfxMultiRecordReader::GetContentVersion() const

/*  [Beschreibung]

    Diese Methode liefert die Version-Kennung des zuletzt mit der Methode
    <SfxMultiRecordReder::GetContent()> ge"offneten Contents.
*/

{
    return _nContentVer;
}

//-------------------------------------------------------------------------

inline bool SfxMultiRecordReader::HasContentVersion( USHORT nVersion ) const

/*  [Beschreibung]

    Diese Methode stellt fest, ob die Version 'nVersion' in der Version des
    zuletzt mit der Methode <SfxMultiRecordReder::GetContent()> ge"offneten
    Contents enthalten ist.
*/

{
    return _nContentVer >= nVersion;
}

//-------------------------------------------------------------------------

inline UINT32 SfxMultiRecordReader::ContentCount() const

/*  [Beschreibung]

    Diese Methode liefert die Anzahl im Record befindlichen Contents.
*/

{
    return _nContentCount;
}

}

#endif

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */