• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)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 
dealloc(const SharedBuffer * released)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 
edit() const38 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 
editResize(size_t newSize) const51 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 
attemptEdit() const71 SharedBuffer* SharedBuffer::attemptEdit() const
72 {
73     if (onlyOwner()) {
74         return const_cast<SharedBuffer*>(this);
75     }
76     return 0;
77 }
78 
reset(size_t new_size) const79 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 
acquire() const89 void SharedBuffer::acquire() const {
90     android_atomic_inc(&mRefs);
91 }
92 
release(uint32_t flags) const93 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