comparison th_ioctx.c @ 678:7e207f1023d9

Split stdio and memio stuff to separate files from th_stdio.c
author Matti Hamalainen <ccr@tnsp.org>
date Sat, 29 Feb 2020 12:19:02 +0200
parents fb4093ad1f7b
children dfc2c9f0577f
comparison
equal deleted inserted replaced
677:927772fb0745 678:7e207f1023d9
6 * Please read file 'COPYING' for information on license and distribution. 6 * Please read file 'COPYING' for information on license and distribution.
7 */ 7 */
8 #include "th_ioctx.h" 8 #include "th_ioctx.h"
9 #include "th_string.h" 9 #include "th_string.h"
10 #include "th_endian.h" 10 #include "th_endian.h"
11 #include <stdio.h>
12 11
13 12
14 static void th_io_update_atime(th_ioctx *ctx) 13 static void th_io_update_atime(th_ioctx *ctx)
15 { 14 {
16 ctx->atime = time(NULL); 15 ctx->atime = time(NULL);
359 358
360 TH_DEFINE_FUNC(le64, uint64_t, LE64) 359 TH_DEFINE_FUNC(le64, uint64_t, LE64)
361 TH_DEFINE_FUNC(be64, uint64_t, BE64) 360 TH_DEFINE_FUNC(be64, uint64_t, BE64)
362 361
363 #undef TH_DEFINE_FUNC 362 #undef TH_DEFINE_FUNC
364
365
366 //
367 // stdio wrappers for I/O contexts
368 //
369 #define CTX_FH ((FILE *) ctx->data)
370
371
372 static int th_stdio_fopen(th_ioctx *ctx)
373 {
374 ctx->data = (void *) fopen(ctx->filename, ctx->mode);
375 ctx->status = th_get_error();
376 return (ctx->data != NULL) ? THERR_OK : THERR_FOPEN;
377 }
378
379
380 static void th_stdio_fclose(th_ioctx *ctx)
381 {
382 if (CTX_FH != NULL)
383 {
384 fclose(CTX_FH);
385 ctx->data = NULL;
386 }
387 }
388
389
390 static int th_stdio_ferror(th_ioctx *ctx)
391 {
392 return ctx->status;
393 }
394
395
396 static off_t th_stdio_ftell(th_ioctx *ctx)
397 {
398 return ftello(CTX_FH);
399 }
400
401
402 static int th_stdio_fseek(th_ioctx *ctx, const off_t pos, const int whence)
403 {
404 int ret = fseeko(CTX_FH, pos, whence);
405 ctx->status = th_get_error();
406 return ret;
407 }
408
409
410 static int th_stdio_freset(th_ioctx *ctx)
411 {
412 if (CTX_FH != NULL)
413 return th_stdio_fseek(ctx, 0, SEEK_SET);
414 else
415 return THERR_OK;
416 }
417
418
419 static off_t th_stdio_fsize(th_ioctx *ctx)
420 {
421 off_t savePos, fileSize;
422
423 // Check if the size is cached
424 if (ctx->size != 0)
425 return ctx->size;
426
427 // Get file size
428 if ((savePos = th_stdio_ftell(ctx)) < 0)
429 return -1;
430
431 if (th_stdio_fseek(ctx, 0, SEEK_END) != 0)
432 return -1;
433
434 if ((fileSize = th_stdio_ftell(ctx)) < 0)
435 return -1;
436
437 if (th_stdio_fseek(ctx, savePos, SEEK_SET) != 0)
438 return -1;
439
440 ctx->size = fileSize;
441 return fileSize;
442 }
443
444
445 static BOOL th_stdio_feof(th_ioctx *ctx)
446 {
447 return feof(CTX_FH);
448 }
449
450
451 static int th_stdio_fgetc(th_ioctx *ctx)
452 {
453 int ret = fgetc(CTX_FH);
454 ctx->status = th_get_error();
455 return ret;
456 }
457
458
459 static int th_stdio_fputc(int v, th_ioctx *ctx)
460 {
461 int ret = fputc(v, CTX_FH);
462 ctx->status = th_get_error();
463 return ret;
464 }
465
466
467 static size_t th_stdio_fread(void *ptr, size_t size, size_t nmemb, th_ioctx *ctx)
468 {
469 size_t ret = fread(ptr, size, nmemb, CTX_FH);
470 ctx->status = th_get_error();
471 return ret;
472 }
473
474
475 static size_t th_stdio_fwrite(const void *ptr, size_t size, size_t nmemb, th_ioctx *ctx)
476 {
477 size_t ret = fwrite(ptr, size, nmemb, CTX_FH);
478 ctx->status = th_get_error();
479 return ret;
480 }
481
482
483 static char * th_stdio_fgets(char *str, int size, th_ioctx *ctx)
484 {
485 char *ret = fgets(str, size, CTX_FH);
486 ctx->status = th_get_error();
487 return ret;
488 }
489
490
491 static int th_stdio_fputs(const char *str, th_ioctx *ctx)
492 {
493 int ret = fputs(str, CTX_FH);
494 ctx->status = th_get_error();
495 return ret;
496 }
497
498
499 static int th_stdio_vfprintf(th_ioctx *ctx, const char *fmt, va_list ap)
500 {
501 int ret = vfprintf(CTX_FH, fmt, ap);
502 ctx->status = th_get_error();
503 return ret;
504 }
505
506
507 const th_ioctx_ops th_stdio_io_ops =
508 {
509 "stdio",
510
511 th_stdio_fopen,
512 th_stdio_fclose,
513
514 th_stdio_freset,
515 th_stdio_ferror,
516 th_stdio_fseek,
517 th_stdio_fsize,
518 th_stdio_ftell,
519 th_stdio_feof,
520 th_stdio_fgetc,
521 th_stdio_fputc,
522 th_stdio_fread,
523 th_stdio_fwrite,
524
525 th_stdio_fgets,
526 th_stdio_fputs,
527 th_stdio_vfprintf,
528 };
529
530
531 static BOOL th_mem_realloc(th_ioctx *ctx, const size_t newSize)
532 {
533 size_t grow;
534
535 if (ctx->maxSize > 0 && newSize > ctx->maxSize)
536 {
537 ctx->status = THERR_BOUNDS;
538 return FALSE;
539 }
540
541 if (newSize < ctx->memAlloc)
542 return TRUE;
543
544 grow = (ctx->minAlloc > 0) ? ctx->minAlloc : 8 * 1024;
545 if (newSize - ctx->memAlloc > grow)
546 grow += newSize - ctx->memAlloc;
547
548 if (ctx->maxSize > 0 && ctx->memAlloc + grow >= ctx->maxSize)
549 {
550 ctx->status = THERR_BOUNDS;
551 return FALSE;
552 }
553
554 ctx->memAlloc += grow;
555 if ((ctx->memData = th_realloc(ctx->memData, ctx->memAlloc)) == NULL)
556 {
557 ctx->status = THERR_MALLOC;
558 return FALSE;
559 }
560
561 ctx->memSize = newSize;
562
563 return TRUE;
564 }
565
566
567 static int th_mem_freset(th_ioctx *ctx)
568 {
569 ctx->memOffset = 0;
570 return THERR_OK;
571 }
572
573
574 static int th_mem_ferror(th_ioctx *ctx)
575 {
576 return ctx->status;
577 }
578
579
580 static int th_mem_fseek(th_ioctx *ctx, const off_t offset, const int whence)
581 {
582 off_t newPos;
583
584 // Calculate the new position
585 switch (whence)
586 {
587 case SEEK_SET:
588 newPos = offset;
589 break;
590
591 case SEEK_CUR:
592 newPos = ctx->memOffset + offset;
593 break;
594
595 case SEEK_END:
596 newPos = ctx->memSize + offset;
597 break;
598
599 default:
600 return -1;
601 }
602
603 // Set the new position
604 ctx->memOffset = newPos;
605
606 // Check the new position
607 if (newPos < 0)
608 return -1;
609
610 //if (!th_mem_realloc(ctx, newPos))
611 // return -1;
612
613 return 0;
614 }
615
616
617 static off_t th_mem_fsize(th_ioctx *ctx)
618 {
619 return ctx->memSize;
620 }
621
622
623 static off_t th_mem_ftell(th_ioctx *ctx)
624 {
625 return ctx->memOffset;
626 }
627
628
629 static BOOL th_mem_feof(th_ioctx *ctx)
630 {
631 return ((size_t) ctx->memOffset) >= ctx->memSize;
632 }
633
634
635 static int th_mem_fgetc(th_ioctx *ctx)
636 {
637 // Check for EOF
638 if ((size_t) ctx->memOffset < ctx->memSize)
639 return ctx->memData[ctx->memOffset++];
640 else
641 return EOF;
642 }
643
644
645 static size_t th_mem_fread(void *buf, size_t size, size_t nmemb, th_ioctx *ctx)
646 {
647 size_t length = size * nmemb;
648
649 // Check if we can read the whole chunk
650 if (((size_t) ctx->memOffset + length) >= ctx->memSize)
651 {
652 nmemb = (ctx->memSize - ctx->memOffset) / size;
653 length = size * nmemb;
654 }
655
656 memcpy(buf, ctx->memData + ctx->memOffset, length);
657 ctx->memOffset += length;
658 return nmemb;
659 }
660
661
662 static int th_mem_fputc(int ch, th_ioctx *ctx)
663 {
664 // Check for EOF
665 if (!th_mem_realloc(ctx, ctx->memOffset + 1))
666 return EOF;
667
668 ctx->memData[ctx->memOffset++] = ch;
669 return ch;
670 }
671
672
673 static size_t th_mem_fwrite(const void *buf, size_t size, size_t nmemb, th_ioctx *ctx)
674 {
675 size_t length = size * nmemb;
676
677 // Check if we can write the whole chunk
678 if (!th_mem_realloc(ctx, ctx->memOffset + length))
679 {
680 nmemb = (ctx->memSize - ctx->memOffset) / size;
681 length = size * nmemb;
682 }
683
684 if (length > 0)
685 {
686 memcpy(ctx->memData + ctx->memOffset, buf, length);
687 ctx->memOffset += length;
688 }
689 return nmemb;
690 }
691
692
693 const th_ioctx_ops th_mem_io_ops =
694 {
695 "MemIO",
696
697 NULL,
698 NULL,
699
700 th_mem_freset,
701 th_mem_ferror,
702 th_mem_fseek,
703 th_mem_fsize,
704 th_mem_ftell,
705 th_mem_feof,
706 th_mem_fgetc,
707 th_mem_fputc,
708 th_mem_fread,
709 th_mem_fwrite,
710
711 NULL,
712 NULL,
713 NULL
714 };