1 /* 2 * SharedBuffer.cpp 3 * Android 4 * 5 * Copyright 2005 The Android Open Source Project 6 * 7 */ 8 9 #include <stdlib.h> 10 #include <string.h> 11 12 #include <cutils/atomic.h> 13 14 #include "tinyutils/SharedBuffer.h" 15 16 // --------------------------------------------------------------------------- 17 18 namespace android { 19 alloc(size_t size)20SharedBuffer* SharedBuffer::alloc(size_t size) 21 { 22 SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size)); 23 if (sb) { 24 sb->mRefs = 1; 25 sb->mSize = size; 26 } 27 return sb; 28 } 29 30 dealloc(const SharedBuffer * released)31ssize_t SharedBuffer::dealloc(const SharedBuffer* released) 32 { 33 if (released->mRefs != 0) return -1; // XXX: invalid operation 34 free(const_cast<SharedBuffer*>(released)); 35 return 0; 36 } 37 edit() const38SharedBuffer* SharedBuffer::edit() const 39 { 40 if (onlyOwner()) { 41 return const_cast<SharedBuffer*>(this); 42 } 43 SharedBuffer* sb = alloc(mSize); 44 if (sb) { 45 memcpy(sb->data(), data(), size()); 46 release(); 47 } 48 return sb; 49 } 50 editResize(size_t newSize) const51SharedBuffer* SharedBuffer::editResize(size_t newSize) const 52 { 53 if (onlyOwner()) { 54 SharedBuffer* buf = const_cast<SharedBuffer*>(this); 55 if (buf->mSize == newSize) return buf; 56 buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize); 57 if (buf != NULL) { 58 buf->mSize = newSize; 59 return buf; 60 } 61 } 62 SharedBuffer* sb = alloc(newSize); 63 if (sb) { 64 const size_t mySize = mSize; 65 memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize); 66 release(); 67 } 68 return sb; 69 } 70 attemptEdit() const71SharedBuffer* SharedBuffer::attemptEdit() const 72 { 73 if (onlyOwner()) { 74 return const_cast<SharedBuffer*>(this); 75 } 76 return 0; 77 } 78 reset(size_t new_size) const79SharedBuffer* SharedBuffer::reset(size_t new_size) const 80 { 81 // cheap-o-reset. 82 SharedBuffer* sb = alloc(new_size); 83 if (sb) { 84 release(); 85 } 86 return sb; 87 } 88 acquire() const89void SharedBuffer::acquire() const { 90 android_atomic_inc(&mRefs); 91 } 92 release(uint32_t flags) const93int32_t SharedBuffer::release(uint32_t flags) const 94 { 95 int32_t prev = 1; 96 if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) { 97 mRefs = 0; 98 if ((flags & eKeepStorage) == 0) { 99 free(const_cast<SharedBuffer*>(this)); 100 } 101 } 102 return prev; 103 } 104 105 106 }; // namespace android 107