comparison src/dmgrowbuf.c @ 1454:fff3b58d031c

Add a growable buffer implementation.
author Matti Hamalainen <ccr@tnsp.org>
date Thu, 10 May 2018 18:33:57 +0300
parents
children a957b318fbe2
comparison
equal deleted inserted replaced
1453:73a4158b2e55 1454:fff3b58d031c
1 /*
2 * DMLib
3 * -- Growable buffer implementation
4 * Programmed and designed by Matti 'ccr' Hamalainen
5 * (C) Copyright 2018 Tecnic Software productions (TNSP)
6 */
7 #include "dmgrowbuf.h"
8
9
10 int dmGrowBufInit(DMGrowBuf *buf, const size_t initial, const size_t mingrow)
11 {
12 if (buf == NULL)
13 return DMERR_NULLPTR;
14
15 buf->len = 0;
16 buf->size = initial;
17 buf->mingrow = mingrow;
18 buf->allocated = FALSE;
19
20 if ((buf->data = dmMalloc(initial)) == NULL)
21 return DMERR_MALLOC;
22
23 return DMERR_OK;
24 }
25
26
27 int dmGrowBufAlloc(DMGrowBuf **pbuf, const size_t initial, const size_t mingrow)
28 {
29 int res;
30
31 if ((*pbuf = dmMalloc0(sizeof(DMGrowBuf))) == NULL)
32 return DMERR_MALLOC;
33
34 if ((res = dmGrowBufInit(*pbuf, initial, mingrow)) != DMERR_OK)
35 {
36 dmGrowBufFree(*pbuf);
37 return res;
38 }
39
40 (*pbuf)->allocated = TRUE;
41 return res;
42 }
43
44
45 void dmGrowBufFree(DMGrowBuf *buf)
46 {
47 if (buf != NULL)
48 {
49 dmFreeR(&buf->data);
50 if (buf->allocated)
51 dmFree(buf);
52 }
53 }
54
55
56 BOOL dmGrowBufGrow(DMGrowBuf *buf, const size_t amount)
57 {
58 if (buf->data == NULL || buf->len + amount > buf->size)
59 {
60 buf->size += amount + (buf->mingrow > 0 ? buf->mingrow : 1024);
61 if ((buf->data = dmRealloc(buf->data, buf->size)) == NULL)
62 return FALSE;
63 }
64
65 return TRUE;
66 }
67
68
69 int dmGrowBufResize(DMGrowBuf *buf)
70 {
71 if (buf == NULL)
72 return DMERR_NULLPTR;
73
74 buf->size = buf->len;
75 if (buf->len == 0)
76 return DMERR_OK;
77
78 if ((buf->data = dmRealloc(buf->data, buf->len)) == NULL)
79 return DMERR_MALLOC;
80
81 return DMERR_OK;
82 }
83
84
85 BOOL dmGrowBufPutU8(DMGrowBuf *buf, const Uint8 value)
86 {
87 if (!dmGrowBufGrow(buf, sizeof(Uint8)))
88 return FALSE;
89
90 buf->data[buf->len++] = value;
91
92 return TRUE;
93 }
94
95
96 BOOL dmGrowBufPutStr(DMGrowBuf *buf, const void *str, const size_t len)
97 {
98 if (str == NULL)
99 return FALSE;
100
101 if (!dmGrowBufGrow(buf, len + 1))
102 return FALSE;
103
104 memcpy(buf->data + buf->len, str, len + 1);
105 buf->len += len;
106
107 return TRUE;
108 }
109
110
111 BOOL dmGrowBufPutU16BE(DMGrowBuf *buf, const Uint16 val)
112 {
113 if (!dmGrowBufGrow(buf, sizeof(Uint16)))
114 return FALSE;
115
116 buf->data[buf->len++] = (val >> 8) & 0xff;
117 buf->data[buf->len++] = val & 0xff;
118
119 return TRUE;
120 }
121
122
123 BOOL dmGrowBufPutU16LE(DMGrowBuf *buf, const Uint16 val)
124 {
125 if (!dmGrowBufGrow(buf, sizeof(Uint16)))
126 return FALSE;
127
128 buf->data[buf->len++] = val & 0xff;
129 buf->data[buf->len++] = (val >> 8) & 0xff;
130
131 return TRUE;
132 }
133
134
135 BOOL dmGrowBufPutU32BE(DMGrowBuf *buf, const Uint32 val)
136 {
137 if (!dmGrowBufGrow(buf, sizeof(Uint32)))
138 return FALSE;
139
140 buf->data[buf->len++] = (val >> 24) & 0xff;
141 buf->data[buf->len++] = (val >> 16) & 0xff;
142 buf->data[buf->len++] = (val >> 8) & 0xff;
143 buf->data[buf->len++] = val & 0xff;
144
145 return TRUE;
146 }
147
148
149 BOOL dmGrowBufPutU32LE(DMGrowBuf *buf, const Uint32 val)
150 {
151 if (!dmGrowBufGrow(buf, sizeof(Uint32)))
152 return FALSE;
153
154 buf->data[buf->len++] = val & 0xff;
155 buf->data[buf->len++] = (val >> 8) & 0xff;
156 buf->data[buf->len++] = (val >> 16) & 0xff;
157 buf->data[buf->len++] = (val >> 24) & 0xff;
158
159 return TRUE;
160 }