source: svn/newcon3bcm2_21bu/BSEAV/lib/utils/biovec.c @ 46

Last change on this file since 46 was 46, checked in by megakiss, 11 years ago

459Mhz로 OTC 주파수 변경

  • Property svn:executable set to *
File size: 12.3 KB
Line 
1/***************************************************************************
2 *     Copyright (c) 2006-2007, Broadcom Corporation
3 *     All Rights Reserved
4 *     Confidential Property of Broadcom Corporation
5 *
6 *  THIS SOFTWARE MAY ONLY BE USED SUBJECT TO AN EXECUTED SOFTWARE LICENSE
7 *  AGREEMENT  BETWEEN THE USER AND BROADCOM.  YOU HAVE NO RIGHT TO USE OR
8 *  EXPLOIT THIS MATERIAL EXCEPT SUBJECT TO THE TERMS OF SUCH AN AGREEMENT.
9 *
10 * $brcm_Workfile: biovec.c $
11 * $brcm_Revision: 6 $
12 * $brcm_Date: 3/29/07 5:28p $
13 *
14 * Module Description:
15 *
16 * ASF parser library
17 *
18 * Revision History:
19 *
20 * $brcm_Log: /BSEAV/lib/utils/biovec.c $
21 *
22 * 6   3/29/07 5:28p vsilyaev
23 * PR 29199: Tested that MSB is not set in the size, e.g. size is lesser
24 * than 2^31
25 *
26 * 5   4/13/06 3:14p vsilyaev
27 * PR 20308: Improved API description
28 *
29 * 4   4/5/06 4:18p vsilyaev
30 * PR 20308: Rerranged data flow to accumulate entire media object, before
31 * converting to PES
32 *
33 * 3   4/4/06 6:49p vsilyaev
34 * PR 20577: Separated ASF parser and ASF stream
35 *
36 * 2   4/3/06 5:59p vsilyaev
37 * PR 20577: optimized bio_cursor_copy function
38 *
39 * 1   3/28/06 11:02a vsilyaev
40 * PR 20308: ASF parser library
41 *
42 *******************************************************************************/
43
44#include "bstd.h"
45#include "biovec.h"
46#include "bkni.h"
47
48BDBG_MODULE(bio_vec);
49
50#define BDBG_MSG_FLOW(x)   
51#define BDBG_MSG_TRACE(x)
52
53void 
54bio_array_init(bio_array *array)
55{
56        array->size = B_IO_ARRAY_INLINE;
57        array->count = 0;
58        array->vec = array->vec_;
59        array->owner = array->owner_;
60        array->length = 0;
61        return;
62}
63
64
65void 
66bio_array_reset(bio_array *array)
67{
68        array->count = 0;
69        array->length = 0;
70        return;
71}
72
73void 
74bio_array_shutdown(bio_array *array)
75{
76        if(array->size>B_IO_ARRAY_INLINE) {
77                /* free mmemory if not embedded */
78                BKNI_Free(array->vec);
79        }
80        return;
81}
82
83
84size_t
85bio_array_add_vec(bio_array *array, const bio_vec *v)
86{
87        BDBG_ASSERT(array);
88        BDBG_ASSERT(array->count <= array->size);
89        if (v->len==0) {
90                BDBG_MSG_TRACE(("%#lx adding zero length vector %#lx:%#lx", (unsigned long)array, (unsigned long)v, (unsigned long)v->base));
91                return array->length;
92        }
93        BDBG_MSG_TRACE(("array_add : %#lx %u %#lx", (unsigned long)array, v->len, (unsigned long)v->base));
94        if(array->count >= array->size) {
95                unsigned i;
96                unsigned size = array->size + 3;
97                bio_vec *vec;
98                bio_vec const **owner;
99
100                BDBG_MSG_TRACE(("growing array %#lx %u->%u", (unsigned long)array, array->size, size));
101                vec =  BKNI_Malloc((sizeof(*vec)+sizeof(void *))*size);
102                BDBG_ASSERT(vec);
103                if (!vec) {
104                        return BIO_EOF;
105                }
106                owner = (bio_vec const **)(vec+size);
107                for(i=0;i<array->size;i++) {
108                        vec[i] = array->vec[i];
109                        owner[i] = array->owner[i];
110                }
111                if(array->size>B_IO_ARRAY_INLINE) {
112                        /* free mmemory if not embedded */
113                        BKNI_Free(array->vec);
114                }
115                array->vec = vec;
116                array->owner = owner;
117                array->size = size;
118        }
119        BDBG_ASSERT(array->size > array->count);
120        array->vec[array->count] = *v;
121        array->owner[array->count] = v;
122        array->count++;
123        array->length += v->len;
124        return array->length;
125}
126
127
128void 
129bio_cursor_init(bio_cursor *cursor, const bio_array *array)
130{
131        BDBG_ASSERT(array);
132        BDBG_ASSERT(cursor);
133        BDBG_MSG_TRACE(("cursor_init: %#lx %#lx %u %u", (unsigned long)cursor, (unsigned long)array, array->count, array->length));
134        cursor->array = array;
135        cursor->pos = 0;
136        /* empty array, trigger refill on first 'next' */
137        cursor->left = 0;
138        cursor->cursor = 0;
139}
140
141size_t 
142bio_array_trim(bio_array *array, bio_cursor *cursor, void (*iov_free)(void *cnxt, const bio_vec *v), void *cnxt)
143{
144        unsigned i;
145        unsigned trim_pos;
146
147        BDBG_ASSERT(cursor->array == array);
148        BDBG_ASSERT(array->size >= array->count);
149
150        BDBG_ASSERT(cursor->pos <= cursor->array->count);
151        BDBG_MSG_TRACE(("array_trim+: %#lx %u %u  cursor: %#lx %u %u", (unsigned long)array, array->count, array->length, (unsigned long)cursor, cursor->pos, cursor->left));
152        trim_pos = cursor->pos;
153        if (cursor->left > 0) {
154                trim_pos--;
155        }
156        if(trim_pos>0) {
157                /* remove dead entries */
158                for(i=0;i<trim_pos;i++) {
159                        iov_free(cnxt, array->owner[i]);
160                        array->length -= array->vec[i].len;
161                }
162                for(i=0;i+trim_pos<array->count;i++) {
163                        array->vec[i] = array->vec[i+trim_pos];
164                        array->owner[i] = array->owner[i+trim_pos];
165                }
166                array->count -= trim_pos;
167        }
168        if (cursor->left > 0) {
169                /* adjust for the partial iov */
170                array->vec[0].base = (void *)cursor->cursor;
171                array->length -= array->vec[0].len - cursor->left;
172                array->vec[0].len = cursor->left;
173        }
174
175        /* adjust cursor */
176        cursor->pos = 0;
177        cursor->left = 0;
178        cursor->cursor = 0;
179        BDBG_MSG_TRACE(("array_trim-: %#lx %u %u", (unsigned long)array, array->count, array->length));
180
181        return 0;
182}
183
184size_t 
185bio_array_len(const bio_array *array)
186{
187        return array->length;
188}
189
190static size_t
191b_io_cursor_refill(bio_cursor *cursor)
192{
193        BDBG_ASSERT(cursor->left<=0);
194        if (cursor->left<0) {
195                return 0;
196        }
197        BDBG_ASSERT(cursor->array);
198        BDBG_ASSERT(cursor->pos <= cursor->array->count);
199        for(;;) {
200                if(cursor->pos >= cursor->array->count) {
201                        BDBG_MSG_TRACE(("cursor_refill: %#lx %u %u EOF", (unsigned long)cursor, cursor->pos, cursor->array->count));
202                        /* reached EOF */
203                        cursor->left = BIO_EOF;
204                        return 0;
205                }
206                cursor->left = cursor->array->vec[cursor->pos].len;
207                if (cursor->left==0) {
208                        cursor->pos++;
209                        continue; /* if empty entry, try fetch new one */
210                }
211                cursor->cursor = cursor->array->vec[cursor->pos].base;
212                BDBG_MSG_TRACE(("cursor_refill: %#lx %u %u %#lx", (unsigned long)cursor, cursor->pos, cursor->left, (unsigned long)cursor->cursor));
213                cursor->pos++;
214                break;
215        }
216        BDBG_ASSERT(cursor->left>0);
217        return (size_t)cursor->left;
218}
219
220int 
221bio_cursor_next(bio_cursor *cursor)
222{
223        int d;
224
225        BDBG_ASSERT(cursor);
226        if (cursor->left<=0) {
227                if (b_io_cursor_refill(cursor)==0) {
228                        return BIO_EOF;
229                }
230        }
231        BDBG_ASSERT(cursor->left>0);
232        cursor->left--;
233        d = *(cursor->cursor++);
234        BDBG_MSG_FLOW(("cursor_next: %#lx %d 0x%02x", (unsigned long)cursor, cursor->left, d));
235        return d;
236}
237
238bool
239bio_cursor_eof(const bio_cursor *cursor)
240{
241        BDBG_ASSERT(cursor);
242        BDBG_ASSERT(cursor->array);
243        BDBG_ASSERT(cursor->pos <= cursor->array->count);
244        return cursor->left < 0;
245}
246
247void
248bio_cursor_skip(bio_cursor *cursor, size_t count)
249{
250        BDBG_MSG_TRACE(("cursor_skip+: %#lx %d %u", (unsigned long)cursor, cursor->left, count));
251        BDBG_ASSERT((int)count>=0);
252        for(;;) {
253                if (cursor->left>=(int)count) {
254                        cursor->cursor+=count;
255                        cursor->left-=count;
256                        break;
257                } else {
258                        if (cursor->left>0) {
259                                count -= cursor->left;
260                                cursor->left = 0;
261                        }
262                        if (b_io_cursor_refill(cursor)==0) {
263                                break;
264                        }
265                }
266        }
267        BDBG_MSG_TRACE(("cursor_skip-: %#lx %d %u", (unsigned long)cursor, cursor->left, count));
268        return ;
269}
270
271#if B_IOVEC_memcpy
272#include <string.h>
273#endif
274
275size_t 
276bio_cursor_copy(bio_cursor *cursor, void *dest, size_t count)
277{
278        size_t i;
279        uint8_t *d = dest;
280        const uint8_t *s = cursor->cursor;
281        int left = cursor->left;
282#if B_IOVEC_memcpy
283#else
284        register uint8_t s0,s1;
285#endif
286
287        BDBG_MSG_TRACE(("cursor_copy+: %#lx %u", (unsigned long)cursor, count));
288
289        BDBG_ASSERT(count>0);
290        for(i=count;i>0;) {
291
292                if (i>=8 &&  left>=8) {
293                /* we optimize for copying 184 bytes at a time, which leads to 23*8 copies */
294#if B_IOVEC_memcpy
295                        memcpy(d,s,8); 
296                        /* this will be inlned into 8 pipelined instructions for unaligned load/store */
297#else
298                        s0 = s[0];
299                        s1 = s[1];
300                        d[0] = s0;
301                        d[1] = s1;
302
303                        s0 = s[2];
304                        s1 = s[3];
305                        d[2] = s0;
306                        d[3] = s1;
307
308                        s0 = s[4];
309                        s1 = s[5];
310                        d[4] = s0;
311                        d[5] = s1;
312
313                        s0 = s[6];
314                        s1 = s[7];
315                        d[6] = s0;
316                        d[7] = s1;
317#endif
318
319                        d+=8;i-=8;
320                        s+=8;
321                        left-=8;
322                } else if (left>=1) {
323                        d[0] = s[0];
324                        d++;i--;
325                        s++;
326                        left--;
327                } else {
328                        cursor->left = left;
329                        cursor->cursor = s;
330                        left = b_io_cursor_refill(cursor);
331                        if (left==0) {
332                                goto done;
333                        }
334                        s = cursor->cursor;
335                        continue;
336                }
337        }
338        cursor->left = left;
339        cursor->cursor = s;
340done:
341        BDBG_MSG_TRACE(("cursor_copy-: %#lx %u", (unsigned long)cursor, count-i));
342        return count-i;
343}
344
345
346
347
348void 
349bio_cursor_save(const bio_cursor *cursor, bio_checkpoint *checkpoint)
350{
351        BDBG_MSG_TRACE(("cursor_save: %#lx", (unsigned long)cursor));
352        checkpoint->left = cursor->left;
353        checkpoint->pos = cursor->pos;
354}
355
356void 
357bio_cursor_rollback(bio_cursor *cursor, const bio_checkpoint *checkpoint)
358{
359        BDBG_MSG_TRACE(("cursor_rollback: %#lx(%d:%u) %lx(%d:%u)", (unsigned long)cursor, cursor->left, cursor->pos, (unsigned long)checkpoint, checkpoint->left, checkpoint->pos));
360        BDBG_ASSERT( cursor->pos >= checkpoint->pos );
361        cursor->left = checkpoint->left;
362        cursor->pos = checkpoint->pos;
363        if (cursor->left<=0) {
364                BDBG_MSG_TRACE(("cursor_rollback: %#lx %u %u EOF", (unsigned long)cursor, cursor->pos, cursor->array->count));
365                return;
366        }
367        BDBG_ASSERT(cursor->array);
368        BDBG_ASSERT(cursor->pos <= cursor->array->count && cursor->pos>0);
369        BDBG_ASSERT(cursor->left <= (int)cursor->array->vec[cursor->pos-1].len);
370        cursor->cursor = cursor->array->vec[cursor->pos-1].base;
371        cursor->cursor += cursor->array->vec[cursor->pos-1].len - cursor->left;
372        BDBG_MSG_TRACE(("cursor_rollback: %#lx(%d:%u:%#lx)", (unsigned long)cursor, cursor->left, cursor->pos, (unsigned long)cursor->cursor));
373        return;
374}
375
376size_t 
377bio_cursor_pos(const bio_cursor *cursor)
378{
379        size_t i;
380        size_t size;
381
382        /* count completed iovec's */
383        for(size=0,i=0;i<cursor->pos;i++) {
384                size += cursor->array->vec[i].len;
385        }
386        /* add current iovec */
387        if (cursor->left>0) {
388                size -= cursor->left;
389        }
390        BDBG_MSG_TRACE(("cursor_pos: %#lx %u", (unsigned long)cursor, size));
391        return size;
392}
393
394size_t 
395bio_cursor_get(bio_cursor *cursor, size_t size, bio_vec *vec, bio_vec const **owner)
396{
397        BDBG_ASSERT(cursor->array);
398        BDBG_ASSERT((int)size>=0);
399        BDBG_MSG_TRACE(("bio_cursor_get+: %#lx %u %d %u", (unsigned long)cursor, cursor->pos, cursor->left, cursor->array->count));
400        if (cursor->left<0) {
401                BDBG_MSG_TRACE(("bio_cursor_get-: %#lx %u %d %u EOF", (unsigned long)cursor, cursor->pos, cursor->left, cursor->array->count));
402                return 0;
403        }
404        if (cursor->left==0) {
405                if (b_io_cursor_refill(cursor)==0) {
406                        BDBG_MSG_TRACE(("bio_cursor_get-: %#lx %u %d %u EOF(refill)", (unsigned long)cursor, cursor->pos, cursor->left, cursor->array->count));
407                        return 0;
408                }
409        }
410        BDBG_ASSERT(cursor->pos >= 1);
411        if (owner) {
412                BDBG_ASSERT(cursor->array->owner);
413                *owner = cursor->array->owner[cursor->pos-1];
414        }
415        vec->base = (void *)cursor->cursor;
416        if((int)size >= cursor->left) {
417                vec->len = cursor->left;
418                cursor->left = 0; /* forces refill */
419        } else {
420                vec->len = size;
421                cursor->left -= size;
422                cursor->cursor += size;
423        }
424        BDBG_MSG_TRACE(("bio_cursor_get-: %#lx %u %d %u -> %#lx:%u", (unsigned long)cursor, cursor->pos, cursor->left, cursor->array->count, (unsigned long)vec->base, vec->len));
425        return vec->len;
426}
427
428size_t
429bio_cursor_reserve(bio_cursor *cursor, size_t count)
430{
431        bio_checkpoint chk;
432        size_t result;
433        BDBG_MSG_TRACE(("bio_cursor_reserve+: %#lx(%d,%u) %u", (unsigned long)cursor, cursor->left, cursor->pos, count));
434
435        BIO_SAVE(cursor, &chk);
436
437        bio_cursor_skip(cursor, count);
438        if (BIO_IS_EOF(cursor)) {
439                int t;
440
441                BDBG_MSG_TRACE(("bio_cursor_reserve=: %#lx(%d,%u) %u EOF", (unsigned long)cursor, cursor->left, cursor->pos, count));
442                bio_cursor_rollback(cursor, &chk);
443                result=count;
444                for(;count>0;count--) {
445                        BIO_NEXT(t,cursor);
446                        if (t==BIO_EOF) {
447                                break;
448                        }
449                }
450                result=result-count;
451        } else {
452                result=count; 
453        }
454
455        bio_cursor_rollback(cursor, &chk);
456
457        BDBG_MSG_TRACE(("bio_cursor_reserve-: %#lx(%d,%u) %u", (unsigned long)cursor, cursor->left, cursor->pos, result));
458        return result;
459}
460
461void 
462bio_cursor_clone(bio_cursor *dst, const bio_cursor *src) 
463{
464        /* do a plain copy */
465        *dst = *src;
466        return;
467}
468
469void
470bio_array_from_iov(bio_array *array, const bio_vec *vec, unsigned count)
471{
472        array->size = 0;
473        array->count = count;
474        array->vec = (bio_vec *)vec;
475        array->length = 0;
476        array->owner = NULL;
477        return;
478}
479
480void 
481bio_cursor_from_iov(bio_cursor *cursor, bio_array *array, const bio_vec *vec, unsigned count)
482{
483        bio_array_from_iov(array, vec, count);
484        bio_cursor_init(cursor, array);
485        return;
486}
487
488
489size_t
490bio_array_add(bio_array *array, const void *base, size_t len)
491{
492        bio_vec v;
493        v.len = len;
494        v.base = (void *)base;
495        return bio_array_add_vec(array, &v);
496}
497
498void 
499bio_cursor_from_range(bio_cursor *cursor, bio_array *array, const void *base, size_t len)
500{
501        bio_array_init(array);
502        bio_array_add(array, base, len);
503        bio_cursor_init(cursor, array);
504        return;
505}
506
507static const bio_array b_empty_array = 
508{
509        0,
510        NULL,
511        {{NULL,0}},
512        0,
513        0,
514        {NULL},
515        NULL
516};
517
518void bio_cursor_empty(bio_cursor *cursor)
519{
520        bio_cursor_init(cursor, &b_empty_array);
521}
522
Note: See TracBrowser for help on using the repository browser.