Leptonica 1.82.0
Image processing and image analysis suite
sarray1.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
140#ifdef HAVE_CONFIG_H
141#include <config_auto.h>
142#endif /* HAVE_CONFIG_H */
143
144#include <string.h>
145#ifndef _WIN32
146#include <dirent.h> /* unix only */
147#include <sys/stat.h>
148#include <limits.h> /* needed for realpath() */
149#include <stdlib.h> /* needed for realpath() */
150#endif /* ! _WIN32 */
151#include "allheaders.h"
152
153static const l_uint32 MaxPtrArraySize = 50000000; /* 50 million */
154static const l_int32 InitialPtrArraySize = 50;
156 /* Static functions */
157static l_int32 sarrayExtendArray(SARRAY *sa);
158
159
160/*--------------------------------------------------------------------------*
161 * String array create/destroy/copy/extend *
162 *--------------------------------------------------------------------------*/
169SARRAY *
170sarrayCreate(l_int32 n)
171{
172SARRAY *sa;
173
174 PROCNAME("sarrayCreate");
175
176 if (n <= 0 || n > MaxPtrArraySize)
178
179 sa = (SARRAY *)LEPT_CALLOC(1, sizeof(SARRAY));
180 if ((sa->array = (char **)LEPT_CALLOC(n, sizeof(char *))) == NULL) {
181 sarrayDestroy(&sa);
182 return (SARRAY *)ERROR_PTR("ptr array not made", procName, NULL);
183 }
184
185 sa->nalloc = n;
186 sa->n = 0;
187 sa->refcount = 1;
188 return sa;
189}
190
191
199SARRAY *
201 const char *initstr)
202{
203l_int32 i;
204SARRAY *sa;
205
206 PROCNAME("sarrayCreateInitialized");
207
208 if (n <= 0)
209 return (SARRAY *)ERROR_PTR("n must be > 0", procName, NULL);
210 if (!initstr)
211 return (SARRAY *)ERROR_PTR("initstr not defined", procName, NULL);
212
213 sa = sarrayCreate(n);
214 for (i = 0; i < n; i++)
215 sarrayAddString(sa, initstr, L_COPY);
216 return sa;
217}
218
219
232SARRAY *
234{
235char separators[] = " \n\t";
236l_int32 i, nsub, size, inword;
237SARRAY *sa;
238
239 PROCNAME("sarrayCreateWordsFromString");
240
241 if (!string)
242 return (SARRAY *)ERROR_PTR("textstr not defined", procName, NULL);
243
244 /* Find the number of words */
245 size = strlen(string);
246 nsub = 0;
247 inword = FALSE;
248 for (i = 0; i < size; i++) {
249 if (inword == FALSE &&
250 (string[i] != ' ' && string[i] != '\t' && string[i] != '\n')) {
251 inword = TRUE;
252 nsub++;
253 } else if (inword == TRUE &&
254 (string[i] == ' ' || string[i] == '\t' || string[i] == '\n')) {
255 inword = FALSE;
256 }
257 }
258
259 if ((sa = sarrayCreate(nsub)) == NULL)
260 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
261 sarraySplitString(sa, string, separators);
262
263 return sa;
264}
265
266
282SARRAY *
284 l_int32 blankflag)
285{
286l_int32 i, nsub, size, startptr;
287char *cstring, *substring;
288SARRAY *sa;
289
290 PROCNAME("sarrayCreateLinesFromString");
291
292 if (!string)
293 return (SARRAY *)ERROR_PTR("textstr not defined", procName, NULL);
294
295 /* Find the number of lines */
296 size = strlen(string);
297 nsub = 0;
298 for (i = 0; i < size; i++) {
299 if (string[i] == '\n')
300 nsub++;
301 }
302
303 if ((sa = sarrayCreate(nsub)) == NULL)
304 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
305
306 if (blankflag) { /* keep blank lines as null strings */
307 /* Make a copy for munging */
308 if ((cstring = stringNew(string)) == NULL) {
309 sarrayDestroy(&sa);
310 return (SARRAY *)ERROR_PTR("cstring not made", procName, NULL);
311 }
312 /* We'll insert nulls like strtok */
313 startptr = 0;
314 for (i = 0; i < size; i++) {
315 if (cstring[i] == '\n') {
316 cstring[i] = '\0';
317 if (i > 0 && cstring[i - 1] == '\r')
318 cstring[i - 1] = '\0'; /* also remove Windows CR */
319 if ((substring = stringNew(cstring + startptr)) == NULL) {
320 sarrayDestroy(&sa);
321 LEPT_FREE(cstring);
322 return (SARRAY *)ERROR_PTR("substring not made",
323 procName, NULL);
324 }
325 sarrayAddString(sa, substring, L_INSERT);
326/* lept_stderr("substring = %s\n", substring); */
327 startptr = i + 1;
328 }
329 }
330 if (startptr < size) { /* no newline at end of last line */
331 if ((substring = stringNew(cstring + startptr)) == NULL) {
332 sarrayDestroy(&sa);
333 LEPT_FREE(cstring);
334 return (SARRAY *)ERROR_PTR("substring not made",
335 procName, NULL);
336 }
337 sarrayAddString(sa, substring, L_INSERT);
338/* lept_stderr("substring = %s\n", substring); */
339 }
340 LEPT_FREE(cstring);
341 } else { /* remove blank lines; use strtok */
342 sarraySplitString(sa, string, "\r\n");
343 }
344
345 return sa;
346}
347
348
361void
363{
364l_int32 i;
365SARRAY *sa;
366
367 PROCNAME("sarrayDestroy");
368
369 if (psa == NULL) {
370 L_WARNING("ptr address is NULL!\n", procName);
371 return;
372 }
373 if ((sa = *psa) == NULL)
374 return;
375
376 sarrayChangeRefcount(sa, -1);
377 if (sarrayGetRefcount(sa) <= 0) {
378 if (sa->array) {
379 for (i = 0; i < sa->n; i++) {
380 if (sa->array[i])
381 LEPT_FREE(sa->array[i]);
382 }
383 LEPT_FREE(sa->array);
384 }
385 LEPT_FREE(sa);
386 }
387 *psa = NULL;
388}
389
390
397SARRAY *
399{
400l_int32 i;
401SARRAY *csa;
402
403 PROCNAME("sarrayCopy");
404
405 if (!sa)
406 return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
407
408 if ((csa = sarrayCreate(sa->nalloc)) == NULL)
409 return (SARRAY *)ERROR_PTR("csa not made", procName, NULL);
410
411 for (i = 0; i < sa->n; i++)
412 sarrayAddString(csa, sa->array[i], L_COPY);
413
414 return csa;
415}
416
417
424SARRAY *
426{
427 PROCNAME("sarrayClone");
428
429 if (!sa)
430 return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
432 return sa;
433}
434
435
450l_ok
452 const char *string,
453 l_int32 copyflag)
454{
455l_int32 n;
456
457 PROCNAME("sarrayAddString");
458
459 if (!sa)
460 return ERROR_INT("sa not defined", procName, 1);
461 if (!string)
462 return ERROR_INT("string not defined", procName, 1);
463 if (copyflag != L_INSERT && copyflag != L_NOCOPY && copyflag != L_COPY)
464 return ERROR_INT("invalid copyflag", procName, 1);
465
466 n = sarrayGetCount(sa);
467 if (n >= sa->nalloc) {
468 if (sarrayExtendArray(sa))
469 return ERROR_INT("extension failed", procName, 1);
470 }
471
472 if (copyflag == L_COPY)
473 sa->array[n] = stringNew(string);
474 else /* L_INSERT or L_NOCOPY */
475 sa->array[n] = (char *)string;
476 sa->n++;
477 return 0;
478}
479
480
493static l_int32
495{
496size_t oldsize, newsize;
497
498 PROCNAME("sarrayExtendArray");
499
500 if (!sa)
501 return ERROR_INT("sa not defined", procName, 1);
502 if (sa->nalloc >= MaxPtrArraySize)
503 return ERROR_INT("sa at maximum ptr size; can't extend", procName, 1);
504 oldsize = sa->nalloc * sizeof(char *);
505 if (sa->nalloc > MaxPtrArraySize / 2) {
506 newsize = MaxPtrArraySize * sizeof(char *);
507 sa->nalloc = MaxPtrArraySize;
508 } else {
509 newsize = 2 * oldsize;
510 sa->nalloc *= 2;
511 }
512 if ((sa->array = (char **)reallocNew((void **)&sa->array,
513 oldsize, newsize)) == NULL)
514 return ERROR_INT("new ptr array not returned", procName, 1);
515
516 return 0;
517}
518
519
527char *
529 l_int32 index)
530{
531char *string;
532char **array;
533l_int32 i, n, nalloc;
534
535 PROCNAME("sarrayRemoveString");
536
537 if (!sa)
538 return (char *)ERROR_PTR("sa not defined", procName, NULL);
539
540 if ((array = sarrayGetArray(sa, &nalloc, &n)) == NULL)
541 return (char *)ERROR_PTR("array not returned", procName, NULL);
542
543 if (index < 0 || index >= n)
544 return (char *)ERROR_PTR("array index out of bounds", procName, NULL);
545
546 string = array[index];
547
548 /* If removed string is not at end of array, shift
549 * to fill in, maintaining original ordering.
550 * Note: if we didn't care about the order, we could
551 * put the last string array[n - 1] directly into the hole. */
552 for (i = index; i < n - 1; i++)
553 array[i] = array[i + 1];
554
555 sa->n--;
556 return string;
557}
558
559
578l_ok
580 l_int32 index,
581 char *newstr,
582 l_int32 copyflag)
583{
584char *str;
585l_int32 n;
586
587 PROCNAME("sarrayReplaceString");
588
589 if (!sa)
590 return ERROR_INT("sa not defined", procName, 1);
591 n = sarrayGetCount(sa);
592 if (index < 0 || index >= n)
593 return ERROR_INT("array index out of bounds", procName, 1);
594 if (!newstr)
595 return ERROR_INT("newstr not defined", procName, 1);
596 if (copyflag != L_INSERT && copyflag != L_COPY)
597 return ERROR_INT("invalid copyflag", procName, 1);
598
599 LEPT_FREE(sa->array[index]);
600 if (copyflag == L_INSERT)
601 str = newstr;
602 else /* L_COPY */
603 str = stringNew(newstr);
604 sa->array[index] = str;
605 return 0;
606}
607
608
615l_ok
617{
618l_int32 i;
619
620 PROCNAME("sarrayClear");
621
622 if (!sa)
623 return ERROR_INT("sa not defined", procName, 1);
624 for (i = 0; i < sa->n; i++) { /* free strings and null ptrs */
625 LEPT_FREE(sa->array[i]);
626 sa->array[i] = NULL;
627 }
628 sa->n = 0;
629 return 0;
630}
631
632
633/*----------------------------------------------------------------------*
634 * Accessors *
635 *----------------------------------------------------------------------*/
642l_int32
644{
645 PROCNAME("sarrayGetCount");
646
647 if (!sa)
648 return ERROR_INT("sa not defined", procName, 0);
649 return sa->n;
650}
651
652
667char **
669 l_int32 *pnalloc,
670 l_int32 *pn)
671{
672char **array;
673
674 PROCNAME("sarrayGetArray");
675
676 if (!sa)
677 return (char **)ERROR_PTR("sa not defined", procName, NULL);
678
679 array = sa->array;
680 if (pnalloc) *pnalloc = sa->nalloc;
681 if (pn) *pn = sa->n;
682
683 return array;
684}
685
686
702char *
704 l_int32 index,
705 l_int32 copyflag)
706{
707 PROCNAME("sarrayGetString");
708
709 if (!sa)
710 return (char *)ERROR_PTR("sa not defined", procName, NULL);
711 if (index < 0 || index >= sa->n)
712 return (char *)ERROR_PTR("index not valid", procName, NULL);
713 if (copyflag != L_NOCOPY && copyflag != L_COPY)
714 return (char *)ERROR_PTR("invalid copyflag", procName, NULL);
715
716 if (copyflag == L_NOCOPY)
717 return sa->array[index];
718 else /* L_COPY */
719 return stringNew(sa->array[index]);
720}
721
722
729l_int32
731{
732 PROCNAME("sarrayGetRefcount");
733
734 if (!sa)
735 return ERROR_INT("sa not defined", procName, UNDEF);
736 return sa->refcount;
737}
738
739
747l_ok
749 l_int32 delta)
750{
751 PROCNAME("sarrayChangeRefcount");
752
753 if (!sa)
754 return ERROR_INT("sa not defined", procName, UNDEF);
755 sa->refcount += delta;
756 return 0;
757}
758
759
760/*----------------------------------------------------------------------*
761 * Conversion to string *
762 *----------------------------------------------------------------------*/
784char *
786 l_int32 addnlflag)
787{
788 PROCNAME("sarrayToString");
789
790 if (!sa)
791 return (char *)ERROR_PTR("sa not defined", procName, NULL);
792
793 return sarrayToStringRange(sa, 0, 0, addnlflag);
794}
795
796
819char *
821 l_int32 first,
822 l_int32 nstrings,
823 l_int32 addnlflag)
824{
825char *dest, *src, *str;
826l_int32 n, i, last, size, index, len;
827
828 PROCNAME("sarrayToStringRange");
829
830 if (!sa)
831 return (char *)ERROR_PTR("sa not defined", procName, NULL);
832 if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2 && addnlflag != 3)
833 return (char *)ERROR_PTR("invalid addnlflag", procName, NULL);
834
835 n = sarrayGetCount(sa);
836
837 /* Empty sa; return char corresponding to addnlflag only */
838 if (n == 0) {
839 if (first == 0) {
840 if (addnlflag == 0)
841 return stringNew("");
842 if (addnlflag == 1)
843 return stringNew("\n");
844 if (addnlflag == 2)
845 return stringNew(" ");
846 else /* addnlflag == 3) */
847 return stringNew(",");
848 } else {
849 return (char *)ERROR_PTR("first not valid", procName, NULL);
850 }
851 }
852
853 /* Determine the range of string indices to be used */
854 if (first < 0 || first >= n)
855 return (char *)ERROR_PTR("first not valid", procName, NULL);
856 if (nstrings == 0 || (nstrings > n - first))
857 nstrings = n - first; /* no overflow */
858 last = first + nstrings - 1;
859
860 /* Determine the size of the output string */
861 size = 0;
862 for (i = first; i <= last; i++) {
863 if ((str = sarrayGetString(sa, i, L_NOCOPY)) == NULL)
864 return (char *)ERROR_PTR("str not found", procName, NULL);
865 size += strlen(str) + 2;
866 }
867 if ((dest = (char *)LEPT_CALLOC(size + 1, sizeof(char))) == NULL)
868 return (char *)ERROR_PTR("dest not made", procName, NULL);
869
870 /* Construct the output */
871 index = 0;
872 for (i = first; i <= last; i++) {
873 src = sarrayGetString(sa, i, L_NOCOPY);
874 len = strlen(src);
875 memcpy(dest + index, src, len);
876 index += len;
877 if (addnlflag == 1) {
878 dest[index] = '\n';
879 index++;
880 } else if (addnlflag == 2) {
881 dest[index] = ' ';
882 index++;
883 } else if (addnlflag == 3) {
884 dest[index] = ',';
885 index++;
886 }
887 }
888
889 return dest;
890}
891
892
893/*----------------------------------------------------------------------*
894 * Concatenate strings uniformly within the sarray *
895 *----------------------------------------------------------------------*/
916SARRAY *
918 l_int32 n,
919 l_int32 addnlflag)
920{
921l_int32 i, first, ntot, nstr;
922char *str;
923NUMA *na;
924SARRAY *saout;
925
926 PROCNAME("sarrayConcatUniformly");
927
928 if (!sa)
929 return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
930 ntot = sarrayGetCount(sa);
931 if (n < 1)
932 return (SARRAY *)ERROR_PTR("n must be >= 1", procName, NULL);
933 if (n > ntot) {
934 L_ERROR("n = %d > ntot = %d\n", procName, n, ntot);
935 return NULL;
936 }
937 if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2 && addnlflag != 3)
938 return (SARRAY *)ERROR_PTR("invalid addnlflag", procName, NULL);
939
940 saout = sarrayCreate(0);
941 na = numaGetUniformBinSizes(ntot, n);
942 for (i = 0, first = 0; i < n; i++) {
943 numaGetIValue(na, i, &nstr);
944 str = sarrayToStringRange(sa, first, nstr, addnlflag);
945 sarrayAddString(saout, str, L_INSERT);
946 first += nstr;
947 }
948 numaDestroy(&na);
949 return saout;
950}
951
952
953/*----------------------------------------------------------------------*
954 * Join 2 sarrays *
955 *----------------------------------------------------------------------*/
968l_ok
970 SARRAY *sa2)
971{
972char *str;
973l_int32 n, i;
974
975 PROCNAME("sarrayJoin");
976
977 if (!sa1)
978 return ERROR_INT("sa1 not defined", procName, 1);
979 if (!sa2)
980 return ERROR_INT("sa2 not defined", procName, 1);
981
982 n = sarrayGetCount(sa2);
983 for (i = 0; i < n; i++) {
984 str = sarrayGetString(sa2, i, L_NOCOPY);
985 if (sarrayAddString(sa1, str, L_COPY) == 1) {
986 L_ERROR("failed to add string at i = %d\n", procName, i);
987 return 1;
988 }
989 }
990 return 0;
991}
992
993
1011l_ok
1013 SARRAY *sa2,
1014 l_int32 start,
1015 l_int32 end)
1016{
1017char *str;
1018l_int32 n, i;
1019
1020 PROCNAME("sarrayAppendRange");
1021
1022 if (!sa1)
1023 return ERROR_INT("sa1 not defined", procName, 1);
1024 if (!sa2)
1025 return ERROR_INT("sa2 not defined", procName, 1);
1026
1027 if (start < 0)
1028 start = 0;
1029 n = sarrayGetCount(sa2);
1030 if (end < 0 || end >= n)
1031 end = n - 1;
1032 if (start > end)
1033 return ERROR_INT("start > end", procName, 1);
1034
1035 for (i = start; i <= end; i++) {
1036 str = sarrayGetString(sa2, i, L_NOCOPY);
1037 sarrayAddString(sa1, str, L_COPY);
1038 }
1039
1040 return 0;
1041}
1042
1043
1044/*----------------------------------------------------------------------*
1045 * Pad an sarray to be the same size as another sarray *
1046 *----------------------------------------------------------------------*/
1063l_ok
1065 SARRAY *sa2,
1066 const char *padstring)
1067{
1068l_int32 i, n1, n2;
1069
1070 PROCNAME("sarrayPadToSameSize");
1071
1072 if (!sa1 || !sa2)
1073 return ERROR_INT("both sa1 and sa2 not defined", procName, 1);
1074
1075 n1 = sarrayGetCount(sa1);
1076 n2 = sarrayGetCount(sa2);
1077 if (n1 < n2) {
1078 for (i = n1; i < n2; i++)
1079 sarrayAddString(sa1, padstring, L_COPY);
1080 } else if (n1 > n2) {
1081 for (i = n2; i < n1; i++)
1082 sarrayAddString(sa2, padstring, L_COPY);
1083 }
1084
1085 return 0;
1086}
1087
1088
1089/*----------------------------------------------------------------------*
1090 * Convert word sarray to line sarray *
1091 *----------------------------------------------------------------------*/
1122SARRAY *
1124 l_int32 linesize)
1125{
1126char *wd, *strl;
1127char emptystring[] = "";
1128l_int32 n, i, len, totlen;
1129SARRAY *sal, *saout;
1130
1131 PROCNAME("sarrayConvertWordsToLines");
1132
1133 if (!sa)
1134 return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
1135
1136 saout = sarrayCreate(0);
1137 n = sarrayGetCount(sa);
1138 totlen = 0;
1139 sal = NULL;
1140 for (i = 0; i < n; i++) {
1141 if (!sal)
1142 sal = sarrayCreate(0);
1143 wd = sarrayGetString(sa, i, L_NOCOPY);
1144 len = strlen(wd);
1145 if (len == 0) { /* end of paragraph: end line & insert blank line */
1146 if (totlen > 0) {
1147 strl = sarrayToString(sal, 2);
1148 sarrayAddString(saout, strl, L_INSERT);
1149 }
1150 sarrayAddString(saout, emptystring, L_COPY);
1151 sarrayDestroy(&sal);
1152 totlen = 0;
1153 } else if (totlen == 0 && len + 1 > linesize) { /* long word! */
1154 sarrayAddString(saout, wd, L_COPY); /* copy to one line */
1155 } else if (totlen + len + 1 > linesize) { /* end line & start new */
1156 strl = sarrayToString(sal, 2);
1157 sarrayAddString(saout, strl, L_INSERT);
1158 sarrayDestroy(&sal);
1159 sal = sarrayCreate(0);
1160 sarrayAddString(sal, wd, L_COPY);
1161 totlen = len + 1;
1162 } else { /* add to current line */
1163 sarrayAddString(sal, wd, L_COPY);
1164 totlen += len + 1;
1165 }
1166 }
1167 if (totlen > 0) { /* didn't end with blank line; output last line */
1168 strl = sarrayToString(sal, 2);
1169 sarrayAddString(saout, strl, L_INSERT);
1170 sarrayDestroy(&sal);
1171 }
1172
1173 return saout;
1174}
1175
1176
1177/*----------------------------------------------------------------------*
1178 * Split string on separator list *
1179 *----------------------------------------------------------------------*/
1180/*
1181 * \brief sarraySplitString()
1182 *
1183 * \param[in] sa to append to; typically empty initially
1184 * \param[in] str string to split; not changed
1185 * \param[in] separators characters that split input string
1186 * \return 0 if OK, 1 on error.
1187 *
1188 * <pre>
1189 * Notes:
1190 * (1) This uses strtokSafe(). See the notes there in utils.c.
1191 * </pre>
1192 */
1193l_int32
1194sarraySplitString(SARRAY *sa,
1195 const char *str,
1196 const char *separators)
1197{
1198char *cstr, *substr, *saveptr;
1199
1200 PROCNAME("sarraySplitString");
1201
1202 if (!sa)
1203 return ERROR_INT("sa not defined", procName, 1);
1204 if (!str)
1205 return ERROR_INT("str not defined", procName, 1);
1206 if (!separators)
1207 return ERROR_INT("separators not defined", procName, 1);
1208
1209 cstr = stringNew(str); /* preserves const-ness of input str */
1210 saveptr = NULL;
1211 substr = strtokSafe(cstr, separators, &saveptr);
1212 if (substr)
1213 sarrayAddString(sa, substr, L_INSERT);
1214 while ((substr = strtokSafe(NULL, separators, &saveptr)))
1215 sarrayAddString(sa, substr, L_INSERT);
1216 LEPT_FREE(cstr);
1217
1218 return 0;
1219}
1220
1221
1222/*----------------------------------------------------------------------*
1223 * Filter sarray *
1224 *----------------------------------------------------------------------*/
1240SARRAY *
1242 const char *substr)
1243{
1244char *str;
1245l_int32 n, i, offset, found;
1246SARRAY *saout;
1247
1248 PROCNAME("sarraySelectBySubstring");
1249
1250 if (!sain)
1251 return (SARRAY *)ERROR_PTR("sain not defined", procName, NULL);
1252
1253 n = sarrayGetCount(sain);
1254 if (!substr || n == 0)
1255 return sarrayCopy(sain);
1256
1257 saout = sarrayCreate(n);
1258 for (i = 0; i < n; i++) {
1259 str = sarrayGetString(sain, i, L_NOCOPY);
1260 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1261 strlen(substr), &offset, &found);
1262 if (found)
1263 sarrayAddString(saout, str, L_COPY);
1264 }
1265
1266 return saout;
1267}
1268
1269
1286SARRAY *
1288 l_int32 first,
1289 l_int32 last)
1290{
1291char *str;
1292l_int32 n, i;
1293SARRAY *saout;
1294
1295 PROCNAME("sarraySelectRange");
1296
1297 if (!sain)
1298 return (SARRAY *)ERROR_PTR("sain not defined", procName, NULL);
1299 if (first < 0) first = 0;
1300 n = sarrayGetCount(sain);
1301 if (last <= 0) last = n - 1;
1302 if (last >= n) {
1303 L_WARNING("last > n - 1; setting to n - 1\n", procName);
1304 last = n - 1;
1305 }
1306 if (first > last)
1307 return (SARRAY *)ERROR_PTR("first must be >= last", procName, NULL);
1308
1309 saout = sarrayCreate(0);
1310 for (i = first; i <= last; i++) {
1311 str = sarrayGetString(sain, i, L_COPY);
1312 sarrayAddString(saout, str, L_INSERT);
1313 }
1314
1315 return saout;
1316}
1317
1318
1355l_int32
1357 l_int32 start,
1358 l_int32 *pactualstart,
1359 l_int32 *pend,
1360 l_int32 *pnewstart,
1361 const char *substr,
1362 l_int32 loc)
1363{
1364char *str;
1365l_int32 n, i, offset, found;
1366
1367 PROCNAME("sarrayParseRange");
1368
1369 if (!sa)
1370 return ERROR_INT("sa not defined", procName, 1);
1371 if (!pactualstart || !pend || !pnewstart)
1372 return ERROR_INT("not all range addresses defined", procName, 1);
1373 n = sarrayGetCount(sa);
1374 *pactualstart = *pend = *pnewstart = n;
1375 if (!substr)
1376 return ERROR_INT("substr not defined", procName, 1);
1377
1378 /* Look for the first string without the marker */
1379 if (start < 0 || start >= n)
1380 return 1;
1381 for (i = start; i < n; i++) {
1382 str = sarrayGetString(sa, i, L_NOCOPY);
1383 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1384 strlen(substr), &offset, &found);
1385 if (loc < 0) {
1386 if (!found) break;
1387 } else {
1388 if (!found || offset != loc) break;
1389 }
1390 }
1391 start = i;
1392 if (i == n) /* couldn't get started */
1393 return 1;
1394
1395 /* Look for the last string without the marker */
1396 *pactualstart = start;
1397 for (i = start + 1; i < n; i++) {
1398 str = sarrayGetString(sa, i, L_NOCOPY);
1399 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1400 strlen(substr), &offset, &found);
1401 if (loc < 0) {
1402 if (found) break;
1403 } else {
1404 if (found && offset == loc) break;
1405 }
1406 }
1407 *pend = i - 1;
1408 start = i;
1409 if (i == n) /* no further range */
1410 return 0;
1411
1412 /* Look for the first string after *pend without the marker.
1413 * This will start the next run of strings, if it exists. */
1414 for (i = start; i < n; i++) {
1415 str = sarrayGetString(sa, i, L_NOCOPY);
1416 arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1417 strlen(substr), &offset, &found);
1418 if (loc < 0) {
1419 if (!found) break;
1420 } else {
1421 if (!found || offset != loc) break;
1422 }
1423 }
1424 if (i < n)
1425 *pnewstart = i;
1426
1427 return 0;
1428}
1429
1430
1431/*----------------------------------------------------------------------*
1432 * Serialize for I/O *
1433 *----------------------------------------------------------------------*/
1440SARRAY *
1441sarrayRead(const char *filename)
1442{
1443FILE *fp;
1444SARRAY *sa;
1445
1446 PROCNAME("sarrayRead");
1447
1448 if (!filename)
1449 return (SARRAY *)ERROR_PTR("filename not defined", procName, NULL);
1450
1451 if ((fp = fopenReadStream(filename)) == NULL)
1452 return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL);
1453 sa = sarrayReadStream(fp);
1454 fclose(fp);
1455 if (!sa)
1456 return (SARRAY *)ERROR_PTR("sa not read", procName, NULL);
1457 return sa;
1458}
1459
1460
1478SARRAY *
1480{
1481char *stringbuf;
1482l_int32 i, n, size, index, bufsize, version, ignore, success;
1483SARRAY *sa;
1484
1485 PROCNAME("sarrayReadStream");
1486
1487 if (!fp)
1488 return (SARRAY *)ERROR_PTR("stream not defined", procName, NULL);
1489
1490 if (fscanf(fp, "\nSarray Version %d\n", &version) != 1)
1491 return (SARRAY *)ERROR_PTR("not an sarray file", procName, NULL);
1492 if (version != SARRAY_VERSION_NUMBER)
1493 return (SARRAY *)ERROR_PTR("invalid sarray version", procName, NULL);
1494 if (fscanf(fp, "Number of strings = %d\n", &n) != 1)
1495 return (SARRAY *)ERROR_PTR("error on # strings", procName, NULL);
1496 if (n < 0)
1497 return (SARRAY *)ERROR_PTR("num string ptrs <= 0", procName, NULL);
1498 if (n > MaxPtrArraySize)
1499 return (SARRAY *)ERROR_PTR("too many string ptrs", procName, NULL);
1500 if (n == 0) L_INFO("the sarray is empty\n", procName);
1501
1502 success = TRUE;
1503 if ((sa = sarrayCreate(n)) == NULL)
1504 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1505 bufsize = 512 + 1;
1506 stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1507
1508 for (i = 0; i < n; i++) {
1509 /* Get the size of the stored string */
1510 if ((fscanf(fp, "%d[%d]:", &index, &size) != 2) || (size > (1 << 30))) {
1511 success = FALSE;
1512 L_ERROR("error on string size\n", procName);
1513 goto cleanup;
1514 }
1515 /* Expand the string buffer if necessary */
1516 if (size > bufsize - 5) {
1517 LEPT_FREE(stringbuf);
1518 bufsize = (l_int32)(1.5 * size);
1519 stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1520 }
1521 /* Read the stored string, plus leading spaces and trailing \n */
1522 if (fread(stringbuf, 1, size + 3, fp) != size + 3) {
1523 success = FALSE;
1524 L_ERROR("error reading string\n", procName);
1525 goto cleanup;
1526 }
1527 /* Remove the \n that was added by sarrayWriteStream() */
1528 stringbuf[size + 2] = '\0';
1529 /* Copy it in, skipping the 2 leading spaces */
1530 sarrayAddString(sa, stringbuf + 2, L_COPY);
1531 }
1532 ignore = fscanf(fp, "\n");
1533
1534cleanup:
1535 LEPT_FREE(stringbuf);
1536 if (!success) sarrayDestroy(&sa);
1537 return sa;
1538}
1539
1540
1548SARRAY *
1549sarrayReadMem(const l_uint8 *data,
1550 size_t size)
1551{
1552FILE *fp;
1553SARRAY *sa;
1554
1555 PROCNAME("sarrayReadMem");
1556
1557 if (!data)
1558 return (SARRAY *)ERROR_PTR("data not defined", procName, NULL);
1559 if ((fp = fopenReadFromMemory(data, size)) == NULL)
1560 return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL);
1561
1562 sa = sarrayReadStream(fp);
1563 fclose(fp);
1564 if (!sa) L_ERROR("sarray not read\n", procName);
1565 return sa;
1566}
1567
1568
1576l_ok
1577sarrayWrite(const char *filename,
1578 SARRAY *sa)
1579{
1580l_int32 ret;
1581FILE *fp;
1582
1583 PROCNAME("sarrayWrite");
1584
1585 if (!filename)
1586 return ERROR_INT("filename not defined", procName, 1);
1587 if (!sa)
1588 return ERROR_INT("sa not defined", procName, 1);
1589
1590 if ((fp = fopenWriteStream(filename, "w")) == NULL)
1591 return ERROR_INT("stream not opened", procName, 1);
1592 ret = sarrayWriteStream(fp, sa);
1593 fclose(fp);
1594 if (ret)
1595 return ERROR_INT("sa not written to stream", procName, 1);
1596 return 0;
1597}
1598
1599
1613l_ok
1615 SARRAY *sa)
1616{
1617l_int32 i, n, len;
1618
1619 PROCNAME("sarrayWriteStream");
1620
1621 if (!fp)
1622 return ERROR_INT("stream not defined", procName, 1);
1623 if (!sa)
1624 return sarrayWriteStderr(sa);
1625
1626 n = sarrayGetCount(sa);
1627 fprintf(fp, "\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1628 fprintf(fp, "Number of strings = %d\n", n);
1629 for (i = 0; i < n; i++) {
1630 len = strlen(sa->array[i]);
1631 fprintf(fp, " %d[%d]: %s\n", i, len, sa->array[i]);
1632 }
1633 fprintf(fp, "\n");
1634
1635 return 0;
1636}
1637
1638
1645l_ok
1647{
1648l_int32 i, n, len;
1649
1650 PROCNAME("sarrayWriteStderr");
1651
1652 if (!sa)
1653 return ERROR_INT("sa not defined", procName, 1);
1654
1655 n = sarrayGetCount(sa);
1656 lept_stderr("\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1657 lept_stderr("Number of strings = %d\n", n);
1658 for (i = 0; i < n; i++) {
1659 len = strlen(sa->array[i]);
1660 lept_stderr(" %d[%d]: %s\n", i, len, sa->array[i]);
1661 }
1662 lept_stderr("\n");
1663 return 0;
1664}
1665
1666
1680l_ok
1681sarrayWriteMem(l_uint8 **pdata,
1682 size_t *psize,
1683 SARRAY *sa)
1684{
1685l_int32 ret;
1686FILE *fp;
1687
1688 PROCNAME("sarrayWriteMem");
1689
1690 if (pdata) *pdata = NULL;
1691 if (psize) *psize = 0;
1692 if (!pdata)
1693 return ERROR_INT("&data not defined", procName, 1);
1694 if (!psize)
1695 return ERROR_INT("&size not defined", procName, 1);
1696 if (!sa)
1697 return ERROR_INT("sa not defined", procName, 1);
1698
1699#if HAVE_FMEMOPEN
1700 if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1701 return ERROR_INT("stream not opened", procName, 1);
1702 ret = sarrayWriteStream(fp, sa);
1703 fputc('\0', fp);
1704 fclose(fp);
1705 *psize = *psize - 1;
1706#else
1707 L_INFO("work-around: writing to a temp file\n", procName);
1708 #ifdef _WIN32
1709 if ((fp = fopenWriteWinTempfile()) == NULL)
1710 return ERROR_INT("tmpfile stream not opened", procName, 1);
1711 #else
1712 if ((fp = tmpfile()) == NULL)
1713 return ERROR_INT("tmpfile stream not opened", procName, 1);
1714 #endif /* _WIN32 */
1715 ret = sarrayWriteStream(fp, sa);
1716 rewind(fp);
1717 *pdata = l_binaryReadStream(fp, psize);
1718 fclose(fp);
1719#endif /* HAVE_FMEMOPEN */
1720 return ret;
1721}
1722
1723
1731l_ok
1732sarrayAppend(const char *filename,
1733 SARRAY *sa)
1734{
1735FILE *fp;
1736
1737 PROCNAME("sarrayAppend");
1738
1739 if (!filename)
1740 return ERROR_INT("filename not defined", procName, 1);
1741 if (!sa)
1742 return ERROR_INT("sa not defined", procName, 1);
1743
1744 if ((fp = fopenWriteStream(filename, "a")) == NULL)
1745 return ERROR_INT("stream not opened", procName, 1);
1746 if (sarrayWriteStream(fp, sa)) {
1747 fclose(fp);
1748 return ERROR_INT("sa not appended to stream", procName, 1);
1749 }
1750
1751 fclose(fp);
1752 return 0;
1753}
1754
1755
1756/*---------------------------------------------------------------------*
1757 * Directory filenames *
1758 *---------------------------------------------------------------------*/
1799SARRAY *
1801 const char *substr,
1802 l_int32 numpre,
1803 l_int32 numpost,
1804 l_int32 maxnum)
1805{
1806l_int32 nfiles;
1807SARRAY *sa, *saout;
1808
1809 PROCNAME("getNumberedPathnamesInDirectory");
1810
1811 if (!dirname)
1812 return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1813
1814 if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
1815 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1816 if ((nfiles = sarrayGetCount(sa)) == 0) {
1817 sarrayDestroy(&sa);
1818 return sarrayCreate(1);
1819 }
1820
1821 saout = convertSortedToNumberedPathnames(sa, numpre, numpost, maxnum);
1822 sarrayDestroy(&sa);
1823 return saout;
1824}
1825
1826
1847SARRAY *
1849 const char *substr,
1850 l_int32 first,
1851 l_int32 nfiles)
1852{
1853char *fname, *fullname;
1854l_int32 i, n, last;
1855SARRAY *sa, *safiles, *saout;
1856
1857 PROCNAME("getSortedPathnamesInDirectory");
1858
1859 if (!dirname)
1860 return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1861
1862 if ((sa = getFilenamesInDirectory(dirname)) == NULL)
1863 return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1864 safiles = sarraySelectBySubstring(sa, substr);
1865 sarrayDestroy(&sa);
1866 n = sarrayGetCount(safiles);
1867 if (n == 0) {
1868 L_WARNING("no files found\n", procName);
1869 return safiles;
1870 }
1871
1872 sarraySort(safiles, safiles, L_SORT_INCREASING);
1873
1874 first = L_MIN(L_MAX(first, 0), n - 1);
1875 if (nfiles == 0)
1876 nfiles = n - first;
1877 last = L_MIN(first + nfiles - 1, n - 1);
1878
1879 saout = sarrayCreate(last - first + 1);
1880 for (i = first; i <= last; i++) {
1881 fname = sarrayGetString(safiles, i, L_NOCOPY);
1882 fullname = pathJoin(dirname, fname);
1883 sarrayAddString(saout, fullname, L_INSERT);
1884 }
1885
1886 sarrayDestroy(&safiles);
1887 return saout;
1888}
1889
1890
1907SARRAY *
1909 l_int32 numpre,
1910 l_int32 numpost,
1911 l_int32 maxnum)
1912{
1913char *fname, *str;
1914l_int32 i, nfiles, num, index;
1915SARRAY *saout;
1916
1917 PROCNAME("convertSortedToNumberedPathnames");
1918
1919 if (!sa)
1920 return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
1921 if ((nfiles = sarrayGetCount(sa)) == 0)
1922 return sarrayCreate(1);
1923
1924 /* Find the last file in the sorted array that has a number
1925 * that (a) matches the count pattern and (b) does not
1926 * exceed %maxnum. %maxnum sets an upper limit on the size
1927 * of the sarray. */
1928 num = 0;
1929 for (i = nfiles - 1; i >= 0; i--) {
1930 fname = sarrayGetString(sa, i, L_NOCOPY);
1931 num = extractNumberFromFilename(fname, numpre, numpost);
1932 if (num < 0) continue;
1933 num = L_MIN(num + 1, maxnum);
1934 break;
1935 }
1936
1937 if (num <= 0) /* none found */
1938 return sarrayCreate(1);
1939
1940 /* Insert pathnames into the output sarray.
1941 * Ignore numbers that are out of the range of sarray. */
1942 saout = sarrayCreateInitialized(num, "");
1943 for (i = 0; i < nfiles; i++) {
1944 fname = sarrayGetString(sa, i, L_NOCOPY);
1945 index = extractNumberFromFilename(fname, numpre, numpost);
1946 if (index < 0 || index >= num) continue;
1947 str = sarrayGetString(saout, index, L_NOCOPY);
1948 if (str[0] != '\0') {
1949 L_WARNING("\n Multiple files with same number: %d\n",
1950 procName, index);
1951 }
1952 sarrayReplaceString(saout, index, fname, L_COPY);
1953 }
1954
1955 return saout;
1956}
1957
1958
1987#ifndef _WIN32
1988
1989SARRAY *
1990getFilenamesInDirectory(const char *dirname)
1991{
1992char dir[PATH_MAX + 1];
1993char *realdir, *stat_path, *ignore;
1994size_t size;
1995SARRAY *safiles;
1996DIR *pdir;
1997struct dirent *pdirentry;
1998int dfd, stat_ret;
1999struct stat st;
2000
2001 PROCNAME("getFilenamesInDirectory");
2002
2003 if (!dirname)
2004 return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
2005 if (dirname[0] == '\0')
2006 return (SARRAY *)ERROR_PTR("dirname is empty", procName, NULL);
2007
2008 /* Who would have thought it was this fiddly to open a directory
2009 and get the files inside? fstatat() works with relative
2010 directory paths, and stat() requires using the absolute path.
2011 realpath works as follows for files and directories:
2012 * If the file or directory exists, realpath returns its path;
2013 else it returns NULL.
2014 * If the second arg to realpath is passed in, the canonical path
2015 is returned there. Use a buffer of sufficient size. If the
2016 second arg is NULL, the path is malloc'd and returned if the
2017 file or directory exists.
2018 We pass in a buffer for the second arg, and check that the canonical
2019 directory path was made. The existence of the directory is checked
2020 later, after its actual path is returned by genPathname(). */
2021 dir[0] = '\0'; /* init empty in case realpath() fails to write it */
2022 ignore = realpath(dirname, dir);
2023 if (dir[0] == '\0')
2024 return (SARRAY *)ERROR_PTR("dir not made", procName, NULL);
2025 realdir = genPathname(dir, NULL);
2026 if ((pdir = opendir(realdir)) == NULL) {
2027 LEPT_FREE(realdir);
2028 return (SARRAY *)ERROR_PTR("pdir not opened", procName, NULL);
2029 }
2030 safiles = sarrayCreate(0);
2031 dfd = dirfd(pdir);
2032 while ((pdirentry = readdir(pdir))) {
2033#if HAVE_FSTATAT
2034 stat_ret = fstatat(dfd, pdirentry->d_name, &st, 0);
2035#else
2036 size = strlen(realdir) + strlen(pdirentry->d_name) + 2;
2037 if (size > PATH_MAX) {
2038 L_ERROR("size = %zu too large; skipping\n", procName, size);
2039 continue;
2040 }
2041 stat_path = (char *)LEPT_CALLOC(size, 1);
2042 snprintf(stat_path, size, "%s/%s", realdir, pdirentry->d_name);
2043 stat_ret = stat(stat_path, &st);
2044 LEPT_FREE(stat_path);
2045#endif
2046 if (stat_ret == 0 && S_ISDIR(st.st_mode))
2047 continue;
2048 sarrayAddString(safiles, pdirentry->d_name, L_COPY);
2049 }
2050 closedir(pdir);
2051 LEPT_FREE(realdir);
2052 return safiles;
2053}
2054
2055#else /* _WIN32 */
2056
2057 /* http://msdn2.microsoft.com/en-us/library/aa365200(VS.85).aspx */
2058#include <windows.h>
2059
2060SARRAY *
2061getFilenamesInDirectory(const char *dirname)
2062{
2063char *pszDir;
2064char *realdir;
2065HANDLE hFind = INVALID_HANDLE_VALUE;
2066SARRAY *safiles;
2067WIN32_FIND_DATAA ffd;
2068
2069 PROCNAME("getFilenamesInDirectory");
2070
2071 if (!dirname)
2072 return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
2073
2074 realdir = genPathname(dirname, NULL);
2075 pszDir = stringJoin(realdir, "\\*");
2076 LEPT_FREE(realdir);
2077
2078 if (strlen(pszDir) + 1 > MAX_PATH) {
2079 LEPT_FREE(pszDir);
2080 return (SARRAY *)ERROR_PTR("dirname is too long", procName, NULL);
2081 }
2082
2083 if ((safiles = sarrayCreate(0)) == NULL) {
2084 LEPT_FREE(pszDir);
2085 return (SARRAY *)ERROR_PTR("safiles not made", procName, NULL);
2086 }
2087
2088 hFind = FindFirstFileA(pszDir, &ffd);
2089 if (INVALID_HANDLE_VALUE == hFind) {
2090 sarrayDestroy(&safiles);
2091 LEPT_FREE(pszDir);
2092 return (SARRAY *)ERROR_PTR("hFind not opened", procName, NULL);
2093 }
2094
2095 while (FindNextFileA(hFind, &ffd) != 0) {
2096 if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) /* skip dirs */
2097 continue;
2098 convertSepCharsInPath(ffd.cFileName, UNIX_PATH_SEPCHAR);
2099 sarrayAddString(safiles, ffd.cFileName, L_COPY);
2100 }
2101
2102 FindClose(hFind);
2103 LEPT_FREE(pszDir);
2104 return safiles;
2105}
2106#endif /* _WIN32 */
#define SARRAY_VERSION_NUMBER
Definition: array.h:123
void numaDestroy(NUMA **pna)
numaDestroy()
Definition: numabasic.c:366
l_ok numaGetIValue(NUMA *na, l_int32 index, l_int32 *pival)
numaGetIValue()
Definition: numabasic.c:754
NUMA * numaGetUniformBinSizes(l_int32 ntotal, l_int32 nbins)
numaGetUniformBinSizes()
Definition: numafunc2.c:1945
@ L_COPY
Definition: pix.h:712
@ L_NOCOPY
Definition: pix.h:710
@ L_INSERT
Definition: pix.h:711
@ L_SORT_INCREASING
Definition: pix.h:729
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1848
SARRAY * convertSortedToNumberedPathnames(SARRAY *sa, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
convertSortedToNumberedPathnames()
Definition: sarray1.c:1908
SARRAY * sarrayConvertWordsToLines(SARRAY *sa, l_int32 linesize)
sarrayConvertWordsToLines()
Definition: sarray1.c:1123
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:170
l_ok sarrayWriteStderr(SARRAY *sa)
sarrayWriteStderr()
Definition: sarray1.c:1646
static const l_int32 InitialPtrArraySize
Definition: sarray1.c:154
char * sarrayToStringRange(SARRAY *sa, l_int32 first, l_int32 nstrings, l_int32 addnlflag)
sarrayToStringRange()
Definition: sarray1.c:820
l_ok sarrayJoin(SARRAY *sa1, SARRAY *sa2)
sarrayJoin()
Definition: sarray1.c:969
SARRAY * sarrayRead(const char *filename)
sarrayRead()
Definition: sarray1.c:1441
l_ok sarrayPadToSameSize(SARRAY *sa1, SARRAY *sa2, const char *padstring)
sarrayPadToSameSize()
Definition: sarray1.c:1064
char * sarrayRemoveString(SARRAY *sa, l_int32 index)
sarrayRemoveString()
Definition: sarray1.c:528
l_ok sarrayReplaceString(SARRAY *sa, l_int32 index, char *newstr, l_int32 copyflag)
sarrayReplaceString()
Definition: sarray1.c:579
l_ok sarrayAppend(const char *filename, SARRAY *sa)
sarrayAppend()
Definition: sarray1.c:1732
SARRAY * sarraySelectRange(SARRAY *sain, l_int32 first, l_int32 last)
sarraySelectRange()
Definition: sarray1.c:1287
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition: sarray1.c:785
SARRAY * sarraySelectBySubstring(SARRAY *sain, const char *substr)
sarraySelectBySubstring()
Definition: sarray1.c:1241
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:703
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:643
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:362
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition: sarray1.c:283
SARRAY * getFilenamesInDirectory(const char *dirname)
getFilenamesInDirectory()
Definition: sarray1.c:1990
SARRAY * sarrayCreateInitialized(l_int32 n, const char *initstr)
sarrayCreateInitialized()
Definition: sarray1.c:200
l_ok sarrayClear(SARRAY *sa)
sarrayClear()
Definition: sarray1.c:616
SARRAY * sarrayReadMem(const l_uint8 *data, size_t size)
sarrayReadMem()
Definition: sarray1.c:1549
char ** sarrayGetArray(SARRAY *sa, l_int32 *pnalloc, l_int32 *pn)
sarrayGetArray()
Definition: sarray1.c:668
static l_int32 sarrayExtendArray(SARRAY *sa)
sarrayExtendArray()
Definition: sarray1.c:494
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:451
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition: sarray1.c:1479
SARRAY * sarrayClone(SARRAY *sa)
sarrayClone()
Definition: sarray1.c:425
l_int32 sarrayGetRefcount(SARRAY *sa)
sarrayGetRefCount()
Definition: sarray1.c:730
SARRAY * sarrayCreateWordsFromString(const char *string)
sarrayCreateWordsFromString()
Definition: sarray1.c:233
l_ok sarrayWrite(const char *filename, SARRAY *sa)
sarrayWrite()
Definition: sarray1.c:1577
l_int32 sarrayParseRange(SARRAY *sa, l_int32 start, l_int32 *pactualstart, l_int32 *pend, l_int32 *pnewstart, const char *substr, l_int32 loc)
sarrayParseRange()
Definition: sarray1.c:1356
SARRAY * sarrayCopy(SARRAY *sa)
sarrayCopy()
Definition: sarray1.c:398
SARRAY * getNumberedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
getNumberedPathnamesInDirectory()
Definition: sarray1.c:1800
l_ok sarrayChangeRefcount(SARRAY *sa, l_int32 delta)
sarrayChangeRefCount()
Definition: sarray1.c:748
l_ok sarrayWriteStream(FILE *fp, SARRAY *sa)
sarrayWriteStream()
Definition: sarray1.c:1614
l_ok sarrayWriteMem(l_uint8 **pdata, size_t *psize, SARRAY *sa)
sarrayWriteMem()
Definition: sarray1.c:1681
l_ok sarrayAppendRange(SARRAY *sa1, SARRAY *sa2, l_int32 start, l_int32 end)
sarrayAppendRange()
Definition: sarray1.c:1012
SARRAY * sarrayConcatUniformly(SARRAY *sa, l_int32 n, l_int32 addnlflag)
sarrayConcatUniformly()
Definition: sarray1.c:917
SARRAY * sarraySort(SARRAY *saout, SARRAY *sain, l_int32 sortorder)
sarraySort()
Definition: sarray2.c:97
Definition: array.h:71
Definition: array.h:127
l_int32 refcount
Definition: array.h:130
l_int32 nalloc
Definition: array.h:128
char ** array
Definition: array.h:131
l_int32 n
Definition: array.h:129
void lept_stderr(const char *fmt,...)
lept_stderr()
Definition: utils1.c:306
FILE * fopenWriteWinTempfile(void)
fopenWriteWinTempfile()
Definition: utils2.c:2055
char * pathJoin(const char *dir, const char *fname)
pathJoin()
Definition: utils2.c:2973
char * strtokSafe(char *cstr, const char *seps, char **psaveptr)
strtokSafe()
Definition: utils2.c:649
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1975
char * genPathname(const char *dir, const char *fname)
genPathname()
Definition: utils2.c:3173
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:2009
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:518
l_ok convertSepCharsInPath(char *path, l_int32 type)
convertSepCharsInPath()
Definition: utils2.c:3108
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1932
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1402
void * reallocNew(void **pindata, size_t oldsize, size_t newsize)
reallocNew()
Definition: utils2.c:1302
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:223
l_int32 extractNumberFromFilename(const char *fname, l_int32 numpre, l_int32 numpost)
extractNumberFromFilename()
Definition: utils2.c:3453
l_ok arrayFindSequence(const l_uint8 *data, size_t datalen, const l_uint8 *sequence, size_t seqlen, l_int32 *poffset, l_int32 *pfound)
arrayFindSequence()
Definition: utils2.c:1233