Writer32Test.cpp 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Copyright 2011 Google Inc.
  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 "include/utils/SkRandom.h"
  8. #include "src/core/SkAutoMalloc.h"
  9. #include "src/core/SkReader32.h"
  10. #include "src/core/SkWriter32.h"
  11. #include "tests/Test.h"
  12. static void check_contents(skiatest::Reporter* reporter, const SkWriter32& writer,
  13. const void* expected, size_t size) {
  14. SkAutoSMalloc<256> storage(size);
  15. REPORTER_ASSERT(reporter, writer.bytesWritten() == size);
  16. writer.flatten(storage.get());
  17. REPORTER_ASSERT(reporter, !memcmp(storage.get(), expected, size));
  18. }
  19. static void test_reserve(skiatest::Reporter* reporter) {
  20. // There used to be a bug where we'd assert your first reservation had to
  21. // fit in external storage if you used it. This would crash in debug mode.
  22. uint8_t storage[4];
  23. SkWriter32 writer(storage, sizeof(storage));
  24. writer.reserve(40);
  25. }
  26. static void test_string_null(skiatest::Reporter* reporter) {
  27. uint8_t storage[8];
  28. SkWriter32 writer(storage, sizeof(storage));
  29. // Can we write nullptr?
  30. writer.writeString(nullptr);
  31. const int32_t expected[] = { 0x0, 0x0 };
  32. check_contents(reporter, writer, expected, sizeof(expected));
  33. }
  34. static void test_rewind(skiatest::Reporter* reporter) {
  35. SkSWriter32<32> writer;
  36. int32_t array[3] = { 1, 2, 4 };
  37. REPORTER_ASSERT(reporter, 0 == writer.bytesWritten());
  38. for (size_t i = 0; i < SK_ARRAY_COUNT(array); ++i) {
  39. writer.writeInt(array[i]);
  40. }
  41. check_contents(reporter, writer, array, sizeof(array));
  42. writer.rewindToOffset(2*sizeof(int32_t));
  43. REPORTER_ASSERT(reporter, sizeof(array) - 4 == writer.bytesWritten());
  44. writer.writeInt(3);
  45. REPORTER_ASSERT(reporter, sizeof(array) == writer.bytesWritten());
  46. array[2] = 3;
  47. check_contents(reporter, writer, array, sizeof(array));
  48. // test rewinding past allocated chunks. This used to crash because we
  49. // didn't truncate our link-list after freeing trailing blocks
  50. {
  51. SkWriter32 writer;
  52. for (int i = 0; i < 100; ++i) {
  53. writer.writeInt(i);
  54. }
  55. REPORTER_ASSERT(reporter, 100*4 == writer.bytesWritten());
  56. for (int j = 100*4; j >= 0; j -= 16) {
  57. writer.rewindToOffset(j);
  58. }
  59. REPORTER_ASSERT(reporter, writer.bytesWritten() < 16);
  60. }
  61. }
  62. static void test_ptr(skiatest::Reporter* reporter) {
  63. SkSWriter32<32> writer;
  64. void* p0 = reporter;
  65. void* p1 = &writer;
  66. // try writing ptrs where at least one of them may be at a non-multiple of
  67. // 8 boundary, to confirm this works on 64bit machines.
  68. writer.writePtr(p0);
  69. writer.write8(0x33);
  70. writer.writePtr(p1);
  71. writer.write8(0x66);
  72. size_t size = writer.bytesWritten();
  73. REPORTER_ASSERT(reporter, 2 * sizeof(void*) + 2 * sizeof(int32_t));
  74. char buffer[32];
  75. SkASSERT(sizeof(buffer) >= size);
  76. writer.flatten(buffer);
  77. SkReader32 reader(buffer, size);
  78. REPORTER_ASSERT(reporter, reader.readPtr() == p0);
  79. REPORTER_ASSERT(reporter, reader.readInt() == 0x33);
  80. REPORTER_ASSERT(reporter, reader.readPtr() == p1);
  81. REPORTER_ASSERT(reporter, reader.readInt() == 0x66);
  82. }
  83. static void test1(skiatest::Reporter* reporter, SkWriter32* writer) {
  84. const uint32_t data[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
  85. for (size_t i = 0; i < SK_ARRAY_COUNT(data); ++i) {
  86. REPORTER_ASSERT(reporter, i*4 == writer->bytesWritten());
  87. writer->write32(data[i]);
  88. REPORTER_ASSERT(reporter, data[i] == writer->readTAt<uint32_t>(i * 4));
  89. }
  90. char buffer[sizeof(data)];
  91. REPORTER_ASSERT(reporter, sizeof(buffer) == writer->bytesWritten());
  92. writer->flatten(buffer);
  93. REPORTER_ASSERT(reporter, !memcmp(data, buffer, sizeof(buffer)));
  94. }
  95. static void test2(skiatest::Reporter* reporter, SkWriter32* writer) {
  96. static const char gStr[] = "abcdefghimjklmnopqrstuvwxyz";
  97. size_t i;
  98. size_t len = 0;
  99. for (i = 0; i <= 26; ++i) {
  100. len += SkWriter32::WriteStringSize(gStr, i);
  101. writer->writeString(gStr, i);
  102. }
  103. REPORTER_ASSERT(reporter, writer->bytesWritten() == len);
  104. SkAutoMalloc storage(len);
  105. writer->flatten(storage.get());
  106. SkReader32 reader;
  107. reader.setMemory(storage.get(), len);
  108. for (i = 0; i <= 26; ++i) {
  109. REPORTER_ASSERT(reporter, !reader.eof());
  110. const char* str = reader.readString(&len);
  111. REPORTER_ASSERT(reporter, i == len);
  112. REPORTER_ASSERT(reporter, strlen(str) == len);
  113. REPORTER_ASSERT(reporter, !memcmp(str, gStr, len));
  114. // Ensure that the align4 of the string is padded with zeroes.
  115. size_t alignedSize = SkAlign4(len + 1);
  116. for (size_t j = len; j < alignedSize; j++) {
  117. REPORTER_ASSERT(reporter, 0 == str[j]);
  118. }
  119. }
  120. REPORTER_ASSERT(reporter, reader.eof());
  121. }
  122. static void testWritePad(skiatest::Reporter* reporter, SkWriter32* writer) {
  123. // Create some random data to write.
  124. const size_t dataSize = 10;
  125. SkAutoTMalloc<uint32_t> originalData(dataSize);
  126. {
  127. SkRandom rand(0);
  128. for (size_t i = 0; i < dataSize; i++) {
  129. originalData[(int) i] = rand.nextU();
  130. }
  131. // Write the random data to the writer at different lengths for
  132. // different alignments.
  133. for (size_t len = 0; len < dataSize; len++) {
  134. writer->writePad(originalData.get(), len);
  135. }
  136. }
  137. size_t totalBytes = writer->bytesWritten();
  138. SkAutoMalloc readStorage(totalBytes);
  139. writer->flatten(readStorage.get());
  140. SkReader32 reader;
  141. reader.setMemory(readStorage.get(), totalBytes);
  142. for (size_t len = 0; len < dataSize; len++) {
  143. const char* readPtr = static_cast<const char*>(reader.skip(len));
  144. // Ensure that the data read is the same as what was written.
  145. REPORTER_ASSERT(reporter, memcmp(readPtr, originalData.get(), len) == 0);
  146. // Ensure that the rest is padded with zeroes.
  147. const char* stop = readPtr + SkAlign4(len);
  148. readPtr += len;
  149. while (readPtr < stop) {
  150. REPORTER_ASSERT(reporter, *readPtr++ == 0);
  151. }
  152. }
  153. }
  154. static void testOverwriteT(skiatest::Reporter* reporter, SkWriter32* writer) {
  155. const size_t padding = 64;
  156. const uint32_t uint1 = 0x12345678;
  157. const uint32_t uint2 = 0x98765432;
  158. const SkScalar scalar1 = 1234.5678f;
  159. const SkScalar scalar2 = 9876.5432f;
  160. const SkRect rect1 = SkRect::MakeXYWH(1, 2, 3, 4);
  161. const SkRect rect2 = SkRect::MakeXYWH(5, 6, 7, 8);
  162. for (size_t i = 0; i < (padding / 4); ++i) {
  163. writer->write32(0);
  164. }
  165. writer->write32(uint1);
  166. writer->writeRect(rect1);
  167. writer->writeScalar(scalar1);
  168. for (size_t i = 0; i < (padding / 4); ++i) {
  169. writer->write32(0);
  170. }
  171. REPORTER_ASSERT(reporter, writer->readTAt<uint32_t>(padding) == uint1);
  172. REPORTER_ASSERT(reporter, writer->readTAt<SkRect>(padding + sizeof(uint32_t)) == rect1);
  173. REPORTER_ASSERT(reporter, writer->readTAt<SkScalar>(
  174. padding + sizeof(uint32_t) + sizeof(SkRect)) == scalar1);
  175. writer->overwriteTAt(padding, uint2);
  176. writer->overwriteTAt(padding + sizeof(uint32_t), rect2);
  177. writer->overwriteTAt(padding + sizeof(uint32_t) + sizeof(SkRect), scalar2);
  178. REPORTER_ASSERT(reporter, writer->readTAt<uint32_t>(padding) == uint2);
  179. REPORTER_ASSERT(reporter, writer->readTAt<SkRect>(padding + sizeof(uint32_t)) == rect2);
  180. REPORTER_ASSERT(reporter, writer->readTAt<SkScalar>(
  181. padding + sizeof(uint32_t) + sizeof(SkRect)) == scalar2);
  182. }
  183. DEF_TEST(Writer32_dynamic, reporter) {
  184. SkWriter32 writer;
  185. test1(reporter, &writer);
  186. writer.reset();
  187. test2(reporter, &writer);
  188. writer.reset();
  189. testWritePad(reporter, &writer);
  190. writer.reset();
  191. testOverwriteT(reporter, &writer);
  192. }
  193. DEF_TEST(Writer32_small, reporter) {
  194. SkSWriter32<8 * sizeof(intptr_t)> writer;
  195. test1(reporter, &writer);
  196. writer.reset(); // should just rewind our storage
  197. test2(reporter, &writer);
  198. writer.reset();
  199. testWritePad(reporter, &writer);
  200. writer.reset();
  201. testOverwriteT(reporter, &writer);
  202. }
  203. DEF_TEST(Writer32_large, reporter) {
  204. SkSWriter32<1024 * sizeof(intptr_t)> writer;
  205. test1(reporter, &writer);
  206. writer.reset(); // should just rewind our storage
  207. test2(reporter, &writer);
  208. writer.reset();
  209. testWritePad(reporter, &writer);
  210. writer.reset();
  211. testOverwriteT(reporter, &writer);
  212. }
  213. DEF_TEST(Writer32_misc, reporter) {
  214. test_reserve(reporter);
  215. test_string_null(reporter);
  216. test_ptr(reporter);
  217. test_rewind(reporter);
  218. }
  219. DEF_TEST(Writer32_data, reporter) {
  220. const char* str = "0123456789";
  221. sk_sp<SkData> data0(SkData::MakeWithCString(str));
  222. sk_sp<SkData> data1(SkData::MakeEmpty());
  223. const size_t sizes[] = {
  224. SkWriter32::WriteDataSize(nullptr),
  225. SkWriter32::WriteDataSize(data0.get()),
  226. SkWriter32::WriteDataSize(data1.get()),
  227. };
  228. SkSWriter32<1000> writer;
  229. size_t sizeWritten = 0;
  230. writer.writeData(nullptr);
  231. sizeWritten += sizes[0];
  232. REPORTER_ASSERT(reporter, sizeWritten == writer.bytesWritten());
  233. writer.writeData(data0.get());
  234. sizeWritten += sizes[1];
  235. REPORTER_ASSERT(reporter, sizeWritten == writer.bytesWritten());
  236. writer.writeData(data1.get());
  237. sizeWritten += sizes[2];
  238. REPORTER_ASSERT(reporter, sizeWritten == writer.bytesWritten());
  239. auto result(writer.snapshotAsData());
  240. SkReader32 reader(result->data(), result->size());
  241. auto d0(reader.readData()),
  242. d1(reader.readData()),
  243. d2(reader.readData());
  244. REPORTER_ASSERT(reporter, 0 == d0->size());
  245. REPORTER_ASSERT(reporter, strlen(str)+1 == d1->size());
  246. REPORTER_ASSERT(reporter, !memcmp(str, d1->data(), strlen(str)+1));
  247. REPORTER_ASSERT(reporter, 0 == d2->size());
  248. REPORTER_ASSERT(reporter, reader.offset() == sizeWritten);
  249. REPORTER_ASSERT(reporter, reader.eof());
  250. }