michael@0: /* michael@0: * Copyright (C) 2005 The Android Open Source Project michael@0: * michael@0: * Licensed under the Apache License, Version 2.0 (the "License"); michael@0: * you may not use this file except in compliance with the License. michael@0: * You may obtain a copy of the License at michael@0: * michael@0: * http://www.apache.org/licenses/LICENSE-2.0 michael@0: * michael@0: * Unless required by applicable law or agreed to in writing, software michael@0: * distributed under the License is distributed on an "AS IS" BASIS, michael@0: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. michael@0: * See the License for the specific language governing permissions and michael@0: * limitations under the License. michael@0: */ michael@0: michael@0: #ifndef ANDROID_SHARED_BUFFER_H michael@0: #define ANDROID_SHARED_BUFFER_H michael@0: michael@0: #include michael@0: #include michael@0: michael@0: // --------------------------------------------------------------------------- michael@0: michael@0: namespace android { michael@0: michael@0: class SharedBuffer michael@0: { michael@0: public: michael@0: michael@0: /* flags to use with release() */ michael@0: enum { michael@0: eKeepStorage = 0x00000001 michael@0: }; michael@0: michael@0: /*! allocate a buffer of size 'size' and acquire() it. michael@0: * call release() to free it. michael@0: */ michael@0: static SharedBuffer* alloc(size_t size); michael@0: michael@0: /*! free the memory associated with the SharedBuffer. michael@0: * Fails if there are any users associated with this SharedBuffer. michael@0: * In other words, the buffer must have been release by all its michael@0: * users. michael@0: */ michael@0: static ssize_t dealloc(const SharedBuffer* released); michael@0: michael@0: //! get the SharedBuffer from the data pointer michael@0: static inline const SharedBuffer* sharedBuffer(const void* data); michael@0: michael@0: //! access the data for read michael@0: inline const void* data() const; michael@0: michael@0: //! access the data for read/write michael@0: inline void* data(); michael@0: michael@0: //! get size of the buffer michael@0: inline size_t size() const; michael@0: michael@0: //! get back a SharedBuffer object from its data michael@0: static inline SharedBuffer* bufferFromData(void* data); michael@0: michael@0: //! get back a SharedBuffer object from its data michael@0: static inline const SharedBuffer* bufferFromData(const void* data); michael@0: michael@0: //! get the size of a SharedBuffer object from its data michael@0: static inline size_t sizeFromData(const void* data); michael@0: michael@0: //! edit the buffer (get a writtable, or non-const, version of it) michael@0: SharedBuffer* edit() const; michael@0: michael@0: //! edit the buffer, resizing if needed michael@0: SharedBuffer* editResize(size_t size) const; michael@0: michael@0: //! like edit() but fails if a copy is required michael@0: SharedBuffer* attemptEdit() const; michael@0: michael@0: //! resize and edit the buffer, loose it's content. michael@0: SharedBuffer* reset(size_t size) const; michael@0: michael@0: //! acquire/release a reference on this buffer michael@0: void acquire() const; michael@0: michael@0: /*! release a reference on this buffer, with the option of not michael@0: * freeing the memory associated with it if it was the last reference michael@0: * returns the previous reference count michael@0: */ michael@0: int32_t release(uint32_t flags = 0) const; michael@0: michael@0: //! returns wether or not we're the only owner michael@0: inline bool onlyOwner() const; michael@0: michael@0: michael@0: private: michael@0: inline SharedBuffer() { } michael@0: inline ~SharedBuffer() { } michael@0: inline SharedBuffer(const SharedBuffer&); michael@0: michael@0: // 16 bytes. must be sized to preserve correct alingment. michael@0: mutable int32_t mRefs; michael@0: size_t mSize; michael@0: uint32_t mReserved[2]; michael@0: }; michael@0: michael@0: // --------------------------------------------------------------------------- michael@0: michael@0: const SharedBuffer* SharedBuffer::sharedBuffer(const void* data) { michael@0: return data ? reinterpret_cast(data)-1 : 0; michael@0: } michael@0: michael@0: const void* SharedBuffer::data() const { michael@0: return this + 1; michael@0: } michael@0: michael@0: void* SharedBuffer::data() { michael@0: return this + 1; michael@0: } michael@0: michael@0: size_t SharedBuffer::size() const { michael@0: return mSize; michael@0: } michael@0: michael@0: SharedBuffer* SharedBuffer::bufferFromData(void* data) michael@0: { michael@0: return ((SharedBuffer*)data)-1; michael@0: } michael@0: michael@0: const SharedBuffer* SharedBuffer::bufferFromData(const void* data) michael@0: { michael@0: return ((const SharedBuffer*)data)-1; michael@0: } michael@0: michael@0: size_t SharedBuffer::sizeFromData(const void* data) michael@0: { michael@0: return (((const SharedBuffer*)data)-1)->mSize; michael@0: } michael@0: michael@0: bool SharedBuffer::onlyOwner() const { michael@0: return (mRefs == 1); michael@0: } michael@0: michael@0: }; // namespace android michael@0: michael@0: // --------------------------------------------------------------------------- michael@0: michael@0: #endif // ANDROID_VECTOR_H