4 * Copyright (c) 2010 project bchan
6 * This software is provided 'as-is', without any express or implied
7 * warranty. In no event will the authors be held liable for any damages
8 * arising from the use of this software.
10 * Permission is granted to anyone to use this software for any purpose,
11 * including commercial applications, and to alter it and redistribute it
12 * freely, subject to the following restrictions:
14 * 1. The origin of this software must not be misrepresented; you must not
15 * claim that you wrote the original software. If you use this software
16 * in a product, an acknowledgment in the product documentation would be
17 * appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must not be
20 * misrepresented as being the original software.
22 * 3. This notice may not be removed or altered from any source
30 #include <bsys/queue.h>
34 #ifdef BCHAN_CONFIG_DEBUG
35 # define DP(arg) printf arg
36 # define DP_ER(msg, err) printf("%s (%d/%x)\n", msg, err>>16, err)
39 # define DP_ER(msg, err) /**/
42 LOCAL arraybase_datanode_t* arraybase_datanode_next(arraybase_datanode_t *node)
44 return (arraybase_datanode_t *)node->queue.next;
47 LOCAL arraybase_datanode_t* arraybase_datanode_prev(arraybase_datanode_t *node)
49 return (arraybase_datanode_t *)node->queue.prev;
52 LOCAL VOID arraybase_datanode_insert(arraybase_datanode_t *node, arraybase_datanode_t *que)
54 QueInsert(&node->queue, &que->queue);
57 LOCAL VOID arraybase_datanode_getunitbyindex(arraybase_datanode_t *node, W unitsize, W index, VP *p)
59 /* comparing index and data lentgh is this user. */
60 *p = (VP)(node->data + unitsize * index);
63 LOCAL VOID arraybase_datanode_writebyindex(arraybase_datanode_t *node, W unitsize, W index, VP p)
67 /* comparing index and data lentgh is this user. */
68 arraybase_datanode_getunitbyindex(node, unitsize, index, &dest);
69 memcpy(dest, p, unitsize);
72 LOCAL W arraybase_datanode_initialize(arraybase_datanode_t *node, W unitsize, W denom)
74 QueInit(&node->queue);
75 node->data = (UB*)malloc(sizeof(UB)*unitsize*denom);
76 if (node->data == NULL) {
82 LOCAL VOID arraybase_datanode_finalize(arraybase_datanode_t *node)
85 QueRemove(&node->queue);
88 LOCAL arraybase_datanode_t* arraybase_datanode_new(W unitsize, W denom)
90 arraybase_datanode_t *node;
93 node = (arraybase_datanode_t *)malloc(sizeof(arraybase_datanode_t));
97 err = arraybase_datanode_initialize(node, unitsize, denom);
105 LOCAL VOID arraybase_datanode_delete(arraybase_datanode_t *node)
107 arraybase_datanode_finalize(node);
111 EXPORT Bool arraybase_getunitbyindex(arraybase_t *arraybase, W index, VP *p)
114 arraybase_datanode_t *node;
119 if (index >= arraybase->datanum) {
123 i_num = index / arraybase->denom;
124 i_data = index % arraybase->denom;
126 node = &arraybase->datalist;
127 for (i = 0; i < i_num; i++) {
128 node = arraybase_datanode_next(node);
131 arraybase_datanode_getunitbyindex(node, arraybase->unitsize, i_data, p);
136 EXPORT Bool arraybase_getunitfirst(arraybase_t *arraybase, VP *p)
138 /* TODO: more efficient. */
139 return arraybase_getunitbyindex(arraybase, 0, p);
142 EXPORT Bool arraybase_getunitlast(arraybase_t *arraybase, VP *p)
144 /* TODO: more efficient. */
145 return arraybase_getunitbyindex(arraybase, arraybase->datanum - 1, p);
148 EXPORT W arraybase_appendunit(arraybase_t *arraybase, VP p)
150 arraybase_datanode_t *node;
153 i_data = arraybase->datanum % arraybase->denom;
154 if ((i_data == 0)&&(arraybase->datanum > 0)) {
155 node = arraybase_datanode_new(arraybase->unitsize, arraybase->denom);
157 return -1; /* TODO */
159 arraybase_datanode_insert(node, &arraybase->datalist);
161 node = arraybase_datanode_prev(&arraybase->datalist);
164 arraybase_datanode_writebyindex(node, arraybase->unitsize, i_data, p);
166 arraybase->datanum++;
171 EXPORT VOID arraybase_truncate(arraybase_t *arraybase, W newlength)
174 arraybase_datanode_t *node, *newlast;
176 if (newlength >= arraybase->datanum) {
180 i_num = (newlength - 1) / arraybase->denom;
181 node = &arraybase->datalist;
182 for (i = 0; i < i_num; i++) {
183 node = arraybase_datanode_next(node);
188 node = arraybase_datanode_prev(&arraybase->datalist);
189 if (node == newlast) {
192 arraybase_datanode_delete(node);
195 arraybase->datanum = newlength;
198 EXPORT W arraybase_length(arraybase_t *arraybase)
200 return arraybase->datanum;
203 EXPORT W arraybase_initialize(arraybase_t *arraybase, W unitsize, W denom)
207 err = arraybase_datanode_initialize(&arraybase->datalist, unitsize, denom);
211 arraybase->unitsize = unitsize;
212 arraybase->denom = denom;
213 arraybase->datanum = 0;
218 EXPORT VOID arraybase_finalize(arraybase_t *arraybase)
220 arraybase_datanode_t *node;
223 node = arraybase_datanode_prev(&arraybase->datalist);
224 if (node == &arraybase->datalist) {
227 arraybase_datanode_delete(node);
229 arraybase_datanode_finalize(&arraybase->datalist);