Leptonica 1.83.1
Image processing and image analysis suite
Loading...
Searching...
No Matches
bytearray.c
Go to the documentation of this file.
1/*====================================================================*
2 - Copyright (C) 2001 Leptonica. All rights reserved.
3 -
4 - Redistribution and use in source and binary forms, with or without
5 - modification, are permitted provided that the following conditions
6 - are met:
7 - 1. Redistributions of source code must retain the above copyright
8 - notice, this list of conditions and the following disclaimer.
9 - 2. Redistributions in binary form must reproduce the above
10 - copyright notice, this list of conditions and the following
11 - disclaimer in the documentation and/or other materials
12 - provided with the distribution.
13 -
14 - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15 - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16 - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17 - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18 - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19 - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20 - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21 - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *====================================================================*/
26
66
67#ifdef HAVE_CONFIG_H
68#include <config_auto.h>
69#endif /* HAVE_CONFIG_H */
70
71#include <string.h>
72#include "allheaders.h"
73#include "array_internal.h"
74
75 /* Bounds on array size */
76static const l_uint32 MaxArraySize = 1000000000; /* 10^9 bytes */
77static const l_int32 InitialArraySize = 200;
78
79 /* Static function */
80static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size);
81
82/*---------------------------------------------------------------------*
83 * Creation, copy, clone, destruction *
84 *---------------------------------------------------------------------*/
97L_BYTEA *
98l_byteaCreate(size_t nbytes)
99{
100L_BYTEA *ba;
101
102 if (nbytes <= 0 || nbytes > MaxArraySize)
103 nbytes = InitialArraySize;
104 ba = (L_BYTEA *)LEPT_CALLOC(1, sizeof(L_BYTEA));
105 ba->data = (l_uint8 *)LEPT_CALLOC(nbytes + 1, sizeof(l_uint8));
106 if (!ba->data) {
107 l_byteaDestroy(&ba);
108 return (L_BYTEA *)ERROR_PTR("ba array not made", __func__, NULL);
109 }
110 ba->nalloc = nbytes + 1;
111 ba->refcount = 1;
112 return ba;
113}
114
115
123L_BYTEA *
124l_byteaInitFromMem(const l_uint8 *data,
125 size_t size)
126{
127L_BYTEA *ba;
128
129 if (!data)
130 return (L_BYTEA *)ERROR_PTR("data not defined", __func__, NULL);
131 if (size <= 0)
132 return (L_BYTEA *)ERROR_PTR("no bytes to initialize", __func__, NULL);
133 if (size > MaxArraySize)
134 return (L_BYTEA *)ERROR_PTR("size is too big", __func__, NULL);
135
136 if ((ba = l_byteaCreate(size)) == NULL)
137 return (L_BYTEA *)ERROR_PTR("ba not made", __func__, NULL);
138 memcpy(ba->data, data, size);
139 ba->size = size;
140 return ba;
141}
142
143
150L_BYTEA *
151l_byteaInitFromFile(const char *fname)
152{
153FILE *fp;
154L_BYTEA *ba;
155
156 if (!fname)
157 return (L_BYTEA *)ERROR_PTR("fname not defined", __func__, NULL);
158
159 if ((fp = fopenReadStream(fname)) == NULL)
160 return (L_BYTEA *)ERROR_PTR("file stream not opened", __func__, NULL);
161 ba = l_byteaInitFromStream(fp);
162 fclose(fp);
163 if (!ba)
164 return (L_BYTEA *)ERROR_PTR("ba not made", __func__, NULL);
165 return ba;
166}
167
168
175L_BYTEA *
177{
178l_uint8 *data;
179size_t nbytes;
180L_BYTEA *ba;
181
182 if (!fp)
183 return (L_BYTEA *)ERROR_PTR("stream not defined", __func__, NULL);
184
185 if ((data = l_binaryReadStream(fp, &nbytes)) == NULL)
186 return (L_BYTEA *)ERROR_PTR("data not read", __func__, NULL);
187 if ((ba = l_byteaCreate(nbytes)) == NULL) {
188 LEPT_FREE(data);
189 return (L_BYTEA *)ERROR_PTR("ba not made", __func__, NULL);
190 }
191 memcpy(ba->data, data, nbytes);
192 ba->size = nbytes;
193 LEPT_FREE(data);
194 return ba;
195}
196
197
210L_BYTEA *
212 l_int32 copyflag)
213{
214 if (!bas)
215 return (L_BYTEA *)ERROR_PTR("bas not defined", __func__, NULL);
216
217 if (copyflag == L_CLONE) {
218 bas->refcount++;
219 return bas;
220 }
221
222 return l_byteaInitFromMem(bas->data, bas->size);
223}
224
225
240void
242{
243L_BYTEA *ba;
244
245 if (pba == NULL) {
246 L_WARNING("ptr address is null!\n", __func__);
247 return;
248 }
249
250 if ((ba = *pba) == NULL)
251 return;
252
253 /* Decrement the ref count. If it is 0, destroy the lba. */
254 if (--ba->refcount == 0) {
255 if (ba->data) LEPT_FREE(ba->data);
256 LEPT_FREE(ba);
257 }
258 *pba = NULL;
259}
260
261
262/*---------------------------------------------------------------------*
263 * Accessors *
264 *---------------------------------------------------------------------*/
271size_t
273{
274 if (!ba)
275 return ERROR_INT("ba not defined", __func__, 0);
276 return ba->size;
277}
278
279
292l_uint8 *
294 size_t *psize)
295{
296 if (!ba)
297 return (l_uint8 *)ERROR_PTR("ba not defined", __func__, NULL);
298 if (!psize)
299 return (l_uint8 *)ERROR_PTR("&size not defined", __func__, NULL);
300
301 *psize = ba->size;
302 return ba->data;
303}
304
305
319l_uint8 *
321 size_t *psize)
322{
323l_uint8 *data;
324
325 if (!psize)
326 return (l_uint8 *)ERROR_PTR("&size not defined", __func__, NULL);
327 *psize = 0;
328 if (!ba)
329 return (l_uint8 *)ERROR_PTR("ba not defined", __func__, NULL);
330
331 data = l_byteaGetData(ba, psize);
332 return l_binaryCopy(data, *psize);
333}
334
335
336/*---------------------------------------------------------------------*
337 * Appending *
338 *---------------------------------------------------------------------*/
347l_ok
349 const l_uint8 *newdata,
350 size_t newbytes)
351{
352size_t size, nalloc, reqsize;
353
354 if (!ba)
355 return ERROR_INT("ba not defined", __func__, 1);
356 if (!newdata)
357 return ERROR_INT("newdata not defined", __func__, 1);
358
359 size = l_byteaGetSize(ba);
360 reqsize = size + newbytes + 1;
361 nalloc = ba->nalloc;
362 if (nalloc < reqsize) {
363 if (l_byteaExtendArrayToSize(ba, 2 * reqsize))
364 return ERROR_INT("extension failed", __func__, 1);
365 }
366
367 memcpy(ba->data + size, newdata, newbytes);
368 ba->size += newbytes;
369 return 0;
370}
371
372
380l_ok
382 const char *str)
383{
384size_t size, len, nalloc, reqsize;
385
386 if (!ba)
387 return ERROR_INT("ba not defined", __func__, 1);
388 if (!str)
389 return ERROR_INT("str not defined", __func__, 1);
390
391 size = l_byteaGetSize(ba);
392 len = strlen(str);
393 reqsize = size + len + 1;
394 nalloc = ba->nalloc;
395 if (nalloc < reqsize) {
396 if (l_byteaExtendArrayToSize(ba, 2 * reqsize))
397 return ERROR_INT("extension failed", __func__, 1);
398 }
399
400 memcpy(ba->data + size, str, len);
401 ba->size += len;
402 return 0;
403}
404
405
419static l_int32
421 size_t size)
422{
423 if (!ba)
424 return ERROR_INT("ba not defined", __func__, 1);
425 if (ba->nalloc > MaxArraySize) /* belt & suspenders */
426 return ERROR_INT("ba has too many ptrs", __func__, 1);
427 if (size > MaxArraySize)
428 return ERROR_INT("size > 1 GB; too large", __func__, 1);
429 if (size <= ba->nalloc) {
430 L_INFO("size too small; no extension\n", __func__);
431 return 0;
432 }
433
434 if ((ba->data =
435 (l_uint8 *)reallocNew((void **)&ba->data, ba->nalloc, size)) == NULL)
436 return ERROR_INT("new array not returned", __func__, 1);
437 ba->nalloc = size;
438 return 0;
439}
440
441
442/*---------------------------------------------------------------------*
443 * String join/split *
444 *---------------------------------------------------------------------*/
458l_ok
460 L_BYTEA **pba2)
461{
462l_uint8 *data2;
463size_t nbytes2;
464L_BYTEA *ba2;
465
466 if (!ba1)
467 return ERROR_INT("ba1 not defined", __func__, 1);
468 if (!pba2)
469 return ERROR_INT("&ba2 not defined", __func__, 1);
470 if ((ba2 = *pba2) == NULL) return 0;
471
472 data2 = l_byteaGetData(ba2, &nbytes2);
473 l_byteaAppendData(ba1, data2, nbytes2);
474
475 l_byteaDestroy(pba2);
476 return 0;
477}
478
479
488l_ok
490 size_t splitloc,
491 L_BYTEA **pba2)
492{
493l_uint8 *data1;
494size_t nbytes1, nbytes2;
495
496 if (!pba2)
497 return ERROR_INT("&ba2 not defined", __func__, 1);
498 *pba2 = NULL;
499 if (!ba1)
500 return ERROR_INT("ba1 not defined", __func__, 1);
501
502 data1 = l_byteaGetData(ba1, &nbytes1);
503 if (splitloc >= nbytes1)
504 return ERROR_INT("splitloc invalid", __func__, 1);
505 nbytes2 = nbytes1 - splitloc;
506
507 /* Make the new lba */
508 *pba2 = l_byteaInitFromMem(data1 + splitloc, nbytes2);
509
510 /* Null the removed bytes in the input lba */
511 memset(data1 + splitloc, 0, nbytes2);
512 ba1->size = splitloc;
513 return 0;
514}
515
516
517/*---------------------------------------------------------------------*
518 * Search *
519 *---------------------------------------------------------------------*/
529l_ok
531 const l_uint8 *sequence,
532 size_t seqlen,
533 L_DNA **pda)
534{
535l_uint8 *data;
536size_t size;
537
538 if (!pda)
539 return ERROR_INT("&da not defined", __func__, 1);
540 *pda = NULL;
541 if (!ba)
542 return ERROR_INT("ba not defined", __func__, 1);
543 if (!sequence)
544 return ERROR_INT("sequence not defined", __func__, 1);
545
546 data = l_byteaGetData(ba, &size);
547 *pda = arrayFindEachSequence(data, size, sequence, seqlen);
548 return 0;
549}
550
551
552/*---------------------------------------------------------------------*
553 * Output to file *
554 *---------------------------------------------------------------------*/
565l_ok
566l_byteaWrite(const char *fname,
567 L_BYTEA *ba,
568 size_t startloc,
569 size_t nbytes)
570{
571l_int32 ret;
572FILE *fp;
573
574 if (!fname)
575 return ERROR_INT("fname not defined", __func__, 1);
576 if (!ba)
577 return ERROR_INT("ba not defined", __func__, 1);
578
579 if ((fp = fopenWriteStream(fname, "wb")) == NULL)
580 return ERROR_INT("stream not opened", __func__, 1);
581 ret = l_byteaWriteStream(fp, ba, startloc, nbytes);
582 fclose(fp);
583 return ret;
584}
585
586
597l_ok
599 L_BYTEA *ba,
600 size_t startloc,
601 size_t nbytes)
602{
603l_uint8 *data;
604size_t size, maxbytes;
605
606 if (!fp)
607 return ERROR_INT("stream not defined", __func__, 1);
608 if (!ba)
609 return ERROR_INT("ba not defined", __func__, 1);
610
611 data = l_byteaGetData(ba, &size);
612 if (startloc >= size)
613 return ERROR_INT("invalid startloc", __func__, 1);
614 maxbytes = size - startloc;
615 nbytes = (nbytes == 0) ? maxbytes : L_MIN(nbytes, maxbytes);
616
617 fwrite(data + startloc, 1, nbytes, fp);
618 return 0;
619}
struct L_Dna L_DNA
Definition array.h:72
struct L_Bytea L_BYTEA
Definition array.h:84
static const l_int32 InitialArraySize
Definition bbuffer.c:109
L_BYTEA * l_byteaInitFromMem(const l_uint8 *data, size_t size)
l_byteaInitFromMem()
Definition bytearray.c:124
L_BYTEA * l_byteaCreate(size_t nbytes)
l_byteaCreate()
Definition bytearray.c:98
size_t l_byteaGetSize(L_BYTEA *ba)
l_byteaGetSize()
Definition bytearray.c:272
L_BYTEA * l_byteaInitFromFile(const char *fname)
l_byteaInitFromFile()
Definition bytearray.c:151
l_ok l_byteaFindEachSequence(L_BYTEA *ba, const l_uint8 *sequence, size_t seqlen, L_DNA **pda)
l_byteaFindEachSequence()
Definition bytearray.c:530
l_ok l_byteaSplit(L_BYTEA *ba1, size_t splitloc, L_BYTEA **pba2)
l_byteaSplit()
Definition bytearray.c:489
L_BYTEA * l_byteaInitFromStream(FILE *fp)
l_byteaInitFromStream()
Definition bytearray.c:176
l_uint8 * l_byteaCopyData(L_BYTEA *ba, size_t *psize)
l_byteaCopyData()
Definition bytearray.c:320
static l_int32 l_byteaExtendArrayToSize(L_BYTEA *ba, size_t size)
l_byteaExtendArrayToSize()
Definition bytearray.c:420
l_ok l_byteaWrite(const char *fname, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWrite()
Definition bytearray.c:566
void l_byteaDestroy(L_BYTEA **pba)
l_byteaDestroy()
Definition bytearray.c:241
l_uint8 * l_byteaGetData(L_BYTEA *ba, size_t *psize)
l_byteaGetData()
Definition bytearray.c:293
L_BYTEA * l_byteaCopy(L_BYTEA *bas, l_int32 copyflag)
l_byteaCopy()
Definition bytearray.c:211
l_ok l_byteaWriteStream(FILE *fp, L_BYTEA *ba, size_t startloc, size_t nbytes)
l_byteaWriteStream()
Definition bytearray.c:598
l_ok l_byteaAppendString(L_BYTEA *ba, const char *str)
l_byteaAppendString()
Definition bytearray.c:381
l_ok l_byteaJoin(L_BYTEA *ba1, L_BYTEA **pba2)
l_byteaJoin()
Definition bytearray.c:459
l_ok l_byteaAppendData(L_BYTEA *ba, const l_uint8 *newdata, size_t newbytes)
l_byteaAppendData()
Definition bytearray.c:348
@ L_CLONE
Definition pix.h:506
l_atomic refcount
size_t size
size_t nalloc
l_uint8 * data