! * \brief sarrayReadStream() * * \param[in] fp file stream * \return sarray, or NULL on error * * * Notes: * (1) We store the size of each string along with the string. * The limit on the number of strings is 2^24. * The limit on the size of any string is 2^30 bytes. * (2) This allows a string to have embedded newlines. By reading * th
| 1379 | * </pre> |
| 1380 | */ |
| 1381 | SARRAY * |
| 1382 | sarrayReadStream(FILE *fp) |
| 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 | } |
no test coverage detected