SkMetaData.cpp 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  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. #include "tools/SkMetaData.h"
  8. #include "include/core/SkRefCnt.h"
  9. #include "include/private/SkMalloc.h"
  10. #include "include/private/SkTo.h"
  11. struct PtrPair {
  12. void* fPtr;
  13. SkMetaData::PtrProc fProc;
  14. };
  15. void* SkMetaData::RefCntProc(void* ptr, bool doRef) {
  16. SkASSERT(ptr);
  17. SkRefCnt* refcnt = reinterpret_cast<SkRefCnt*>(ptr);
  18. if (doRef) {
  19. refcnt->ref();
  20. } else {
  21. refcnt->unref();
  22. }
  23. return ptr;
  24. }
  25. SkMetaData::SkMetaData() : fRec(nullptr)
  26. {
  27. }
  28. SkMetaData::SkMetaData(const SkMetaData& src) : fRec(nullptr)
  29. {
  30. *this = src;
  31. }
  32. SkMetaData::~SkMetaData()
  33. {
  34. this->reset();
  35. }
  36. void SkMetaData::reset()
  37. {
  38. Rec* rec = fRec;
  39. while (rec) {
  40. if (kPtr_Type == rec->fType) {
  41. PtrPair* pair = (PtrPair*)rec->data();
  42. if (pair->fProc && pair->fPtr) {
  43. pair->fPtr = pair->fProc(pair->fPtr, false);
  44. }
  45. }
  46. Rec* next = rec->fNext;
  47. Rec::Free(rec);
  48. rec = next;
  49. }
  50. fRec = nullptr;
  51. }
  52. SkMetaData& SkMetaData::operator=(const SkMetaData& src)
  53. {
  54. this->reset();
  55. const Rec* rec = src.fRec;
  56. while (rec)
  57. {
  58. this->set(rec->name(), rec->data(), rec->fDataLen, (Type)rec->fType, rec->fDataCount);
  59. rec = rec->fNext;
  60. }
  61. return *this;
  62. }
  63. void SkMetaData::setS32(const char name[], int32_t value)
  64. {
  65. (void)this->set(name, &value, sizeof(int32_t), kS32_Type, 1);
  66. }
  67. void SkMetaData::setScalar(const char name[], SkScalar value)
  68. {
  69. (void)this->set(name, &value, sizeof(SkScalar), kScalar_Type, 1);
  70. }
  71. SkScalar* SkMetaData::setScalars(const char name[], int count, const SkScalar values[])
  72. {
  73. SkASSERT(count > 0);
  74. if (count > 0)
  75. return (SkScalar*)this->set(name, values, sizeof(SkScalar), kScalar_Type, count);
  76. return nullptr;
  77. }
  78. void SkMetaData::setString(const char name[], const char value[])
  79. {
  80. (void)this->set(name, value, sizeof(char), kString_Type, SkToInt(strlen(value) + 1));
  81. }
  82. void SkMetaData::setPtr(const char name[], void* ptr, PtrProc proc) {
  83. PtrPair pair = { ptr, proc };
  84. (void)this->set(name, &pair, sizeof(PtrPair), kPtr_Type, 1);
  85. }
  86. void SkMetaData::setBool(const char name[], bool value)
  87. {
  88. (void)this->set(name, &value, sizeof(bool), kBool_Type, 1);
  89. }
  90. void SkMetaData::setData(const char name[], const void* data, size_t byteCount) {
  91. (void)this->set(name, data, sizeof(char), kData_Type, SkToInt(byteCount));
  92. }
  93. void* SkMetaData::set(const char name[], const void* data, size_t dataSize, Type type, int count)
  94. {
  95. SkASSERT(name);
  96. SkASSERT(dataSize);
  97. SkASSERT(count > 0);
  98. (void)this->remove(name, type);
  99. size_t len = strlen(name);
  100. Rec* rec = Rec::Alloc(sizeof(Rec) + dataSize * count + len + 1);
  101. #ifndef SK_DEBUG
  102. rec->fType = SkToU8(type);
  103. #else
  104. rec->fType = type;
  105. #endif
  106. rec->fDataLen = SkToU8(dataSize);
  107. rec->fDataCount = SkToU16(count);
  108. if (data)
  109. memcpy(rec->data(), data, dataSize * count);
  110. memcpy(rec->name(), name, len + 1);
  111. if (kPtr_Type == type) {
  112. PtrPair* pair = (PtrPair*)rec->data();
  113. if (pair->fProc && pair->fPtr) {
  114. pair->fPtr = pair->fProc(pair->fPtr, true);
  115. }
  116. }
  117. rec->fNext = fRec;
  118. fRec = rec;
  119. return rec->data();
  120. }
  121. bool SkMetaData::findS32(const char name[], int32_t* value) const
  122. {
  123. const Rec* rec = this->find(name, kS32_Type);
  124. if (rec)
  125. {
  126. SkASSERT(rec->fDataCount == 1);
  127. if (value)
  128. *value = *(const int32_t*)rec->data();
  129. return true;
  130. }
  131. return false;
  132. }
  133. bool SkMetaData::findScalar(const char name[], SkScalar* value) const
  134. {
  135. const Rec* rec = this->find(name, kScalar_Type);
  136. if (rec)
  137. {
  138. SkASSERT(rec->fDataCount == 1);
  139. if (value)
  140. *value = *(const SkScalar*)rec->data();
  141. return true;
  142. }
  143. return false;
  144. }
  145. const SkScalar* SkMetaData::findScalars(const char name[], int* count, SkScalar values[]) const
  146. {
  147. const Rec* rec = this->find(name, kScalar_Type);
  148. if (rec)
  149. {
  150. if (count)
  151. *count = rec->fDataCount;
  152. if (values)
  153. memcpy(values, rec->data(), rec->fDataCount * rec->fDataLen);
  154. return (const SkScalar*)rec->data();
  155. }
  156. return nullptr;
  157. }
  158. bool SkMetaData::findPtr(const char name[], void** ptr, PtrProc* proc) const {
  159. const Rec* rec = this->find(name, kPtr_Type);
  160. if (rec) {
  161. SkASSERT(rec->fDataCount == 1);
  162. const PtrPair* pair = (const PtrPair*)rec->data();
  163. if (ptr) {
  164. *ptr = pair->fPtr;
  165. }
  166. if (proc) {
  167. *proc = pair->fProc;
  168. }
  169. return true;
  170. }
  171. return false;
  172. }
  173. const char* SkMetaData::findString(const char name[]) const
  174. {
  175. const Rec* rec = this->find(name, kString_Type);
  176. SkASSERT(rec == nullptr || rec->fDataLen == sizeof(char));
  177. return rec ? (const char*)rec->data() : nullptr;
  178. }
  179. bool SkMetaData::findBool(const char name[], bool* value) const
  180. {
  181. const Rec* rec = this->find(name, kBool_Type);
  182. if (rec)
  183. {
  184. SkASSERT(rec->fDataCount == 1);
  185. if (value)
  186. *value = *(const bool*)rec->data();
  187. return true;
  188. }
  189. return false;
  190. }
  191. const void* SkMetaData::findData(const char name[], size_t* length) const {
  192. const Rec* rec = this->find(name, kData_Type);
  193. if (rec) {
  194. SkASSERT(rec->fDataLen == sizeof(char));
  195. if (length) {
  196. *length = rec->fDataCount;
  197. }
  198. return rec->data();
  199. }
  200. return nullptr;
  201. }
  202. const SkMetaData::Rec* SkMetaData::find(const char name[], Type type) const
  203. {
  204. const Rec* rec = fRec;
  205. while (rec)
  206. {
  207. if (rec->fType == type && !strcmp(rec->name(), name))
  208. return rec;
  209. rec = rec->fNext;
  210. }
  211. return nullptr;
  212. }
  213. bool SkMetaData::remove(const char name[], Type type) {
  214. Rec* rec = fRec;
  215. Rec* prev = nullptr;
  216. while (rec) {
  217. Rec* next = rec->fNext;
  218. if (rec->fType == type && !strcmp(rec->name(), name)) {
  219. if (prev) {
  220. prev->fNext = next;
  221. } else {
  222. fRec = next;
  223. }
  224. if (kPtr_Type == type) {
  225. PtrPair* pair = (PtrPair*)rec->data();
  226. if (pair->fProc && pair->fPtr) {
  227. (void)pair->fProc(pair->fPtr, false);
  228. }
  229. }
  230. Rec::Free(rec);
  231. return true;
  232. }
  233. prev = rec;
  234. rec = next;
  235. }
  236. return false;
  237. }
  238. bool SkMetaData::removeS32(const char name[])
  239. {
  240. return this->remove(name, kS32_Type);
  241. }
  242. bool SkMetaData::removeScalar(const char name[])
  243. {
  244. return this->remove(name, kScalar_Type);
  245. }
  246. bool SkMetaData::removeString(const char name[])
  247. {
  248. return this->remove(name, kString_Type);
  249. }
  250. bool SkMetaData::removePtr(const char name[])
  251. {
  252. return this->remove(name, kPtr_Type);
  253. }
  254. bool SkMetaData::removeBool(const char name[])
  255. {
  256. return this->remove(name, kBool_Type);
  257. }
  258. bool SkMetaData::removeData(const char name[]) {
  259. return this->remove(name, kData_Type);
  260. }
  261. ///////////////////////////////////////////////////////////////////////////////
  262. SkMetaData::Iter::Iter(const SkMetaData& metadata) {
  263. fRec = metadata.fRec;
  264. }
  265. void SkMetaData::Iter::reset(const SkMetaData& metadata) {
  266. fRec = metadata.fRec;
  267. }
  268. const char* SkMetaData::Iter::next(SkMetaData::Type* t, int* count) {
  269. const char* name = nullptr;
  270. if (fRec) {
  271. if (t) {
  272. *t = (SkMetaData::Type)fRec->fType;
  273. }
  274. if (count) {
  275. *count = fRec->fDataCount;
  276. }
  277. name = fRec->name();
  278. fRec = fRec->fNext;
  279. }
  280. return name;
  281. }
  282. ///////////////////////////////////////////////////////////////////////////////
  283. SkMetaData::Rec* SkMetaData::Rec::Alloc(size_t size) {
  284. return (Rec*)sk_malloc_throw(size);
  285. }
  286. void SkMetaData::Rec::Free(Rec* rec) {
  287. sk_free(rec);
  288. }