1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* 29857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * Copyright 2005 The Android Open Source Project 3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 49857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 59857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * you may not use this file except in compliance with the License. 69857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * You may obtain a copy of the License at 7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 89857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 99857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * 109857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * Unless required by applicable law or agreed to in writing, software 119857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 129857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * See the License for the specific language governing permissions and 149857d99eecc389389da261a72461322d5cfb8eebMathias Agopian * limitations under the License. 15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */ 16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h> 18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h> 19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <cutils/atomic.h> 21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 229857d99eecc389389da261a72461322d5cfb8eebMathias Agopian#include "SharedBuffer.h" 23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project// --------------------------------------------------------------------------- 25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectnamespace android { 279857d99eecc389389da261a72461322d5cfb8eebMathias Agopiannamespace tinyutils { 28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSharedBuffer* SharedBuffer::alloc(size_t size) 30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SharedBuffer* sb = static_cast<SharedBuffer *>(malloc(sizeof(SharedBuffer) + size)); 32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sb) { 33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sb->mRefs = 1; 34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project sb->mSize = size; 35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sb; 37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t SharedBuffer::dealloc(const SharedBuffer* released) 41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (released->mRefs != 0) return -1; // XXX: invalid operation 43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(const_cast<SharedBuffer*>(released)); 44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSharedBuffer* SharedBuffer::edit() const 48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (onlyOwner()) { 50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return const_cast<SharedBuffer*>(this); 51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SharedBuffer* sb = alloc(mSize); 53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sb) { 54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(sb->data(), data(), size()); 55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project release(); 56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sb; 58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSharedBuffer* SharedBuffer::editResize(size_t newSize) const 61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (onlyOwner()) { 63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SharedBuffer* buf = const_cast<SharedBuffer*>(this); 64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buf->mSize == newSize) return buf; 65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf = (SharedBuffer*)realloc(buf, sizeof(SharedBuffer) + newSize); 66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (buf != NULL) { 67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project buf->mSize = newSize; 68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return buf; 69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SharedBuffer* sb = alloc(newSize); 72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sb) { 73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project const size_t mySize = mSize; 74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project memcpy(sb->data(), data(), newSize < mySize ? newSize : mySize); 75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project release(); 76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sb; 78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSharedBuffer* SharedBuffer::attemptEdit() const 81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (onlyOwner()) { 83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return const_cast<SharedBuffer*>(this); 84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return 0; 86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSharedBuffer* SharedBuffer::reset(size_t new_size) const 89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project // cheap-o-reset. 91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project SharedBuffer* sb = alloc(new_size); 92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (sb) { 93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project release(); 94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return sb; 96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid SharedBuffer::acquire() const { 99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project android_atomic_inc(&mRefs); 100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint32_t SharedBuffer::release(uint32_t flags) const 103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{ 104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project int32_t prev = 1; 105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if (onlyOwner() || ((prev = android_atomic_dec(&mRefs)) == 1)) { 106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project mRefs = 0; 107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project if ((flags & eKeepStorage) == 0) { 108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project free(const_cast<SharedBuffer*>(this)); 109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project } 111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project return prev; 112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} 113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project 1149857d99eecc389389da261a72461322d5cfb8eebMathias Agopian} // namespace tinyutils 1159857d99eecc389389da261a72461322d5cfb8eebMathias Agopian} // namespace android 116