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