1 /* 2 * Copyright 2006 The Android Open Source Project 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkDescriptor_DEFINED 9 #define SkDescriptor_DEFINED 10 11 #include <memory> 12 #include <new> 13 14 #include "include/private/SkMacros.h" 15 #include "include/private/SkNoncopyable.h" 16 #include "src/core/SkBuffer.h" 17 #include "src/core/SkFontPriv.h" 18 #include "src/core/SkScalerContext.h" 19 20 class SkDescriptor : SkNoncopyable { 21 public: ComputeOverhead(int entryCount)22 static size_t ComputeOverhead(int entryCount) { 23 SkASSERT(entryCount >= 0); 24 return sizeof(SkDescriptor) + entryCount * sizeof(Entry); 25 } 26 27 static std::unique_ptr<SkDescriptor> Alloc(size_t length); 28 29 // 30 // Ensure the unsized delete is called. 31 void operator delete(void* p); 32 void* operator new(size_t); new(size_t,void * p)33 void* operator new(size_t, void* p) { return p; } 34 35 void flatten(SkWriteBuffer& buffer) const; 36 getLength()37 uint32_t getLength() const { return fLength; } 38 void* addEntry(uint32_t tag, size_t length, const void* data = nullptr); 39 void computeChecksum(); 40 41 // Assumes that getLength <= capacity of this SkDescriptor. 42 bool isValid() const; 43 44 #ifdef SK_DEBUG assertChecksum()45 void assertChecksum() const { 46 SkASSERT(SkDescriptor::ComputeChecksum(this) == fChecksum); 47 } 48 #endif 49 50 const void* findEntry(uint32_t tag, uint32_t* length) const; 51 52 std::unique_ptr<SkDescriptor> copy() const; 53 54 // This assumes that all memory added has a length that is a multiple of 4. This is checked 55 // by the assert in addEntry. 56 bool operator==(const SkDescriptor& other) const; 57 bool operator!=(const SkDescriptor& other) const { return !(*this == other); } 58 getChecksum()59 uint32_t getChecksum() const { return fChecksum; } 60 61 struct Entry { 62 uint32_t fTag; 63 uint32_t fLen; 64 }; 65 66 #ifdef SK_DEBUG getCount()67 uint32_t getCount() const { return fCount; } 68 #endif 69 70 SkString dumpRec() const; 71 72 private: 73 SkDescriptor() = default; 74 friend class SkDescriptorTestHelper; 75 friend class SkAutoDescriptor; 76 77 static uint32_t ComputeChecksum(const SkDescriptor* desc); 78 79 uint32_t fChecksum{0}; // must be first 80 uint32_t fLength{sizeof(SkDescriptor)}; // must be second 81 uint32_t fCount{0}; 82 }; 83 84 class SkAutoDescriptor { 85 public: 86 SkAutoDescriptor(); 87 explicit SkAutoDescriptor(size_t size); 88 explicit SkAutoDescriptor(const SkDescriptor&); 89 SkAutoDescriptor(const SkAutoDescriptor&); 90 SkAutoDescriptor& operator=(const SkAutoDescriptor&); 91 SkAutoDescriptor(SkAutoDescriptor&&); 92 SkAutoDescriptor& operator=(SkAutoDescriptor&&); 93 ~SkAutoDescriptor(); 94 95 // Returns no value if there is an error. 96 static std::optional<SkAutoDescriptor> MakeFromBuffer(SkReadBuffer& buffer); 97 98 void reset(size_t size); 99 void reset(const SkDescriptor& desc); getDesc()100 SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; } 101 102 private: 103 void free(); 104 static constexpr size_t kStorageSize 105 = sizeof(SkDescriptor) 106 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec 107 + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface 108 + 32; // slop for occasional small extras 109 110 SkDescriptor* fDesc{nullptr}; 111 alignas(uint32_t) char fStorage[kStorageSize]; 112 }; 113 114 #endif //SkDescriptor_DEFINED 115