added k60d100m project
[adk-bluetooth-test.git] / adk-stack / sgBuf.c
blobef971e6e534fb680d7bb7a1fd18b912c37991d94
1 /*
2 * Copyright (C) 2012 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 #define ADK_INTERNAL
17 #include "fwk.h"
18 #include "sgBuf.h"
19 #include <string.h>
22 #define INFO_MASK_NEEDS_FREE 0x80000000
23 #define INFO_MASK_SIZE 0x00FFFFFF
26 void sg_init(sg_buf* buf){
28 buf->first = NULL;
29 buf->last = NULL;
30 buf->totalLen = 0;
33 sg_buf* sg_alloc(void){
35 sg_buf* b = malloc(sizeof(sg_buf));
36 if(b) sg_init(b);
38 return b;
41 void sg_free(sg_buf* buf){
43 sg_buf_node* n = buf->first;
44 sg_buf_node* t;
46 while(n){
48 if(n->info & INFO_MASK_NEEDS_FREE) free((void *)(n->data));
50 t = n->next;
51 free(n);
52 n = t;
56 uint32_t sg_length(const sg_buf* buf){
58 return buf->totalLen;
61 static sg_buf_node* sg_alloc_node(const uint8_t* data, uint32_t len, uint8_t flags){
63 sg_buf_node* n;
64 uint32_t sz;
66 if(len &~ INFO_MASK_SIZE) return NULL; //too big
68 sz = sizeof(sg_buf_node);
69 if(flags & SG_FLAG_MAKE_A_COPY) sz += len;
71 n = malloc(sz);
73 if(n){
75 if(flags & SG_FLAG_MAKE_A_COPY){
77 uint8_t* ptr = (uint8_t*)(n + 1);
78 memcpy(ptr, data, len);
79 data = ptr;
80 flags &=~ SG_FLAG_NEEDS_FREEING; //definitely not
83 n->info = len | ((flags & SG_FLAG_NEEDS_FREEING) ? INFO_MASK_NEEDS_FREE : 0);
84 n->data = data;
86 return n;
89 char sg_add_front(sg_buf* buf, const uint8_t* data, uint32_t len, uint8_t flags){
91 sg_buf_node* n = sg_alloc_node(data, len, flags);
93 if(!n) return 0;
95 n->next = buf->first;
96 buf->first = n;
97 if(!buf->last) buf->last = n;
99 buf->totalLen += len;
101 return 1;
104 char sg_add_back(sg_buf* buf, const uint8_t* data, uint32_t len, uint8_t flags){
106 sg_buf_node* n = sg_alloc_node(data, len, flags);
108 if(!n) return 0;
110 n->next = NULL;
111 if(buf->last) buf->last->next = n;
112 else buf->first = n;
113 buf->last = n;
115 buf->totalLen += len;
117 return 1;
120 void sg_concat_back(sg_buf* buf, sg_buf* second){
122 buf->totalLen += second->totalLen;
124 if(buf->last) buf->last->next = second->first;
125 else buf->first = second->first;
126 buf->last = second->last;
128 sg_init(second);
131 void sg_concat_front(sg_buf* buf, sg_buf* second){
133 sg_concat_back(second, buf);
134 *buf = *second;
136 sg_init(buf);
139 sg_iter sg_iter_start(const sg_buf* buf){
141 return (sg_iter)(buf->first);
144 char sg_iter_next(sg_iter* iterP, const uint8_t** buf, uint32_t* sz){
146 sg_buf_node* n = (sg_buf_node*)*iterP;
148 if(!n) return 0; //end of line
150 if(buf) *buf = n->data;
151 if(sz) *sz = n->info & INFO_MASK_SIZE;
153 *iterP = n->next;
154 return 1;
157 void sg_copyto(const sg_buf* buf, uint8_t* dst){
159 sg_buf_node* n = buf->first;
160 uint32_t len;
162 while(n){
164 len = n->info & INFO_MASK_SIZE;
166 memcpy(dst, n->data, len);
167 dst += len;
169 n = n->next;