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