1 /* 2 * Copyright 2015 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 8 #ifndef SkRWBuffer_DEFINED 9 #define SkRWBuffer_DEFINED 10 11 #include "SkRefCnt.h" 12 13 struct SkBufferBlock; 14 struct SkBufferHead; 15 class SkRWBuffer; 16 class SkStreamAsset; 17 18 /** 19 * Contains a read-only, thread-sharable block of memory. To access the memory, the caller must 20 * instantiate a local iterator, as the memory is stored in 1 or more contiguous blocks. 21 */ 22 class SK_API SkROBuffer : public SkRefCnt { 23 public: 24 /** 25 * Return the logical length of the data owned/shared by this buffer. It may be stored in 26 * multiple contiguous blocks, accessible via the iterator. 27 */ size()28 size_t size() const { return fAvailable; } 29 30 class SK_API Iter { 31 public: 32 Iter(const SkROBuffer*); 33 34 void reset(const SkROBuffer*); 35 36 /** 37 * Return the current continuous block of memory, or nullptr if the iterator is exhausted 38 */ 39 const void* data() const; 40 41 /** 42 * Returns the number of bytes in the current continguous block of memory, or 0 if the 43 * iterator is exhausted. 44 */ 45 size_t size() const; 46 47 /** 48 * Advance to the next contiguous block of memory, returning true if there is another 49 * block, or false if the iterator is exhausted. 50 */ 51 bool next(); 52 53 private: 54 const SkBufferBlock* fBlock; 55 size_t fRemaining; 56 const SkROBuffer* fBuffer; 57 }; 58 59 private: 60 SkROBuffer(const SkBufferHead* head, size_t available, const SkBufferBlock* fTail); 61 virtual ~SkROBuffer(); 62 63 const SkBufferHead* fHead; 64 const size_t fAvailable; 65 const SkBufferBlock* fTail; 66 67 friend class SkRWBuffer; 68 }; 69 70 /** 71 * Accumulates bytes of memory that are "appended" to it, growing internal storage as needed. 72 * The growth is done such that at any time in the writer's thread, an RBuffer or StreamAsset 73 * can be snapped off (and safely passed to another thread). The RBuffer/StreamAsset snapshot 74 * can see the previously stored bytes, but will be unaware of any future writes. 75 */ 76 class SK_API SkRWBuffer { 77 public: 78 SkRWBuffer(size_t initialCapacity = 0); 79 ~SkRWBuffer(); 80 size()81 size_t size() const { return fTotalUsed; } 82 83 /** 84 * Append |length| bytes from |buffer|. 85 * 86 * If the caller knows in advance how much more data they are going to append, they can 87 * pass a |reserve| hint (representing the number of upcoming bytes *in addition* to the 88 * current append), to minimize the number of internal allocations. 89 */ 90 void append(const void* buffer, size_t length, size_t reserve = 0); 91 92 SkROBuffer* newRBufferSnapshot() const; 93 SkStreamAsset* newStreamSnapshot() const; 94 95 #ifdef SK_DEBUG 96 void validate() const; 97 #else validate()98 void validate() const {} 99 #endif 100 101 private: 102 SkBufferHead* fHead; 103 SkBufferBlock* fTail; 104 size_t fTotalUsed; 105 }; 106 107 #endif 108