SkReader32.h 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*
  2. * Copyright 2008 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. #ifndef SkReader32_DEFINED
  8. #define SkReader32_DEFINED
  9. #include "include/core/SkData.h"
  10. #include "include/core/SkMatrix.h"
  11. #include "include/core/SkPath.h"
  12. #include "include/core/SkRRect.h"
  13. #include "include/core/SkRegion.h"
  14. #include "include/core/SkScalar.h"
  15. #include "include/private/SkNoncopyable.h"
  16. class SkString;
  17. class SkReader32 : SkNoncopyable {
  18. public:
  19. SkReader32() : fCurr(nullptr), fStop(nullptr), fBase(nullptr) {}
  20. SkReader32(const void* data, size_t size) {
  21. this->setMemory(data, size);
  22. }
  23. void setMemory(const void* data, size_t size) {
  24. SkASSERT(ptr_align_4(data));
  25. SkASSERT(SkAlign4(size) == size);
  26. fBase = fCurr = (const char*)data;
  27. fStop = (const char*)data + size;
  28. }
  29. size_t size() const { return fStop - fBase; }
  30. size_t offset() const { return fCurr - fBase; }
  31. bool eof() const { return fCurr >= fStop; }
  32. const void* base() const { return fBase; }
  33. const void* peek() const { return fCurr; }
  34. size_t available() const { return fStop - fCurr; }
  35. bool isAvailable(size_t size) const { return size <= this->available(); }
  36. void rewind() { fCurr = fBase; }
  37. void setOffset(size_t offset) {
  38. SkASSERT(SkAlign4(offset) == offset);
  39. SkASSERT(offset <= this->size());
  40. fCurr = fBase + offset;
  41. }
  42. bool readBool() { return this->readInt() != 0; }
  43. int32_t readInt() {
  44. SkASSERT(ptr_align_4(fCurr));
  45. int32_t value = *(const int32_t*)fCurr;
  46. fCurr += sizeof(value);
  47. SkASSERT(fCurr <= fStop);
  48. return value;
  49. }
  50. void* readPtr() {
  51. void* ptr;
  52. // we presume this "if" is resolved at compile-time
  53. if (4 == sizeof(void*)) {
  54. ptr = *(void**)fCurr;
  55. } else {
  56. memcpy(&ptr, fCurr, sizeof(void*));
  57. }
  58. fCurr += sizeof(void*);
  59. return ptr;
  60. }
  61. SkScalar readScalar() {
  62. SkASSERT(ptr_align_4(fCurr));
  63. SkScalar value = *(const SkScalar*)fCurr;
  64. fCurr += sizeof(value);
  65. SkASSERT(fCurr <= fStop);
  66. return value;
  67. }
  68. const void* skip(size_t size) {
  69. SkASSERT(ptr_align_4(fCurr));
  70. const void* addr = fCurr;
  71. fCurr += SkAlign4(size);
  72. SkASSERT(fCurr <= fStop);
  73. return addr;
  74. }
  75. template <typename T> const T& skipT() {
  76. SkASSERT(SkAlign4(sizeof(T)) == sizeof(T));
  77. return *(const T*)this->skip(sizeof(T));
  78. }
  79. void read(void* dst, size_t size) {
  80. SkASSERT(0 == size || dst != nullptr);
  81. SkASSERT(ptr_align_4(fCurr));
  82. sk_careful_memcpy(dst, fCurr, size);
  83. fCurr += SkAlign4(size);
  84. SkASSERT(fCurr <= fStop);
  85. }
  86. uint8_t readU8() { return (uint8_t)this->readInt(); }
  87. uint16_t readU16() { return (uint16_t)this->readInt(); }
  88. int32_t readS32() { return this->readInt(); }
  89. uint32_t readU32() { return this->readInt(); }
  90. bool readPath(SkPath* path) {
  91. return this->readObjectFromMemory(path);
  92. }
  93. bool readMatrix(SkMatrix* matrix) {
  94. return this->readObjectFromMemory(matrix);
  95. }
  96. bool readRRect(SkRRect* rrect) {
  97. return this->readObjectFromMemory(rrect);
  98. }
  99. bool readRegion(SkRegion* rgn) {
  100. return this->readObjectFromMemory(rgn);
  101. }
  102. /**
  103. * Read the length of a string (written by SkWriter32::writeString) into
  104. * len (if len is not nullptr) and return the null-ternimated address of the
  105. * string within the reader's buffer.
  106. */
  107. const char* readString(size_t* len = nullptr);
  108. /**
  109. * Read the string (written by SkWriter32::writeString) and return it in
  110. * copy (if copy is not null). Return the length of the string.
  111. */
  112. size_t readIntoString(SkString* copy);
  113. sk_sp<SkData> readData() {
  114. uint32_t byteLength = this->readU32();
  115. if (0 == byteLength) {
  116. return SkData::MakeEmpty();
  117. }
  118. return SkData::MakeWithCopy(this->skip(byteLength), byteLength);
  119. }
  120. private:
  121. template <typename T> bool readObjectFromMemory(T* obj) {
  122. size_t size = obj->readFromMemory(this->peek(), this->available());
  123. // If readFromMemory() fails (which means that available() was too small), it returns 0
  124. bool success = (size > 0) && (size <= this->available()) && (SkAlign4(size) == size);
  125. // In case of failure, we want to skip to the end
  126. (void)this->skip(success ? size : this->available());
  127. return success;
  128. }
  129. // these are always 4-byte aligned
  130. const char* fCurr; // current position within buffer
  131. const char* fStop; // end of buffer
  132. const char* fBase; // beginning of buffer
  133. #ifdef SK_DEBUG
  134. static bool ptr_align_4(const void* ptr) {
  135. return (((const char*)ptr - (const char*)nullptr) & 3) == 0;
  136. }
  137. #endif
  138. };
  139. #endif