00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef SkDescriptor_DEFINED
00018 #define SkDescriptor_DEFINED
00019
00020 #include "SkTypes.h"
00021
00022 class SkDescriptor : SkNoncopyable {
00023 public:
00024 static size_t ComputeOverhead(int entryCount)
00025 {
00026 SkASSERT(entryCount >= 0);
00027 return sizeof(SkDescriptor) + entryCount * sizeof(Entry);
00028 }
00029
00030 static SkDescriptor* Alloc(size_t length)
00031 {
00032 SkASSERT(SkAlign4(length) == length);
00033 SkDescriptor* desc = (SkDescriptor*)sk_malloc_throw(length);
00034 return desc;
00035 }
00036
00037 static void Free(SkDescriptor* desc)
00038 {
00039 sk_free(desc);
00040 }
00041
00042 void init()
00043 {
00044 fLength = sizeof(SkDescriptor);
00045 fCount = 0;
00046 }
00047
00048 uint32_t getLength() const { return fLength; }
00049
00050 void* addEntry(uint32_t tag, uint32_t length, const void* data = NULL)
00051 {
00052 SkASSERT(tag);
00053 SkASSERT(SkAlign4(length) == length);
00054 SkASSERT(this->findEntry(tag, NULL) == NULL);
00055
00056 Entry* entry = (Entry*)((char*)this + fLength);
00057 entry->fTag = tag;
00058 entry->fLen = length;
00059 if (data)
00060 memcpy(entry + 1, data, length);
00061
00062 fCount += 1;
00063 fLength += sizeof(Entry) + length;
00064 return (entry + 1);
00065 }
00066
00067 void computeChecksum()
00068 {
00069 fChecksum = SkDescriptor::ComputeChecksum(this);
00070 }
00071
00072 #ifdef SK_DEBUG
00073 void assertChecksum() const
00074 {
00075 SkASSERT(fChecksum == SkDescriptor::ComputeChecksum(this));
00076 }
00077 #endif
00078
00079 const void* findEntry(uint32_t tag, uint32_t* length) const
00080 {
00081 const Entry* entry = (const Entry*)(this + 1);
00082 int count = fCount;
00083
00084 while (--count >= 0)
00085 {
00086 if (entry->fTag == tag)
00087 {
00088 if (length)
00089 *length = entry->fLen;
00090 return entry + 1;
00091 }
00092 entry = (const Entry*)((const char*)(entry + 1) + entry->fLen);
00093 }
00094 return NULL;
00095 }
00096
00097 SkDescriptor* copy() const
00098 {
00099 SkDescriptor* desc = SkDescriptor::Alloc(fLength);
00100 memcpy(desc, this, fLength);
00101 return desc;
00102 }
00103
00104 bool equals(const SkDescriptor& other) const
00105 {
00106
00107
00108
00109
00110
00111
00112
00113 const uint32_t* aa = (const uint32_t*)this;
00114 const uint32_t* bb = (const uint32_t*)&other;
00115 const uint32_t* stop = (const uint32_t*)((const char*)aa + fLength);
00116 do {
00117 if (*aa++ != *bb++)
00118 return false;
00119 } while (aa < stop);
00120 return true;
00121 }
00122
00123 struct Entry {
00124 uint32_t fTag;
00125 uint32_t fLen;
00126 };
00127
00128 #ifdef SK_DEBUG
00129 uint32_t getChecksum() const { return fChecksum; }
00130 uint32_t getCount() const { return fCount; }
00131 #endif
00132
00133 private:
00134 uint32_t fChecksum;
00135 uint32_t fLength;
00136 uint32_t fCount;
00137
00138 static uint32_t ComputeChecksum(const SkDescriptor* desc)
00139 {
00140 const uint32_t* ptr = (const uint32_t*)desc + 1;
00141 const uint32_t* stop = (const uint32_t*)((const char*)desc + desc->fLength);
00142 uint32_t sum = 0;
00143
00144 SkASSERT(ptr < stop);
00145 do {
00146 sum = (sum << 1) | (sum >> 31);
00147 sum ^= *ptr++;
00148 } while (ptr < stop);
00149
00150 return sum;
00151 }
00152
00153
00154 SkDescriptor() {}
00155 };
00156
00157 #include "SkScalerContext.h"
00158
00159 class SkAutoDescriptor : SkNoncopyable {
00160 public:
00161 SkAutoDescriptor(size_t size)
00162 {
00163 if (size <= sizeof(fStorage))
00164 fDesc = (SkDescriptor*)(void*)fStorage;
00165 else
00166 fDesc = SkDescriptor::Alloc(size);
00167 }
00168 ~SkAutoDescriptor()
00169 {
00170 if (fDesc != (SkDescriptor*)(void*)fStorage)
00171 SkDescriptor::Free(fDesc);
00172 }
00173 SkDescriptor* getDesc() const { return fDesc; }
00174 private:
00175 enum {
00176 kStorageSize = sizeof(SkDescriptor)
00177 + sizeof(SkDescriptor::Entry) + sizeof(SkScalerContext::Rec)
00178 + sizeof(SkDescriptor::Entry) + sizeof(void*)
00179 + 32
00180 };
00181 SkDescriptor* fDesc;
00182 uint32_t fStorage[(kStorageSize + 3) >> 2];
00183 };
00184
00185
00186 #endif
00187