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/base/SkMacros.h" 15 #include "include/private/base/SkNoncopyable.h" 16 #include "src/base/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 getCount()66 uint32_t getCount() const { return fCount; } 67 68 SkString dumpRec() const; 69 70 private: 71 SkDescriptor() = default; 72 friend class SkDescriptorTestHelper; 73 friend class SkAutoDescriptor; 74 75 static uint32_t ComputeChecksum(const SkDescriptor* desc); 76 77 uint32_t fChecksum{0}; // must be first 78 uint32_t fLength{sizeof(SkDescriptor)}; // must be second 79 uint32_t fCount{0}; 80 }; 81 82 class SkAutoDescriptor { 83 public: 84 SkAutoDescriptor(); 85 explicit SkAutoDescriptor(size_t size); 86 explicit SkAutoDescriptor(const SkDescriptor&); 87 SkAutoDescriptor(const SkAutoDescriptor&); 88 SkAutoDescriptor& operator=(const SkAutoDescriptor&); 89 SkAutoDescriptor(SkAutoDescriptor&&); 90 SkAutoDescriptor& operator=(SkAutoDescriptor&&); 91 ~SkAutoDescriptor(); 92 93 // Returns no value if there is an error. 94 static std::optional<SkAutoDescriptor> MakeFromBuffer(SkReadBuffer& buffer); 95 96 void reset(size_t size); 97 void reset(const SkDescriptor& desc); getDesc()98 SkDescriptor* getDesc() const { SkASSERT(fDesc); return fDesc; } 99 100 private: 101 void free(); 102 static constexpr size_t kStorageSize 103 = sizeof(SkDescriptor) 104 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContextRec) // for rec 105 + sizeof(SkDescriptor::Entry) + sizeof(void*) // for typeface 106 + 32; // slop for occasional small extras 107 108 SkDescriptor* fDesc{nullptr}; 109 alignas(uint32_t) char fStorage[kStorageSize]; 110 }; 111 112 #endif //SkDescriptor_DEFINED 113