Home | History | Annotate | Download | only in tinyutils
      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 
     20 SharedBuffer* 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 
     31 ssize_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 
     38 SharedBuffer* 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 
     51 SharedBuffer* 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 
     71 SharedBuffer* SharedBuffer::attemptEdit() const
     72 {
     73     if (onlyOwner()) {
     74         return const_cast<SharedBuffer*>(this);
     75     }
     76     return 0;
     77 }
     78 
     79 SharedBuffer* 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 
     89 void SharedBuffer::acquire() const {
     90     android_atomic_inc(&mRefs);
     91 }
     92 
     93 int32_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