@@ -35,6 +35,8 @@ class StructField
3535
3636 bool isNative () const { return m_type -> type () <= CspType::Type::MAX_NATIVE_TYPE; }
3737
38+ bool isOptional () const { return m_isOptional; }
39+
3840 void setOffset ( size_t off ) { m_offset = off; }
3941 void setMaskOffset ( size_t off, uint8_t bit )
4042 {
@@ -75,7 +77,7 @@ class StructField
7577protected:
7678
7779 StructField ( CspTypePtr type, const std::string & fieldname,
78- size_t size, size_t alignment );
80+ size_t size, size_t alignment, bool isOptional );
7981
8082 void setIsSet ( Struct * s ) const
8183 {
@@ -108,6 +110,7 @@ class StructField
108110 uint8_t m_maskBit;
109111 uint8_t m_maskBitMask;
110112 CspTypePtr m_type;
113+ const bool m_isOptional;
111114};
112115
113116using StructFieldPtr = std::shared_ptr<StructField>;
@@ -120,7 +123,7 @@ class NativeStructField : public StructField
120123
121124public:
122125 NativeStructField () {}
123- NativeStructField ( const std::string & fieldname ) : NativeStructField( CspType::fromCType<T>::type(), fieldname )
126+ NativeStructField ( const std::string & fieldname, bool isOptional ) : NativeStructField( CspType::fromCType<T>::type(), fieldname, isOptional )
124127 {
125128 }
126129
@@ -157,7 +160,7 @@ class NativeStructField : public StructField
157160 }
158161
159162protected:
160- NativeStructField ( CspTypePtr type, const std::string & fieldname ) : StructField( type, fieldname, sizeof ( T ), alignof ( T ) )
163+ NativeStructField ( CspTypePtr type, const std::string & fieldname, bool isOptional ) : StructField( type, fieldname, sizeof ( T ), alignof ( T ), isOptional )
161164 {}
162165};
163166
@@ -179,7 +182,8 @@ using TimeStructField = NativeStructField<Time>;
179182class CspEnumStructField final : public NativeStructField<CspEnum>
180183{
181184public:
182- CspEnumStructField ( CspTypePtr type, const std::string & fieldname ) : NativeStructField( type, fieldname )
185+ CspEnumStructField ( CspTypePtr type, const std::string & fieldname, bool isOptional ) : NativeStructField( type,
186+ fieldname, isOptional )
183187 {}
184188};
185189
@@ -218,8 +222,8 @@ class NotImplementedStructField : public StructField
218222class NonNativeStructField : public StructField
219223{
220224public:
221- NonNativeStructField ( CspTypePtr type, const std::string &fieldname, size_t size, size_t alignment ) :
222- StructField ( type, fieldname, size, alignment )
225+ NonNativeStructField ( CspTypePtr type, const std::string &fieldname, size_t size, size_t alignment, bool isOptional ) :
226+ StructField ( type, fieldname, size, alignment, isOptional )
223227 {}
224228
225229 virtual void initialize ( Struct * s ) const = 0;
@@ -244,8 +248,8 @@ class StringStructField final : public NonNativeStructField
244248public:
245249 using CType = csp::CspType::StringCType;
246250
247- StringStructField ( CspTypePtr type, const std::string & fieldname ) :
248- NonNativeStructField ( type, fieldname, sizeof ( CType ), alignof ( CType ) )
251+ StringStructField ( CspTypePtr type, const std::string & fieldname, bool isOptional ) :
252+ NonNativeStructField ( type, fieldname, sizeof ( CType ), alignof ( CType ), isOptional )
249253 {}
250254
251255 void initialize ( Struct * s ) const override
@@ -343,8 +347,8 @@ class ArrayStructField : public NonNativeStructField
343347 }
344348
345349public:
346- ArrayStructField ( CspTypePtr arrayType, const std::string & fieldname ) :
347- NonNativeStructField( arrayType, fieldname, sizeof ( CType ), alignof( CType ) )
350+ ArrayStructField ( CspTypePtr arrayType, const std::string & fieldname, bool isOptional ) :
351+ NonNativeStructField( arrayType, fieldname, sizeof ( CType ), alignof( CType ), isOptional )
348352 {}
349353
350354 const CType & value ( const Struct * s ) const
@@ -421,8 +425,8 @@ class ArrayStructField : public NonNativeStructField
421425class DialectGenericStructField : public NonNativeStructField
422426{
423427public:
424- DialectGenericStructField ( const std::string & fieldname, size_t size, size_t alignment ) :
425- NonNativeStructField ( CspType::DIALECT_GENERIC(), fieldname, size, alignment )
428+ DialectGenericStructField ( const std::string & fieldname, size_t size, size_t alignment, bool isOptional ) :
429+ NonNativeStructField ( CspType::DIALECT_GENERIC(), fieldname, size, alignment, isOptional )
426430 {}
427431
428432 const DialectGenericType & value ( const Struct * s ) const
@@ -587,21 +591,24 @@ class StructMeta : public std::enable_shared_from_this<StructMeta>
587591 using FieldNames = std::vector<std::string>;
588592
589593 // Fields will be re-arranged and assigned their offsets in StructMeta for optimal performance
590- StructMeta ( const std::string & name, const Fields & fields, std::shared_ptr<StructMeta> base = nullptr );
594+ StructMeta ( const std::string & name, const Fields & fields, bool isStrict, std::shared_ptr<StructMeta> base = nullptr );
591595 virtual ~StructMeta ();
592596
593597 const std::string & name () const { return m_name; }
594598 size_t size () const { return m_size; }
595599 size_t partialSize () const { return m_partialSize; }
596600
597601 bool isNative () const { return m_isFullyNative; }
602+ bool isStrict () const { return m_isStrict; }
598603
599604 const Fields & fields () const { return m_fields; }
600605 const FieldNames & fieldNames () const { return m_fieldnames; }
601606
602607 size_t maskLoc () const { return m_maskLoc; }
603608 size_t maskSize () const { return m_maskSize; }
604609
610+ void validate ( const Struct * s ) const ;
611+
605612 const StructFieldPtr & field ( const char * name ) const
606613 {
607614 static StructFieldPtr s_empty;
@@ -652,7 +659,8 @@ class StructMeta : public std::enable_shared_from_this<StructMeta>
652659 std::shared_ptr<StructMeta> m_base;
653660 StructPtr m_default;
654661 FieldMap m_fieldMap;
655-
662+ bool m_isStrict;
663+
656664 // fields in order, memory owners of field objects which in turn own the key memory
657665 // m_fields includes all base fields as well. m_fieldnames maintains the proper iteration order of fields
658666 Fields m_fields;
@@ -738,6 +746,11 @@ class Struct
738746 return meta () -> allFieldsSet ( this );
739747 }
740748
749+ void validate () const
750+ {
751+ meta () -> validate ( this );
752+ }
753+
741754
742755 // used to cache dialect representations of this struct, if needed
743756 void * dialectPtr () const { return hidden () -> dialectPtr; }
@@ -822,8 +835,8 @@ bool TypedStructPtr<T>::operator==( const TypedStructPtr<T> & rhs ) const
822835class StructStructField final : public NonNativeStructField
823836{
824837public:
825- StructStructField ( CspTypePtr cspType, const std::string &fieldname ) :
826- NonNativeStructField ( cspType, fieldname, sizeof ( StructPtr ), alignof ( StructPtr ) )
838+ StructStructField ( CspTypePtr cspType, const std::string &fieldname, bool isOptional ) :
839+ NonNativeStructField ( cspType, fieldname, sizeof ( StructPtr ), alignof ( StructPtr ), isOptional )
827840 {
828841 CSP_ASSERT ( cspType -> type () == CspType::Type::STRUCT );
829842 m_meta = std::static_pointer_cast<const CspStructType>( cspType ) -> meta ();
0 commit comments