blob: 41eea00a51ea0dd14eb14b2f7d6a8a868fdb6259 [file] [log] [blame]
Sharvil Nanavati1878c422014-12-15 01:37:59 -08001/******************************************************************************
2 *
Jakub Pawlowski5b790fe2017-09-18 09:00:20 -07003 * Copyright 2014 Google, Inc.
Sharvil Nanavati1878c422014-12-15 01:37:59 -08004 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
Chris Mantonf8027002015-03-12 09:22:48 -070019#define LOG_TAG "bt_osi_buffer"
Sharvil Nanavati1878c422014-12-15 01:37:59 -080020
Marie Janssen49a86702015-07-08 11:48:57 -070021#include "osi/include/buffer.h"
22
Jack Hef2af1c42016-12-13 01:59:12 -080023#include <base/logging.h>
Sharvil Nanavati1878c422014-12-15 01:37:59 -080024#include <stdint.h>
25
26#include "osi/include/allocator.h"
Sharvil Nanavati1878c422014-12-15 01:37:59 -080027#include "osi/include/log.h"
28
29struct buffer_t {
Myles Watsonb55040c2016-10-19 13:15:34 -070030 buffer_t* root;
Sharvil Nanavati1878c422014-12-15 01:37:59 -080031 size_t refcount;
32 size_t length;
33 uint8_t data[];
34};
35
Myles Watsonb55040c2016-10-19 13:15:34 -070036buffer_t* buffer_new(size_t size) {
Jack Hef2af1c42016-12-13 01:59:12 -080037 CHECK(size > 0);
Sharvil Nanavati1878c422014-12-15 01:37:59 -080038
Myles Watsonb55040c2016-10-19 13:15:34 -070039 buffer_t* buffer =
40 static_cast<buffer_t*>(osi_calloc(sizeof(buffer_t) + size));
Sharvil Nanavati1878c422014-12-15 01:37:59 -080041
42 buffer->root = buffer;
43 buffer->refcount = 1;
44 buffer->length = size;
45
46 return buffer;
47}
48
Myles Watsonb55040c2016-10-19 13:15:34 -070049buffer_t* buffer_new_ref(const buffer_t* buf) {
Jack Hef2af1c42016-12-13 01:59:12 -080050 CHECK(buf != NULL);
Sharvil Nanavati1878c422014-12-15 01:37:59 -080051 return buffer_new_slice(buf, buf->length);
52}
53
Myles Watsonb55040c2016-10-19 13:15:34 -070054buffer_t* buffer_new_slice(const buffer_t* buf, size_t slice_size) {
Jack Hef2af1c42016-12-13 01:59:12 -080055 CHECK(buf != NULL);
56 CHECK(slice_size > 0);
57 CHECK(slice_size <= buf->length);
Sharvil Nanavati1878c422014-12-15 01:37:59 -080058
Myles Watsonb55040c2016-10-19 13:15:34 -070059 buffer_t* ret = static_cast<buffer_t*>(osi_calloc(sizeof(buffer_t)));
Sharvil Nanavati1878c422014-12-15 01:37:59 -080060
61 ret->root = buf->root;
62 ret->refcount = SIZE_MAX;
63 ret->length = slice_size;
64
65 ++buf->root->refcount;
66
67 return ret;
68}
69
Myles Watsonb55040c2016-10-19 13:15:34 -070070void buffer_free(buffer_t* buffer) {
71 if (!buffer) return;
Sharvil Nanavati1878c422014-12-15 01:37:59 -080072
73 if (buffer->root != buffer) {
74 // We're a leaf node. Delete the root node if we're the last referent.
Myles Watsonb55040c2016-10-19 13:15:34 -070075 if (--buffer->root->refcount == 0) osi_free(buffer->root);
Sharvil Nanavati1878c422014-12-15 01:37:59 -080076 osi_free(buffer);
77 } else if (--buffer->refcount == 0) {
78 // We're a root node. Roots are only deleted when their refcount goes to 0.
79 osi_free(buffer);
80 }
81}
82
Myles Watsonb55040c2016-10-19 13:15:34 -070083void* buffer_ptr(const buffer_t* buf) {
Jack Hef2af1c42016-12-13 01:59:12 -080084 CHECK(buf != NULL);
Sharvil Nanavati1878c422014-12-15 01:37:59 -080085 return buf->root->data + buf->root->length - buf->length;
86}
87
Myles Watsonb55040c2016-10-19 13:15:34 -070088size_t buffer_length(const buffer_t* buf) {
Jack Hef2af1c42016-12-13 01:59:12 -080089 CHECK(buf != NULL);
Sharvil Nanavati1878c422014-12-15 01:37:59 -080090 return buf->length;
91}