comparison th_ioctx_mem.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
children 81d1a3f53b87
comparison
equal deleted inserted replaced
677:927772fb0745 678:7e207f1023d9
1 /*
2 * Simple I/O abstraction and context handling layer
3 * Programmed and designed by Matti 'ccr' Hamalainen
4 * (C) Copyright 2012-2020 Tecnic Software productions (TNSP)
5 *
6 * Please read file 'COPYING' for information on license and distribution.
7 */
8 #include "th_ioctx.h"
9
10
11 static BOOL th_mem_realloc(th_ioctx *ctx, const size_t newSize)
12 {
13 size_t grow;
14
15 if (ctx->maxSize > 0 && newSize > ctx->maxSize)
16 {
17 ctx->status = THERR_BOUNDS;
18 return FALSE;
19 }
20
21 if (newSize < ctx->memAlloc)
22 return TRUE;
23
24 grow = (ctx->minAlloc > 0) ? ctx->minAlloc : 8 * 1024;
25 if (newSize - ctx->memAlloc > grow)
26 grow += newSize - ctx->memAlloc;
27
28 if (ctx->maxSize > 0 && ctx->memAlloc + grow >= ctx->maxSize)
29 {
30 ctx->status = THERR_BOUNDS;
31 return FALSE;
32 }
33
34 ctx->memAlloc += grow;
35 if ((ctx->memData = th_realloc(ctx->memData, ctx->memAlloc)) == NULL)
36 {
37 ctx->status = THERR_MALLOC;
38 return FALSE;
39 }
40
41 ctx->memSize = newSize;
42
43 return TRUE;
44 }
45
46
47 static int th_mem_freset(th_ioctx *ctx)
48 {
49 ctx->memOffset = 0;
50 return THERR_OK;
51 }
52
53
54 static int th_mem_ferror(th_ioctx *ctx)
55 {
56 return ctx->status;
57 }
58
59
60 static int th_mem_fseek(th_ioctx *ctx, const off_t offset, const int whence)
61 {
62 off_t newPos;
63
64 // Calculate the new position
65 switch (whence)
66 {
67 case SEEK_SET:
68 newPos = offset;
69 break;
70
71 case SEEK_CUR:
72 newPos = ctx->memOffset + offset;
73 break;
74
75 case SEEK_END:
76 newPos = ctx->memSize + offset;
77 break;
78
79 default:
80 return -1;
81 }
82
83 // Set the new position
84 ctx->memOffset = newPos;
85
86 // Check the new position
87 if (newPos < 0)
88 return -1;
89
90 //if (!th_mem_realloc(ctx, newPos))
91 // return -1;
92
93 return 0;
94 }
95
96
97 static off_t th_mem_fsize(th_ioctx *ctx)
98 {
99 return ctx->memSize;
100 }
101
102
103 static off_t th_mem_ftell(th_ioctx *ctx)
104 {
105 return ctx->memOffset;
106 }
107
108
109 static BOOL th_mem_feof(th_ioctx *ctx)
110 {
111 return ((size_t) ctx->memOffset) >= ctx->memSize;
112 }
113
114
115 static int th_mem_fgetc(th_ioctx *ctx)
116 {
117 // Check for EOF
118 if ((size_t) ctx->memOffset < ctx->memSize)
119 return ctx->memData[ctx->memOffset++];
120 else
121 return EOF;
122 }
123
124
125 static size_t th_mem_fread(void *buf, size_t size, size_t nmemb, th_ioctx *ctx)
126 {
127 size_t length = size * nmemb;
128
129 // Check if we can read the whole chunk
130 if (((size_t) ctx->memOffset + length) >= ctx->memSize)
131 {
132 nmemb = (ctx->memSize - ctx->memOffset) / size;
133 length = size * nmemb;
134 }
135
136 memcpy(buf, ctx->memData + ctx->memOffset, length);
137 ctx->memOffset += length;
138 return nmemb;
139 }
140
141
142 static int th_mem_fputc(int ch, th_ioctx *ctx)
143 {
144 // Check for EOF
145 if (!th_mem_realloc(ctx, ctx->memOffset + 1))
146 return EOF;
147
148 ctx->memData[ctx->memOffset++] = ch;
149 return ch;
150 }
151
152
153 static size_t th_mem_fwrite(const void *buf, size_t size, size_t nmemb, th_ioctx *ctx)
154 {
155 size_t length = size * nmemb;
156
157 // Check if we can write the whole chunk
158 if (!th_mem_realloc(ctx, ctx->memOffset + length))
159 {
160 nmemb = (ctx->memSize - ctx->memOffset) / size;
161 length = size * nmemb;
162 }
163
164 if (length > 0)
165 {
166 memcpy(ctx->memData + ctx->memOffset, buf, length);
167 ctx->memOffset += length;
168 }
169 return nmemb;
170 }
171
172
173 const th_ioctx_ops th_mem_io_ops =
174 {
175 "MemIO",
176
177 NULL,
178 NULL,
179
180 th_mem_freset,
181 th_mem_ferror,
182 th_mem_fseek,
183 th_mem_fsize,
184 th_mem_ftell,
185 th_mem_feof,
186 th_mem_fgetc,
187 th_mem_fputc,
188 th_mem_fread,
189 th_mem_fwrite,
190
191 NULL,
192 NULL,
193 NULL
194 };