Leptonica  1.77.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 
136 #include <string.h>
137 #ifndef _WIN32
138 #include <dirent.h> /* unix only */
139 #include <sys/stat.h>
140 #include <limits.h> /* needed for realpath() */
141 #include <stdlib.h> /* needed for realpath() */
142 #endif /* ! _WIN32 */
143 #include "allheaders.h"
144 
145 static const l_int32 INITIAL_PTR_ARRAYSIZE = 50; /* n'importe quoi */
146 static const l_int32 L_BUF_SIZE = 512;
147 
148  /* Static functions */
149 static l_int32 sarrayExtendArray(SARRAY *sa);
150 
151 
152 /*--------------------------------------------------------------------------*
153  * String array create/destroy/copy/extend *
154  *--------------------------------------------------------------------------*/
162 SARRAY *
163 sarrayCreate(l_int32 n)
164 {
165 SARRAY *sa;
166 
167  PROCNAME("sarrayCreate");
168 
169  if (n <= 0)
170  n = INITIAL_PTR_ARRAYSIZE;
171 
172  sa = (SARRAY *)LEPT_CALLOC(1, sizeof(SARRAY));
173  if ((sa->array = (char **)LEPT_CALLOC(n, sizeof(char *))) == NULL) {
174  sarrayDestroy(&sa);
175  return (SARRAY *)ERROR_PTR("ptr array not made", procName, NULL);
176  }
177 
178  sa->nalloc = n;
179  sa->n = 0;
180  sa->refcount = 1;
181  return sa;
182 }
183 
184 
192 SARRAY *
194  const char *initstr)
195 {
196 l_int32 i;
197 SARRAY *sa;
198 
199  PROCNAME("sarrayCreateInitialized");
200 
201  if (n <= 0)
202  return (SARRAY *)ERROR_PTR("n must be > 0", procName, NULL);
203  if (!initstr)
204  return (SARRAY *)ERROR_PTR("initstr not defined", procName, NULL);
205 
206  sa = sarrayCreate(n);
207  for (i = 0; i < n; i++)
208  sarrayAddString(sa, initstr, L_COPY);
209  return sa;
210 }
211 
212 
225 SARRAY *
226 sarrayCreateWordsFromString(const char *string)
227 {
228 char separators[] = " \n\t";
229 l_int32 i, nsub, size, inword;
230 SARRAY *sa;
231 
232  PROCNAME("sarrayCreateWordsFromString");
233 
234  if (!string)
235  return (SARRAY *)ERROR_PTR("textstr not defined", procName, NULL);
236 
237  /* Find the number of words */
238  size = strlen(string);
239  nsub = 0;
240  inword = FALSE;
241  for (i = 0; i < size; i++) {
242  if (inword == FALSE &&
243  (string[i] != ' ' && string[i] != '\t' && string[i] != '\n')) {
244  inword = TRUE;
245  nsub++;
246  } else if (inword == TRUE &&
247  (string[i] == ' ' || string[i] == '\t' || string[i] == '\n')) {
248  inword = FALSE;
249  }
250  }
251 
252  if ((sa = sarrayCreate(nsub)) == NULL)
253  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
254  sarraySplitString(sa, string, separators);
255 
256  return sa;
257 }
258 
259 
275 SARRAY *
276 sarrayCreateLinesFromString(const char *string,
277  l_int32 blankflag)
278 {
279 l_int32 i, nsub, size, startptr;
280 char *cstring, *substring;
281 SARRAY *sa;
282 
283  PROCNAME("sarrayCreateLinesFromString");
284 
285  if (!string)
286  return (SARRAY *)ERROR_PTR("textstr not defined", procName, NULL);
287 
288  /* Find the number of lines */
289  size = strlen(string);
290  nsub = 0;
291  for (i = 0; i < size; i++) {
292  if (string[i] == '\n')
293  nsub++;
294  }
295 
296  if ((sa = sarrayCreate(nsub)) == NULL)
297  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
298 
299  if (blankflag) { /* keep blank lines as null strings */
300  /* Make a copy for munging */
301  if ((cstring = stringNew(string)) == NULL) {
302  sarrayDestroy(&sa);
303  return (SARRAY *)ERROR_PTR("cstring not made", procName, NULL);
304  }
305  /* We'll insert nulls like strtok */
306  startptr = 0;
307  for (i = 0; i < size; i++) {
308  if (cstring[i] == '\n') {
309  cstring[i] = '\0';
310  if (i > 0 && cstring[i - 1] == '\r')
311  cstring[i - 1] = '\0'; /* also remove Windows CR */
312  if ((substring = stringNew(cstring + startptr)) == NULL) {
313  sarrayDestroy(&sa);
314  LEPT_FREE(cstring);
315  return (SARRAY *)ERROR_PTR("substring not made",
316  procName, NULL);
317  }
318  sarrayAddString(sa, substring, L_INSERT);
319 /* fprintf(stderr, "substring = %s\n", substring); */
320  startptr = i + 1;
321  }
322  }
323  if (startptr < size) { /* no newline at end of last line */
324  if ((substring = stringNew(cstring + startptr)) == NULL) {
325  sarrayDestroy(&sa);
326  LEPT_FREE(cstring);
327  return (SARRAY *)ERROR_PTR("substring not made",
328  procName, NULL);
329  }
330  sarrayAddString(sa, substring, L_INSERT);
331 /* fprintf(stderr, "substring = %s\n", substring); */
332  }
333  LEPT_FREE(cstring);
334  } else { /* remove blank lines; use strtok */
335  sarraySplitString(sa, string, "\r\n");
336  }
337 
338  return sa;
339 }
340 
341 
354 void
356 {
357 l_int32 i;
358 SARRAY *sa;
359 
360  PROCNAME("sarrayDestroy");
361 
362  if (psa == NULL) {
363  L_WARNING("ptr address is NULL!\n", procName);
364  return;
365  }
366  if ((sa = *psa) == NULL)
367  return;
368 
369  sarrayChangeRefcount(sa, -1);
370  if (sarrayGetRefcount(sa) <= 0) {
371  if (sa->array) {
372  for (i = 0; i < sa->n; i++) {
373  if (sa->array[i])
374  LEPT_FREE(sa->array[i]);
375  }
376  LEPT_FREE(sa->array);
377  }
378  LEPT_FREE(sa);
379  }
380 
381  *psa = NULL;
382  return;
383 }
384 
385 
392 SARRAY *
394 {
395 l_int32 i;
396 SARRAY *csa;
397 
398  PROCNAME("sarrayCopy");
399 
400  if (!sa)
401  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
402 
403  if ((csa = sarrayCreate(sa->nalloc)) == NULL)
404  return (SARRAY *)ERROR_PTR("csa not made", procName, NULL);
405 
406  for (i = 0; i < sa->n; i++)
407  sarrayAddString(csa, sa->array[i], L_COPY);
408 
409  return csa;
410 }
411 
412 
419 SARRAY *
421 {
422  PROCNAME("sarrayClone");
423 
424  if (!sa)
425  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
426  sarrayChangeRefcount(sa, 1);
427  return sa;
428 }
429 
430 
445 l_ok
447  const char *string,
448  l_int32 copyflag)
449 {
450 l_int32 n;
451 
452  PROCNAME("sarrayAddString");
453 
454  if (!sa)
455  return ERROR_INT("sa not defined", procName, 1);
456  if (!string)
457  return ERROR_INT("string not defined", procName, 1);
458  if (copyflag != L_INSERT && copyflag != L_NOCOPY && copyflag != L_COPY)
459  return ERROR_INT("invalid copyflag", procName, 1);
460 
461  n = sarrayGetCount(sa);
462  if (n >= sa->nalloc)
463  sarrayExtendArray(sa);
464 
465  if (copyflag == L_COPY)
466  sa->array[n] = stringNew(string);
467  else /* L_INSERT or L_NOCOPY */
468  sa->array[n] = (char *)string;
469  sa->n++;
470  return 0;
471 }
472 
473 
480 static l_int32
482 {
483  PROCNAME("sarrayExtendArray");
484 
485  if (!sa)
486  return ERROR_INT("sa not defined", procName, 1);
487 
488  if ((sa->array = (char **)reallocNew((void **)&sa->array,
489  sizeof(char *) * sa->nalloc,
490  2 * sizeof(char *) * sa->nalloc)) == NULL)
491  return ERROR_INT("new ptr array not returned", procName, 1);
492 
493  sa->nalloc *= 2;
494  return 0;
495 }
496 
497 
505 char *
507  l_int32 index)
508 {
509 char *string;
510 char **array;
511 l_int32 i, n, nalloc;
512 
513  PROCNAME("sarrayRemoveString");
514 
515  if (!sa)
516  return (char *)ERROR_PTR("sa not defined", procName, NULL);
517 
518  if ((array = sarrayGetArray(sa, &nalloc, &n)) == NULL)
519  return (char *)ERROR_PTR("array not returned", procName, NULL);
520 
521  if (index < 0 || index >= n)
522  return (char *)ERROR_PTR("array index out of bounds", procName, NULL);
523 
524  string = array[index];
525 
526  /* If removed string is not at end of array, shift
527  * to fill in, maintaining original ordering.
528  * Note: if we didn't care about the order, we could
529  * put the last string array[n - 1] directly into the hole. */
530  for (i = index; i < n - 1; i++)
531  array[i] = array[i + 1];
532 
533  sa->n--;
534  return string;
535 }
536 
537 
556 l_ok
558  l_int32 index,
559  char *newstr,
560  l_int32 copyflag)
561 {
562 char *str;
563 l_int32 n;
564 
565  PROCNAME("sarrayReplaceString");
566 
567  if (!sa)
568  return ERROR_INT("sa not defined", procName, 1);
569  n = sarrayGetCount(sa);
570  if (index < 0 || index >= n)
571  return ERROR_INT("array index out of bounds", procName, 1);
572  if (!newstr)
573  return ERROR_INT("newstr not defined", procName, 1);
574  if (copyflag != L_INSERT && copyflag != L_COPY)
575  return ERROR_INT("invalid copyflag", procName, 1);
576 
577  LEPT_FREE(sa->array[index]);
578  if (copyflag == L_INSERT)
579  str = newstr;
580  else /* L_COPY */
581  str = stringNew(newstr);
582  sa->array[index] = str;
583  return 0;
584 }
585 
586 
593 l_ok
595 {
596 l_int32 i;
597 
598  PROCNAME("sarrayClear");
599 
600  if (!sa)
601  return ERROR_INT("sa not defined", procName, 1);
602  for (i = 0; i < sa->n; i++) { /* free strings and null ptrs */
603  LEPT_FREE(sa->array[i]);
604  sa->array[i] = NULL;
605  }
606  sa->n = 0;
607  return 0;
608 }
609 
610 
611 /*----------------------------------------------------------------------*
612  * Accessors *
613  *----------------------------------------------------------------------*/
620 l_int32
622 {
623  PROCNAME("sarrayGetCount");
624 
625  if (!sa)
626  return ERROR_INT("sa not defined", procName, 0);
627  return sa->n;
628 }
629 
630 
645 char **
647  l_int32 *pnalloc,
648  l_int32 *pn)
649 {
650 char **array;
651 
652  PROCNAME("sarrayGetArray");
653 
654  if (!sa)
655  return (char **)ERROR_PTR("sa not defined", procName, NULL);
656 
657  array = sa->array;
658  if (pnalloc) *pnalloc = sa->nalloc;
659  if (pn) *pn = sa->n;
660 
661  return array;
662 }
663 
664 
680 char *
682  l_int32 index,
683  l_int32 copyflag)
684 {
685  PROCNAME("sarrayGetString");
686 
687  if (!sa)
688  return (char *)ERROR_PTR("sa not defined", procName, NULL);
689  if (index < 0 || index >= sa->n)
690  return (char *)ERROR_PTR("index not valid", procName, NULL);
691  if (copyflag != L_NOCOPY && copyflag != L_COPY)
692  return (char *)ERROR_PTR("invalid copyflag", procName, NULL);
693 
694  if (copyflag == L_NOCOPY)
695  return sa->array[index];
696  else /* L_COPY */
697  return stringNew(sa->array[index]);
698 }
699 
700 
707 l_int32
709 {
710  PROCNAME("sarrayGetRefcount");
711 
712  if (!sa)
713  return ERROR_INT("sa not defined", procName, UNDEF);
714  return sa->refcount;
715 }
716 
717 
725 l_ok
727  l_int32 delta)
728 {
729  PROCNAME("sarrayChangeRefcount");
730 
731  if (!sa)
732  return ERROR_INT("sa not defined", procName, UNDEF);
733  sa->refcount += delta;
734  return 0;
735 }
736 
737 
738 /*----------------------------------------------------------------------*
739  * Conversion to string *
740  *----------------------------------------------------------------------*/
762 char *
764  l_int32 addnlflag)
765 {
766  PROCNAME("sarrayToString");
767 
768  if (!sa)
769  return (char *)ERROR_PTR("sa not defined", procName, NULL);
770 
771  return sarrayToStringRange(sa, 0, 0, addnlflag);
772 }
773 
774 
797 char *
799  l_int32 first,
800  l_int32 nstrings,
801  l_int32 addnlflag)
802 {
803 char *dest, *src, *str;
804 l_int32 n, i, last, size, index, len;
805 
806  PROCNAME("sarrayToStringRange");
807 
808  if (!sa)
809  return (char *)ERROR_PTR("sa not defined", procName, NULL);
810  if (addnlflag != 0 && addnlflag != 1 && addnlflag != 2)
811  return (char *)ERROR_PTR("invalid addnlflag", procName, NULL);
812 
813  n = sarrayGetCount(sa);
814 
815  /* Empty sa; return char corresponding to addnlflag only */
816  if (n == 0) {
817  if (first == 0) {
818  if (addnlflag == 0)
819  return stringNew("");
820  if (addnlflag == 1)
821  return stringNew("\n");
822  else /* addnlflag == 2) */
823  return stringNew(" ");
824  } else {
825  return (char *)ERROR_PTR("first not valid", procName, NULL);
826  }
827  }
828 
829  if (first < 0 || first >= n)
830  return (char *)ERROR_PTR("first not valid", procName, NULL);
831  if (nstrings == 0 || (nstrings > n - first))
832  nstrings = n - first; /* no overflow */
833  last = first + nstrings - 1;
834 
835  size = 0;
836  for (i = first; i <= last; i++) {
837  if ((str = sarrayGetString(sa, i, L_NOCOPY)) == NULL)
838  return (char *)ERROR_PTR("str not found", procName, NULL);
839  size += strlen(str) + 2;
840  }
841 
842  if ((dest = (char *)LEPT_CALLOC(size + 1, sizeof(char))) == NULL)
843  return (char *)ERROR_PTR("dest not made", procName, NULL);
844 
845  index = 0;
846  for (i = first; i <= last; i++) {
847  src = sarrayGetString(sa, i, L_NOCOPY);
848  len = strlen(src);
849  memcpy(dest + index, src, len);
850  index += len;
851  if (addnlflag == 1) {
852  dest[index] = '\n';
853  index++;
854  } else if (addnlflag == 2) {
855  dest[index] = ' ';
856  index++;
857  }
858  }
859 
860  return dest;
861 }
862 
863 
864 /*----------------------------------------------------------------------*
865  * Join 2 sarrays *
866  *----------------------------------------------------------------------*/
879 l_ok
881  SARRAY *sa2)
882 {
883 char *str;
884 l_int32 n, i;
885 
886  PROCNAME("sarrayJoin");
887 
888  if (!sa1)
889  return ERROR_INT("sa1 not defined", procName, 1);
890  if (!sa2)
891  return ERROR_INT("sa2 not defined", procName, 1);
892 
893  n = sarrayGetCount(sa2);
894  for (i = 0; i < n; i++) {
895  str = sarrayGetString(sa2, i, L_NOCOPY);
896  sarrayAddString(sa1, str, L_COPY);
897  }
898 
899  return 0;
900 }
901 
902 
919 l_ok
921  SARRAY *sa2,
922  l_int32 start,
923  l_int32 end)
924 {
925 char *str;
926 l_int32 n, i;
927 
928  PROCNAME("sarrayAppendRange");
929 
930  if (!sa1)
931  return ERROR_INT("sa1 not defined", procName, 1);
932  if (!sa2)
933  return ERROR_INT("sa2 not defined", procName, 1);
934 
935  if (start < 0)
936  start = 0;
937  n = sarrayGetCount(sa2);
938  if (end < 0 || end >= n)
939  end = n - 1;
940  if (start > end)
941  return ERROR_INT("start > end", procName, 1);
942 
943  for (i = start; i <= end; i++) {
944  str = sarrayGetString(sa2, i, L_NOCOPY);
945  sarrayAddString(sa1, str, L_COPY);
946  }
947 
948  return 0;
949 }
950 
951 
952 /*----------------------------------------------------------------------*
953  * Pad an sarray to be the same size as another sarray *
954  *----------------------------------------------------------------------*/
971 l_ok
973  SARRAY *sa2,
974  const char *padstring)
975 {
976 l_int32 i, n1, n2;
977 
978  PROCNAME("sarrayPadToSameSize");
979 
980  if (!sa1 || !sa2)
981  return ERROR_INT("both sa1 and sa2 not defined", procName, 1);
982 
983  n1 = sarrayGetCount(sa1);
984  n2 = sarrayGetCount(sa2);
985  if (n1 < n2) {
986  for (i = n1; i < n2; i++)
987  sarrayAddString(sa1, padstring, L_COPY);
988  } else if (n1 > n2) {
989  for (i = n2; i < n1; i++)
990  sarrayAddString(sa2, padstring, L_COPY);
991  }
992 
993  return 0;
994 }
995 
996 
997 /*----------------------------------------------------------------------*
998  * Convert word sarray to line sarray *
999  *----------------------------------------------------------------------*/
1028 SARRAY *
1030  l_int32 linesize)
1031 {
1032 char *wd, *strl;
1033 char emptystring[] = "";
1034 l_int32 n, i, len, totlen;
1035 SARRAY *sal, *saout;
1036 
1037  PROCNAME("sarrayConvertWordsToLines");
1038 
1039  if (!sa)
1040  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
1041 
1042  saout = sarrayCreate(0);
1043  n = sarrayGetCount(sa);
1044  totlen = 0;
1045  sal = NULL;
1046  for (i = 0; i < n; i++) {
1047  if (!sal)
1048  sal = sarrayCreate(0);
1049  wd = sarrayGetString(sa, i, L_NOCOPY);
1050  len = strlen(wd);
1051  if (len == 0) { /* end of paragraph: end line & insert blank line */
1052  if (totlen > 0) {
1053  strl = sarrayToString(sal, 2);
1054  sarrayAddString(saout, strl, L_INSERT);
1055  }
1056  sarrayAddString(saout, emptystring, L_COPY);
1057  sarrayDestroy(&sal);
1058  totlen = 0;
1059  } else if (totlen == 0 && len + 1 > linesize) { /* long word! */
1060  sarrayAddString(saout, wd, L_COPY); /* copy to one line */
1061  } else if (totlen + len + 1 > linesize) { /* end line & start new */
1062  strl = sarrayToString(sal, 2);
1063  sarrayAddString(saout, strl, L_INSERT);
1064  sarrayDestroy(&sal);
1065  sal = sarrayCreate(0);
1066  sarrayAddString(sal, wd, L_COPY);
1067  totlen = len + 1;
1068  } else { /* add to current line */
1069  sarrayAddString(sal, wd, L_COPY);
1070  totlen += len + 1;
1071  }
1072  }
1073  if (totlen > 0) { /* didn't end with blank line; output last line */
1074  strl = sarrayToString(sal, 2);
1075  sarrayAddString(saout, strl, L_INSERT);
1076  sarrayDestroy(&sal);
1077  }
1078 
1079  return saout;
1080 }
1081 
1082 
1083 /*----------------------------------------------------------------------*
1084  * Split string on separator list *
1085  *----------------------------------------------------------------------*/
1086 /*
1087  * sarraySplitString()
1088  *
1089  * Input: sa (to append to; typically empty initially)
1090  * str (string to split; not changed)
1091  * separators (characters that split input string)
1092  * Return: 0 if OK, 1 on error.
1093  *
1094  * Notes:
1095  * (1) This uses strtokSafe(). See the notes there in utils.c.
1096  */
1097 l_int32
1098 sarraySplitString(SARRAY *sa,
1099  const char *str,
1100  const char *separators)
1101 {
1102 char *cstr, *substr, *saveptr;
1103 
1104  PROCNAME("sarraySplitString");
1105 
1106  if (!sa)
1107  return ERROR_INT("sa not defined", procName, 1);
1108  if (!str)
1109  return ERROR_INT("str not defined", procName, 1);
1110  if (!separators)
1111  return ERROR_INT("separators not defined", procName, 1);
1112 
1113  cstr = stringNew(str); /* preserves const-ness of input str */
1114  saveptr = NULL;
1115  substr = strtokSafe(cstr, separators, &saveptr);
1116  if (substr)
1117  sarrayAddString(sa, substr, L_INSERT);
1118  while ((substr = strtokSafe(NULL, separators, &saveptr)))
1119  sarrayAddString(sa, substr, L_INSERT);
1120  LEPT_FREE(cstr);
1121 
1122  return 0;
1123 }
1124 
1125 
1126 /*----------------------------------------------------------------------*
1127  * Filter sarray *
1128  *----------------------------------------------------------------------*/
1144 SARRAY *
1146  const char *substr)
1147 {
1148 char *str;
1149 l_int32 n, i, offset, found;
1150 SARRAY *saout;
1151 
1152  PROCNAME("sarraySelectBySubstring");
1153 
1154  if (!sain)
1155  return (SARRAY *)ERROR_PTR("sain not defined", procName, NULL);
1156 
1157  n = sarrayGetCount(sain);
1158  if (!substr || n == 0)
1159  return sarrayCopy(sain);
1160 
1161  saout = sarrayCreate(n);
1162  for (i = 0; i < n; i++) {
1163  str = sarrayGetString(sain, i, L_NOCOPY);
1164  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1165  strlen(substr), &offset, &found);
1166  if (found)
1167  sarrayAddString(saout, str, L_COPY);
1168  }
1169 
1170  return saout;
1171 }
1172 
1173 
1190 SARRAY *
1192  l_int32 first,
1193  l_int32 last)
1194 {
1195 char *str;
1196 l_int32 n, i;
1197 SARRAY *saout;
1198 
1199  PROCNAME("sarraySelectByRange");
1200 
1201  if (!sain)
1202  return (SARRAY *)ERROR_PTR("sain not defined", procName, NULL);
1203  if (first < 0) first = 0;
1204  n = sarrayGetCount(sain);
1205  if (last <= 0) last = n - 1;
1206  if (last >= n) {
1207  L_WARNING("last > n - 1; setting to n - 1\n", procName);
1208  last = n - 1;
1209  }
1210  if (first > last)
1211  return (SARRAY *)ERROR_PTR("first must be >= last", procName, NULL);
1212 
1213  saout = sarrayCreate(0);
1214  for (i = first; i <= last; i++) {
1215  str = sarrayGetString(sain, i, L_COPY);
1216  sarrayAddString(saout, str, L_INSERT);
1217  }
1218 
1219  return saout;
1220 }
1221 
1222 
1259 l_int32
1261  l_int32 start,
1262  l_int32 *pactualstart,
1263  l_int32 *pend,
1264  l_int32 *pnewstart,
1265  const char *substr,
1266  l_int32 loc)
1267 {
1268 char *str;
1269 l_int32 n, i, offset, found;
1270 
1271  PROCNAME("sarrayParseRange");
1272 
1273  if (!sa)
1274  return ERROR_INT("sa not defined", procName, 1);
1275  if (!pactualstart || !pend || !pnewstart)
1276  return ERROR_INT("not all range addresses defined", procName, 1);
1277  n = sarrayGetCount(sa);
1278  *pactualstart = *pend = *pnewstart = n;
1279  if (!substr)
1280  return ERROR_INT("substr not defined", procName, 1);
1281 
1282  /* Look for the first string without the marker */
1283  if (start < 0 || start >= n)
1284  return 1;
1285  for (i = start; i < n; i++) {
1286  str = sarrayGetString(sa, i, L_NOCOPY);
1287  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1288  strlen(substr), &offset, &found);
1289  if (loc < 0) {
1290  if (!found) break;
1291  } else {
1292  if (!found || offset != loc) break;
1293  }
1294  }
1295  start = i;
1296  if (i == n) /* couldn't get started */
1297  return 1;
1298 
1299  /* Look for the last string without the marker */
1300  *pactualstart = start;
1301  for (i = start + 1; i < n; i++) {
1302  str = sarrayGetString(sa, i, L_NOCOPY);
1303  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1304  strlen(substr), &offset, &found);
1305  if (loc < 0) {
1306  if (found) break;
1307  } else {
1308  if (found && offset == loc) break;
1309  }
1310  }
1311  *pend = i - 1;
1312  start = i;
1313  if (i == n) /* no further range */
1314  return 0;
1315 
1316  /* Look for the first string after *pend without the marker.
1317  * This will start the next run of strings, if it exists. */
1318  for (i = start; i < n; i++) {
1319  str = sarrayGetString(sa, i, L_NOCOPY);
1320  arrayFindSequence((l_uint8 *)str, strlen(str), (l_uint8 *)substr,
1321  strlen(substr), &offset, &found);
1322  if (loc < 0) {
1323  if (!found) break;
1324  } else {
1325  if (!found || offset != loc) break;
1326  }
1327  }
1328  if (i < n)
1329  *pnewstart = i;
1330 
1331  return 0;
1332 }
1333 
1334 
1335 /*----------------------------------------------------------------------*
1336  * Serialize for I/O *
1337  *----------------------------------------------------------------------*/
1344 SARRAY *
1345 sarrayRead(const char *filename)
1346 {
1347 FILE *fp;
1348 SARRAY *sa;
1349 
1350  PROCNAME("sarrayRead");
1351 
1352  if (!filename)
1353  return (SARRAY *)ERROR_PTR("filename not defined", procName, NULL);
1354 
1355  if ((fp = fopenReadStream(filename)) == NULL)
1356  return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL);
1357  sa = sarrayReadStream(fp);
1358  fclose(fp);
1359  if (!sa)
1360  return (SARRAY *)ERROR_PTR("sa not read", procName, NULL);
1361  return sa;
1362 }
1363 
1364 
1381 SARRAY *
1383 {
1384 char *stringbuf;
1385 l_int32 i, n, size, index, bufsize, version, ignore, success;
1386 SARRAY *sa;
1387 
1388  PROCNAME("sarrayReadStream");
1389 
1390  if (!fp)
1391  return (SARRAY *)ERROR_PTR("stream not defined", procName, NULL);
1392 
1393  if (fscanf(fp, "\nSarray Version %d\n", &version) != 1)
1394  return (SARRAY *)ERROR_PTR("not an sarray file", procName, NULL);
1395  if (version != SARRAY_VERSION_NUMBER)
1396  return (SARRAY *)ERROR_PTR("invalid sarray version", procName, NULL);
1397  if (fscanf(fp, "Number of strings = %d\n", &n) != 1)
1398  return (SARRAY *)ERROR_PTR("error on # strings", procName, NULL);
1399  if (n > (1 << 24))
1400  return (SARRAY *)ERROR_PTR("more than 2^24 strings!", procName, NULL);
1401 
1402  success = TRUE;
1403  if ((sa = sarrayCreate(n)) == NULL)
1404  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1405  bufsize = L_BUF_SIZE + 1;
1406  stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1407 
1408  for (i = 0; i < n; i++) {
1409  /* Get the size of the stored string */
1410  if ((fscanf(fp, "%d[%d]:", &index, &size) != 2) || (size > (1 << 30))) {
1411  success = FALSE;
1412  L_ERROR("error on string size\n", procName);
1413  goto cleanup;
1414  }
1415  /* Expand the string buffer if necessary */
1416  if (size > bufsize - 5) {
1417  LEPT_FREE(stringbuf);
1418  bufsize = (l_int32)(1.5 * size);
1419  stringbuf = (char *)LEPT_CALLOC(bufsize, sizeof(char));
1420  }
1421  /* Read the stored string, plus leading spaces and trailing \n */
1422  if (fread(stringbuf, 1, size + 3, fp) != size + 3) {
1423  success = FALSE;
1424  L_ERROR("error reading string\n", procName);
1425  goto cleanup;
1426  }
1427  /* Remove the \n that was added by sarrayWriteStream() */
1428  stringbuf[size + 2] = '\0';
1429  /* Copy it in, skipping the 2 leading spaces */
1430  sarrayAddString(sa, stringbuf + 2, L_COPY);
1431  }
1432  ignore = fscanf(fp, "\n");
1433 
1434 cleanup:
1435  LEPT_FREE(stringbuf);
1436  if (!success) sarrayDestroy(&sa);
1437  return sa;
1438 }
1439 
1440 
1448 SARRAY *
1449 sarrayReadMem(const l_uint8 *data,
1450  size_t size)
1451 {
1452 FILE *fp;
1453 SARRAY *sa;
1454 
1455  PROCNAME("sarrayReadMem");
1456 
1457  if (!data)
1458  return (SARRAY *)ERROR_PTR("data not defined", procName, NULL);
1459  if ((fp = fopenReadFromMemory(data, size)) == NULL)
1460  return (SARRAY *)ERROR_PTR("stream not opened", procName, NULL);
1461 
1462  sa = sarrayReadStream(fp);
1463  fclose(fp);
1464  if (!sa) L_ERROR("sarray not read\n", procName);
1465  return sa;
1466 }
1467 
1468 
1476 l_ok
1477 sarrayWrite(const char *filename,
1478  SARRAY *sa)
1479 {
1480 l_int32 ret;
1481 FILE *fp;
1482 
1483  PROCNAME("sarrayWrite");
1484 
1485  if (!filename)
1486  return ERROR_INT("filename not defined", procName, 1);
1487  if (!sa)
1488  return ERROR_INT("sa not defined", procName, 1);
1489 
1490  if ((fp = fopenWriteStream(filename, "w")) == NULL)
1491  return ERROR_INT("stream not opened", procName, 1);
1492  ret = sarrayWriteStream(fp, sa);
1493  fclose(fp);
1494  if (ret)
1495  return ERROR_INT("sa not written to stream", procName, 1);
1496  return 0;
1497 }
1498 
1499 
1513 l_ok
1515  SARRAY *sa)
1516 {
1517 l_int32 i, n, len;
1518 
1519  PROCNAME("sarrayWriteStream");
1520 
1521  if (!fp)
1522  return ERROR_INT("stream not defined", procName, 1);
1523  if (!sa)
1524  return ERROR_INT("sa not defined", procName, 1);
1525 
1526  n = sarrayGetCount(sa);
1527  fprintf(fp, "\nSarray Version %d\n", SARRAY_VERSION_NUMBER);
1528  fprintf(fp, "Number of strings = %d\n", n);
1529  for (i = 0; i < n; i++) {
1530  len = strlen(sa->array[i]);
1531  fprintf(fp, " %d[%d]: %s\n", i, len, sa->array[i]);
1532  }
1533  fprintf(fp, "\n");
1534 
1535  return 0;
1536 }
1537 
1538 
1552 l_ok
1553 sarrayWriteMem(l_uint8 **pdata,
1554  size_t *psize,
1555  SARRAY *sa)
1556 {
1557 l_int32 ret;
1558 FILE *fp;
1559 
1560  PROCNAME("sarrayWriteMem");
1561 
1562  if (pdata) *pdata = NULL;
1563  if (psize) *psize = 0;
1564  if (!pdata)
1565  return ERROR_INT("&data not defined", procName, 1);
1566  if (!psize)
1567  return ERROR_INT("&size not defined", procName, 1);
1568  if (!sa)
1569  return ERROR_INT("sa not defined", procName, 1);
1570 
1571 #if HAVE_FMEMOPEN
1572  if ((fp = open_memstream((char **)pdata, psize)) == NULL)
1573  return ERROR_INT("stream not opened", procName, 1);
1574  ret = sarrayWriteStream(fp, sa);
1575 #else
1576  L_INFO("work-around: writing to a temp file\n", procName);
1577  #ifdef _WIN32
1578  if ((fp = fopenWriteWinTempfile()) == NULL)
1579  return ERROR_INT("tmpfile stream not opened", procName, 1);
1580  #else
1581  if ((fp = tmpfile()) == NULL)
1582  return ERROR_INT("tmpfile stream not opened", procName, 1);
1583  #endif /* _WIN32 */
1584  ret = sarrayWriteStream(fp, sa);
1585  rewind(fp);
1586  *pdata = l_binaryReadStream(fp, psize);
1587 #endif /* HAVE_FMEMOPEN */
1588  fclose(fp);
1589  return ret;
1590 }
1591 
1592 
1600 l_ok
1601 sarrayAppend(const char *filename,
1602  SARRAY *sa)
1603 {
1604 FILE *fp;
1605 
1606  PROCNAME("sarrayAppend");
1607 
1608  if (!filename)
1609  return ERROR_INT("filename not defined", procName, 1);
1610  if (!sa)
1611  return ERROR_INT("sa not defined", procName, 1);
1612 
1613  if ((fp = fopenWriteStream(filename, "a")) == NULL)
1614  return ERROR_INT("stream not opened", procName, 1);
1615  if (sarrayWriteStream(fp, sa)) {
1616  fclose(fp);
1617  return ERROR_INT("sa not appended to stream", procName, 1);
1618  }
1619 
1620  fclose(fp);
1621  return 0;
1622 }
1623 
1624 
1625 /*---------------------------------------------------------------------*
1626  * Directory filenames *
1627  *---------------------------------------------------------------------*/
1668 SARRAY *
1670  const char *substr,
1671  l_int32 numpre,
1672  l_int32 numpost,
1673  l_int32 maxnum)
1674 {
1675 l_int32 nfiles;
1676 SARRAY *sa, *saout;
1677 
1678  PROCNAME("getNumberedPathnamesInDirectory");
1679 
1680  if (!dirname)
1681  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1682 
1683  if ((sa = getSortedPathnamesInDirectory(dirname, substr, 0, 0)) == NULL)
1684  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1685  if ((nfiles = sarrayGetCount(sa)) == 0) {
1686  sarrayDestroy(&sa);
1687  return sarrayCreate(1);
1688  }
1689 
1690  saout = convertSortedToNumberedPathnames(sa, numpre, numpost, maxnum);
1691  sarrayDestroy(&sa);
1692  return saout;
1693 }
1694 
1695 
1716 SARRAY *
1717 getSortedPathnamesInDirectory(const char *dirname,
1718  const char *substr,
1719  l_int32 first,
1720  l_int32 nfiles)
1721 {
1722 char *fname, *fullname;
1723 l_int32 i, n, last;
1724 SARRAY *sa, *safiles, *saout;
1725 
1726  PROCNAME("getSortedPathnamesInDirectory");
1727 
1728  if (!dirname)
1729  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1730 
1731  if ((sa = getFilenamesInDirectory(dirname)) == NULL)
1732  return (SARRAY *)ERROR_PTR("sa not made", procName, NULL);
1733  safiles = sarraySelectBySubstring(sa, substr);
1734  sarrayDestroy(&sa);
1735  n = sarrayGetCount(safiles);
1736  if (n == 0) {
1737  L_WARNING("no files found\n", procName);
1738  return safiles;
1739  }
1740 
1741  sarraySort(safiles, safiles, L_SORT_INCREASING);
1742 
1743  first = L_MIN(L_MAX(first, 0), n - 1);
1744  if (nfiles == 0)
1745  nfiles = n - first;
1746  last = L_MIN(first + nfiles - 1, n - 1);
1747 
1748  saout = sarrayCreate(last - first + 1);
1749  for (i = first; i <= last; i++) {
1750  fname = sarrayGetString(safiles, i, L_NOCOPY);
1751  fullname = pathJoin(dirname, fname);
1752  sarrayAddString(saout, fullname, L_INSERT);
1753  }
1754 
1755  sarrayDestroy(&safiles);
1756  return saout;
1757 }
1758 
1759 
1776 SARRAY *
1778  l_int32 numpre,
1779  l_int32 numpost,
1780  l_int32 maxnum)
1781 {
1782 char *fname, *str;
1783 l_int32 i, nfiles, num, index;
1784 SARRAY *saout;
1785 
1786  PROCNAME("convertSortedToNumberedPathnames");
1787 
1788  if (!sa)
1789  return (SARRAY *)ERROR_PTR("sa not defined", procName, NULL);
1790  if ((nfiles = sarrayGetCount(sa)) == 0)
1791  return sarrayCreate(1);
1792 
1793  /* Find the last file in the sorted array that has a number
1794  * that (a) matches the count pattern and (b) does not
1795  * exceed %maxnum. %maxnum sets an upper limit on the size
1796  * of the sarray. */
1797  num = 0;
1798  for (i = nfiles - 1; i >= 0; i--) {
1799  fname = sarrayGetString(sa, i, L_NOCOPY);
1800  num = extractNumberFromFilename(fname, numpre, numpost);
1801  if (num < 0) continue;
1802  num = L_MIN(num + 1, maxnum);
1803  break;
1804  }
1805 
1806  if (num <= 0) /* none found */
1807  return sarrayCreate(1);
1808 
1809  /* Insert pathnames into the output sarray.
1810  * Ignore numbers that are out of the range of sarray. */
1811  saout = sarrayCreateInitialized(num, "");
1812  for (i = 0; i < nfiles; i++) {
1813  fname = sarrayGetString(sa, i, L_NOCOPY);
1814  index = extractNumberFromFilename(fname, numpre, numpost);
1815  if (index < 0 || index >= num) continue;
1816  str = sarrayGetString(saout, index, L_NOCOPY);
1817  if (str[0] != '\0') {
1818  L_WARNING("\n Multiple files with same number: %d\n",
1819  procName, index);
1820  }
1821  sarrayReplaceString(saout, index, fname, L_COPY);
1822  }
1823 
1824  return saout;
1825 }
1826 
1827 
1856 #ifndef _WIN32
1857 
1858 SARRAY *
1859 getFilenamesInDirectory(const char *dirname)
1860 {
1861 char dir[PATH_MAX + 1];
1862 char *realdir, *stat_path, *ignore;
1863 size_t size;
1864 SARRAY *safiles;
1865 DIR *pdir;
1866 struct dirent *pdirentry;
1867 int dfd, stat_ret;
1868 struct stat st;
1869 
1870  PROCNAME("getFilenamesInDirectory");
1871 
1872  if (!dirname)
1873  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1874 
1875  /* It's nice to ignore directories. fstatat() works with relative
1876  directory paths, but stat() requires using the absolute path.
1877  Also, do not pass NULL as the second parameter to realpath();
1878  use a buffer of sufficient size. */
1879  ignore = realpath(dirname, dir); /* see note above */
1880  realdir = genPathname(dir, NULL);
1881  if ((pdir = opendir(realdir)) == NULL) {
1882  LEPT_FREE(realdir);
1883  return (SARRAY *)ERROR_PTR("pdir not opened", procName, NULL);
1884  }
1885  safiles = sarrayCreate(0);
1886  dfd = dirfd(pdir);
1887  while ((pdirentry = readdir(pdir))) {
1888 #if HAVE_FSTATAT
1889  stat_ret = fstatat(dfd, pdirentry->d_name, &st, 0);
1890 #else
1891  size = strlen(realdir) + strlen(pdirentry->d_name) + 2;
1892  if (size > PATH_MAX) {
1893  L_ERROR("size = %lu too large; skipping\n", procName,
1894  (unsigned long)size);
1895  continue;
1896  }
1897  stat_path = (char *)LEPT_CALLOC(size, 1);
1898  snprintf(stat_path, size, "%s/%s", realdir, pdirentry->d_name);
1899  stat_ret = stat(stat_path, &st);
1900  LEPT_FREE(stat_path);
1901 #endif
1902  if (stat_ret == 0 && S_ISDIR(st.st_mode))
1903  continue;
1904  sarrayAddString(safiles, pdirentry->d_name, L_COPY);
1905  }
1906  closedir(pdir);
1907  LEPT_FREE(realdir);
1908  return safiles;
1909 }
1910 
1911 #else /* _WIN32 */
1912 
1913  /* http://msdn2.microsoft.com/en-us/library/aa365200(VS.85).aspx */
1914 #include <windows.h>
1915 
1916 SARRAY *
1917 getFilenamesInDirectory(const char *dirname)
1918 {
1919 char *pszDir;
1920 char *realdir;
1921 HANDLE hFind = INVALID_HANDLE_VALUE;
1922 SARRAY *safiles;
1923 WIN32_FIND_DATAA ffd;
1924 
1925  PROCNAME("getFilenamesInDirectory");
1926 
1927  if (!dirname)
1928  return (SARRAY *)ERROR_PTR("dirname not defined", procName, NULL);
1929 
1930  realdir = genPathname(dirname, NULL);
1931  pszDir = stringJoin(realdir, "\\*");
1932  LEPT_FREE(realdir);
1933 
1934  if (strlen(pszDir) + 1 > MAX_PATH) {
1935  LEPT_FREE(pszDir);
1936  return (SARRAY *)ERROR_PTR("dirname is too long", procName, NULL);
1937  }
1938 
1939  if ((safiles = sarrayCreate(0)) == NULL) {
1940  LEPT_FREE(pszDir);
1941  return (SARRAY *)ERROR_PTR("safiles not made", procName, NULL);
1942  }
1943 
1944  hFind = FindFirstFileA(pszDir, &ffd);
1945  if (INVALID_HANDLE_VALUE == hFind) {
1946  sarrayDestroy(&safiles);
1947  LEPT_FREE(pszDir);
1948  return (SARRAY *)ERROR_PTR("hFind not opened", procName, NULL);
1949  }
1950 
1951  while (FindNextFileA(hFind, &ffd) != 0) {
1952  if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) /* skip dirs */
1953  continue;
1954  convertSepCharsInPath(ffd.cFileName, UNIX_PATH_SEPCHAR);
1955  sarrayAddString(safiles, ffd.cFileName, L_COPY);
1956  }
1957 
1958  FindClose(hFind);
1959  LEPT_FREE(pszDir);
1960  return safiles;
1961 }
1962 #endif /* _WIN32 */
char * sarrayToString(SARRAY *sa, l_int32 addnlflag)
sarrayToString()
Definition: sarray1.c:763
Definition: pix.h:717
FILE * fp
Definition: regutils.h:119
SARRAY * sarrayCopy(SARRAY *sa)
sarrayCopy()
Definition: sarray1.c:393
char * genPathname(const char *dir, const char *fname)
genPathname()
Definition: utils2.c:2880
#define SARRAY_VERSION_NUMBER
Definition: array.h:113
Definition: pix.h:716
char * stringNew(const char *src)
stringNew()
Definition: utils2.c:215
char * sarrayRemoveString(SARRAY *sa, l_int32 index)
sarrayRemoveString()
Definition: sarray1.c:506
SARRAY * sarrayCreate(l_int32 n)
sarrayCreate()
Definition: sarray1.c:163
l_ok sarrayWriteStream(FILE *fp, SARRAY *sa)
sarrayWriteStream()
Definition: sarray1.c:1514
char * sarrayToStringRange(SARRAY *sa, l_int32 first, l_int32 nstrings, l_int32 addnlflag)
sarrayToStringRange()
Definition: sarray1.c:798
SARRAY * getFilenamesInDirectory(const char *dirname)
getFilenamesInDirectory()
Definition: sarray1.c:1859
FILE * fopenReadFromMemory(const l_uint8 *data, size_t size)
fopenReadFromMemory()
Definition: utils2.c:1734
l_ok sarrayWriteMem(l_uint8 **pdata, size_t *psize, SARRAY *sa)
sarrayWriteMem()
Definition: sarray1.c:1553
l_ok sarrayPadToSameSize(SARRAY *sa1, SARRAY *sa2, const char *padstring)
sarrayPadToSameSize()
Definition: sarray1.c:972
void * reallocNew(void **pindata, l_int32 oldsize, l_int32 newsize)
reallocNew()
Definition: utils2.c:1161
SARRAY * sarrayConvertWordsToLines(SARRAY *sa, l_int32 linesize)
sarrayConvertWordsToLines()
Definition: sarray1.c:1029
SARRAY * getNumberedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
getNumberedPathnamesInDirectory()
Definition: sarray1.c:1669
Definition: array.h:116
l_ok sarrayAppendRange(SARRAY *sa1, SARRAY *sa2, l_int32 start, l_int32 end)
sarrayAppendRange()
Definition: sarray1.c:920
l_ok sarrayWrite(const char *filename, SARRAY *sa)
sarrayWrite()
Definition: sarray1.c:1477
l_int32 n
Definition: array.h:119
l_ok sarrayAddString(SARRAY *sa, const char *string, l_int32 copyflag)
sarrayAddString()
Definition: sarray1.c:446
l_int32 refcount
Definition: array.h:120
l_ok sarrayAppend(const char *filename, SARRAY *sa)
sarrayAppend()
Definition: sarray1.c:1601
FILE * fopenWriteWinTempfile()
fopenWriteWinTempfile()
Definition: utils2.c:1780
char * sarrayGetString(SARRAY *sa, l_int32 index, l_int32 copyflag)
sarrayGetString()
Definition: sarray1.c:681
char ** sarrayGetArray(SARRAY *sa, l_int32 *pnalloc, l_int32 *pn)
sarrayGetArray()
Definition: sarray1.c:646
l_ok sarrayClear(SARRAY *sa)
sarrayClear()
Definition: sarray1.c:594
SARRAY * sarrayReadMem(const l_uint8 *data, size_t size)
sarrayReadMem()
Definition: sarray1.c:1449
SARRAY * sarrayCreateLinesFromString(const char *string, l_int32 blankflag)
sarrayCreateLinesFromString()
Definition: sarray1.c:276
SARRAY * getSortedPathnamesInDirectory(const char *dirname, const char *substr, l_int32 first, l_int32 nfiles)
getSortedPathnamesInDirectory()
Definition: sarray1.c:1717
l_int32 success
Definition: regutils.h:124
SARRAY * sarrayClone(SARRAY *sa)
sarrayClone()
Definition: sarray1.c:420
l_int32 extractNumberFromFilename(const char *fname, l_int32 numpre, l_int32 numpost)
extractNumberFromFilename()
Definition: utils2.c:3142
SARRAY * sarraySelectByRange(SARRAY *sain, l_int32 first, l_int32 last)
sarraySelectByRange()
Definition: sarray1.c:1191
FILE * fopenWriteStream(const char *filename, const char *modestring)
fopenWriteStream()
Definition: utils2.c:1700
FILE * fopenReadStream(const char *filename)
fopenReadStream()
Definition: utils2.c:1657
static l_int32 sarrayExtendArray(SARRAY *sa)
sarrayExtendArray()
Definition: sarray1.c:481
l_uint8 * l_binaryReadStream(FILE *fp, size_t *pnbytes)
l_binaryReadStream()
Definition: utils2.c:1262
l_int32 sarrayGetCount(SARRAY *sa)
sarrayGetCount()
Definition: sarray1.c:621
l_int32 nalloc
Definition: array.h:118
l_int32 sarrayGetRefcount(SARRAY *sa)
sarrayGetRefCount()
Definition: sarray1.c:708
SARRAY * convertSortedToNumberedPathnames(SARRAY *sa, l_int32 numpre, l_int32 numpost, l_int32 maxnum)
convertSortedToNumberedPathnames()
Definition: sarray1.c:1777
SARRAY * sarrayRead(const char *filename)
sarrayRead()
Definition: sarray1.c:1345
l_ok sarrayJoin(SARRAY *sa1, SARRAY *sa2)
sarrayJoin()
Definition: sarray1.c:880
l_ok sarrayReplaceString(SARRAY *sa, l_int32 index, char *newstr, l_int32 copyflag)
sarrayReplaceString()
Definition: sarray1.c:557
SARRAY * sarraySort(SARRAY *saout, SARRAY *sain, l_int32 sortorder)
sarraySort()
Definition: sarray2.c:95
char * pathJoin(const char *dir, const char *fname)
pathJoin()
Definition: utils2.c:2686
Definition: pix.h:718
char * stringJoin(const char *src1, const char *src2)
stringJoin()
Definition: utils2.c:509
l_ok sarrayChangeRefcount(SARRAY *sa, l_int32 delta)
sarrayChangeRefCount()
Definition: sarray1.c:726
SARRAY * sarrayCreateInitialized(l_int32 n, const char *initstr)
sarrayCreateInitialized()
Definition: sarray1.c:193
l_ok convertSepCharsInPath(char *path, l_int32 type)
convertSepCharsInPath()
Definition: utils2.c:2817
char * strtokSafe(char *cstr, const char *seps, char **psaveptr)
strtokSafe()
Definition: utils2.c:640
char ** array
Definition: array.h:121
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:1260
l_int32 index
Definition: regutils.h:123
SARRAY * sarrayReadStream(FILE *fp)
sarrayReadStream()
Definition: sarray1.c:1382
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:1092
SARRAY * sarraySelectBySubstring(SARRAY *sain, const char *substr)
sarraySelectBySubstring()
Definition: sarray1.c:1145
SARRAY * sarrayCreateWordsFromString(const char *string)
sarrayCreateWordsFromString()
Definition: sarray1.c:226
static const l_int32 L_BUF_SIZE
Definition: classapp.c:55
void sarrayDestroy(SARRAY **psa)
sarrayDestroy()
Definition: sarray1.c:355