blob: ef781a75c6beeaf2ff4118e695245490496c3181 [file] [log] [blame]
The Android Open Source Project4f6e8d72008-10-21 07:00:00 -07001/*
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
18namespace android {
19
20SharedBuffer* 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
31ssize_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
38SharedBuffer* 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
51SharedBuffer* 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
71SharedBuffer* SharedBuffer::attemptEdit() const
72{
73 if (onlyOwner()) {
74 return const_cast<SharedBuffer*>(this);
75 }
76 return 0;
77}
78
79SharedBuffer* 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
89void SharedBuffer::acquire() const {
90 android_atomic_inc(&mRefs);
91}
92
93int32_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