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