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 };