Skip to content

Commit e433afa

Browse files
committed
new methods: equals, appendfile
1 parent f366685 commit e433afa

File tree

6 files changed

+170
-21
lines changed

6 files changed

+170
-21
lines changed

.github/workflows/test.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ jobs:
3131
lua -v
3232
cd tests
3333
lua test01.lua
34+
lua test02.lua
3435
cd ../examples
3536
lua example01.lua
3637

doc/README.md

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
* [array:setlen()](#array_setlen)
2525
* [array:reserve()](#array_reserve)
2626
* [array:tostring()](#array_tostring)
27+
* [array:equals()](#array_equals)
28+
* [array:appendfile()](#array_appendfile)
2729

2830
<!-- ---------------------------------------------------------------------------------------- -->
2931
## Overview
@@ -46,7 +48,7 @@ local carray = require("carray")
4648
## Module Functions
4749
<!-- ---------------------------------------------------------------------------------------- -->
4850

49-
* <a id="carray_new">**` carray.new(type[, count])
51+
* <a id="carray_new">**`carray.new(type[, count])
5052
`**</a>
5153

5254
Creates a new array object with the specified element type.
@@ -109,9 +111,17 @@ to [carray.new()](#carray_new).
109111

110112
Array objects can be created by calling the module function [carray.new()](#carray_new).
111113

114+
If not other specified, array methods return the array object to allow method chaining,
115+
e.g.
116+
```lua
117+
local a = carray.new("char"):append("testdata:"):appendfile("test1.data")
118+
```
119+
creates a new array with data from string and file content and assigns this array to the
120+
variable *a*.
121+
112122
<!-- ---------------------------------------------------------------------------------------- -->
113123

114-
* <a id="array_get">**` array:get(pos1[, pos2])
124+
* <a id="array_get">**`array:get(pos1[, pos2])
115125
`** </a>
116126

117127
Get elements from the array.
@@ -128,7 +138,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
128138

129139
<!-- ---------------------------------------------------------------------------------------- -->
130140

131-
* <a id="array_set">**` array:set(pos, ...)
141+
* <a id="array_set">**`array:set(pos, ...)
132142
`** </a>
133143

134144
Sets the given elements at the specified position of the array object.
@@ -147,7 +157,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
147157

148158
<!-- ---------------------------------------------------------------------------------------- -->
149159

150-
* <a id="array_append">**` array:append(...)
160+
* <a id="array_append">**`array:append(...)
151161
`** </a>
152162

153163
Appends the given elements to the end of the array object.
@@ -160,7 +170,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
160170

161171
<!-- ---------------------------------------------------------------------------------------- -->
162172

163-
* <a id="array_insert">**` array:insert(pos, ...)
173+
* <a id="array_insert">**`array:insert(pos, ...)
164174
`** </a>
165175

166176
Inserts the given elements at the specified position of the array object.
@@ -175,7 +185,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
175185

176186
<!-- ---------------------------------------------------------------------------------------- -->
177187

178-
* <a id="array_setsub">**` array:setsub(pos0, array2, pos1, pos2)
188+
* <a id="array_setsub">**`array:setsub(pos0, array2, pos1, pos2)
179189
`** </a>
180190

181191
Sets elements of another array *array2* to the specified position *pos0*
@@ -201,7 +211,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
201211

202212
<!-- ---------------------------------------------------------------------------------------- -->
203213

204-
* <a id="array_appendsub">**` array:appendsub(array2, pos1, pos2)
214+
* <a id="array_appendsub">**`array:appendsub(array2, pos1, pos2)
205215
`** </a>
206216

207217
Appends elements of another array *array2* to the end of the array object.
@@ -222,7 +232,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
222232

223233
<!-- ---------------------------------------------------------------------------------------- -->
224234

225-
* <a id="array_insertsub">**` array:insertsub(pos0, array2, pos1, pos2)
235+
* <a id="array_insertsub">**`array:insertsub(pos0, array2, pos1, pos2)
226236
`** </a>
227237

228238
Inserts elements of another array *array2* to the specified position *pos0*
@@ -246,7 +256,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
246256

247257
<!-- ---------------------------------------------------------------------------------------- -->
248258

249-
* <a id="array_remove">**` array:remove(pos1[, pos2])
259+
* <a id="array_remove">**`array:remove(pos1[, pos2])
250260
`** </a>
251261

252262
Removes elements from the array.
@@ -264,14 +274,14 @@ Array objects can be created by calling the module function [carray.new()](#carr
264274

265275
<!-- ---------------------------------------------------------------------------------------- -->
266276

267-
* <a id="array_len">**` array:len()
277+
* <a id="array_len">**`array:len()
268278
`** </a>
269279

270280
Returns the number of elements in the array object.
271281

272282
<!-- ---------------------------------------------------------------------------------------- -->
273283

274-
* <a id="array_type">**` array:type()
284+
* <a id="array_type">**`array:type()
275285
`** </a>
276286

277287
Returns the element type name as string value. Possible values are:
@@ -287,7 +297,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
287297

288298
<!-- ---------------------------------------------------------------------------------------- -->
289299

290-
* <a id="array_basetype">**` array:basetype()
300+
* <a id="array_basetype">**`array:basetype()
291301
`** </a>
292302

293303
Returns the element base type name as string value. Possible values are:
@@ -300,7 +310,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
300310

301311
<!-- ---------------------------------------------------------------------------------------- -->
302312

303-
* <a id="array_bitwidth">**` array:bitwidth()
313+
* <a id="array_bitwidth">**`array:bitwidth()
304314
`** </a>
305315

306316
Returns the number of bits per element as integer value.
@@ -309,7 +319,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
309319

310320
<!-- ---------------------------------------------------------------------------------------- -->
311321

312-
* <a id="array_reset">**` array:reset([shrink])
322+
* <a id="array_reset">**`array:reset([shrink])
313323
`** </a>
314324

315325
Resets the array to length 0.
@@ -321,7 +331,7 @@ Array objects can be created by calling the module function [carray.new()](#carr
321331

322332
<!-- ---------------------------------------------------------------------------------------- -->
323333

324-
* <a id="array_setlen">**` array:setlen(newlen[, shrink])
334+
* <a id="array_setlen">**`array:setlen(newlen[, shrink])
325335
`** </a>
326336

327337
Sets how many elements can be stored in the array.
@@ -337,22 +347,23 @@ Array objects can be created by calling the module function [carray.new()](#carr
337347

338348
<!-- ---------------------------------------------------------------------------------------- -->
339349

340-
* <a id="array_reserve">**` array:reserve([count])
350+
* <a id="array_reserve">**`array:reserve([count])
341351
`** </a>
342352

343-
Sets or get the reserve count. The reserve count denotes the number of new elements that
353+
Sets or gets the reserve count. The reserve count denotes the number of new elements that
344354
can be appended to the array without the need to re-allocate the array's memory.
345355

346356
* *count* - optional integer, if greater zero this methods assures that the reserve is at
347357
least *count* number of elements. If zero or less the reserve is
348358
released, i.e. the allocated memory for this array object is not greater than
349359
needed for the [arry:len()](#array_len) number of elements in this array.
350360

351-
This method returns the current reserve count.
361+
This method returns the current reserve count if no argument *count* is given,
362+
otherwise the array object itself is returned to allow method chaining.
352363

353364
<!-- ---------------------------------------------------------------------------------------- -->
354365

355-
* <a id="array_tostring">**` array:tostring([pos1, pos2])
366+
* <a id="array_tostring">**`array:tostring([pos1, pos2])
356367
`** </a>
357368

358369
Returns array elements as string value for arrays that have element type *signed char*
@@ -371,6 +382,24 @@ Array objects can be created by calling the module function [carray.new()](#carr
371382

372383
<!-- ---------------------------------------------------------------------------------------- -->
373384

385+
* <a id="array_equals">**`array:equals(array2)
386+
`** </a>
387+
388+
Returns *true* if the two arrays are having the same number and type of elements.
389+
390+
<!-- ---------------------------------------------------------------------------------------- -->
391+
392+
* <a id="array_appendfile">**`array:appendfile(file[, pos])
393+
`** </a>
394+
395+
Appends the content of the given file to the array.
396+
397+
* *file* - a file name string or open file handle.
398+
* *pos* - optional integer, the maximal number of elements that are read from the
399+
given file.
400+
401+
<!-- ---------------------------------------------------------------------------------------- -->
402+
374403
[Lua]: https://www.lua.org
375404
[Carray C API]: https://github.com/lua-capis/lua-carray-capi
376405

src/carray.c

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include <limits.h>
2+
#include <stdio.h>
3+
#include <stddef.h>
24

35
#define CARRAY_CAPI_IMPLEMENT_SET_CAPI 1
46
#define CARRAY_CAPI_IMPLEMENT_GET_CAPI 1
@@ -1206,7 +1208,8 @@ static int Carray_reserve(lua_State* L)
12061208
else if (newRes <= 0) {
12071209
carray_capi_impl.resizeCarray(impl, currCount, -1);
12081210
}
1209-
return 0;
1211+
lua_settop(L, 1);
1212+
return 1;
12101213
}
12111214
lua_pushinteger(L, impl->elementCapacity - impl->elementCount);
12121215
return 1;
@@ -1278,6 +1281,92 @@ static int Carray_resizable(lua_State* L)
12781281

12791282
/* ============================================================================================ */
12801283

1284+
static int Carray_appendfile(lua_State* L)
1285+
{
1286+
int arg = 1;
1287+
CarrayUserData* udata = checkWritableUdata(L, arg);
1288+
carray* impl = udata->impl;
1289+
1290+
luaL_Stream* stream = (luaL_Stream*)luaL_testudata(L, ++arg, LUA_FILEHANDLE);
1291+
FILE* file;
1292+
if (stream) {
1293+
file = stream->f;
1294+
if (!file) {
1295+
return luaL_argerror(L, arg, "invalid file");
1296+
}
1297+
} else {
1298+
const char* name = lua_tostring(L, arg);
1299+
if (!name) {
1300+
luaL_argerror(L, arg, "file handle or name expected");
1301+
}
1302+
file = fopen(name, "rb");
1303+
if (!file) {
1304+
luaL_argerror(L, arg, "cannot open file");
1305+
}
1306+
}
1307+
lua_Integer maxCount = -1;
1308+
if (!lua_isnoneornil(L, ++arg)) {
1309+
maxCount = luaL_checkinteger(L, arg);
1310+
if (maxCount <= 0) {
1311+
if (!stream) fclose(file);
1312+
lua_settop(L, 1);
1313+
return 1;
1314+
}
1315+
}
1316+
size_t elementSize = impl->elementSize;
1317+
again:;
1318+
size_t elementCount = impl->elementCount;
1319+
size_t nitems;
1320+
if (maxCount > 0) {
1321+
nitems = maxCount;
1322+
} else {
1323+
nitems = impl->elementCapacity - elementCount;
1324+
if (nitems < 8*1024) {
1325+
nitems = 8*1024;
1326+
}
1327+
}
1328+
char* data = carray_capi_impl.resizeCarray(impl, elementCount + nitems, 0);
1329+
if (!data) {
1330+
if (!stream) fclose(file);
1331+
return luaL_error(L, "resizing carray failed");
1332+
}
1333+
size_t rslt = fread(data + (elementSize * elementCount), elementSize, nitems, file);
1334+
if (rslt > 0) {
1335+
impl->elementCount = elementCount + rslt;
1336+
if (rslt == nitems && maxCount < 0) {
1337+
goto again;
1338+
}
1339+
} else {
1340+
impl->elementCount = elementCount;
1341+
}
1342+
if (rslt < nitems && ferror(file)) {
1343+
int en = errno;
1344+
if (!stream) fclose(file);
1345+
return luaL_error(L, "error reading from file: %s (errno=%d)", strerror(en), en);
1346+
}
1347+
if (!stream) fclose(file);
1348+
lua_settop(L, 1);
1349+
return 1;
1350+
}
1351+
1352+
/* ============================================================================================ */
1353+
1354+
static int Carray_equals(lua_State* L)
1355+
{
1356+
carray* udata1 = checkReadableUdata(L, 1)->impl;
1357+
carray* udata2 = checkReadableUdata(L, 2)->impl;
1358+
1359+
size_t dataLength = udata1->elementSize * udata1->elementCount;
1360+
1361+
lua_pushboolean(L, udata1->elementType == udata2->elementType
1362+
&& udata1->elementSize == udata2->elementSize
1363+
&& udata1->elementCount == udata2->elementCount
1364+
&& (dataLength == 0 || memcmp(udata1->buffer, udata2->buffer, dataLength) == 0));
1365+
return 1;
1366+
}
1367+
1368+
/* ============================================================================================ */
1369+
12811370
static int Carray_toString(lua_State* L)
12821371
{
12831372
CarrayUserData* udata = luaL_checkudata(L, 1, CARRAY_CLASS_NAME);
@@ -1326,6 +1415,8 @@ static const luaL_Reg CarrayMethods[] =
13261415
{ "bitwidth", Carray_bitwidth },
13271416
{ "writable", Carray_writable },
13281417
{ "resizable", Carray_resizable },
1418+
{ "equals", Carray_equals },
1419+
{ "appendfile", Carray_appendfile },
13291420
{ NULL, NULL } /* sentinel */
13301421
};
13311422

tests/test01.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -845,4 +845,4 @@ do
845845
assert(a:tostring() == "1232345678")
846846
end
847847
PRINT("==================================================================================")
848-
print("OK.")
848+
print("test01 OK.")

tests/test02.data

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
123456789

tests/test02.lua

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
c=require"carray"
2+
a=c.new"char"
3+
assert(a==a:appendfile("test02.data"))
4+
assert(a:len() == 10)
5+
assert(a:tostring(1,-1) == "123456789\n")
6+
a:reset():appendfile("test02.data", 2)
7+
assert(a:len() == 2)
8+
assert(a:tostring(1,-1) == "12")
9+
f=io.open("test02.data", "rb")
10+
11+
a:reset():appendfile(f, 2)
12+
assert(a:len() == 2)
13+
assert(a:tostring(1,-1) == "12")
14+
15+
a:appendfile(f, 2)
16+
assert(a:len() == 4)
17+
assert(a:tostring(1,-1) == "1234")
18+
19+
a:appendfile(f, 10)
20+
assert(a:len() == 10)
21+
assert(a:tostring(1,-1) == "123456789\n")
22+
23+
assert(a:equals(c.new("char"):appendfile("test02.data")))
24+
25+
assert(not a:equals(c.new("char"):appendfile("test02.data", 3)))
26+
27+
print("test02 OK.")

0 commit comments

Comments
 (0)