Home | History | Annotate | Download | only in core
      1 
      2 /*
      3  * Copyright 2008 The Android Open Source Project
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 #ifndef SkWriter32_DEFINED
     11 #define SkWriter32_DEFINED
     12 
     13 #include "SkTypes.h"
     14 
     15 #include "SkScalar.h"
     16 #include "SkPoint.h"
     17 #include "SkRect.h"
     18 
     19 class SkStream;
     20 class SkWStream;
     21 
     22 class SkWriter32 : SkNoncopyable {
     23 public:
     24     SkWriter32(size_t minSize)
     25         : fMinSize(minSize),
     26           fSize(0),
     27           fSingleBlock(NULL),
     28           fSingleBlockSize(0),
     29           fHead(NULL),
     30           fTail(NULL) {
     31     }
     32     ~SkWriter32();
     33 
     34     /**
     35      *  Returns the single block backing the writer, or NULL if the memory is
     36      *  to be dynamically allocated.
     37      */
     38     void* getSingleBlock() const { return fSingleBlock; }
     39 
     40     /**
     41      *  Specify the single block to back the writer, rathern than dynamically
     42      *  allocating the memory. If block == NULL, then the writer reverts to
     43      *  dynamic allocation (and resets).
     44      */
     45     void reset(void* block, size_t size);
     46 
     47     bool writeBool(bool value) {
     48         this->writeInt(value);
     49         return value;
     50     }
     51 
     52     void writeInt(int32_t value) {
     53         *(int32_t*)this->reserve(sizeof(value)) = value;
     54     }
     55 
     56     void write8(int32_t value) {
     57         *(int32_t*)this->reserve(sizeof(value)) = value & 0xFF;
     58     }
     59 
     60     void write16(int32_t value) {
     61         *(int32_t*)this->reserve(sizeof(value)) = value & 0xFFFF;
     62     }
     63 
     64     void write32(int32_t value) {
     65         *(int32_t*)this->reserve(sizeof(value)) = value;
     66     }
     67 
     68     void writeScalar(SkScalar value) {
     69         *(SkScalar*)this->reserve(sizeof(value)) = value;
     70     }
     71 
     72     void writePoint(const SkPoint& pt) {
     73         *(SkPoint*)this->reserve(sizeof(pt)) = pt;
     74     }
     75 
     76     void writeRect(const SkRect& rect) {
     77         *(SkRect*)this->reserve(sizeof(rect)) = rect;
     78     }
     79 
     80     // write count bytes (must be a multiple of 4)
     81     void writeMul4(const void* values, size_t size) {
     82         this->write(values, size);
     83     }
     84 
     85     /**
     86      *  Write size bytes from values. size must be a multiple of 4, though
     87      *  values need not be 4-byte aligned.
     88      */
     89     void write(const void* values, size_t size) {
     90         SkASSERT(SkAlign4(size) == size);
     91         // if we could query how much is avail in the current block, we might
     92         // copy that much, and then alloc the rest. That would reduce the waste
     93         // in the current block
     94         memcpy(this->reserve(size), values, size);
     95     }
     96 
     97     void writePad(const void* src, size_t size);
     98 
     99     /**
    100      *  Writes a string to the writer, which can be retrieved with
    101      *  SkReader32::readString().
    102      *  The length can be specified, or if -1 is passed, it will be computed by
    103      *  calling strlen(). The length must be < 0xFFFF
    104      */
    105     void writeString(const char* str, size_t len = (size_t)-1);
    106 
    107     /**
    108      *  Computes the size (aligned to multiple of 4) need to write the string
    109      *  in a call to writeString(). If the length is not specified, it will be
    110      *  computed by calling strlen().
    111      */
    112     static size_t WriteStringSize(const char* str, size_t len = (size_t)-1);
    113 
    114     // return the current offset (will always be a multiple of 4)
    115     uint32_t  size() const { return fSize; }
    116     void      reset();
    117     uint32_t* reserve(size_t size); // size MUST be multiple of 4
    118 
    119     // return the address of the 4byte int at the specified offset (which must
    120     // be a multiple of 4. This does not allocate any new space, so the returned
    121     // address is only valid for 1 int.
    122     uint32_t* peek32(size_t offset);
    123 
    124     // copy into a single buffer (allocated by caller). Must be at least size()
    125     void flatten(void* dst) const;
    126 
    127     // read from the stream, and write up to length bytes. Return the actual
    128     // number of bytes written.
    129     size_t readFromStream(SkStream*, size_t length);
    130 
    131     bool writeToStream(SkWStream*);
    132 
    133 private:
    134     size_t      fMinSize;
    135     uint32_t    fSize;
    136 
    137     char*       fSingleBlock;
    138     uint32_t    fSingleBlockSize;
    139 
    140     struct Block;
    141     Block*  fHead;
    142     Block*  fTail;
    143 
    144     Block* newBlock(size_t bytes);
    145 };
    146 
    147 #endif
    148