Mercurial > hg > th-libs
comparison th_ioctx.c @ 675:fb4093ad1f7b
Add MemIO ioctx functionality.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Tue, 25 Feb 2020 06:15:08 +0200 |
parents | 24cbab6e88c6 |
children | 7e207f1023d9 |
comparison
equal
deleted
inserted
replaced
674:dfabc7eef3dd | 675:fb4093ad1f7b |
---|---|
272 { | 272 { |
273 if (ctx->fops->fputs != NULL) | 273 if (ctx->fops->fputs != NULL) |
274 return ctx->fops->fputs(ptr, ctx); | 274 return ctx->fops->fputs(ptr, ctx); |
275 | 275 |
276 const char *p = ptr; | 276 const char *p = ptr; |
277 int retv = 0; | 277 int rval = 0; |
278 while (*p && (retv = ctx->fops->fputc(*p, ctx)) != EOF) p++; | 278 while (*p && (rval = ctx->fops->fputc(*p, ctx)) != EOF) p++; |
279 return retv; | 279 return rval; |
280 } | 280 } |
281 | 281 |
282 | 282 |
283 int thvfprintf(th_ioctx *ctx, const char *fmt, va_list ap) | 283 int thvfprintf(th_ioctx *ctx, const char *fmt, va_list ap) |
284 { | 284 { |
294 } | 294 } |
295 | 295 |
296 | 296 |
297 int thfprintf(th_ioctx *ctx, const char *fmt, ...) | 297 int thfprintf(th_ioctx *ctx, const char *fmt, ...) |
298 { | 298 { |
299 int retv; | 299 int rval; |
300 va_list ap; | 300 va_list ap; |
301 va_start(ap, fmt); | 301 va_start(ap, fmt); |
302 retv = thvfprintf(ctx, fmt, ap); | 302 rval = thvfprintf(ctx, fmt, ap); |
303 va_end(ap); | 303 va_end(ap); |
304 return retv; | 304 return rval; |
305 } | 305 } |
306 | 306 |
307 | 307 |
308 BOOL thfread_str(th_ioctx *ctx, void *ptr, const size_t len) | 308 BOOL thfread_str(th_ioctx *ctx, void *ptr, const size_t len) |
309 { | 309 { |
524 | 524 |
525 th_stdio_fgets, | 525 th_stdio_fgets, |
526 th_stdio_fputs, | 526 th_stdio_fputs, |
527 th_stdio_vfprintf, | 527 th_stdio_vfprintf, |
528 }; | 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 }; |