88 ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
89 }
90 # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
91 # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
92
93 /* Check that _code compiles in a method environment */
94 #define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
95 inline void _compiles_assertion_on_line_##_line (void) const \
96 { _code; }
97 # define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
98 # define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
99
100
101 #define DEFINE_SIZE_STATIC(size) \
102 DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
103 static const unsigned int static_size = (size); \
104 static const unsigned int min_size = (size); \
105 inline unsigned int get_size (void) const { return (size); }
106
107 #define DEFINE_SIZE_UNION(size, _member) \
108 DEFINE_INSTANCE_ASSERTION (this->u._member.static_size == (size)); \
109 static const unsigned int min_size = (size)
110
111 #define DEFINE_SIZE_MIN(size) \
112 DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
113 static const unsigned int min_size = (size)
114
115 #define DEFINE_SIZE_ARRAY(size, array) \
116 DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
117 DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
118 static const unsigned int min_size = (size)
119
120 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
121 DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
122 DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
123 static const unsigned int min_size = (size)
124
125
126
127 /*
128 * Null objects
633 static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
634 inline int cmp (Type a) const
635 {
636 Type b = v;
637 if (sizeof (Type) < sizeof (int))
638 return (int) a - (int) b;
639 else
640 return a < b ? -1 : a == b ? 0 : +1;
641 }
642 inline bool sanitize (hb_sanitize_context_t *c) const
643 {
644 TRACE_SANITIZE (this);
645 return_trace (likely (c->check_struct (this)));
646 }
647 protected:
648 BEInt<Type, Size> v;
649 public:
650 DEFINE_SIZE_STATIC (Size);
651 };
652
653 typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */
654 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
655 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
656 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
657 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */
658 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
659
660 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
661 typedef SHORT FWORD;
662
663 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
664 typedef USHORT UFWORD;
665
666 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
667 struct F2DOT14 : SHORT
668 {
669 //inline float to_float (void) const { return ???; }
670 //inline void set_float (float f) { v.set (f * ???); }
671 public:
672 DEFINE_SIZE_STATIC (2);
673 };
788 inline const Type& operator () (const void *base) const
789 {
790 unsigned int offset = *this;
791 if (unlikely (!offset)) return Null(Type);
792 return StructAtOffset<Type> (base, offset);
793 }
794
795 inline Type& serialize (hb_serialize_context_t *c, const void *base)
796 {
797 Type *t = c->start_embed<Type> ();
798 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
799 return *t;
800 }
801
802 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
803 {
804 TRACE_SANITIZE (this);
805 if (unlikely (!c->check_struct (this))) return_trace (false);
806 unsigned int offset = *this;
807 if (unlikely (!offset)) return_trace (true);
808 const Type &obj = StructAtOffset<Type> (base, offset);
809 return_trace (likely (obj.sanitize (c)) || neuter (c));
810 }
811 template <typename T>
812 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
813 {
814 TRACE_SANITIZE (this);
815 if (unlikely (!c->check_struct (this))) return_trace (false);
816 unsigned int offset = *this;
817 if (unlikely (!offset)) return_trace (true);
818 const Type &obj = StructAtOffset<Type> (base, offset);
819 return_trace (likely (obj.sanitize (c, user_data)) || neuter (c));
820 }
821
822 /* Set the offset to Null */
823 inline bool neuter (hb_sanitize_context_t *c) const {
824 return c->try_set (this, 0);
825 }
826 DEFINE_SIZE_STATIC (sizeof(OffsetType));
827 };
828 template <typename Base, typename OffsetType, typename Type>
829 static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
830 template <typename Base, typename OffsetType, typename Type>
831 static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
832
833
834 /*
835 * Array Types
836 */
837
931 if (!this->array[i].cmp (x))
932 return i;
933 return -1;
934 }
935
936 private:
937 inline bool sanitize_shallow (hb_sanitize_context_t *c) const
938 {
939 TRACE_SANITIZE (this);
940 return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len));
941 }
942
943 public:
944 LenType len;
945 Type array[VAR];
946 public:
947 DEFINE_SIZE_ARRAY (sizeof (LenType), array);
948 };
949
950 /* Array of Offset's */
951 template <typename Type>
952 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {};
953
954 /* Array of offsets relative to the beginning of the array itself. */
955 template <typename Type>
956 struct OffsetListOf : OffsetArrayOf<Type>
957 {
958 inline const Type& operator [] (unsigned int i) const
959 {
960 if (unlikely (i >= this->len)) return Null(Type);
961 return this+this->array[i];
962 }
963
964 inline bool sanitize (hb_sanitize_context_t *c) const
965 {
966 TRACE_SANITIZE (this);
967 return_trace (OffsetArrayOf<Type>::sanitize (c, this));
968 }
969 template <typename T>
970 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const
971 {
972 TRACE_SANITIZE (this);
|
88 ASSERT_INSTANCE_POD (*this); /* Make sure it's POD. */ \
89 }
90 # define _DEFINE_INSTANCE_ASSERTION0(_line, _assertion) _DEFINE_INSTANCE_ASSERTION1 (_line, _assertion)
91 # define DEFINE_INSTANCE_ASSERTION(_assertion) _DEFINE_INSTANCE_ASSERTION0 (__LINE__, _assertion)
92
93 /* Check that _code compiles in a method environment */
94 #define _DEFINE_COMPILES_ASSERTION1(_line, _code) \
95 inline void _compiles_assertion_on_line_##_line (void) const \
96 { _code; }
97 # define _DEFINE_COMPILES_ASSERTION0(_line, _code) _DEFINE_COMPILES_ASSERTION1 (_line, _code)
98 # define DEFINE_COMPILES_ASSERTION(_code) _DEFINE_COMPILES_ASSERTION0 (__LINE__, _code)
99
100
101 #define DEFINE_SIZE_STATIC(size) \
102 DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size)); \
103 static const unsigned int static_size = (size); \
104 static const unsigned int min_size = (size); \
105 inline unsigned int get_size (void) const { return (size); }
106
107 #define DEFINE_SIZE_UNION(size, _member) \
108 DEFINE_INSTANCE_ASSERTION (0*sizeof(this->u._member.static_size) + sizeof(this->u._member) == (size)); \
109 static const unsigned int min_size = (size)
110
111 #define DEFINE_SIZE_MIN(size) \
112 DEFINE_INSTANCE_ASSERTION (sizeof (*this) >= (size)); \
113 static const unsigned int min_size = (size)
114
115 #define DEFINE_SIZE_ARRAY(size, array) \
116 DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (array[0])); \
117 DEFINE_COMPILES_ASSERTION ((void) array[0].static_size) \
118 static const unsigned int min_size = (size)
119
120 #define DEFINE_SIZE_ARRAY2(size, array1, array2) \
121 DEFINE_INSTANCE_ASSERTION (sizeof (*this) == (size) + sizeof (this->array1[0]) + sizeof (this->array2[0])); \
122 DEFINE_COMPILES_ASSERTION ((void) array1[0].static_size; (void) array2[0].static_size) \
123 static const unsigned int min_size = (size)
124
125
126
127 /*
128 * Null objects
633 static inline int cmp (const IntType<Type,Size> *a, const IntType<Type,Size> *b) { return b->cmp (*a); }
634 inline int cmp (Type a) const
635 {
636 Type b = v;
637 if (sizeof (Type) < sizeof (int))
638 return (int) a - (int) b;
639 else
640 return a < b ? -1 : a == b ? 0 : +1;
641 }
642 inline bool sanitize (hb_sanitize_context_t *c) const
643 {
644 TRACE_SANITIZE (this);
645 return_trace (likely (c->check_struct (this)));
646 }
647 protected:
648 BEInt<Type, Size> v;
649 public:
650 DEFINE_SIZE_STATIC (Size);
651 };
652
653 typedef IntType<int8_t , 1> CHAR; /* 8-bit signed integer. */
654 typedef IntType<uint8_t , 1> BYTE; /* 8-bit unsigned integer. */
655 typedef IntType<int8_t , 1> INT8; /* 8-bit signed integer. */
656 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */
657 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */
658 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */
659 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */
660 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */
661
662 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */
663 typedef SHORT FWORD;
664
665 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */
666 typedef USHORT UFWORD;
667
668 /* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
669 struct F2DOT14 : SHORT
670 {
671 //inline float to_float (void) const { return ???; }
672 //inline void set_float (float f) { v.set (f * ???); }
673 public:
674 DEFINE_SIZE_STATIC (2);
675 };
790 inline const Type& operator () (const void *base) const
791 {
792 unsigned int offset = *this;
793 if (unlikely (!offset)) return Null(Type);
794 return StructAtOffset<Type> (base, offset);
795 }
796
797 inline Type& serialize (hb_serialize_context_t *c, const void *base)
798 {
799 Type *t = c->start_embed<Type> ();
800 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
801 return *t;
802 }
803
804 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
805 {
806 TRACE_SANITIZE (this);
807 if (unlikely (!c->check_struct (this))) return_trace (false);
808 unsigned int offset = *this;
809 if (unlikely (!offset)) return_trace (true);
810 if (unlikely (!c->check_range (base, offset))) return_trace (false);
811 const Type &obj = StructAtOffset<Type> (base, offset);
812 return_trace (likely (obj.sanitize (c)) || neuter (c));
813 }
814 template <typename T>
815 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data) const
816 {
817 TRACE_SANITIZE (this);
818 if (unlikely (!c->check_struct (this))) return_trace (false);
819 unsigned int offset = *this;
820 if (unlikely (!offset)) return_trace (true);
821 if (unlikely (!c->check_range (base, offset))) return_trace (false);
822 const Type &obj = StructAtOffset<Type> (base, offset);
823 return_trace (likely (obj.sanitize (c, user_data)) || neuter (c));
824 }
825
826 /* Set the offset to Null */
827 inline bool neuter (hb_sanitize_context_t *c) const {
828 return c->try_set (this, 0);
829 }
830 DEFINE_SIZE_STATIC (sizeof(OffsetType));
831 };
832 template <typename Base, typename OffsetType, typename Type>
833 static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType> &offset) { return offset (base); }
834 template <typename Base, typename OffsetType, typename Type>
835 static inline Type& operator + (Base &base, OffsetTo<Type, OffsetType> &offset) { return offset (base); }
836
837
838 /*
839 * Array Types
840 */
841
935 if (!this->array[i].cmp (x))
936 return i;
937 return -1;
938 }
939
940 private:
941 inline bool sanitize_shallow (hb_sanitize_context_t *c) const
942 {
943 TRACE_SANITIZE (this);
944 return_trace (c->check_struct (this) && c->check_array (array, Type::static_size, len));
945 }
946
947 public:
948 LenType len;
949 Type array[VAR];
950 public:
951 DEFINE_SIZE_ARRAY (sizeof (LenType), array);
952 };
953
954 /* Array of Offset's */
955 template <typename Type, typename OffsetType=USHORT>
956 struct OffsetArrayOf : ArrayOf<OffsetTo<Type, OffsetType> > {};
957
958 /* Array of offsets relative to the beginning of the array itself. */
959 template <typename Type>
960 struct OffsetListOf : OffsetArrayOf<Type>
961 {
962 inline const Type& operator [] (unsigned int i) const
963 {
964 if (unlikely (i >= this->len)) return Null(Type);
965 return this+this->array[i];
966 }
967
968 inline bool sanitize (hb_sanitize_context_t *c) const
969 {
970 TRACE_SANITIZE (this);
971 return_trace (OffsetArrayOf<Type>::sanitize (c, this));
972 }
973 template <typename T>
974 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const
975 {
976 TRACE_SANITIZE (this);
|