forked from niftools/nifskope
-
Notifications
You must be signed in to change notification settings - Fork 0
/
nifvalue.h
670 lines (593 loc) · 24.1 KB
/
nifvalue.h
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
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
/***** BEGIN LICENSE BLOCK *****
BSD License
Copyright (c) 2005-2012, NIF File Format Library and Tools
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the NIF File Format Library and Tools project may not be
used to endorse or promote products derived from this software
without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
***** END LICENCE BLOCK *****/
#ifndef NIFVALUE_H
#define NIFVALUE_H
#include <QDataStream>
#include <QIODevice>
#include <QPair>
#include <QVariant>
#include <QHash>
#include <QString>
#include "niftypes.h"
//! \file nifvalue.h NifValue, NifIStream, NifOStream, NifSStream
// if there is demand for it, consider moving these into Options
//! Number of decimals when editing vector types (Vector2, Vector3, Vector4)
#define VECTOR_DECIMALS 4
//! Maximum/minimum range when editing vector types (Vector2, Vector3, Vector4)
#define VECTOR_RANGE 100000000
//! Number of decimals when editing Quat rotations in Euler mode
#define ROTATION_COARSE 2
//! Number of decimals when editing Quat rotations in Axis-Angle mode
#define ROTATION_FINE 5
//! Number of decimals when editing color types (Color3, Color4)
#define COLOR_DECIMALS 3
//! Increment when editing color types (Color3, Color4)
#define COLOR_STEP 0.01
//! A generic class used for storing a value of any type.
/*!
* The NifValue::Type enum lists all supported types.
*/
class NifValue
{
Q_DECLARE_TR_FUNCTIONS(NifValue)
public:
//! List of all types implemented internally by NifSkope.
/*!
* To add a new type, add a new enumerant to Type, and update NifValue::initialize()
* to reflect the name of the type as used in the xml.
*/
enum Type
{
// all count types should come between tBool and tUInt
tBool = 0,
tByte = 1,
tWord = 2,
tFlags = 3,
tStringOffset = 4,
tStringIndex = 5,
tBlockTypeIndex = 6,
tInt = 7,
tShort = 8,
tUInt = 9,
//
tLink = 10,
tUpLink = 11,
tFloat = 12,
// all string types should come between tSizedString and tChar8String
tSizedString = 13,
tText = 15,
tShortString = 16,
tHeaderString = 18,
tLineString = 19,
tChar8String = 20,
//
tColor3 = 21,
tColor4 = 22,
tVector3 = 23,
tQuat = 24,
tQuatXYZW = 25,
tMatrix = 26,
tMatrix4 = 27,
tVector2 = 28,
tVector4 = 29,
tTriangle = 30,
tFileVersion = 31,
tByteArray = 32,
tStringPalette = 33,
tString = 34, //!< not a regular string: an integer for nif versions 20.1.0.3 and up
tFilePath = 35, //!< not a string: requires special handling for slash/backslash etc.
tByteMatrix = 36,
tBlob = 37,
tNone = 0xff
};
enum EnumType
{
eNone, //!< Not an enum
eDefault, //!< Standard enum
eFlags, //!< bitflag enum
};
// *** apparently not used ***
//template <typename T> static Type typeId();
//! Initialize the class data
/*!
* Sets typeMap. Clears typeTxt and enumMap (which will be filled later during xml parsing).
*/
static void initialize();
//! Get the Type corresponding to a string typId, as stored in the typeMap.
/*!
* \param typId The type string (as used in the xml).
* \return The Type corresponding to the string, or tNone if the type is not found.
*/
static Type type( const QString & typId );
//! Get a html formatted description of the type.
static QString typeDescription( const QString & typId );
//! Update the typeTxt map with the type description. Newline characters are replaced by html line break tags.
static void setTypeDescription( const QString & typId, const QString & txt );
//! Register an alias for a type.
/*!
* This is done by updating the typeMap and maps the alias string to the type
* corresponding to the internal string.
*/
static bool registerAlias( const QString & alias, const QString & internal );
//! A struct holding information about a enumeration
struct EnumOptions {
EnumType t; //!< The enumeration type
QHash<quint32, QPair<QString, QString> > o; //!< The enumeration dictionary as a value, a name and a description
};
//! Register an enum type.
static bool registerEnumType( const QString & eid, EnumType eTyp );
//! Register an option for an enum type.
/*!
* \param eid The name of the enum type.
* \param oid The name of the option of that type to add.
* \param oval The value of that option.
* \param otxt The documentation string for the option.
* \return true if successful, false if the option value was already registered.
*/
static bool registerEnumOption( const QString & eid, const QString & oid, quint32 oval, const QString & otxt );
//! Get the name of an option from its value.
static QString enumOptionName( const QString & eid, quint32 oval );
//! Get the documentation string of an option from its value.
static QString enumOptionText( const QString & eid, quint32 oval );
//! Get an option from an option string.
/*!
* \param eid The name of the enum type.
* \param oid The name of the option.
* \param ok Is set to true if successful, is set to false if the option string was not found.
*/
static quint32 enumOptionValue( const QString & eid, const QString & oid, bool * ok = 0 );
//! Get list of all options that have been registered for the given enum type.
static QStringList enumOptions( const QString & eid );
//! Get type of enum for given enum type
static EnumType enumType( const QString & eid );
//! Get list of all options that have been registered for the given enum type.
static const EnumOptions& enumOptionData( const QString & eid );
//! Constructor - initialize the value to nothing, type tNone.
NifValue() { typ = tNone; abstract = false; }
//! Constructor - initialize the value to a default value of the specified type.
NifValue( Type t );
//! Copy constructor.
NifValue( const NifValue & other );
//! Destructor.
~NifValue();
//! Clear the data, setting its type to tNone.
void clear();
//! Change the type of data stored.
/*!
* Clears existing data, changes its type, and then reinitializes the data to its default.
* Note that if Type is the same as originally, then the data is not cleared.
*/
void changeType( Type );
//! Get the abstract flag on this value. Does not seem to be reliably initialised yet.
inline bool isAbstract() { return abstract; }
//! Set the abstract flag on this value.
inline void setAbstract( bool flag ) { abstract = flag; }
//! Assignment. Performs a deep copy of the data.
void operator=( const NifValue & other );
//! Get the type.
Type type() const { return typ; }
//! Check if the type is not tNone.
static bool isValid( Type t ) { return t != tNone; }
//! Check if a type is of a link type (Ref or Ptr in xml).
static bool isLink( Type t ) { return t == tLink || t == tUpLink; }
//! Check if the type of the data is not tNone.
bool isValid() const { return typ != tNone; }
//! Check if the type of the data is a color type (Color3 or Color4 in xml).
bool isColor() const { return typ == tColor3 || typ == tColor4; }
//! Check if the type of the data is a count.
bool isCount() const { return (typ >= tBool && typ <= tUInt); }
//! Check if the type of the data is a flag type (Flags in xml).
bool isFlags() const { return typ == tFlags; }
//! Check if the type of the data is a float type (Float in xml).
bool isFloat() const { return typ == tFloat; }
//! Check if the type of the data is of a link type (Ref or Ptr in xml).
bool isLink() const { return typ == tLink || typ == tUpLink; }
//! Check if the type of the data is a 3x3 matrix type (Matrix33 in xml).
bool isMatrix() const { return typ == tMatrix; }
//! Check if the type of the data is a 4x4 matrix type (Matrix44 in xml).
bool isMatrix4() const { return typ == tMatrix4; }
//! Check if the type of the data is a quaternion type.
bool isQuat() const { return typ == tQuat || typ == tQuatXYZW; }
//! Check if the type of the data is a string type.
bool isString() const { return (typ >= tSizedString && typ <= tChar8String) || typ == tString; }
//! Check if the type of the data is a Vector 4.
bool isVector4() const { return typ == tVector4; }
//! Check if the type of the data is a Vector 3.
bool isVector3() const { return typ == tVector3; }
//! Check if the type of the data is a Vector 2.
bool isVector2() const { return typ == tVector2; }
//! Check if the type of the data is a triangle type.
bool isTriangle() const { return typ == tTriangle; }
//! Check if the type of the data is a byte array.
bool isByteArray() const { return typ == tByteArray || typ == tStringPalette || typ == tBlob; }
//! Check if the type of the data is a File Version.
bool isFileVersion() const { return typ == tFileVersion; }
//! Check if the type of the data is a byte matrix.
bool isByteMatrix() const { return typ == tByteMatrix; }
//! Return the value of the data as a QColor, if applicable.
QColor toColor() const;
//! Return the value of the data as a count.
quint32 toCount() const;
//! Return the value of the data as a float.
float toFloat() const;
//! Return the value of the data as a link, if applicable.
qint32 toLink() const;
//! Return the value of the data as a file version, if applicable.
quint32 toFileVersion() const;
//! Return a string which represents the value of the data.
QString toString() const;
//! See the documentation of QVariant for details.
QVariant toVariant() const;
//! Set this value to a count.
/**
* \return True if applicable, false otherwise
*/
bool setCount( quint32 );
//! Set this value to a float.
/**
* \return True if applicable, false otherwise
*/
bool setFloat( float );
//! Set this value to a link.
/**
* \return True if applicable, false otherwise
*/
bool setLink( int );
//! Set this value to a file version.
/**
* \return True if applicable, false otherwise
*/
bool setFileVersion( quint32 );
//! Set this value from a string.
/**
* \return True if applicable, false otherwise
*/
bool fromString( const QString & );
//! Set this value from a QVariant.
/**
* \return True if applicable, false otherwise
*/
bool fromVariant( const QVariant & );
//! Check whether the data is of type T.
template <typename T> bool ask( T * t = 0 ) const;
//! Get the data in the form of something of type T.
template <typename T> T get() const;
//! Set the data from an instance of type T. Return true if successful.
template <typename T> bool set( const T & x );
protected:
//! The type of this data.
Type typ;
//! The structure containing the data.
union Value
{
quint8 u08;
quint16 u16;
quint32 u32;
qint32 i32;
float f32;
void * data;
};
//! The data value.
Value val;
//! If the value represents an abstract field. Does not seem to be reliably initialised yet.
bool abstract;
//! Get the data as an object of type T.
/*!
* If the type t is not equal to the actual type of the data, then return T(). Serves
* as a helper function for get, intended for internal use only.
*/
template <typename T> T getType( Type t ) const;
//! Set the data from an object of type T.
/*!
* If the type t is not equal to the actual type of the data, then return false, else
* return true. Helper function for set, intended for internal use only.
*/
template <typename T> bool setType( Type t, T v );
//! A dictionary yielding the Type from a type string.
static QHash<QString, Type> typeMap;
//! A dictionary yielding the enumeration dictionary from a string.
/*!
* Enums are stored as mappings from quint32 to pairs of strings, where
* the first string in the pair is the enumerant string, and the second
* is the enumerant documentation string. For example,
* enumMap["AlphaFormat"][1] = QPair<"ALPHA_BINARY", "Texture is either fully transparent or fully opaque.">
*/
static QHash<QString, EnumOptions> enumMap;
//! A dictionary yielding the documentation string of a type string.
static QHash<QString, QString> typeTxt;
//! A dictionary yielding the underlying type string from an alias string.
/*!
* Enums are stored as an underlying type (not always uint) which is normally not visible.
* This dictionary allows that type to be exposed, eg. for NifValue::typeDescription().
*/
static QHash<QString, QString> aliasMap;
friend class NifIStream;
friend class NifOStream;
friend class NifSStream;
};
// documented above; should this really be inlined?
// GCC only allows type punning via union (http://gcc.gnu.org/onlinedocs/gcc-4.2.1/gcc/Optimize-Options.html#index-fstrict_002daliasing-550)
// This also works on GCC 3.4.5
inline quint32 NifValue::toCount() const { if ( isCount() || isFloat() ) return val.u32; else return 0; }
// documented above
inline float NifValue::toFloat() const { if ( isFloat() ) return val.f32; else return 0.0; }
// documented above
inline qint32 NifValue::toLink() const { if ( isLink() ) return val.i32; else return -1; }
// documented above
inline quint32 NifValue::toFileVersion() const { if ( isFileVersion() ) return val.u32; else return 0; }
// documented above
inline bool NifValue::setCount( quint32 c ) { if ( isCount() ) { val.u32 = c; return true; } else return false; }
// documented above
inline bool NifValue::setFloat( float f ) { if ( isFloat() ) { val.f32 = f; return true; } else return false; }
// documented above
inline bool NifValue::setLink( int l ) { if ( isLink() ) { val.i32 = l; return true; } else return false; }
// documented above
inline bool NifValue::setFileVersion( quint32 v ) { if ( isFileVersion() ) { val.u32 = v; return true; } else return false; }
template <typename T> inline T NifValue::getType( Type t ) const
{
if ( typ == t )
return *static_cast<T*>( val.data ); // WARNING: this throws an exception if the type of v is not the original type by which val.data was initialized; the programmer must make sure that T matches t.
else
return T();
}
template <typename T> inline bool NifValue::setType( Type t, T v )
{
if ( typ == t )
{
*static_cast<T*>( val.data ) = v; // WARNING: this throws an exception if the type of v is not the original type by which val.data was initialized; the programmer must make sure that T matches t.
return true;
}
return false;
}
template <> inline bool NifValue::get() const { return toCount(); }
template <> inline qint32 NifValue::get() const { return toCount(); }
template <> inline quint32 NifValue::get() const { return toCount(); }
template <> inline qint16 NifValue::get() const { return toCount(); }
template <> inline quint16 NifValue::get() const { return toCount(); }
template <> inline quint8 NifValue::get() const { return toCount(); }
template <> inline float NifValue::get() const { return toFloat(); }
template <> inline QColor NifValue::get() const { return toColor(); }
template <> inline QVariant NifValue::get() const { return toVariant(); }
template <> inline Matrix NifValue::get() const { return getType<Matrix>( tMatrix ); }
template <> inline Matrix4 NifValue::get() const { return getType<Matrix4>( tMatrix4 ); }
template <> inline Vector4 NifValue::get() const { return getType<Vector4>( tVector4 ); }
template <> inline Vector3 NifValue::get() const { return getType<Vector3>( tVector3 ); }
template <> inline Vector2 NifValue::get() const { return getType<Vector2>( tVector2 ); }
template <> inline Color3 NifValue::get() const { return getType<Color3>( tColor3 ); }
template <> inline Color4 NifValue::get() const { return getType<Color4>( tColor4 ); }
template <> inline Triangle NifValue::get() const { return getType<Triangle>( tTriangle ); }
template <> inline QString NifValue::get() const
{
if ( isString() )
return *static_cast<QString*>( val.data );
else
return QString();
}
template <> inline QByteArray NifValue::get() const
{
if ( isByteArray() )
return *static_cast<QByteArray*>( val.data );
else
return QByteArray();
}
template <> inline QByteArray* NifValue::get() const
{
if ( isByteArray() )
return static_cast<QByteArray*>( val.data );
else
return NULL;
}
template <> inline Quat NifValue::get() const
{
if ( isQuat() )
return *static_cast<Quat*>( val.data );
else
return Quat();
}
template <> inline ByteMatrix* NifValue::get() const
{
if ( isByteMatrix() )
return static_cast<ByteMatrix*>( val.data );
else
return NULL;
}
//! Set the data from a boolean. Return true if successful.
template <> inline bool NifValue::set( const bool & b ) { return setCount( b ); }
//! Set the data from an integer. Return true if successful.
template <> inline bool NifValue::set( const int & i ) { return setCount( i ); }
//! Set the data from an unsigned integer. Return true if successful.
template <> inline bool NifValue::set( const quint32 & i ) { return setCount( i ); }
//! Set the data from a short. Return true if successful.
template <> inline bool NifValue::set( const qint16 & i ) { return setCount( i ); }
//! Set the data from an unsigned short. Return true if successful.
template <> inline bool NifValue::set( const quint16 & i ) { return setCount( i ); }
//! Set the data from an unsigned byte. Return true if successful.
template <> inline bool NifValue::set( const quint8 & i ) { return setCount( i ); }
//! Set the data from a float. Return true if successful.
template <> inline bool NifValue::set( const float & f ) { return setFloat( f ); }
//! Set the data from a Matrix. Return true if successful.
template <> inline bool NifValue::set( const Matrix & x ) { return setType( tMatrix, x ); }
//! Set the data from a Matrix4. Return true if successful.
template <> inline bool NifValue::set( const Matrix4 & x ) { return setType( tMatrix4, x ); }
//! Set the data from a Vector4. Return true if successful.
template <> inline bool NifValue::set( const Vector4 & x ) { return setType( tVector4, x ); }
//! Set the data from a Vector3. Return true if successful.
template <> inline bool NifValue::set( const Vector3 & x ) { return setType( tVector3, x ); }
//! Set the data from a Vector2. Return true if successful.
template <> inline bool NifValue::set( const Vector2 & x ) { return setType( tVector2, x ); }
//! Set the data from a Color3. Return true if successful.
template <> inline bool NifValue::set( const Color3 & x ) { return setType( tColor3, x ); }
//! Set the data from a Color4. Return true if successful.
template <> inline bool NifValue::set( const Color4 & x ) { return setType( tColor4, x ); }
//! Set the data from a Triangle. Return true if successful.
template <> inline bool NifValue::set( const Triangle & x ) { return setType( tTriangle, x ); }
// should this really be inlined?
//! Set the data from a string. Return true if successful.
template <> inline bool NifValue::set( const QString & x )
{
if ( isString() )
{
if ( val.data == NULL )
{
val.data = new QString;
}
*static_cast<QString*>( val.data ) = x;
return true;
}
return false;
}
// should this really be inlined?
//! Set the data from a byte array. Return true if successful.
template <> inline bool NifValue::set( const QByteArray & x )
{
if ( isByteArray() )
{
*static_cast<QByteArray*>( val.data ) = x;
return true;
}
return false;
}
// should this really be inlined?
//! Set the data from a quaternion. Return true if successful.
template <> inline bool NifValue::set( const Quat & x )
{
if ( isQuat() )
{
*static_cast<Quat*>( val.data ) = x;
return true;
}
return false;
}
//! Check whether the data is a boolean.
template <> inline bool NifValue::ask( bool * ) const { return isCount(); }
//! Check whether the data is an integer.
template <> inline bool NifValue::ask( int * ) const { return isCount(); }
//! Check whether the data is a short.
template <> inline bool NifValue::ask( short * ) const { return isCount(); }
//! Check whether the data is a float.
template <> inline bool NifValue::ask( float * ) const { return isFloat(); }
//! Check whether the data is a Matrix.
template <> inline bool NifValue::ask( Matrix * ) const { return type() == tMatrix; }
//! Check whether the data is a Matrix4.
template <> inline bool NifValue::ask( Matrix4 * ) const { return type() == tMatrix4; }
//! Check whether the data is a quaternion.
template <> inline bool NifValue::ask( Quat * ) const { return isQuat(); }
//! Check whether the data is a Vector4.
template <> inline bool NifValue::ask( Vector4 * ) const { return type() == tVector4; }
//! Check whether the data is a Vector3.
template <> inline bool NifValue::ask( Vector3 * ) const { return type() == tVector3; }
//! Check whether the data is a Vector2.
template <> inline bool NifValue::ask( Vector2 * ) const { return type() == tVector2; }
//! Check whether the data is a Color3.
template <> inline bool NifValue::ask( Color3 * ) const { return type() == tColor3; }
//! Check whether the data is a Color4.
template <> inline bool NifValue::ask( Color4 * ) const { return type() == tColor4; }
//! Check whether the data is a Triangle.
template <> inline bool NifValue::ask( Triangle * ) const { return type() == tTriangle; }
//! Check whether the data is a string.
template <> inline bool NifValue::ask( QString * ) const { return isString(); }
//! Check whether the data is a byte array.
template <> inline bool NifValue::ask( QByteArray * ) const { return isByteArray(); }
class BaseModel;
class NifItem;
//! An input stream that reads a file into a model.
class NifIStream
{
Q_DECLARE_TR_FUNCTIONS(NifIStream)
public:
//! Constructor.
NifIStream( BaseModel * m, QIODevice * d ) : model( m ), device( d )
{
init();
}
//! Reads a NifValue from the underlying device. Returns true if successful.
bool read( NifValue & );
private:
//! The model that data is being read into.
BaseModel * model;
//! The underlying device that data is being read from.
QIODevice * device;
//! The data stream that is wrapped around the device (simplifies endian conversion)
QDataStream * dataStream;
//! Initialises the stream.
void init();
//! Whether a boolean is 32-bit.
bool bool32bit;
//! Whether link adjustment is required.
bool linkAdjust;
//! Whether string adjustment is required.
bool stringAdjust;
//! Whether the model is big-endian
bool bigEndian;
//! The maximum length of a string that can be read.
int maxLength;
};
//! An output stream that writes a model to a file.
class NifOStream
{
Q_DECLARE_TR_FUNCTIONS(NifOStream)
public:
//! Constructor.
NifOStream( const BaseModel * n, QIODevice * d ) : model( n ), device( d ) { init(); }
//! Writes a NifValue to the underlying device. Returns true if successful.
bool write( const NifValue & );
private:
//! The model that data is being read from.
const BaseModel * model;
//! The underlying device that data is being written to.
QIODevice * device;
//! Initialises the stream.
void init();
//! Whether a boolean is 32-bit.
bool bool32bit;
//! Whether link adjustment is required.
bool linkAdjust;
//! Whether string adjustment is required.
bool stringAdjust;
//! Whether the model is big-endian
bool bigEndian;
};
//! A stream that determines the size of values in a model.
class NifSStream
{
public:
//! Constructor.
NifSStream( const BaseModel * n ) : model( n ) { init(); }
//! Determine the size of a given NifValue.
int size( const NifValue & );
private:
//! The model that values are being sized for.
const BaseModel * model;
//! Initialises the stream.
void init();
//! Whether booleans are 32-bit or not.
bool bool32bit;
//! Whether string adjustment is required.
bool stringAdjust;
};
Q_DECLARE_METATYPE( NifValue )
#endif