OLD | NEW |
1 /* | 1 /* |
2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. | 2 * Copyright © 2007,2008,2009,2010 Red Hat, Inc. |
3 * Copyright © 2012 Google, Inc. | 3 * Copyright © 2012 Google, Inc. |
4 * | 4 * |
5 * This is part of HarfBuzz, a text shaping library. | 5 * This is part of HarfBuzz, a text shaping library. |
6 * | 6 * |
7 * Permission is hereby granted, without written agreement and without | 7 * Permission is hereby granted, without written agreement and without |
8 * license or royalty fees, to use, copy, modify, and distribute this | 8 * license or royalty fees, to use, copy, modify, and distribute this |
9 * software and its documentation for any purpose, provided that the | 9 * software and its documentation for any purpose, provided that the |
10 * above copyright notice and the following two paragraphs appear in | 10 * above copyright notice and the following two paragraphs appear in |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
147 template <> \ | 147 template <> \ |
148 /*static*/ inline const Type& Null<Type> (void) { \ | 148 /*static*/ inline const Type& Null<Type> (void) { \ |
149 return *CastP<Type> (_Null##Type); \ | 149 return *CastP<Type> (_Null##Type); \ |
150 } /* The following line really exists such that we end in a place needing semico
lon */ \ | 150 } /* The following line really exists such that we end in a place needing semico
lon */ \ |
151 ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) | 151 ASSERT_STATIC (Type::min_size + 1 <= sizeof (_Null##Type)) |
152 | 152 |
153 /* Accessor macro. */ | 153 /* Accessor macro. */ |
154 #define Null(Type) Null<Type>() | 154 #define Null(Type) Null<Type>() |
155 | 155 |
156 | 156 |
| 157 /* |
| 158 * Dispatch |
| 159 */ |
| 160 |
| 161 template <typename Context, typename Return, unsigned int MaxDebugDepth> |
| 162 struct hb_dispatch_context_t |
| 163 { |
| 164 static const unsigned int max_debug_depth = MaxDebugDepth; |
| 165 typedef Return return_t; |
| 166 template <typename T, typename F> |
| 167 inline bool may_dispatch (const T *obj, const F *format) { return true; } |
| 168 static return_t no_dispatch_return_value (void) { return Context::default_retu
rn_value (); } |
| 169 }; |
| 170 |
157 | 171 |
158 /* | 172 /* |
159 * Sanitize | 173 * Sanitize |
160 */ | 174 */ |
161 | 175 |
162 #ifndef HB_DEBUG_SANITIZE | 176 #ifndef HB_DEBUG_SANITIZE |
163 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) | 177 #define HB_DEBUG_SANITIZE (HB_DEBUG+0) |
164 #endif | 178 #endif |
165 | 179 |
166 | 180 |
167 #define TRACE_SANITIZE(this) \ | 181 #define TRACE_SANITIZE(this) \ |
168 hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \ | 182 hb_auto_trace_t<HB_DEBUG_SANITIZE, bool> trace \ |
169 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ | 183 (&c->debug_depth, c->get_name (), this, HB_FUNC, \ |
170 ""); | 184 ""); |
171 | 185 |
172 /* This limits sanitizing time on really broken fonts. */ | 186 /* This limits sanitizing time on really broken fonts. */ |
173 #ifndef HB_SANITIZE_MAX_EDITS | 187 #ifndef HB_SANITIZE_MAX_EDITS |
174 #define HB_SANITIZE_MAX_EDITS 100 | 188 #define HB_SANITIZE_MAX_EDITS 100 |
175 #endif | 189 #endif |
176 | 190 |
177 struct hb_sanitize_context_t | 191 struct hb_sanitize_context_t : |
| 192 hb_dispatch_context_t<hb_sanitize_context_t, bool, HB_DEBUG_SANITIZE> |
178 { | 193 { |
| 194 inline hb_sanitize_context_t (void) : |
| 195 debug_depth (0), |
| 196 start (NULL), end (NULL), |
| 197 writable (false), edit_count (0), |
| 198 blob (NULL) {} |
| 199 |
179 inline const char *get_name (void) { return "SANITIZE"; } | 200 inline const char *get_name (void) { return "SANITIZE"; } |
180 static const unsigned int max_debug_depth = HB_DEBUG_SANITIZE; | |
181 typedef bool return_t; | |
182 template <typename T, typename F> | 201 template <typename T, typename F> |
183 inline bool may_dispatch (const T *obj, const F *format) | 202 inline bool may_dispatch (const T *obj, const F *format) |
184 { return format->sanitize (this); } | 203 { return format->sanitize (this); } |
185 template <typename T> | 204 template <typename T> |
186 inline return_t dispatch (const T &obj) { return obj.sanitize (this); } | 205 inline return_t dispatch (const T &obj) { return obj.sanitize (this); } |
187 static return_t default_return_value (void) { return true; } | 206 static return_t default_return_value (void) { return true; } |
| 207 static return_t no_dispatch_return_value (void) { return false; } |
188 bool stop_sublookup_iteration (const return_t r) const { return !r; } | 208 bool stop_sublookup_iteration (const return_t r) const { return !r; } |
189 | 209 |
190 inline void init (hb_blob_t *b) | 210 inline void init (hb_blob_t *b) |
191 { | 211 { |
192 this->blob = hb_blob_reference (b); | 212 this->blob = hb_blob_reference (b); |
193 this->writable = false; | 213 this->writable = false; |
194 } | 214 } |
195 | 215 |
196 inline void start_processing (void) | 216 inline void start_processing (void) |
197 { | 217 { |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 hb_blob_t *blob; | 308 hb_blob_t *blob; |
289 }; | 309 }; |
290 | 310 |
291 | 311 |
292 | 312 |
293 /* Template to sanitize an object. */ | 313 /* Template to sanitize an object. */ |
294 template <typename Type> | 314 template <typename Type> |
295 struct Sanitizer | 315 struct Sanitizer |
296 { | 316 { |
297 static hb_blob_t *sanitize (hb_blob_t *blob) { | 317 static hb_blob_t *sanitize (hb_blob_t *blob) { |
298 hb_sanitize_context_t c[1] = {{0, NULL, NULL, false, 0, NULL}}; | 318 hb_sanitize_context_t c[1]; |
299 bool sane; | 319 bool sane; |
300 | 320 |
301 /* TODO is_sane() stuff */ | 321 /* TODO is_sane() stuff */ |
302 | 322 |
303 c->init (blob); | 323 c->init (blob); |
304 | 324 |
305 retry: | 325 retry: |
306 DEBUG_MSG_FUNC (SANITIZE, c->start, "start"); | 326 DEBUG_MSG_FUNC (SANITIZE, c->start, "start"); |
307 | 327 |
308 c->start_processing (); | 328 c->start_processing (); |
(...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ | 549 * All OpenType fonts use Motorola-style byte ordering (Big Endian):" */ |
530 | 550 |
531 /* | 551 /* |
532 * Int types | 552 * Int types |
533 */ | 553 */ |
534 | 554 |
535 | 555 |
536 template <typename Type, int Bytes> struct BEInt; | 556 template <typename Type, int Bytes> struct BEInt; |
537 | 557 |
538 template <typename Type> | 558 template <typename Type> |
| 559 struct BEInt<Type, 1> |
| 560 { |
| 561 public: |
| 562 inline void set (Type V) |
| 563 { |
| 564 v = V; |
| 565 } |
| 566 inline operator Type (void) const |
| 567 { |
| 568 return v; |
| 569 } |
| 570 private: uint8_t v; |
| 571 }; |
| 572 template <typename Type> |
539 struct BEInt<Type, 2> | 573 struct BEInt<Type, 2> |
540 { | 574 { |
541 public: | 575 public: |
542 inline void set (Type V) | 576 inline void set (Type V) |
543 { | 577 { |
544 v[0] = (V >> 8) & 0xFF; | 578 v[0] = (V >> 8) & 0xFF; |
545 v[1] = (V ) & 0xFF; | 579 v[1] = (V ) & 0xFF; |
546 } | 580 } |
547 inline operator Type (void) const | 581 inline operator Type (void) const |
548 { | 582 { |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
603 { | 637 { |
604 Type b = v; | 638 Type b = v; |
605 if (sizeof (Type) < sizeof (int)) | 639 if (sizeof (Type) < sizeof (int)) |
606 return (int) a - (int) b; | 640 return (int) a - (int) b; |
607 else | 641 else |
608 return a < b ? -1 : a == b ? 0 : +1; | 642 return a < b ? -1 : a == b ? 0 : +1; |
609 } | 643 } |
610 inline bool sanitize (hb_sanitize_context_t *c) const | 644 inline bool sanitize (hb_sanitize_context_t *c) const |
611 { | 645 { |
612 TRACE_SANITIZE (this); | 646 TRACE_SANITIZE (this); |
613 return TRACE_RETURN (likely (c->check_struct (this))); | 647 return_trace (likely (c->check_struct (this))); |
614 } | 648 } |
615 protected: | 649 protected: |
616 BEInt<Type, Size> v; | 650 BEInt<Type, Size> v; |
617 public: | 651 public: |
618 DEFINE_SIZE_STATIC (Size); | 652 DEFINE_SIZE_STATIC (Size); |
619 }; | 653 }; |
620 | 654 |
621 typedef»» uint8_t» BYTE;» /* 8-bit unsigned integer. */ | 655 typedef»IntType<uint8_t», 1> BYTE;» /* 8-bit unsigned integer. */ |
622 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ | 656 typedef IntType<uint16_t, 2> USHORT; /* 16-bit unsigned integer. */ |
623 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ | 657 typedef IntType<int16_t, 2> SHORT; /* 16-bit signed integer. */ |
624 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ | 658 typedef IntType<uint32_t, 4> ULONG; /* 32-bit unsigned integer. */ |
625 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ | 659 typedef IntType<int32_t, 4> LONG; /* 32-bit signed integer. */ |
626 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ | 660 typedef IntType<uint32_t, 3> UINT24; /* 24-bit unsigned integer. */ |
627 | 661 |
628 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ | 662 /* 16-bit signed integer (SHORT) that describes a quantity in FUnits. */ |
629 typedef SHORT FWORD; | 663 typedef SHORT FWORD; |
630 | 664 |
631 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ | 665 /* 16-bit unsigned integer (USHORT) that describes a quantity in FUnits. */ |
632 typedef USHORT UFWORD; | 666 typedef USHORT UFWORD; |
633 | 667 |
634 /* Date represented in number of seconds since 12:00 midnight, January 1, | 668 /* Date represented in number of seconds since 12:00 midnight, January 1, |
635 * 1904. The value is represented as a signed 64-bit integer. */ | 669 * 1904. The value is represented as a signed 64-bit integer. */ |
636 struct LONGDATETIME | 670 struct LONGDATETIME |
637 { | 671 { |
638 inline bool sanitize (hb_sanitize_context_t *c) const | 672 inline bool sanitize (hb_sanitize_context_t *c) const |
639 { | 673 { |
640 TRACE_SANITIZE (this); | 674 TRACE_SANITIZE (this); |
641 return TRACE_RETURN (likely (c->check_struct (this))); | 675 return_trace (likely (c->check_struct (this))); |
642 } | 676 } |
643 protected: | 677 protected: |
644 LONG major; | 678 LONG major; |
645 ULONG minor; | 679 ULONG minor; |
646 public: | 680 public: |
647 DEFINE_SIZE_STATIC (8); | 681 DEFINE_SIZE_STATIC (8); |
648 }; | 682 }; |
649 | 683 |
650 /* Array of four uint8s (length = 32 bits) used to identify a script, language | 684 /* Array of four uint8s (length = 32 bits) used to identify a script, language |
651 * system, feature, or baseline */ | 685 * system, feature, or baseline */ |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
708 * Version Numbers | 742 * Version Numbers |
709 */ | 743 */ |
710 | 744 |
711 struct FixedVersion | 745 struct FixedVersion |
712 { | 746 { |
713 inline uint32_t to_int (void) const { return (major << 16) + minor; } | 747 inline uint32_t to_int (void) const { return (major << 16) + minor; } |
714 | 748 |
715 inline bool sanitize (hb_sanitize_context_t *c) const | 749 inline bool sanitize (hb_sanitize_context_t *c) const |
716 { | 750 { |
717 TRACE_SANITIZE (this); | 751 TRACE_SANITIZE (this); |
718 return TRACE_RETURN (c->check_struct (this)); | 752 return_trace (c->check_struct (this)); |
719 } | 753 } |
720 | 754 |
721 USHORT major; | 755 USHORT major; |
722 USHORT minor; | 756 USHORT minor; |
723 public: | 757 public: |
724 DEFINE_SIZE_STATIC (4); | 758 DEFINE_SIZE_STATIC (4); |
725 }; | 759 }; |
726 | 760 |
727 | 761 |
728 | 762 |
(...skipping 15 matching lines...) Expand all Loading... |
744 inline Type& serialize (hb_serialize_context_t *c, const void *base) | 778 inline Type& serialize (hb_serialize_context_t *c, const void *base) |
745 { | 779 { |
746 Type *t = c->start_embed<Type> (); | 780 Type *t = c->start_embed<Type> (); |
747 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ | 781 this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */ |
748 return *t; | 782 return *t; |
749 } | 783 } |
750 | 784 |
751 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const | 785 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
752 { | 786 { |
753 TRACE_SANITIZE (this); | 787 TRACE_SANITIZE (this); |
754 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 788 if (unlikely (!c->check_struct (this))) return_trace (false); |
755 unsigned int offset = *this; | 789 unsigned int offset = *this; |
756 if (unlikely (!offset)) return TRACE_RETURN (true); | 790 if (unlikely (!offset)) return_trace (true); |
757 const Type &obj = StructAtOffset<Type> (base, offset); | 791 const Type &obj = StructAtOffset<Type> (base, offset); |
758 return TRACE_RETURN (likely (obj.sanitize (c)) || neuter (c)); | 792 return_trace (likely (obj.sanitize (c)) || neuter (c)); |
759 } | 793 } |
760 template <typename T> | 794 template <typename T> |
761 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const | 795 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const |
762 { | 796 { |
763 TRACE_SANITIZE (this); | 797 TRACE_SANITIZE (this); |
764 if (unlikely (!c->check_struct (this))) return TRACE_RETURN (false); | 798 if (unlikely (!c->check_struct (this))) return_trace (false); |
765 unsigned int offset = *this; | 799 unsigned int offset = *this; |
766 if (unlikely (!offset)) return TRACE_RETURN (true); | 800 if (unlikely (!offset)) return_trace (true); |
767 const Type &obj = StructAtOffset<Type> (base, offset); | 801 const Type &obj = StructAtOffset<Type> (base, offset); |
768 return TRACE_RETURN (likely (obj.sanitize (c, user_data)) || neuter (c)); | 802 return_trace (likely (obj.sanitize (c, user_data)) || neuter (c)); |
769 } | 803 } |
770 | 804 |
771 /* Set the offset to Null */ | 805 /* Set the offset to Null */ |
772 inline bool neuter (hb_sanitize_context_t *c) const { | 806 inline bool neuter (hb_sanitize_context_t *c) const { |
773 return c->try_set (this, 0); | 807 return c->try_set (this, 0); |
774 } | 808 } |
775 DEFINE_SIZE_STATIC (sizeof(OffsetType)); | 809 DEFINE_SIZE_STATIC (sizeof(OffsetType)); |
776 }; | 810 }; |
777 template <typename Base, typename OffsetType, typename Type> | 811 template <typename Base, typename OffsetType, typename Type> |
778 static inline const Type& operator + (const Base &base, const OffsetTo<Type, Off
setType> &offset) { return offset (base); } | 812 static inline const Type& operator + (const Base &base, const OffsetTo<Type, Off
setType> &offset) { return offset (base); } |
(...skipping 30 matching lines...) Expand all Loading... |
809 { | 843 { |
810 return array[i]; | 844 return array[i]; |
811 } | 845 } |
812 inline unsigned int get_size (void) const | 846 inline unsigned int get_size (void) const |
813 { return len.static_size + len * Type::static_size; } | 847 { return len.static_size + len * Type::static_size; } |
814 | 848 |
815 inline bool serialize (hb_serialize_context_t *c, | 849 inline bool serialize (hb_serialize_context_t *c, |
816 unsigned int items_len) | 850 unsigned int items_len) |
817 { | 851 { |
818 TRACE_SERIALIZE (this); | 852 TRACE_SERIALIZE (this); |
819 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 853 if (unlikely (!c->extend_min (*this))) return_trace (false); |
820 len.set (items_len); /* TODO(serialize) Overflow? */ | 854 len.set (items_len); /* TODO(serialize) Overflow? */ |
821 if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); | 855 if (unlikely (!c->extend (*this))) return_trace (false); |
822 return TRACE_RETURN (true); | 856 return_trace (true); |
823 } | 857 } |
824 | 858 |
825 inline bool serialize (hb_serialize_context_t *c, | 859 inline bool serialize (hb_serialize_context_t *c, |
826 Supplier<Type> &items, | 860 Supplier<Type> &items, |
827 unsigned int items_len) | 861 unsigned int items_len) |
828 { | 862 { |
829 TRACE_SERIALIZE (this); | 863 TRACE_SERIALIZE (this); |
830 if (unlikely (!serialize (c, items_len))) return TRACE_RETURN (false); | 864 if (unlikely (!serialize (c, items_len))) return_trace (false); |
831 for (unsigned int i = 0; i < items_len; i++) | 865 for (unsigned int i = 0; i < items_len; i++) |
832 array[i] = items[i]; | 866 array[i] = items[i]; |
833 items.advance (items_len); | 867 items.advance (items_len); |
834 return TRACE_RETURN (true); | 868 return_trace (true); |
835 } | 869 } |
836 | 870 |
837 inline bool sanitize (hb_sanitize_context_t *c) const | 871 inline bool sanitize (hb_sanitize_context_t *c) const |
838 { | 872 { |
839 TRACE_SANITIZE (this); | 873 TRACE_SANITIZE (this); |
840 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 874 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
841 | 875 |
842 /* Note: for structs that do not reference other structs, | 876 /* Note: for structs that do not reference other structs, |
843 * we do not need to call their sanitize() as we already did | 877 * we do not need to call their sanitize() as we already did |
844 * a bound check on the aggregate array size. We just include | 878 * a bound check on the aggregate array size. We just include |
845 * a small unreachable expression to make sure the structs | 879 * a small unreachable expression to make sure the structs |
846 * pointed to do have a simple sanitize(), ie. they do not | 880 * pointed to do have a simple sanitize(), ie. they do not |
847 * reference other structs via offsets. | 881 * reference other structs via offsets. |
848 */ | 882 */ |
849 (void) (false && array[0].sanitize (c)); | 883 (void) (false && array[0].sanitize (c)); |
850 | 884 |
851 return TRACE_RETURN (true); | 885 return_trace (true); |
852 } | 886 } |
853 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const | 887 inline bool sanitize (hb_sanitize_context_t *c, const void *base) const |
854 { | 888 { |
855 TRACE_SANITIZE (this); | 889 TRACE_SANITIZE (this); |
856 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 890 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
857 unsigned int count = len; | 891 unsigned int count = len; |
858 for (unsigned int i = 0; i < count; i++) | 892 for (unsigned int i = 0; i < count; i++) |
859 if (unlikely (!array[i].sanitize (c, base))) | 893 if (unlikely (!array[i].sanitize (c, base))) |
860 return TRACE_RETURN (false); | 894 return_trace (false); |
861 return TRACE_RETURN (true); | 895 return_trace (true); |
862 } | 896 } |
863 template <typename T> | 897 template <typename T> |
864 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const | 898 inline bool sanitize (hb_sanitize_context_t *c, const void *base, T user_data)
const |
865 { | 899 { |
866 TRACE_SANITIZE (this); | 900 TRACE_SANITIZE (this); |
867 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 901 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
868 unsigned int count = len; | 902 unsigned int count = len; |
869 for (unsigned int i = 0; i < count; i++) | 903 for (unsigned int i = 0; i < count; i++) |
870 if (unlikely (!array[i].sanitize (c, base, user_data))) | 904 if (unlikely (!array[i].sanitize (c, base, user_data))) |
871 return TRACE_RETURN (false); | 905 return_trace (false); |
872 return TRACE_RETURN (true); | 906 return_trace (true); |
873 } | 907 } |
874 | 908 |
875 template <typename SearchType> | 909 template <typename SearchType> |
876 inline int lsearch (const SearchType &x) const | 910 inline int lsearch (const SearchType &x) const |
877 { | 911 { |
878 unsigned int count = len; | 912 unsigned int count = len; |
879 for (unsigned int i = 0; i < count; i++) | 913 for (unsigned int i = 0; i < count; i++) |
880 if (!this->array[i].cmp (x)) | 914 if (!this->array[i].cmp (x)) |
881 return i; | 915 return i; |
882 return -1; | 916 return -1; |
883 } | 917 } |
884 | 918 |
885 private: | 919 private: |
886 inline bool sanitize_shallow (hb_sanitize_context_t *c) const | 920 inline bool sanitize_shallow (hb_sanitize_context_t *c) const |
887 { | 921 { |
888 TRACE_SANITIZE (this); | 922 TRACE_SANITIZE (this); |
889 return TRACE_RETURN (c->check_struct (this) && c->check_array (this, Type::s
tatic_size, len)); | 923 return_trace (c->check_struct (this) && c->check_array (array, Type::static_
size, len)); |
890 } | 924 } |
891 | 925 |
892 public: | 926 public: |
893 LenType len; | 927 LenType len; |
894 Type array[VAR]; | 928 Type array[VAR]; |
895 public: | 929 public: |
896 DEFINE_SIZE_ARRAY (sizeof (LenType), array); | 930 DEFINE_SIZE_ARRAY (sizeof (LenType), array); |
897 }; | 931 }; |
898 | 932 |
899 /* Array of Offset's */ | 933 /* Array of Offset's */ |
900 template <typename Type> | 934 template <typename Type> |
901 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; | 935 struct OffsetArrayOf : ArrayOf<OffsetTo<Type> > {}; |
902 | 936 |
903 /* Array of offsets relative to the beginning of the array itself. */ | 937 /* Array of offsets relative to the beginning of the array itself. */ |
904 template <typename Type> | 938 template <typename Type> |
905 struct OffsetListOf : OffsetArrayOf<Type> | 939 struct OffsetListOf : OffsetArrayOf<Type> |
906 { | 940 { |
907 inline const Type& operator [] (unsigned int i) const | 941 inline const Type& operator [] (unsigned int i) const |
908 { | 942 { |
909 if (unlikely (i >= this->len)) return Null(Type); | 943 if (unlikely (i >= this->len)) return Null(Type); |
910 return this+this->array[i]; | 944 return this+this->array[i]; |
911 } | 945 } |
912 | 946 |
913 inline bool sanitize (hb_sanitize_context_t *c) const | 947 inline bool sanitize (hb_sanitize_context_t *c) const |
914 { | 948 { |
915 TRACE_SANITIZE (this); | 949 TRACE_SANITIZE (this); |
916 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this)); | 950 return_trace (OffsetArrayOf<Type>::sanitize (c, this)); |
917 } | 951 } |
918 template <typename T> | 952 template <typename T> |
919 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const | 953 inline bool sanitize (hb_sanitize_context_t *c, T user_data) const |
920 { | 954 { |
921 TRACE_SANITIZE (this); | 955 TRACE_SANITIZE (this); |
922 return TRACE_RETURN (OffsetArrayOf<Type>::sanitize (c, this, user_data)); | 956 return_trace (OffsetArrayOf<Type>::sanitize (c, this, user_data)); |
923 } | 957 } |
924 }; | 958 }; |
925 | 959 |
926 | 960 |
927 /* An array starting at second element. */ | 961 /* An array starting at second element. */ |
928 template <typename Type, typename LenType=USHORT> | 962 template <typename Type, typename LenType=USHORT> |
929 struct HeadlessArrayOf | 963 struct HeadlessArrayOf |
930 { | 964 { |
931 inline const Type& operator [] (unsigned int i) const | 965 inline const Type& operator [] (unsigned int i) const |
932 { | 966 { |
933 if (unlikely (i >= len || !i)) return Null(Type); | 967 if (unlikely (i >= len || !i)) return Null(Type); |
934 return array[i-1]; | 968 return array[i-1]; |
935 } | 969 } |
936 inline unsigned int get_size (void) const | 970 inline unsigned int get_size (void) const |
937 { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } | 971 { return len.static_size + (len ? len - 1 : 0) * Type::static_size; } |
938 | 972 |
939 inline bool serialize (hb_serialize_context_t *c, | 973 inline bool serialize (hb_serialize_context_t *c, |
940 Supplier<Type> &items, | 974 Supplier<Type> &items, |
941 unsigned int items_len) | 975 unsigned int items_len) |
942 { | 976 { |
943 TRACE_SERIALIZE (this); | 977 TRACE_SERIALIZE (this); |
944 if (unlikely (!c->extend_min (*this))) return TRACE_RETURN (false); | 978 if (unlikely (!c->extend_min (*this))) return_trace (false); |
945 len.set (items_len); /* TODO(serialize) Overflow? */ | 979 len.set (items_len); /* TODO(serialize) Overflow? */ |
946 if (unlikely (!items_len)) return TRACE_RETURN (true); | 980 if (unlikely (!items_len)) return_trace (true); |
947 if (unlikely (!c->extend (*this))) return TRACE_RETURN (false); | 981 if (unlikely (!c->extend (*this))) return_trace (false); |
948 for (unsigned int i = 0; i < items_len - 1; i++) | 982 for (unsigned int i = 0; i < items_len - 1; i++) |
949 array[i] = items[i]; | 983 array[i] = items[i]; |
950 items.advance (items_len - 1); | 984 items.advance (items_len - 1); |
951 return TRACE_RETURN (true); | 985 return_trace (true); |
952 } | 986 } |
953 | 987 |
954 inline bool sanitize_shallow (hb_sanitize_context_t *c) const | 988 inline bool sanitize_shallow (hb_sanitize_context_t *c) const |
955 { | 989 { |
956 return c->check_struct (this) | 990 return c->check_struct (this) |
957 && c->check_array (this, Type::static_size, len); | 991 && c->check_array (this, Type::static_size, len); |
958 } | 992 } |
959 | 993 |
960 inline bool sanitize (hb_sanitize_context_t *c) const | 994 inline bool sanitize (hb_sanitize_context_t *c) const |
961 { | 995 { |
962 TRACE_SANITIZE (this); | 996 TRACE_SANITIZE (this); |
963 if (unlikely (!sanitize_shallow (c))) return TRACE_RETURN (false); | 997 if (unlikely (!sanitize_shallow (c))) return_trace (false); |
964 | 998 |
965 /* Note: for structs that do not reference other structs, | 999 /* Note: for structs that do not reference other structs, |
966 * we do not need to call their sanitize() as we already did | 1000 * we do not need to call their sanitize() as we already did |
967 * a bound check on the aggregate array size. We just include | 1001 * a bound check on the aggregate array size. We just include |
968 * a small unreachable expression to make sure the structs | 1002 * a small unreachable expression to make sure the structs |
969 * pointed to do have a simple sanitize(), ie. they do not | 1003 * pointed to do have a simple sanitize(), ie. they do not |
970 * reference other structs via offsets. | 1004 * reference other structs via offsets. |
971 */ | 1005 */ |
972 (void) (false && array[0].sanitize (c)); | 1006 (void) (false && array[0].sanitize (c)); |
973 | 1007 |
974 return TRACE_RETURN (true); | 1008 return_trace (true); |
975 } | 1009 } |
976 | 1010 |
977 LenType len; | 1011 LenType len; |
978 Type array[VAR]; | 1012 Type array[VAR]; |
979 public: | 1013 public: |
980 DEFINE_SIZE_ARRAY (sizeof (LenType), array); | 1014 DEFINE_SIZE_ARRAY (sizeof (LenType), array); |
981 }; | 1015 }; |
982 | 1016 |
983 | 1017 |
984 /* An array with sorted elements. Supports binary searching. */ | 1018 /* An array with sorted elements. Supports binary searching. */ |
(...skipping 18 matching lines...) Expand all Loading... |
1003 } | 1037 } |
1004 return -1; | 1038 return -1; |
1005 } | 1039 } |
1006 }; | 1040 }; |
1007 | 1041 |
1008 | 1042 |
1009 } /* namespace OT */ | 1043 } /* namespace OT */ |
1010 | 1044 |
1011 | 1045 |
1012 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ | 1046 #endif /* HB_OPEN_TYPE_PRIVATE_HH */ |
OLD | NEW |