BinaryParser v1.0.0
Parse binary files with ease.
Loading...
Searching...
No Matches
parser.h
Go to the documentation of this file.
1/*
2MIT License
3
4Copyright (c) 2026 NorbCodes
5
6Permission is hereby granted, free of charge, to any person obtaining a copy
7of this software and associated documentation files (the "Software"), to deal
8in the Software without restriction, including without limitation the rights
9to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10copies of the Software, and to permit persons to whom the Software is
11furnished to do so, subject to the following conditions:
12
13The above copyright notice and this permission notice shall be included in all
14copies or substantial portions of the Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22SOFTWARE.
23*/
24
32
33#ifndef BPARSER_PARSER
34#define BPARSER_PARSER
35
36#include <stdlib.h>
37#include <stdint.h>
38#include <string.h>
39#include <time.h>
40
42
43#if (BPARSER_VERSION_DEV == 1) && !defined(BPARSER_DEV_WARN)
44#error You're using a dev build of BinaryParser. It is still in development and it's VERY volatile! Use with caution.
45#endif // BPARSER_VERSION_DEV
46
53#define BPARSER_UINT8 0
54
61#define BPARSER_UINT16 1
62
69#define BPARSER_UINT24 2
70
77#define BPARSER_UINT32 3
78
85#define BPARSER_UINT64 4
86
93#define BPARSER_UINT128 5
94
101#define BPARSER_INT8 6
102
109#define BPARSER_INT16 7
110
117#define BPARSER_INT24 8
118
125#define BPARSER_INT32 9
126
133#define BPARSER_INT64 10
134
141#define BPARSER_INT128 11
142
149#define BPARSER_STR 12
150
157#define BPARSER_N_BYTES 13
158
165#define BPARSER_FIXED_STR 14
166
173#define BPARSER_FLOAT 15
174
181#define BPARSER_DOUBLE 16
182
189#define BPARSER_UNIX_TIME 17
190
197#define BPARSER_UNICODE_FROM_UTF8_STR 18
198
205#define BPARSER_UNICODE_FROM_UTF8_F_STR 19
206
213#define BPARSER_UTF8_STR 20
214
221#define BPARSER_UTF8_F_STR 21
222
229#define BPARSER_BOOLS 22
230
237#define BPARSER_BOOL_RUN 23
238
239// Seek modes
240
247#define BPARSER_SEEK_TO 150
248
255#define BPARSER_SEEK_FORWARD 151
256
263#define BPARSER_SEEK_BACKWARD 152
264
271#define BPARSER_SEEK_FROM_END 153
272
278#define BPARSER_NO_SEEK 154
279
280// Error codes
281
289#define BPARSER_RO_ARRAY_ERROR -20
290
296#define BPARSER_MALLOC_ERROR -21
297
303#define BPARSER_NO_FUNC_PASSED -22
304
310#define BPARSER_SPRINTF_ERROR -23
311
319#define BPARSER_BACKWARD_SEEK_ERROR -24
320
327#define BPARSER_SEEK_FROM_END_ERROR -25
328
335#define BPARSER_EOF_ERROR -26
336
343#define BPARSER_CALLOC_ERROR -27
344
352#define BPARSER_UNKNOWN_ENDIAN -28
353
361#define BPARSER_UNKNOWN_READ_TYPE -29
362
368#define BPARSER_FOPEN_ERROR -30
369
377#define BPARSER_FSEEK_ERROR -31
378
386#define BPARSER_FTELL_ERROR -32
387
393#define BPARSER_FREAD_EOF_ERROR -33
394
401#define BPARSER_SEEK_ERROR -34
402
409#define BPARSER_BAD_INTEGRAL_TYPE -35
410
417#define BPARSER_BAD_REALLOC_METHOD -36
418
424#define BPARSER_REALLOC_FACTOR_TOO_SMALL -37
425
431#define BPARSER_RENAME_NOT_FOUND -38
432
438#define BPARSER_PDC_INIT_ERROR -39
439
445#define BPARSER_PDC_RO_COPY_ERROR -40
446
452#define BPARSER_NULL_NAME -41
453
459#define BPARSER_SHORT_NAME -42
460
466#define BPARSER_NO_PARSER -43
467
473#define BPARSER_ZERO_LENGTH -44
474
481#define BPARSER_NAME_IS_NOT_UNIQUE -45
482
488#define BPARSER_NO_BOOLS_TO_READ -46
489
495#define BPARSER_PDC_DATA_COPY_ERROR -47
496
502#define BPARSER_FREAD_ERROR -48
503
509#define BPARSER_FREAD_UNKNOWN_ERROR -49
510
516#define BPARSER_NULL_DATA -50
517
523#define BPARSER_NOTHING_TO_PARSE -51
524
530#define BPARSER_EMPTY_FILE -52
531
537#define BPARSER_BAD_OVERRIDE -53
538
544#define BPARSER_OK(expr) ((expr)>=(BPARSER_RO_ARRAY_ERROR))
545
551#define BPARSER_LITTLE_ENDIAN 0
552
558#define BPARSER_BIG_ENDIAN 1
559
565#define BPARSER_DEFAULT_ENDIAN 2
566
572#define BPARSER_REALLOC_METHOD_PLUS 240
573
579#define BPARSER_REALLOC_METHOD_MULT 241
580
585#define bparser_read_uint8(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_UINT8, BPARSER_DEFAULT_ENDIAN)
586
591#define bparser_read_int8(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_INT8, BPARSER_DEFAULT_ENDIAN)
592
597#define bparser_read_uint16(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_UINT16, BPARSER_DEFAULT_ENDIAN)
598
603#define bparser_read_int16(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_INT16, BPARSER_DEFAULT_ENDIAN)
604
609#define bparser_read_uint24(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_UINT24, BPARSER_DEFAULT_ENDIAN)
610
615#define bparser_read_int24(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_INT24, BPARSER_DEFAULT_ENDIAN)
616
621#define bparser_read_uint32(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_UINT32, BPARSER_DEFAULT_ENDIAN)
622
627#define bparser_read_int32(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_INT32, BPARSER_DEFAULT_ENDIAN)
628
633#define bparser_read_uint64(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_UINT64, BPARSER_DEFAULT_ENDIAN)
634
639#define bparser_read_int64(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_INT64, BPARSER_DEFAULT_ENDIAN)
640
645#define bparser_read_uint128(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_UINT128, BPARSER_DEFAULT_ENDIAN)
646
651#define bparser_read_int128(Parser, Name) bparser_read_integral(Parser, Name, BPARSER_INT128, BPARSER_DEFAULT_ENDIAN)
652
653#ifdef __cplusplus
654extern "C"
655{
656#endif // __cplusplus
657
658struct bparser_parser_s; // Forward declare
659
665#define BPARSER_BYTES_F_ARGS struct bparser_parser_s* MParser, uint8_t* Bytes, size_t Length
666
672#define BPARSER_BYTES_SEQ_F_ARGS struct bparser_parser_s* MParser, uint8_t Byte, size_t Index
673
679#define BPARSER_OVERRIDE_ERROR 99
680
686#define BPARSER_OVERRIDE_TRUE 100
687
693#define BPARSER_OVERRIDE_SKIP 101
694
700#define BPARSER_OVERRIDE_DO_NOTHING 102
701
707
713
719#define BPARSER_BOOL_HANDLER_F_ARGS uint8_t Boolean
720
726#define BPARSER_BOOL_F_ARGS struct bparser_parser_s* MParser
727
733
739
744typedef struct bparser_bool_funcs_s
745{
747 bparser_bool_f Func;
748}
750
755typedef struct bparser_seek_data_s
756{
757 uint64_t Pos;
758 uint8_t Mode;
759}
761
771typedef struct bparser_read_s
772{
773 uint8_t Type;
774 char* Name;
775 size_t Parameter1;
776 bparser_bytes_f Parameter2;
777 uint8_t Endian;
778 bparser_bool_funcs_t Parameter3;
780 bparser_bytes_seq_f Parameter4;
781}
783
792typedef struct bparser_data_s
793{
794 void* DataPtr;
795 uint8_t Type;
796 char* Name;
797 size_t NBytesLength;
798}
800
805typedef void* (*bparser_calloc_like_f)(size_t num, size_t size);
806
811typedef void (*bparser_free_like_f)(void* ptr);
812
817typedef void* (*bparser_malloc_like_f)(size_t size);
818
823typedef void* (*bparser_realloc_like_f)(void* ptr, size_t size);
824
831typedef struct bparser_parser_s
832{
833 // Read order and data arrays
834 bparser_read_t* ReadOrder;
835 size_t ReadOrderLength;
836 size_t ReadOrderMaxLength;
837 bparser_data_t* Data;
838 size_t DataCount;
839 // Callbacks
840 bparser_calloc_like_f CallocF;
842 bparser_malloc_like_f MallocF;
843 bparser_realloc_like_f ReallocF;
844 // Endianess
845 uint8_t Endian;
846 // Position changeable with seek
848 // Realloc method/factor
849 double ReallocFactor;
850 uint8_t ReallocMethod;
851 // Override behaviour
852 uint8_t Override;
853}
855
865
872
881
889
897
905
913
922char bparser_read_integral(bparser_parser_t* MParser, const char* Name, uint8_t Type, uint8_t Endian);
923
930char bparser_read_null_str(bparser_parser_t* MParser, const char* Name);
931
939
946char bparser_read_utf8_null_str(bparser_parser_t* MParser, const char* Name);
947
955char bparser_read_fixed_len_str(bparser_parser_t* MParser, const char* Name, size_t Length);
956
966char bparser_read_unicode_from_utf8_fixed_str(bparser_parser_t* MParser, const char* Name, size_t Length);
967
977char bparser_read_utf8_fixed_len_str(bparser_parser_t* MParser, const char* Name, size_t Length);
978
986char bparser_read_bytes(bparser_parser_t* MParser, const char* Name, size_t NBytes);
987
997
1007
1016char bparser_read_array(bparser_parser_t* MParser, const char* Name, size_t Items, uint8_t ItemType);
1017
1027char bparser_read_2d_array(bparser_parser_t* MParser, const char* Name, size_t Cols, size_t Rows, uint8_t ItemType);
1028
1035char bparser_read_float(bparser_parser_t* MParser, const char* Name);
1036
1043char bparser_read_double(bparser_parser_t* MParser, const char* Name);
1044
1051char bparser_read_unix_time(bparser_parser_t* MParser, const char* Name);
1052
1059char bparser_read_8_booleans(bparser_parser_t* MParser, const char* Name);
1060
1067char bparser_read_16_booleans(bparser_parser_t* MParser, const char* Name);
1068
1075char bparser_read_24_booleans(bparser_parser_t* MParser, const char* Name);
1076
1083char bparser_read_32_booleans(bparser_parser_t* MParser, const char* Name);
1084
1091char bparser_read_64_booleans(bparser_parser_t* MParser, const char* Name);
1092
1099char bparser_read_128_booleans(bparser_parser_t* MParser, const char* Name);
1100
1110
1118char bparser_read(bparser_parser_t* MParser, uint8_t* Data, size_t Size);
1119
1126char bparser_fread(bparser_parser_t* MParser, const char* Filename);
1127
1135char bparser_check_magic_num(const uint8_t* Data, const uint8_t* MagicNum, size_t Length);
1136
1144char bparser_check_magic_num_char(const uint8_t* Data, const char* MagicNum, size_t Length);
1145
1152void* bparser_get(const bparser_parser_t* MParser, const char* Name);
1153
1159
1165
1173char bparser_seek(bparser_parser_t* MParser, uint64_t Pos, uint8_t Mode);
1174
1181
1188
1194const char* bparser_error_str(char Error);
1195
1202
1209
1217
1228
1238
1249char bparser_parser_set_realloc_method(bparser_parser_t* MParser, double N, uint8_t ReallocMethod);
1250
1261
1271void* bparser_data_deep_copy(const bparser_parser_t* MParser, bparser_data_t* Dest, char* Failure);
1272
1279const bparser_data_t* bparser_get_data_at(const bparser_parser_t* MParser, size_t Indx);
1280
1288void bparser_destroy_read_order(bparser_read_t* Array, size_t Length, bparser_free_like_f FreeCallback);
1289
1297void bparser_destroy_data(bparser_data_t* Array, size_t Length, bparser_free_like_f FreeCallback);
1298
1306char bparser_rename(bparser_parser_t* MParser, const char* Src, const char* New);
1307
1318
1331
1339
1347char bparser_set_override(bparser_parser_t* MParser, uint8_t Override);
1348
1349#ifdef BPARSER_IMPLEMENTATION
1350
1351bparser_parser_t* bparser_init(bparser_malloc_like_f MallocLikeFunc, bparser_calloc_like_f CallocLikeFunc, bparser_realloc_like_f ReallocLikeFunc, bparser_free_like_f FreeLikeFunc)
1352{
1353 bparser_malloc_like_f _M = (MallocLikeFunc) ? MallocLikeFunc : malloc;
1354 bparser_calloc_like_f _C = (CallocLikeFunc) ? CallocLikeFunc : calloc;
1355 bparser_realloc_like_f _R = (ReallocLikeFunc) ? ReallocLikeFunc : realloc;
1356 bparser_free_like_f _F = (FreeLikeFunc) ? FreeLikeFunc : free;
1357
1358 void* _1 = _M(sizeof(bparser_parser_t));
1359 void* _2 = _C(2, sizeof(bparser_read_t));
1360
1361 if (!_1 || !_2)
1362 {
1363 return NULL;
1364 }
1365
1367 _New->ReadOrder = (bparser_read_t*)_2;
1368 _New->ReadOrderLength = 0;
1369 _New->ReadOrderMaxLength = 2;
1370 _New->Data = NULL;
1371 _New->DataCount = 0;
1372
1373 // Set callbacks
1374 _New->MallocF = _M;
1375 _New->CallocF = _C;
1376 _New->ReallocF = _R;
1377 _New->FreeF = _F;
1378
1379 _New->Endian = BPARSER_BIG_ENDIAN;
1380
1381 _New->Seek.Pos = 0;
1382 _New->Seek.Mode = BPARSER_NO_SEEK;
1383
1384 _New->ReallocMethod = BPARSER_REALLOC_METHOD_MULT;
1385 _New->ReallocFactor = 2.0;
1386
1387 _New->Override = BPARSER_OVERRIDE_ERROR;
1388
1389 return _New;
1390}
1391
1392void bparser_destroy(bparser_parser_t* MParser)
1393{
1394 if (!MParser)
1395 {
1396 return;
1397 }
1398 bparser_destroy_read_order(MParser->ReadOrder, MParser->ReadOrderLength, MParser->FreeF);
1399 bparser_destroy_data(MParser->Data, MParser->DataCount, MParser->FreeF);
1400 MParser->FreeF(MParser);
1401}
1402
1404{
1405 if (!MParser)
1406 {
1407 return;
1408 }
1409 MParser->FreeF(MParser);
1410}
1411
1413{
1414 if (!MParser) { return NULL; }
1415 MParser->MallocF = (Malloc) ? Malloc : malloc;
1416 return (MParser->MallocF);
1417}
1418
1420{
1421 if (!MParser) { return NULL; }
1422 MParser->CallocF = (Calloc) ? Calloc : calloc;
1423 return (MParser->CallocF);
1424}
1425
1427{
1428 if (!MParser) { return NULL; }
1429 MParser->ReallocF = (Realloc) ? Realloc : realloc;
1430 return (MParser->ReallocF);
1431}
1432
1434{
1435 if (!MParser) { return NULL; }
1436 MParser->FreeF = (Free) ? Free : free;
1437 return (MParser->FreeF);
1438}
1439
1440char _resize_ro_array(bparser_parser_t* MParser)
1441{
1442 if (MParser->ReadOrderLength + 1 > MParser->ReadOrderMaxLength)
1443 {
1444 size_t NewSize = 0;
1445
1446 switch (MParser->ReallocMethod)
1447 {
1449 NewSize = (size_t)(((double)MParser->ReadOrderMaxLength) * MParser->ReallocFactor);
1450 break;
1451
1453 NewSize = (size_t)(((double)MParser->ReadOrderMaxLength) + MParser->ReallocFactor);
1454 break;
1455 }
1456
1457 void* _New = MParser->ReallocF(MParser->ReadOrder, sizeof(bparser_read_t) * (NewSize));
1458 if (_New)
1459 {
1460 MParser->ReadOrder = _New;
1461 MParser->ReadOrderMaxLength = NewSize;
1462 return 1;
1463 }
1464 return 0;
1465 }
1466 return 1;
1467}
1468
1469bparser_read_t* _init_read(bparser_parser_t* MParser)
1470{
1471 bparser_read_t* _Temp = &( MParser->ReadOrder[MParser->ReadOrderLength] );
1472 _Temp->Name = NULL;
1473 _Temp->Endian = MParser->Endian;
1474 _Temp->Parameter1 = 0;
1475 _Temp->Parameter2 = NULL;
1476 _Temp->Parameter3 = (bparser_bool_funcs_t){NULL, NULL};
1477 _Temp->Parameter4 = NULL;
1478 _Temp->Seek = MParser->Seek;
1479 _Temp->Type = 0xFF;
1480 return _Temp;
1481}
1482
1483bparser_read_t* _find_collision(bparser_parser_t* MParser, const char* Name)
1484{
1485 for (size_t I = 0; I < MParser->ReadOrderLength; I++)
1486 {
1487 if (!MParser->ReadOrder[I].Name)
1488 {
1489 continue;
1490 }
1491
1492 if ( strcmp(MParser->ReadOrder[I].Name, Name) == 0 )
1493 {
1494 return &(MParser->ReadOrder[I]);
1495 }
1496 }
1497 return NULL;
1498}
1499
1500bparser_read_t* _get_read_rule_to_set(bparser_parser_t* MParser, const char* Name, char* Error)
1501{
1502 bparser_read_t* _CollidedWith = NULL;
1503
1504 if (MParser->Override != BPARSER_OVERRIDE_DO_NOTHING)
1505 {
1506 _CollidedWith = _find_collision(MParser, Name);
1507 }
1508
1509 if (_CollidedWith)
1510 {
1511 switch (MParser->Override)
1512 {
1515 return NULL;
1516
1518 return _CollidedWith;
1519
1521 *Error = 1;
1522 return NULL;
1523 }
1524 }
1525
1526 bparser_read_t* _Temp = _init_read(MParser);
1527 MParser->ReadOrderLength++;
1528 return _Temp;
1529}
1530
1531char bparser_read_integral(bparser_parser_t* MParser, const char* Name, uint8_t Type, uint8_t Endian)
1532{
1533 if (!MParser)
1534 {
1535 return BPARSER_NO_PARSER;
1536 }
1537
1538 if (!Name)
1539 {
1540 return BPARSER_NULL_NAME;
1541 }
1542
1543 if (strlen(Name) < 1)
1544 {
1545 return BPARSER_SHORT_NAME;
1546 }
1547
1548 if (Type > BPARSER_INT128)
1549 {
1551 }
1552
1553 if (Endian != BPARSER_BIG_ENDIAN && Endian != BPARSER_LITTLE_ENDIAN && Endian != BPARSER_DEFAULT_ENDIAN)
1554 {
1556 }
1557
1558 if(!_resize_ro_array(MParser))
1559 {
1561 }
1562
1563 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1564
1565 if (!_Name)
1566 {
1567 return BPARSER_MALLOC_ERROR;
1568 }
1569
1570 char Error = 0;
1571 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1572
1573 if (!_Temp)
1574 {
1575 return Error;
1576 }
1577
1578 _Temp->Name = (char*)_Name;
1579 strcpy(_Temp->Name, Name);
1580 _Temp->Type = Type;
1581
1582 if (Endian != BPARSER_DEFAULT_ENDIAN)
1583 {
1584 _Temp->Endian = Endian;
1585 }
1586
1587 // Reset seek
1588 MParser->Seek.Pos = 0;
1589 MParser->Seek.Mode = BPARSER_NO_SEEK;
1590 return 1;
1591}
1592
1593char bparser_read_null_str(bparser_parser_t* MParser, const char* Name)
1594{
1595 if (!MParser)
1596 {
1597 return BPARSER_NO_PARSER;
1598 }
1599
1600 if (!Name)
1601 {
1602 return BPARSER_NULL_NAME;
1603 }
1604
1605 if (strlen(Name) < 1)
1606 {
1607 return BPARSER_SHORT_NAME;
1608 }
1609
1610 if(!_resize_ro_array(MParser))
1611 {
1613 }
1614
1615 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1616
1617 if (!_Name)
1618 {
1619 return BPARSER_MALLOC_ERROR;
1620 }
1621
1622 char Error = 0;
1623 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1624
1625 if (!_Temp)
1626 {
1627 return Error;
1628 }
1629
1630 _Temp->Name = (char*)_Name;
1631 strcpy(_Temp->Name, Name);
1632 _Temp->Type = BPARSER_STR;
1633 MParser->Seek.Pos = 0;
1634 MParser->Seek.Mode = BPARSER_NO_SEEK;
1635 return 1;
1636}
1637
1638char bparser_read_unicode_from_utf8_null_str(bparser_parser_t* MParser, const char* Name)
1639{
1640 if (!MParser)
1641 {
1642 return BPARSER_NO_PARSER;
1643 }
1644
1645 if (!Name)
1646 {
1647 return BPARSER_NULL_NAME;
1648 }
1649
1650 if (strlen(Name) < 1)
1651 {
1652 return BPARSER_SHORT_NAME;
1653 }
1654
1655 if(!_resize_ro_array(MParser))
1656 {
1658 }
1659
1660 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1661
1662 if (!_Name)
1663 {
1664 return BPARSER_MALLOC_ERROR;
1665 }
1666
1667 char Error = 0;
1668 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1669
1670 if (!_Temp)
1671 {
1672 return Error;
1673 }
1674
1675 _Temp->Name = (char*)_Name;
1676 strcpy(_Temp->Name, Name);
1677 _Temp->Type = BPARSER_UNICODE_FROM_UTF8_STR;
1678 MParser->Seek.Pos = 0;
1679 MParser->Seek.Mode = BPARSER_NO_SEEK;
1680 return 1;
1681}
1682
1683char bparser_read_utf8_null_str(bparser_parser_t* MParser, const char* Name)
1684{
1685 if (!MParser)
1686 {
1687 return BPARSER_NO_PARSER;
1688 }
1689
1690 if (!Name)
1691 {
1692 return BPARSER_NULL_NAME;
1693 }
1694
1695 if (strlen(Name) < 1)
1696 {
1697 return BPARSER_SHORT_NAME;
1698 }
1699
1700 if(!_resize_ro_array(MParser))
1701 {
1703 }
1704
1705 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1706
1707 if (!_Name)
1708 {
1709 return BPARSER_MALLOC_ERROR;
1710 }
1711
1712 char Error = 0;
1713 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1714
1715 if (!_Temp)
1716 {
1717 return Error;
1718 }
1719
1720 _Temp->Name = (char*)_Name;
1721 strcpy(_Temp->Name, Name);
1722 _Temp->Type = BPARSER_UTF8_STR;
1723 MParser->Seek.Pos = 0;
1724 MParser->Seek.Mode = BPARSER_NO_SEEK;
1725 return 1;
1726}
1727
1728char bparser_read_fixed_len_str(bparser_parser_t* MParser, const char* Name, size_t Length)
1729{
1730 if (!MParser)
1731 {
1732 return BPARSER_NO_PARSER;
1733 }
1734
1735 if (!Name)
1736 {
1737 return BPARSER_NULL_NAME;
1738 }
1739
1740 if (strlen(Name) < 1)
1741 {
1742 return BPARSER_SHORT_NAME;
1743 }
1744
1745 if (Length == 0)
1746 {
1747 return BPARSER_ZERO_LENGTH;
1748 }
1749
1750 if(!_resize_ro_array(MParser))
1751 {
1753 }
1754
1755 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1756
1757 if (!_Name)
1758 {
1759 return BPARSER_MALLOC_ERROR;
1760 }
1761
1762 char Error = 0;
1763 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1764
1765 if (!_Temp)
1766 {
1767 return Error;
1768 }
1769
1770 _Temp->Name = (char*)_Name;
1771 strcpy(_Temp->Name, Name);
1772 _Temp->Type = BPARSER_FIXED_STR;
1773 _Temp->Parameter1 = Length;
1774 MParser->Seek.Pos = 0;
1775 MParser->Seek.Mode = BPARSER_NO_SEEK;
1776 return 1;
1777}
1778
1779char bparser_read_unicode_from_utf8_fixed_str(bparser_parser_t* MParser, const char* Name, size_t Length)
1780{
1781 if (!MParser)
1782 {
1783 return BPARSER_NO_PARSER;
1784 }
1785
1786 if (!Name)
1787 {
1788 return BPARSER_NULL_NAME;
1789 }
1790
1791 if (strlen(Name) < 1)
1792 {
1793 return BPARSER_SHORT_NAME;
1794 }
1795
1796 if (Length == 0)
1797 {
1798 return BPARSER_ZERO_LENGTH;
1799 }
1800
1801 if(!_resize_ro_array(MParser))
1802 {
1804 }
1805
1806 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1807
1808 if (!_Name)
1809 {
1810 return BPARSER_MALLOC_ERROR;
1811 }
1812
1813 char Error = 0;
1814 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1815
1816 if (!_Temp)
1817 {
1818 return Error;
1819 }
1820
1821 _Temp->Name = (char*)_Name;
1822 strcpy(_Temp->Name, Name);
1823 _Temp->Type = BPARSER_UNICODE_FROM_UTF8_F_STR;
1824 _Temp->Parameter1 = Length;
1825 MParser->Seek.Pos = 0;
1826 MParser->Seek.Mode = BPARSER_NO_SEEK;
1827 return 1;
1828}
1829
1830char bparser_read_utf8_fixed_len_str(bparser_parser_t* MParser, const char* Name, size_t Length)
1831{
1832 if (!MParser)
1833 {
1834 return BPARSER_NO_PARSER;
1835 }
1836
1837 if (!Name)
1838 {
1839 return BPARSER_NULL_NAME;
1840 }
1841
1842 if (strlen(Name) < 1)
1843 {
1844 return BPARSER_SHORT_NAME;
1845 }
1846
1847 if (Length == 0)
1848 {
1849 return BPARSER_ZERO_LENGTH;
1850 }
1851
1852 if(!_resize_ro_array(MParser))
1853 {
1855 }
1856
1857 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1858
1859 if (!_Name)
1860 {
1861 return BPARSER_MALLOC_ERROR;
1862 }
1863
1864 char Error = 0;
1865 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1866
1867 if (!_Temp)
1868 {
1869 return Error;
1870 }
1871
1872 _Temp->Name = (char*)_Name;
1873 strcpy(_Temp->Name, Name);
1874 _Temp->Type = BPARSER_UTF8_F_STR;
1875 _Temp->Parameter1 = Length;
1876 MParser->Seek.Pos = 0;
1877 MParser->Seek.Mode = BPARSER_NO_SEEK;
1878 return 1;
1879}
1880
1881char bparser_read_bytes(bparser_parser_t* MParser, const char* Name, size_t NBytes)
1882{
1883 if (!MParser)
1884 {
1885 return BPARSER_NO_PARSER;
1886 }
1887
1888 if (!Name)
1889 {
1890 return BPARSER_NULL_NAME;
1891 }
1892
1893 if (strlen(Name) < 1)
1894 {
1895 return BPARSER_SHORT_NAME;
1896 }
1897
1898 if (NBytes == 0)
1899 {
1900 return BPARSER_ZERO_LENGTH;
1901 }
1902
1903 if(!_resize_ro_array(MParser))
1904 {
1906 }
1907
1908 void* _Name = MParser->MallocF( strlen(Name) + 1 );
1909
1910 if (!_Name)
1911 {
1912 return BPARSER_MALLOC_ERROR;
1913 }
1914
1915 char Error = 0;
1916 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
1917
1918 if (!_Temp)
1919 {
1920 return Error;
1921 }
1922
1923 _Temp->Name = (char*)_Name;
1924 strcpy(_Temp->Name, Name);
1925 _Temp->Type = BPARSER_N_BYTES;
1926 _Temp->Parameter1 = NBytes;
1927 MParser->Seek.Pos = 0;
1928 MParser->Seek.Mode = BPARSER_NO_SEEK;
1929 return 1;
1930}
1931
1932char bparser_read_bytes_and_run(bparser_parser_t* MParser, size_t NBytes, bparser_bytes_f Func)
1933{
1934 if (!MParser)
1935 {
1936 return BPARSER_NO_PARSER;
1937 }
1938
1939 if (NBytes == 0)
1940 {
1941 return BPARSER_ZERO_LENGTH;
1942 }
1943
1944 if(!_resize_ro_array(MParser))
1945 {
1947 }
1948
1949 bparser_read_t* _Temp = _init_read(MParser);
1950 _Temp->Type = BPARSER_N_BYTES;
1951 _Temp->Parameter1 = NBytes;
1952
1953 if (Func == NULL)
1954 {
1956 }
1957 _Temp->Parameter2 = Func;
1958
1959 MParser->Seek.Pos = 0;
1960 MParser->Seek.Mode = BPARSER_NO_SEEK;
1961 MParser->ReadOrderLength++;
1962 return 1;
1963}
1964
1966{
1967 if (!MParser)
1968 {
1969 return BPARSER_NO_PARSER;
1970 }
1971
1972 if (NBytes == 0)
1973 {
1974 return BPARSER_ZERO_LENGTH;
1975 }
1976
1977 if(!_resize_ro_array(MParser))
1978 {
1980 }
1981
1982 bparser_read_t* _Temp = _init_read(MParser);
1983 _Temp->Type = BPARSER_N_BYTES;
1984 _Temp->Parameter1 = NBytes;
1985
1986 if (Func == NULL)
1987 {
1989 }
1990 _Temp->Parameter4 = Func;
1991
1992 MParser->Seek.Pos = 0;
1993 MParser->Seek.Mode = BPARSER_NO_SEEK;
1994 MParser->ReadOrderLength++;
1995 return 1;
1996}
1997
1998char bparser_read_array(bparser_parser_t* MParser, const char* Name, size_t Items, uint8_t ItemType)
1999{
2000 if (!MParser)
2001 {
2002 return BPARSER_NO_PARSER;
2003 }
2004
2005 if (!Name)
2006 {
2007 return BPARSER_NULL_NAME;
2008 }
2009
2010 if (strlen(Name) < 1)
2011 {
2012 return BPARSER_SHORT_NAME;
2013 }
2014
2015 if (Items == 0)
2016 {
2017 return BPARSER_ZERO_LENGTH;
2018 }
2019
2020 if (ItemType > BPARSER_BOOL_RUN)
2021 {
2023 }
2024
2025 for (size_t Item = 0; Item < Items; Item++)
2026 {
2027 if(!_resize_ro_array(MParser))
2028 {
2030 }
2031
2032 void* _Name = MParser->MallocF( strlen(Name) + 16 );
2033
2034 if (!_Name)
2035 {
2036 return BPARSER_MALLOC_ERROR;
2037 }
2038
2039 if(sprintf((char*)_Name, "%s[%lld]", Name, Item) < 0)
2040 {
2041 return BPARSER_SPRINTF_ERROR;
2042 }
2043
2044 char Error = 0;
2045 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, (char*)_Name, &Error);
2046
2047 if (!_Temp)
2048 {
2049 return Error;
2050 }
2051
2052 _Temp->Name = (char*)_Name;
2053 _Temp->Type = ItemType;
2054 MParser->Seek.Pos = 0;
2055 MParser->Seek.Mode = BPARSER_NO_SEEK;
2056 }
2057 return 1;
2058}
2059
2060char bparser_read_2d_array(bparser_parser_t* MParser, const char* Name, size_t Cols, size_t Rows, uint8_t ItemType)
2061{
2062 if (!MParser)
2063 {
2064 return BPARSER_NO_PARSER;
2065 }
2066
2067 if (!Name)
2068 {
2069 return BPARSER_NULL_NAME;
2070 }
2071
2072 if (strlen(Name) < 1)
2073 {
2074 return BPARSER_SHORT_NAME;
2075 }
2076
2077 if ((!Cols) || (!Rows))
2078 {
2079 return BPARSER_ZERO_LENGTH;
2080 }
2081
2082 if (ItemType > BPARSER_BOOL_RUN)
2083 {
2085 }
2086
2087 for (size_t Y = 0; Y < Rows; Y++)
2088 {
2089 for (size_t X = 0; X < Cols; X++)
2090 {
2091 if(!_resize_ro_array(MParser))
2092 {
2094 }
2095
2096 void* _Name = MParser->MallocF( strlen(Name) + 16 );
2097
2098 if (!_Name)
2099 {
2100 return BPARSER_MALLOC_ERROR;
2101 }
2102
2103 if(sprintf((char*)_Name, "%s[%lld][%lld]", Name, Y, X) < 0)
2104 {
2105 return BPARSER_SPRINTF_ERROR;
2106 }
2107
2108 char Error = 0;
2109 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, (char*)_Name, &Error);
2110
2111 if (!_Temp)
2112 {
2113 return Error;
2114 }
2115
2116 _Temp->Name = _Name;
2117 _Temp->Type = ItemType;
2118 MParser->Seek.Pos = 0;
2119 MParser->Seek.Mode = BPARSER_NO_SEEK;
2120 }
2121 }
2122 return 1;
2123}
2124
2125char bparser_read_float(bparser_parser_t* MParser, const char* Name)
2126{
2127 if (!MParser)
2128 {
2129 return BPARSER_NO_PARSER;
2130 }
2131
2132 if (!Name)
2133 {
2134 return BPARSER_NULL_NAME;
2135 }
2136
2137 if (strlen(Name) < 1)
2138 {
2139 return BPARSER_SHORT_NAME;
2140 }
2141
2142 if(!_resize_ro_array(MParser))
2143 {
2145 }
2146
2147 void* _Name = MParser->MallocF( strlen(Name) + 1 );
2148
2149 if (!_Name)
2150 {
2151 return BPARSER_MALLOC_ERROR;
2152 }
2153
2154 char Error = 0;
2155 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
2156
2157 if (!_Temp)
2158 {
2159 return Error;
2160 }
2161
2162 _Temp->Name = (char*)_Name;
2163 strcpy(_Temp->Name, Name);
2164 _Temp->Type = BPARSER_FLOAT;
2165 MParser->Seek.Pos = 0;
2166 MParser->Seek.Mode = BPARSER_NO_SEEK;
2167 return 1;
2168}
2169
2170char bparser_read_double(bparser_parser_t* MParser, const char* Name)
2171{
2172 if (!MParser)
2173 {
2174 return BPARSER_NO_PARSER;
2175 }
2176
2177 if (!Name)
2178 {
2179 return BPARSER_NULL_NAME;
2180 }
2181
2182 if (strlen(Name) < 1)
2183 {
2184 return BPARSER_SHORT_NAME;
2185 }
2186
2187 if(!_resize_ro_array(MParser))
2188 {
2190 }
2191
2192 void* _Name = MParser->MallocF( strlen(Name) + 1 );
2193
2194 if (!_Name)
2195 {
2196 return BPARSER_MALLOC_ERROR;
2197 }
2198
2199 char Error = 0;
2200 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
2201
2202 if (!_Temp)
2203 {
2204 return Error;
2205 }
2206
2207 _Temp->Name = (char*)_Name;
2208 strcpy(_Temp->Name, Name);
2209 _Temp->Type = BPARSER_DOUBLE;
2210 MParser->Seek.Pos = 0;
2211 MParser->Seek.Mode = BPARSER_NO_SEEK;
2212 return 1;
2213}
2214
2215char bparser_read_unix_time(bparser_parser_t* MParser, const char* Name)
2216{
2217 if (!MParser)
2218 {
2219 return BPARSER_NO_PARSER;
2220 }
2221
2222 if (!Name)
2223 {
2224 return BPARSER_NULL_NAME;
2225 }
2226
2227 if (strlen(Name) < 1)
2228 {
2229 return BPARSER_SHORT_NAME;
2230 }
2231
2232 if(!_resize_ro_array(MParser))
2233 {
2235 }
2236
2237 void* _Name = MParser->MallocF( strlen(Name) + 1 );
2238
2239 if (!_Name)
2240 {
2241 return BPARSER_MALLOC_ERROR;
2242 }
2243
2244 char Error = 0;
2245 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, Name, &Error);
2246
2247 if (!_Temp)
2248 {
2249 return Error;
2250 }
2251
2252 _Temp->Name = (char*)_Name;
2253 strcpy(_Temp->Name, Name);
2254 _Temp->Type = BPARSER_UNIX_TIME;
2255 MParser->Seek.Pos = 0;
2256 MParser->Seek.Mode = BPARSER_NO_SEEK;
2257 return 1;
2258}
2259
2260char _bparser_bool(bparser_parser_t* MParser, const char* Name, size_t A)
2261{
2262 if (!MParser)
2263 {
2264 return BPARSER_NO_PARSER;
2265 }
2266
2267 if (!Name)
2268 {
2269 return BPARSER_NULL_NAME;
2270 }
2271
2272 if (strlen(Name) < 1)
2273 {
2274 return BPARSER_SHORT_NAME;
2275 }
2276
2277 if (A == 0)
2278 {
2280 }
2281
2282 for (size_t U = 0; U < A; U++)
2283 {
2284 for (size_t W = 0; W < 8; W++)
2285 {
2286 if(!_resize_ro_array(MParser))
2287 {
2289 }
2290
2291 void* _Name = MParser->MallocF( strlen(Name) + 16 );
2292
2293 if (!_Name)
2294 {
2295 return BPARSER_MALLOC_ERROR;
2296 }
2297
2298 if(sprintf((char*)_Name, "%s[%lld]", Name, W + (U * 8)) < 0)
2299 {
2300 return BPARSER_SPRINTF_ERROR;
2301 }
2302
2303 char Error = 0;
2304 bparser_read_t* _Temp = _get_read_rule_to_set(MParser, _Name, &Error);
2305
2306 if (!_Temp)
2307 {
2308 return Error;
2309 }
2310
2311 _Temp->Name = _Name;
2312 _Temp->Type = BPARSER_BOOLS;
2313 _Temp->Parameter1 = W;
2314 MParser->Seek.Pos = 0;
2315 MParser->Seek.Mode = BPARSER_NO_SEEK;
2316 }
2317 }
2318
2319 return 1;
2320}
2321
2322char bparser_read_8_booleans(bparser_parser_t* MParser, const char* Name)
2323{
2324 return _bparser_bool(MParser, Name, 1);
2325}
2326
2327char bparser_read_16_booleans(bparser_parser_t* MParser, const char* Name)
2328{
2329 return _bparser_bool(MParser, Name, 2);
2330}
2331
2332char bparser_read_24_booleans(bparser_parser_t* MParser, const char* Name)
2333{
2334 return _bparser_bool(MParser, Name, 3);
2335}
2336
2337char bparser_read_32_booleans(bparser_parser_t* MParser, const char* Name)
2338{
2339 return _bparser_bool(MParser, Name, 4);
2340}
2341
2342char bparser_read_64_booleans(bparser_parser_t* MParser, const char* Name)
2343{
2344 return _bparser_bool(MParser, Name, 8);
2345}
2346
2347char bparser_read_128_booleans(bparser_parser_t* MParser, const char* Name)
2348{
2349 return _bparser_bool(MParser, Name, 16);
2350}
2351
2352char _bparser_default_hfunc(uint8_t Boolean)
2353{
2354 return (Boolean > 0);
2355}
2356
2358{
2359 if (!MParser)
2360 {
2361 return BPARSER_NO_PARSER;
2362 }
2363
2364 if(!_resize_ro_array(MParser))
2365 {
2367 }
2368
2369 bparser_read_t* _Temp = _init_read(MParser);
2370 _Temp->Type = BPARSER_BOOL_RUN;
2371
2372 _Temp->Parameter3.HFunc = (HFunc) ? HFunc : _bparser_default_hfunc;
2373 if (Func == NULL)
2374 {
2376 }
2377 _Temp->Parameter3.Func = Func;
2378
2379 MParser->Seek.Pos = 0;
2380 MParser->Seek.Mode = BPARSER_NO_SEEK;
2381 MParser->ReadOrderLength++;
2382 return 1;
2383}
2384
2385void _utf8_get_length(const uint8_t* Data, size_t* Chars, size_t* LengthInBytes, size_t FixedLen)
2386{
2387 size_t Pos = 0;
2388 size_t Char = 0;
2389
2390 while (Char < FixedLen)
2391 {
2392 uint8_t Curr = *(Data + Pos);
2393
2394 if ( Curr == 0 )
2395 {
2396 *LengthInBytes += 1;
2397 break;
2398 }
2399
2400 if ( Curr <= 127 )
2401 {
2402 // byte starts with 0, which means no further bytes are read
2403 Pos += 1;
2404 *LengthInBytes += 1;
2405 }
2406 else if ( Curr >= 192 && Curr <= 223 )
2407 {
2408 // byte starts with 110, which means the UTF8 char is encoded in 2 bytes
2409 Pos += 2;
2410 *LengthInBytes += 2;
2411 }
2412 else if ( Curr >= 224 && Curr <= 239 )
2413 {
2414 // byte starts with 1110, which means the UTF8 char is encoded in 3 bytes
2415 Pos += 3;
2416 *LengthInBytes += 3;
2417 }
2418 else if ( Curr >= 240 && Curr <= 247 )
2419 {
2420 // byte starts with 11110, which means the UTF8 char is encoded in 4 bytes
2421 Pos += 4;
2422 *LengthInBytes += 4;
2423 }
2424
2425 if (Chars)
2426 {
2427 (*Chars) += 1;
2428 }
2429
2430 Char++;
2431 }
2432}
2433
2434uint32_t _utf8_read(const uint8_t* Data, size_t* Offset)
2435{
2436 uint8_t First = *(Data);
2437
2438 if ( First >= 128 && First <= 191 )
2439 {
2440 // Continuation byte at the beginning, abort
2441 (*Offset)++;
2442 return 0xFFFD;
2443 }
2444
2445 if ( First <= 127 )
2446 {
2447 // byte starts with 0, which means no further bytes are read
2448 (*Offset)++;
2449 return (uint32_t)First;
2450 }
2451
2452 uint8_t Second = *(Data + 1);
2453
2454 if ( First >= 192 && First <= 223 )
2455 {
2456 // byte starts with 110, which means the UTF8 char is encoded in 2 bytes
2457
2458 // Check overlong
2459 if ( (First == 0xC0 || First == 0xC1) && Second < 0xA0)
2460 {
2461 return 0xFFFD;
2462 }
2463
2464 if ( Second >= 128 && Second <= 191 )
2465 {
2466 // Second byte starts with bits 10, continue
2467 (*Offset) += 2;
2468 uint32_t _1 = (((uint32_t)First) & 31) << 6;
2469 uint32_t _2 = ((uint32_t)Second) & 63;
2470 uint32_t _F = (_1 | _2);
2471
2472 // utf16 surrogate range
2473 if (_F >= 0xD800 && _F <= 0xDFFF)
2474 {
2475 return 0xFFFD;
2476 }
2477
2478 return _F;
2479 }
2480 else
2481 {
2482 (*Offset) += 2;
2483 return 0xFFFD;
2484 }
2485 }
2486
2487 uint8_t Third = *(Data + 2);
2488
2489 if ( First >= 224 && First <= 239 )
2490 {
2491 // byte starts with 1110, which means the UTF8 char is encoded in 3 bytes
2492
2493 // Check overlong
2494 if ( First == 0xE0 && Second < 0xA0 )
2495 {
2496 return 0xFFFD;
2497 }
2498
2499 (*Offset) += 3;
2500 if ( Second < 128 || Second > 191 )
2501 {
2502 return 0xFFFD;
2503 }
2504 if ( Third < 128 || Third > 191 )
2505 {
2506 return 0xFFFD;
2507 }
2508 // `Second` and `Third` bytes are valid continuation bytes
2509 uint32_t _1 = (((uint32_t)First) & 15) << 12;
2510 uint32_t _2 = (((uint32_t)Second) & 63) << 6;
2511 uint32_t _3 = ((uint32_t)Third) & 63;
2512 return (_1 | _2 | _3);
2513 }
2514
2515 uint8_t Fourth = *(Data + 3);
2516
2517 if ( First >= 240 && First <= 247 )
2518 {
2519 // byte starts with 11110, which means the UTF8 char is encoded in 4 bytes
2520
2521 // Check if less than 0x90 because
2522 // hello
2523 // i've been waiting here for you
2524 // everlong (encoding)
2525 if (First == 0xF0 && Second < 0x90)
2526 {
2527 return 0xFFFD;
2528 }
2529
2530 (*Offset) += 4;
2531 if ( Second < 128 || Second > 191 )
2532 {
2533 return 0xFFFD;
2534 }
2535 if ( Third < 128 || Third > 191 )
2536 {
2537 return 0xFFFD;
2538 }
2539 if ( Fourth < 128 || Fourth > 191 )
2540 {
2541 return 0xFFFD;
2542 }
2543 // `Second` and `Third` and `Fourth` bytes are valid continuation bytes, proceed
2544 uint32_t _1 = (((uint32_t)First) & 7) << 18;
2545 uint32_t _2 = (((uint32_t)Second) & 63) << 12;
2546 uint32_t _3 = (((uint32_t)Third) & 63) << 6;
2547 uint32_t _4 = ((uint32_t)Fourth) & 63;
2548 uint32_t _F = (_1 | _2 | _3 | _4);
2549
2550 if (_F > 0x10FFFF)
2551 {
2552 return 0xFFFD;
2553 }
2554
2555 return _F;
2556 }
2557
2558 (*Offset)++;
2559 return 0xFFFD;
2560}
2561
2562char bparser_read(bparser_parser_t* MParser, uint8_t* Data, size_t Size)
2563{
2564 if (!MParser)
2565 {
2566 return BPARSER_NO_PARSER;
2567 }
2568
2569 if (!Data)
2570 {
2571 return BPARSER_NULL_DATA;
2572 }
2573
2574 if (Size == 0)
2575 {
2577 }
2578
2579 bparser_destroy_data(MParser->Data, MParser->DataCount, MParser->FreeF);
2580 MParser->Data = NULL;
2581
2582 void* _DataPtr = MParser->MallocF( sizeof(bparser_data_t) * MParser->ReadOrderLength );
2583
2584 if (!_DataPtr)
2585 {
2586 return BPARSER_MALLOC_ERROR;
2587 }
2588
2589 memset(_DataPtr, 0, sizeof(bparser_data_t) * MParser->ReadOrderLength);
2590 MParser->Data = (bparser_data_t*)_DataPtr;
2591 MParser->DataCount = MParser->ReadOrderLength;
2592 MParser->Seek = (bparser_seek_data_t){0, BPARSER_NO_SEEK};
2593 size_t Pos = 0;
2594
2595 for (size_t ReadPos = 0; ReadPos < MParser->ReadOrderLength; ReadPos++)
2596 {
2597 uint8_t ReadType = MParser->ReadOrder[ReadPos].Type;
2598 size_t Parameter1 = MParser->ReadOrder[ReadPos].Parameter1;
2599 bparser_bytes_f Parameter2 = MParser->ReadOrder[ReadPos].Parameter2;
2600 uint8_t Endianess = MParser->ReadOrder[ReadPos].Endian;
2601 bparser_bool_funcs_t* Parameter3 = &( MParser->ReadOrder[ReadPos].Parameter3 );
2602 bparser_seek_data_t* SeekData = &( MParser->ReadOrder[ReadPos].Seek );
2603 bparser_bytes_seq_f Parameter4 = MParser->ReadOrder[ReadPos].Parameter4;
2604
2605 MParser->Data[ReadPos].Name = NULL;
2606 MParser->Data[ReadPos].Type = 0;
2607 MParser->Data[ReadPos].DataPtr = NULL;
2608 MParser->Data[ReadPos].NBytesLength = 0;
2609
2610 if (SeekData->Mode == BPARSER_SEEK_TO)
2611 {
2612 Pos = SeekData->Pos;
2613 }
2614 else if (SeekData->Mode == BPARSER_SEEK_FORWARD)
2615 {
2616 Pos += SeekData->Pos;
2617 }
2618 else if (SeekData->Mode == BPARSER_SEEK_BACKWARD)
2619 {
2620 if (SeekData->Pos > Pos)
2621 {
2623 }
2624 Pos -= SeekData->Pos;
2625 }
2626 else if (SeekData->Mode == BPARSER_SEEK_FROM_END)
2627 {
2628 if ( ((int64_t)Size) - ((int64_t)SeekData->Pos + 1) < 0 )
2629 {
2631 }
2632 Pos = Size - (SeekData->Pos + 1);
2633 }
2634
2635 if (Pos >= Size)
2636 {
2637 return BPARSER_EOF_ERROR;
2638 }
2639
2640 void* _DataTypePtr = NULL;
2641
2642 if (ReadType == BPARSER_UINT8 || ReadType == BPARSER_INT8)
2643 {
2644 _DataTypePtr = MParser->MallocF(1);
2645
2646 if (!_DataTypePtr)
2647 {
2648 return BPARSER_MALLOC_ERROR;
2649 }
2650
2651 uint8_t* _Temp = (uint8_t*)_DataTypePtr;
2652 *_Temp = *(Data + Pos);
2653 MParser->Data[ReadPos].DataPtr = (void*)_Temp;
2654 Pos += 1;
2655 }
2656 else if (ReadType == BPARSER_UINT16 || ReadType == BPARSER_INT16)
2657 {
2658 _DataTypePtr = MParser->MallocF(2);
2659
2660 if (!_DataTypePtr)
2661 {
2662 return BPARSER_MALLOC_ERROR;
2663 }
2664
2665 uint16_t* _Temp = (uint16_t*)_DataTypePtr;
2666 uint16_t B1 = *(Data + Pos);
2667 uint16_t B2 = *(Data + Pos + 1);
2668
2669 if (Endianess == BPARSER_BIG_ENDIAN)
2670 {
2671 *_Temp = (B1 << 8) + B2;
2672 }
2673 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2674 {
2675 *_Temp = (B2 << 8) + B1;
2676 }
2677 else
2678 {
2680 }
2681
2682 MParser->Data[ReadPos].DataPtr = (void*)_Temp;
2683 Pos += 2;
2684 }
2685 else if (ReadType == BPARSER_UINT32 || ReadType == BPARSER_INT32)
2686 {
2687 _DataTypePtr = MParser->MallocF(4);
2688
2689 if (!_DataTypePtr)
2690 {
2691 return BPARSER_MALLOC_ERROR;
2692 }
2693
2694 uint32_t* _Temp = (uint32_t*)_DataTypePtr;
2695 uint32_t B1 = *(Data + Pos);
2696 uint32_t B2 = *(Data + Pos + 1);
2697 uint32_t B3 = *(Data + Pos + 2);
2698 uint32_t B4 = *(Data + Pos + 3);
2699
2700 if (Endianess == BPARSER_BIG_ENDIAN)
2701 {
2702 *_Temp = (B1 << 24) + (B2 << 16) + (B3 << 8) + B4;
2703 }
2704 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2705 {
2706 *_Temp = (B4 << 24) + (B3 << 16) + (B2 << 8) + B1;
2707 }
2708 else
2709 {
2711 }
2712
2713 MParser->Data[ReadPos].DataPtr = (void*)_Temp;
2714 Pos += 4;
2715 }
2716 else if (ReadType == BPARSER_UINT64 || ReadType == BPARSER_INT64)
2717 {
2718 _DataTypePtr = MParser->MallocF(8);
2719
2720 if (!_DataTypePtr)
2721 {
2722 return BPARSER_MALLOC_ERROR;
2723 }
2724
2725 uint64_t* _Temp = (uint64_t*)_DataTypePtr;
2726 uint64_t B1 = *(Data + Pos);
2727 uint64_t B2 = *(Data + Pos + 1);
2728 uint64_t B3 = *(Data + Pos + 2);
2729 uint64_t B4 = *(Data + Pos + 3);
2730 uint64_t B5 = *(Data + Pos + 4);
2731 uint64_t B6 = *(Data + Pos + 5);
2732 uint64_t B7 = *(Data + Pos + 6);
2733 uint64_t B8 = *(Data + Pos + 7);
2734
2735 if (Endianess == BPARSER_BIG_ENDIAN)
2736 {
2737 *_Temp = (B1 << 56) + (B2 << 48) + (B3 << 40) + (B4 << 32) + (B5 << 24) + (B6 << 16) + (B7 << 8) + B8;
2738 }
2739 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2740 {
2741 *_Temp = (B8 << 56) + (B7 << 48) + (B6 << 40) + (B5 << 32) + (B4 << 24) + (B3 << 16) + (B2 << 8) + B1;
2742 }
2743 else
2744 {
2746 }
2747
2748 MParser->Data[ReadPos].DataPtr = (void*)_Temp;
2749 Pos += 8;
2750 }
2751 else if (ReadType == BPARSER_UINT128 || ReadType == BPARSER_INT128)
2752 {
2753 _DataTypePtr = MParser->MallocF(16);
2754
2755 if (!_DataTypePtr)
2756 {
2757 return BPARSER_MALLOC_ERROR;
2758 }
2759
2760 uint64_t _1 = 0;
2761 uint64_t _2 = 0;
2762
2763 uint64_t B1 = *(Data + Pos);
2764 uint64_t B2 = *(Data + Pos + 1);
2765 uint64_t B3 = *(Data + Pos + 2);
2766 uint64_t B4 = *(Data + Pos + 3);
2767 uint64_t B5 = *(Data + Pos + 4);
2768 uint64_t B6 = *(Data + Pos + 5);
2769 uint64_t B7 = *(Data + Pos + 6);
2770 uint64_t B8 = *(Data + Pos + 7);
2771 uint64_t B9 = *(Data + Pos + 8); // 8 as in, size of uint64 in bytes
2772 uint64_t B10 = *(Data + Pos + 8 + 1);
2773 uint64_t B11 = *(Data + Pos + 8 + 2);
2774 uint64_t B12 = *(Data + Pos + 8 + 3);
2775 uint64_t B13 = *(Data + Pos + 8 + 4);
2776 uint64_t B14 = *(Data + Pos + 8 + 5);
2777 uint64_t B15 = *(Data + Pos + 8 + 6);
2778 uint64_t B16 = *(Data + Pos + 8 + 7);
2779
2780 if (Endianess == BPARSER_BIG_ENDIAN)
2781 {
2782 _1 = (B1 << 56) + (B2 << 48) + (B3 << 40) + (B4 << 32) + (B5 << 24) + (B6 << 16) + (B7 << 8) + B8;
2783 _2 = (B9 << 56) + (B10 << 48) + (B11 << 40) + (B12 << 32) + (B13 << 24) + (B14 << 16) + (B15 << 8) + B16;
2784 }
2785 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2786 {
2787 _1 = (B16 << 56) + (B15 << 48) + (B14 << 40) + (B13 << 32) + (B12 << 24) + (B11 << 16) + (B10 << 8) + B9;
2788 _2 = (B8 << 56) + (B7 << 48) + (B6 << 40) + (B5 << 32) + (B4 << 24) + (B3 << 16) + (B2 << 8) + B1;
2789 }
2790 else
2791 {
2793 }
2794
2795 memcpy(((uint64_t*)_DataTypePtr), &_1, 8);
2796 memcpy(((uint64_t*)_DataTypePtr) + 1, &_2, 8);
2797
2798 MParser->Data[ReadPos].DataPtr = (void*)_DataTypePtr;
2799 Pos += 16;
2800 }
2801 else if (ReadType == BPARSER_STR || ReadType == BPARSER_UTF8_STR)
2802 {
2803 size_t Length = strlen( (const char*)(Data + Pos) ) + 1;
2804
2805 _DataTypePtr = MParser->CallocF(Length, 1);
2806
2807 if (!_DataTypePtr)
2808 {
2809 return BPARSER_CALLOC_ERROR;
2810 }
2811
2812 strcpy(_DataTypePtr, (const char*)(Data + Pos));
2813
2814 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2815 Pos += Length;
2816 }
2817 else if (ReadType == BPARSER_UNICODE_FROM_UTF8_STR || ReadType == BPARSER_UNICODE_FROM_UTF8_F_STR)
2818 {
2819 size_t LengthInBytes = 0;
2820 size_t Chars = 0;
2821
2822 _utf8_get_length(Data + Pos, &Chars, &LengthInBytes, (ReadType == BPARSER_UNICODE_FROM_UTF8_F_STR) ? Parameter1 : UINT64_MAX);
2823
2824 _DataTypePtr = MParser->CallocF(Chars + 1, sizeof(uint32_t));
2825 // Chars + 1 because of that extra null char
2826
2827 if (!_DataTypePtr)
2828 {
2829 return BPARSER_CALLOC_ERROR;
2830 }
2831
2832 uint32_t* String = (uint32_t*)_DataTypePtr;
2833
2834 size_t Offset = 0;
2835 for (size_t Char = 0; Char < Chars; Char++)
2836 {
2837 String[Char] = _utf8_read(Data + Pos + Offset, &Offset);
2838 }
2839
2840 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2841 Pos += LengthInBytes;
2842 }
2843 else if (ReadType == BPARSER_FIXED_STR)
2844 {
2845 void* _DataTypePtr = MParser->CallocF(Parameter1 + 1, 1);
2846 memcpy(_DataTypePtr, Data + Pos, Parameter1);
2847 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2848 Pos += Parameter1;
2849 }
2850 else if (ReadType == BPARSER_UTF8_F_STR)
2851 {
2852 size_t Bytes = 0;
2853 _utf8_get_length(Data + Pos, NULL, &Bytes, Parameter1);
2854 void* _DataTypePtr = MParser->CallocF(Bytes + 1, 1);
2855 memcpy(_DataTypePtr, Data + Pos, Bytes);
2856 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2857 Pos += Bytes;
2858 }
2859 else if (ReadType == BPARSER_N_BYTES)
2860 {
2861 void* _DataTypePtr = MParser->CallocF(Parameter1, 1);
2862
2863 if (!_DataTypePtr)
2864 {
2865 return BPARSER_CALLOC_ERROR;
2866 }
2867
2868 uint8_t* Bytes = (uint8_t*)_DataTypePtr;
2869 memcpy(Bytes, Data + Pos, Parameter1); // how was this uncaught for so long?
2870 // is supposed to be Data + Pos, not just Data!
2871
2872 if (Parameter2)
2873 {
2874 ((bparser_bytes_f)Parameter2)(MParser, Bytes, Parameter1);
2875 MParser->Data[ReadPos].DataPtr = NULL;
2876 MParser->FreeF(_DataTypePtr); // oops
2877 }
2878 else if (Parameter4)
2879 {
2880 for (size_t I = 0; I < Parameter1; I++)
2881 {
2882 ((bparser_bytes_seq_f)Parameter4)(MParser, Bytes[I], I);
2883 }
2884 MParser->Data[ReadPos].DataPtr = NULL;
2885 MParser->FreeF(_DataTypePtr); // oops
2886 }
2887 else
2888 {
2889 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2890 MParser->Data[ReadPos].NBytesLength = Parameter1;
2891 }
2892
2893 Pos += Parameter1;
2894 }
2895 else if (ReadType == BPARSER_FLOAT)
2896 {
2897 _DataTypePtr = MParser->MallocF(4);
2898
2899 if (!_DataTypePtr)
2900 {
2901 return BPARSER_MALLOC_ERROR;
2902 }
2903
2904 uint32_t Temp = 0;
2905 uint32_t B1 = *(Data + Pos);
2906 uint32_t B2 = *(Data + Pos + 1);
2907 uint32_t B3 = *(Data + Pos + 2);
2908 uint32_t B4 = *(Data + Pos + 3);
2909
2910 if (Endianess == BPARSER_BIG_ENDIAN)
2911 {
2912 Temp = (B1 << 24) + (B2 << 16) + (B3 << 8) + B4;
2913 }
2914 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2915 {
2916 Temp = (B4 << 24) + (B3 << 16) + (B2 << 8) + B1;
2917 }
2918 else
2919 {
2921 }
2922
2923 memcpy(_DataTypePtr, &Temp, 4);
2924
2925 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2926 Pos += 4;
2927 }
2928 else if (ReadType == BPARSER_DOUBLE)
2929 {
2930 _DataTypePtr = MParser->MallocF(8);
2931
2932 if (!_DataTypePtr)
2933 {
2934 return BPARSER_MALLOC_ERROR;
2935 }
2936
2937 uint64_t Temp = 0;
2938 uint64_t B1 = *(Data + Pos);
2939 uint64_t B2 = *(Data + Pos + 1);
2940 uint64_t B3 = *(Data + Pos + 2);
2941 uint64_t B4 = *(Data + Pos + 3);
2942 uint64_t B5 = *(Data + Pos + 4);
2943 uint64_t B6 = *(Data + Pos + 5);
2944 uint64_t B7 = *(Data + Pos + 6);
2945 uint64_t B8 = *(Data + Pos + 7);
2946
2947 if (Endianess == BPARSER_BIG_ENDIAN)
2948 {
2949 Temp = (B1 << 56) + (B2 << 48) + (B3 << 40) + (B4 << 32) + (B5 << 24) + (B6 << 16) + (B7 << 8) + B8;
2950 }
2951 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2952 {
2953 Temp = (B8 << 56) + (B7 << 48) + (B6 << 40) + (B5 << 32) + (B4 << 24) + (B3 << 16) + (B2 << 8) + B1;
2954 }
2955 else
2956 {
2958 }
2959
2960 memcpy(_DataTypePtr, &Temp, 8);
2961
2962 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
2963 Pos += 8;
2964 }
2965 else if (ReadType == BPARSER_UNIX_TIME)
2966 {
2967 _DataTypePtr = MParser->MallocF( sizeof(time_t) );
2968
2969 if (!_DataTypePtr)
2970 {
2971 return BPARSER_MALLOC_ERROR;
2972 }
2973
2974 time_t* Temp = (time_t*)_DataTypePtr;
2975 uint32_t B1 = *(Data + Pos);
2976 uint32_t B2 = *(Data + Pos + 1);
2977 uint32_t B3 = *(Data + Pos + 2);
2978 uint32_t B4 = *(Data + Pos + 3);
2979
2980 if (Endianess == BPARSER_BIG_ENDIAN)
2981 {
2982 *Temp = (B1 << 24) + (B2 << 16) + (B3 << 8) + B4;
2983 }
2984 else if (Endianess == BPARSER_LITTLE_ENDIAN)
2985 {
2986 *Temp = (B4 << 24) + (B3 << 16) + (B2 << 8) + B1;
2987 }
2988 else
2989 {
2991 }
2992
2993 MParser->Data[ReadPos].DataPtr = (void*)Temp;
2994 Pos += 4;
2995 }
2996 else if (ReadType == BPARSER_UINT24 || ReadType == BPARSER_INT24)
2997 {
2998 _DataTypePtr = MParser->MallocF(4);
2999
3000 if (!_DataTypePtr)
3001 {
3002 return BPARSER_MALLOC_ERROR;
3003 }
3004
3005 uint32_t* _Temp = (uint32_t*)_DataTypePtr;
3006 uint32_t B1 = *(Data + Pos);
3007 uint32_t B2 = *(Data + Pos + 1);
3008 uint32_t B3 = *(Data + Pos + 2);
3009
3010 if (Endianess == BPARSER_BIG_ENDIAN)
3011 {
3012 *_Temp = (B1 << 16) + (B2 << 8) + B3;
3013 }
3014 else if (Endianess == BPARSER_LITTLE_ENDIAN)
3015 {
3016 *_Temp = (B3 << 16) + (B2 << 8) + B1;
3017 }
3018 else
3019 {
3021 }
3022
3023 if (ReadType == BPARSER_INT24 && (*_Temp) > 0x800000)
3024 {
3025 *_Temp -= (0x1000000);
3026 }
3027
3028 MParser->Data[ReadPos].DataPtr = (void*)_Temp;
3029 Pos += 3;
3030 }
3031 else if (ReadType == BPARSER_BOOLS)
3032 {
3033 _DataTypePtr = MParser->MallocF(1);
3034
3035 if (!_DataTypePtr)
3036 {
3037 return BPARSER_MALLOC_ERROR;
3038 }
3039
3040 if (*(Data + Pos) & (1 << (7 - Parameter1)))
3041 {
3042 *((uint8_t*)_DataTypePtr) = 1;
3043 }
3044 else
3045 {
3046 *((uint8_t*)_DataTypePtr) = 0;
3047 }
3048
3049 MParser->Data[ReadPos].DataPtr = _DataTypePtr;
3050
3051 if (Parameter1 == 7)
3052 {
3053 Pos += 1;
3054 }
3055 }
3056 else if (ReadType == BPARSER_BOOL_RUN)
3057 {
3058 if ( Parameter3->HFunc(*(Data + Pos)) )
3059 {
3060 Parameter3->Func(MParser);
3061 }
3062 Pos += 1;
3063 }
3064 else
3065 {
3067 }
3068
3069 if (MParser->ReadOrder[ReadPos].Name)
3070 {
3071 void* _Name = MParser->MallocF(strlen(MParser->ReadOrder[ReadPos].Name) + 1);
3072
3073 if (!_Name)
3074 {
3075 return BPARSER_MALLOC_ERROR;
3076 }
3077
3078 MParser->Data[ReadPos].Name = (char*)_Name;
3079 strcpy(MParser->Data[ReadPos].Name, MParser->ReadOrder[ReadPos].Name);
3080 }
3081 else
3082 {
3083 MParser->Data[ReadPos].Name = NULL;
3084 }
3085
3086 MParser->Data[ReadPos].Type = ReadType;
3087 }
3088
3089 return 1;
3090}
3091
3092char bparser_fread(bparser_parser_t* MParser, const char* Filename)
3093{
3094 if (!MParser)
3095 {
3096 return BPARSER_NO_PARSER;
3097 }
3098
3099 if (!Filename)
3100 {
3101 return BPARSER_NULL_NAME;
3102 }
3103
3104 if (strlen(Filename) < 1)
3105 {
3106 return BPARSER_SHORT_NAME;
3107 }
3108
3109 FILE* _F = fopen(Filename, "rb");
3110
3111 if (!_F)
3112 {
3113 return BPARSER_FOPEN_ERROR;
3114 }
3115
3116 if( fseek(_F, 0, SEEK_END) )
3117 {
3118 fclose(_F);
3119 return BPARSER_FSEEK_ERROR;
3120 }
3121
3122 long Size = ftell(_F);
3123 if (Size == 0)
3124 {
3125 return BPARSER_EMPTY_FILE;
3126 }
3127 rewind(_F);
3128
3129 if (Size < 0)
3130 {
3131 fclose(_F);
3132 return BPARSER_FTELL_ERROR;
3133 }
3134
3135 uint8_t* Data = calloc(Size + 1, 1);
3136
3137 if (!Data)
3138 {
3139 fclose(_F);
3140 return BPARSER_CALLOC_ERROR;
3141 }
3142
3143 if ( fread(Data, 1, Size, _F) != Size )
3144 {
3145 fclose(_F);
3146
3147 if (feof(_F)) { return BPARSER_FREAD_EOF_ERROR; }
3148 else if (ferror(_F)) { return BPARSER_FREAD_ERROR; }
3149 else { return BPARSER_FREAD_UNKNOWN_ERROR; }
3150 }
3151
3152 fclose(_F);
3153 char Res = bparser_read(MParser, Data, Size);
3154 free(Data);
3155 return Res;
3156}
3157
3158char bparser_check_magic_num(const uint8_t* Data, const uint8_t* MagicNum, size_t Length)
3159{
3160 if ( (!Data) || (!MagicNum) )
3161 {
3162 return BPARSER_NULL_DATA;
3163 }
3164
3165 if (Length < 1)
3166 {
3167 return BPARSER_ZERO_LENGTH;
3168 }
3169
3170 for (size_t N = 0; N < Length; N++)
3171 {
3172 if ( *(Data + N) != *(MagicNum + N) )
3173 {
3174 return 0;
3175 }
3176 }
3177 return 1;
3178}
3179
3180char bparser_check_magic_num_char(const uint8_t* Data, const char* MagicNum, size_t Length)
3181{
3182 if ( (!Data) || (!MagicNum) )
3183 {
3184 return BPARSER_NULL_DATA;
3185 }
3186
3187 if (Length < 1)
3188 {
3189 return BPARSER_ZERO_LENGTH;
3190 }
3191
3192 for (size_t N = 0; N < Length; N++)
3193 {
3194 if ( *(Data + N) != (uint8_t)(*(MagicNum + N)) )
3195 {
3196 return 0;
3197 }
3198 }
3199 return 1;
3200}
3201
3202void* bparser_get(const bparser_parser_t* MParser, const char* Name)
3203{
3204 if (!MParser)
3205 {
3206 return NULL;
3207 }
3208
3209 if (!Name)
3210 {
3211 return NULL;
3212 }
3213
3214 if (strlen(Name) < 1)
3215 {
3216 return NULL;
3217 }
3218
3219 for (size_t D = 0; D < MParser->ReadOrderLength; D++)
3220 {
3221 if (!MParser->Data[D].Name)
3222 {
3223 continue;
3224 }
3225
3226 if ( strcmp(MParser->Data[D].Name, Name) == 0 )
3227 {
3228 return MParser->Data[D].DataPtr;
3229 }
3230 }
3231 return NULL;
3232}
3233
3235{
3236 if (!MParser) { return; }
3237 MParser->Endian = BPARSER_LITTLE_ENDIAN;
3238}
3239
3241{
3242 if (!MParser) { return; }
3243 MParser->Endian = BPARSER_BIG_ENDIAN;
3244}
3245
3246char bparser_seek(bparser_parser_t* MParser, uint64_t Pos, uint8_t Mode)
3247{
3248 if (!MParser)
3249 {
3250 return BPARSER_NO_PARSER;
3251 }
3252
3253 if (Mode >= BPARSER_SEEK_TO && Mode < BPARSER_NO_SEEK)
3254 {
3255 MParser->Seek.Pos = Pos;
3256 MParser->Seek.Mode = Mode;
3257 return 1;
3258 }
3259
3260 return BPARSER_SEEK_ERROR;
3261}
3262
3263char bparser_rewind(bparser_parser_t* MParser)
3264{
3265 return bparser_seek(MParser, 0, BPARSER_SEEK_TO);
3266}
3267
3268char bparser_unwind(bparser_parser_t* MParser)
3269{
3270 return bparser_seek(MParser, 0, BPARSER_SEEK_FROM_END);
3271}
3272
3273const char* bparser_error_str(char Error)
3274{
3275 switch (Error)
3276 {
3278 return "realloc (or user-defined function replacing realloc) has errored out and caused the Read Order array not to resize.";
3279
3281 return "malloc (or user-defined function replacing malloc) has returned NULLPTR.";
3282
3284 return "Either bparser_read_bytes_and_run or bparser_read_bool_and_run have been called with their Func parameter set to NULLPTR.";
3285
3287 return "When reading array, 2D array or bool array, sprintf has errored out when creating name string.";
3288
3290 return "Seeking backward caused the position marker to go into negative range.";
3291
3293 return "Seeking from the end caused the position marker to go into negative range.";
3294
3295 case BPARSER_EOF_ERROR:
3296 return "Position marker reached EOF when there was more data instructed to read.";
3297
3299 return "calloc (or user-defined function replacing calloc) has returned NULLPTR.";
3300
3302 return "When reading an integer, unknown endianess was detected.";
3303
3305 return "Unknown read type.";
3306
3308 return "In bparser_fread(), fopen() errored out.";
3309
3311 return "In bparser_fread(), fseek() errored out.";
3312
3314 return "In bparser_fread(), ftell() errored out.";
3315
3317 return "In bparser_fread(), fread() errored out on an unexpected EOF.";
3318
3319 case BPARSER_SEEK_ERROR:
3320 return "Seeking mode out of range.";
3321
3323 return "bparser_read_integral() was supplied with an illegal integral type.";
3324
3326 return "bparser_parser_set_realloc_method() was supplied with an illegal realloc method (neither BPARSER_REALLOC_METHOD_PLUS or BPARSER_REALLOC_METHOD_MULT).";
3327
3329 return "bparser_parser_set_realloc_method() was supplied with a realloc factor smaller than 1.0.";
3330
3332 return "bparser_rename() cannot find data object of name supplied by `Src` argument.";
3333
3335 return "bparser_init() has failed when called in bparser_parser_deep_copy().";
3336
3338 return "bparser_read_order_deep_copy() has failed when called in bparser_parser_deep_copy().";
3339
3340 case BPARSER_NULL_NAME:
3341 return "A string argument of the function is a NULL pointer.";
3342
3343 case BPARSER_SHORT_NAME:
3344 return "A string argument of the function is too short.";
3345
3346 case BPARSER_NO_PARSER:
3347 return "A function that changes or reads a parser instance, has no parser instance specified.";
3348
3350 return "`Size`, `Length`, `Count` or the like are too low.";
3351
3353 return "A read rule that was about to be created was given a name that is in use by another read rule. Use `bparser_set_override()` to disable this error.";
3354
3356 return "Argument `A` of `_bparser_bool` is zero.";
3357
3359 return "bparser_data_deep_copy() has failed when called in bparser_parser_deep_copy().";
3360
3362 return "In bparser_fread(), fread() errored out.";
3363
3365 return "In bparser_fread(), fread() returned an unknown error...";
3366
3367 case BPARSER_NULL_DATA:
3368 return "bparser_read() argument `Data` is NULL!";
3369
3371 return "bparser_read() argument `Size` is zero!";
3372
3373 case BPARSER_EMPTY_FILE:
3374 return "bparser_fread() tried to read an empty file!";
3375
3377 return "bparser_set_override() has been specified with an unknown override method.";
3378
3379 default:
3380 return "No error.";
3381 }
3382}
3383
3384size_t bparser_get_data_count(const bparser_parser_t* MParser)
3385{
3386 return (MParser->DataCount);
3387}
3388
3390{
3391 return (MParser->ReadOrderLength);
3392}
3393
3394bparser_read_t* bparser_get_read_order_at(const bparser_parser_t* MParser, size_t Index)
3395{
3396 if (!MParser)
3397 {
3398 return NULL;
3399 }
3400
3401 if (Index > MParser->ReadOrderLength)
3402 {
3403 return NULL;
3404 }
3405 return &(MParser->ReadOrder[Index]);
3406}
3407
3409{
3410 if (!MParser)
3411 {
3412 return NULL;
3413 }
3414
3415 bparser_read_t* _D = Dest;
3416
3417 if (!Dest)
3418 {
3419 void* Placeholder = MParser->CallocF(MParser->ReadOrderMaxLength, sizeof(bparser_read_t));
3420
3421 if (!Placeholder)
3422 {
3423 return NULL;
3424 }
3425
3426 _D = (bparser_read_t*)Placeholder;
3427 }
3428
3429 memcpy(_D, MParser->ReadOrder, sizeof(bparser_read_t) * MParser->ReadOrderLength);
3430 return _D;
3431}
3432
3434{
3435 if (!MParser)
3436 {
3437 return NULL;
3438 }
3439
3440 bparser_read_t* _D = Dest;
3441
3442 if (!Dest)
3443 {
3444 void* Placeholder = MParser->CallocF(MParser->ReadOrderMaxLength, sizeof(bparser_read_t));
3445
3446 if (!Placeholder)
3447 {
3448 return NULL;
3449 }
3450
3451 _D = (bparser_read_t*)Placeholder;
3452 }
3453
3454 for (size_t Indx = 0; Indx < MParser->ReadOrderLength; Indx++)
3455 {
3456 // Copy name
3457 if (MParser->ReadOrder[Indx].Name)
3458 {
3459 _D[Indx].Name = MParser->CallocF(strlen(MParser->ReadOrder[Indx].Name) + 1, sizeof(char));
3460 strcpy(_D[Indx].Name, MParser->ReadOrder[Indx].Name);
3461 }
3462 else
3463 {
3464 _D[Indx].Name = NULL;
3465 }
3466
3467 // Literals / func ptrs
3468 _D[Indx].Endian = MParser->ReadOrder[Indx].Endian;
3469 _D[Indx].Type = MParser->ReadOrder[Indx].Type;
3470 _D[Indx].Seek = MParser->ReadOrder[Indx].Seek;
3471 _D[Indx].Parameter1 = MParser->ReadOrder[Indx].Parameter1;
3472 _D[Indx].Parameter2 = MParser->ReadOrder[Indx].Parameter2;
3473 _D[Indx].Parameter3 = MParser->ReadOrder[Indx].Parameter3;
3474 _D[Indx].Parameter4 = MParser->ReadOrder[Indx].Parameter4;
3475 }
3476
3477 return _D;
3478}
3479
3480char bparser_parser_set_realloc_method(bparser_parser_t* MParser, double N, uint8_t ReallocMethod)
3481{
3482 if (!MParser)
3483 {
3484 return BPARSER_NO_PARSER;
3485 }
3486
3487 if ((ReallocMethod != BPARSER_REALLOC_METHOD_PLUS) && (ReallocMethod != BPARSER_REALLOC_METHOD_MULT))
3488 {
3490 }
3491
3492 if (N < 1.0)
3493 {
3495 }
3496
3497 MParser->ReallocFactor = N;
3498 MParser->ReallocMethod = ReallocMethod;
3499 return 1;
3500}
3501
3503{
3504 if (!MParser)
3505 {
3506 return NULL;
3507 }
3508
3509 bparser_data_t* _D = Dest;
3510 if (!Dest)
3511 {
3512 void* Placeholder = MParser->CallocF(MParser->DataCount, sizeof(bparser_data_t));
3513
3514 if (!Placeholder)
3515 {
3516 return NULL;
3517 }
3518
3519 _D = (bparser_data_t*)Placeholder;
3520 }
3521 memcpy(_D, MParser->Data, sizeof(bparser_data_t) * MParser->DataCount);
3522 return _D;
3523}
3524
3525void* bparser_data_deep_copy(const bparser_parser_t* MParser, bparser_data_t* Dest, char* Failure)
3526{
3527 char _Temp = 0;
3528 char* _F = (Failure) ? Failure : &_Temp;
3529
3530 if (!MParser)
3531 {
3532 *_F = BPARSER_NO_PARSER;
3533 return NULL;
3534 }
3535
3536 bparser_data_t* _D = Dest;
3537
3538 if (!Dest)
3539 {
3540 void* Placeholder = MParser->CallocF(MParser->DataCount, sizeof(bparser_data_t));
3541
3542 if (!Placeholder)
3543 {
3545 return NULL;
3546 }
3547
3548 _D = (bparser_data_t*)Placeholder;
3549 }
3550
3551 for (size_t Indx = 0; Indx < bparser_get_data_count(MParser); Indx++)
3552 {
3553 // Copy name
3554 _D[Indx].Name = MParser->CallocF(strlen(MParser->Data[Indx].Name) + 1, sizeof(char));
3555
3556 if (!(_D[Indx].Name))
3557 {
3559 return NULL;
3560 }
3561
3562 strcpy(_D[Indx].Name, MParser->Data[Indx].Name);
3563
3564 _D[Indx].Type = MParser->Data[Indx].Type;
3565 _D[Indx].NBytesLength = 0;
3566
3567 // Now for the tiresome type checking...
3568 switch (_D[Indx].Type)
3569 {
3570 case BPARSER_UINT8:
3571 case BPARSER_INT8:
3572 {
3573 _D[Indx].DataPtr = MParser->MallocF(1);
3574 if (!(_D[Indx].DataPtr))
3575 {
3577 return NULL;
3578 }
3579 *((uint8_t*)_D[Indx].DataPtr) = *((uint8_t*)MParser->Data[Indx].DataPtr);
3580 }
3581 break;
3582
3583 case BPARSER_UINT16:
3584 case BPARSER_INT16:
3585 {
3586 _D[Indx].DataPtr = MParser->MallocF(2);
3587 if (!(_D[Indx].DataPtr))
3588 {
3590 return NULL;
3591 }
3592 *((uint16_t*)_D[Indx].DataPtr) = *((uint16_t*)MParser->Data[Indx].DataPtr);
3593 }
3594 break;
3595
3596 case BPARSER_UINT32:
3597 case BPARSER_INT32:
3598 {
3599 _D[Indx].DataPtr = MParser->MallocF(4);
3600 if (!(_D[Indx].DataPtr))
3601 {
3603 return NULL;
3604 }
3605 *((uint32_t*)_D[Indx].DataPtr) = *((uint32_t*)MParser->Data[Indx].DataPtr);
3606 }
3607 break;
3608
3609 case BPARSER_UINT64:
3610 case BPARSER_INT64:
3611 {
3612 _D[Indx].DataPtr = MParser->MallocF(8);
3613 if (!(_D[Indx].DataPtr))
3614 {
3616 return NULL;
3617 }
3618 *((uint64_t*)_D[Indx].DataPtr) = *((uint64_t*)MParser->Data[Indx].DataPtr);
3619 }
3620 break;
3621
3622 case BPARSER_UINT128:
3623 case BPARSER_INT128:
3624 {
3625 _D[Indx].DataPtr = MParser->MallocF(16);
3626 if (!(_D[Indx].DataPtr))
3627 {
3629 return NULL;
3630 }
3631 *((uint64_t*)_D[Indx].DataPtr) = *((uint64_t*)MParser->Data[Indx].DataPtr);
3632 *((uint64_t*)_D[Indx].DataPtr + 1) = *((uint64_t*)MParser->Data[Indx].DataPtr + 1);
3633 }
3634 break;
3635
3636 case BPARSER_STR:
3637 case BPARSER_UTF8_STR:
3638 case BPARSER_FIXED_STR:
3639 case BPARSER_UTF8_F_STR:
3640 {
3641 _D[Indx].DataPtr = MParser->CallocF(strlen( (const char*)MParser->Data[Indx].DataPtr ) + 1, 1);
3642 if (!(_D[Indx].DataPtr))
3643 {
3645 return NULL;
3646 }
3647 strcpy((char*)_D[Indx].DataPtr, (const char*)MParser->Data[Indx].DataPtr);
3648 }
3649 break;
3650
3653 {
3654 size_t Count = 0;
3655
3656 // this will count all the uint32's including the null one
3657 do
3658 {
3659 Count++;
3660 }
3661 while ( *(((uint32_t*)(MParser->Data[Indx].DataPtr) + Count)) != 0 );
3662
3663 _D[Indx].DataPtr = MParser->CallocF(Count, sizeof(uint32_t));
3664 if (!(_D[Indx].DataPtr))
3665 {
3667 return NULL;
3668 }
3669 memcpy(_D[Indx].DataPtr, MParser->Data[Indx].DataPtr, sizeof(uint32_t) * Count);
3670 }
3671 break;
3672
3673 case BPARSER_N_BYTES:
3674 {
3675 _D[Indx].DataPtr = MParser->CallocF(MParser->Data[Indx].NBytesLength, 1);
3676 if (!(_D[Indx].DataPtr))
3677 {
3679 return NULL;
3680 }
3681 memcpy(_D[Indx].DataPtr, MParser->Data[Indx].DataPtr, MParser->Data[Indx].NBytesLength);
3682 _D[Indx].NBytesLength = MParser->Data[Indx].NBytesLength;
3683 }
3684 break;
3685
3686 case BPARSER_FLOAT:
3687 {
3688 _D[Indx].DataPtr = MParser->MallocF(4);
3689 if (!(_D[Indx].DataPtr))
3690 {
3692 return NULL;
3693 }
3694 *((float*)_D[Indx].DataPtr) = *((float*)MParser->Data[Indx].DataPtr);
3695 }
3696 break;
3697
3698 case BPARSER_DOUBLE:
3699 {
3700 _D[Indx].DataPtr = MParser->MallocF(8);
3701 if (!(_D[Indx].DataPtr))
3702 {
3704 return NULL;
3705 }
3706 *((double*)_D[Indx].DataPtr) = *((double*)MParser->Data[Indx].DataPtr);
3707 }
3708 break;
3709
3710 case BPARSER_UNIX_TIME:
3711 {
3712 _D[Indx].DataPtr = MParser->MallocF( sizeof(time_t) );
3713 if (!(_D[Indx].DataPtr))
3714 {
3716 return NULL;
3717 }
3718 *((time_t*)_D[Indx].DataPtr) = *((time_t*)MParser->Data[Indx].DataPtr);
3719 }
3720 break;
3721
3722 case BPARSER_UINT24:
3723 case BPARSER_INT24:
3724 {
3725 _D[Indx].DataPtr = MParser->MallocF(4);
3726 if (!(_D[Indx].DataPtr))
3727 {
3729 return NULL;
3730 }
3731 *((uint32_t*)_D[Indx].DataPtr) = *((uint32_t*)MParser->Data[Indx].DataPtr);
3732 }
3733 break;
3734
3735 case BPARSER_BOOLS:
3736 {
3737 _D[Indx].DataPtr = MParser->MallocF(1);
3738 if (!(_D[Indx].DataPtr))
3739 {
3741 return NULL;
3742 }
3743 *((uint8_t*)_D[Indx].DataPtr) = *((uint8_t*)MParser->Data[Indx].DataPtr);
3744 }
3745 break;
3746
3747 default:
3748 {
3750 return NULL;
3751 }
3752 }
3753 }
3754
3755 return _D;
3756}
3757
3758const bparser_data_t* bparser_get_data_at(const bparser_parser_t* MParser, size_t Indx)
3759{
3760 if (!MParser)
3761 {
3762 return NULL;
3763 }
3764
3765 if (Indx >= bparser_get_data_count(MParser))
3766 {
3767 return NULL;
3768 }
3769
3770 return &(MParser->Data[Indx]);
3771}
3772
3773void bparser_destroy_read_order(bparser_read_t* Array, size_t Length, bparser_free_like_f FreeCallback)
3774{
3775 bparser_free_like_f FreeF = (FreeCallback) ? FreeCallback : free;
3776
3777 if (Array)
3778 {
3779 for (size_t I = 0; I < Length; I++)
3780 {
3781 if (Array[I].Name)
3782 {
3783 FreeF(Array[I].Name);
3784 }
3785 }
3786 FreeF(Array);
3787 }
3788}
3789
3790void bparser_destroy_data(bparser_data_t* Array, size_t Length, bparser_free_like_f FreeCallback)
3791{
3792 bparser_free_like_f FreeF = (FreeCallback) ? FreeCallback : free;
3793
3794 if (Array)
3795 {
3796 for (size_t D = 0; D < Length; D++)
3797 {
3798 // holy shit horrible bug there was (don't check commit history)
3799 if (Array[D].DataPtr)
3800 {
3801 FreeF(Array[D].DataPtr);
3802 }
3803
3804 if (Array[D].Name)
3805 {
3806 FreeF(Array[D].Name);
3807 }
3808 }
3809 FreeF(Array);
3810 }
3811}
3812
3813char bparser_rename(bparser_parser_t* MParser, const char* Src, const char* New)
3814{
3815 if (!MParser)
3816 {
3817 return BPARSER_NO_PARSER;
3818 }
3819
3820 if ( (!Src) || (!New) )
3821 {
3822 return BPARSER_NULL_NAME;
3823 }
3824
3825 if ( (strlen(Src) < 1) || (strlen(New) < 1) )
3826 {
3827 return BPARSER_SHORT_NAME;
3828 }
3829
3830 for (size_t D = 0; D < MParser->ReadOrderLength; D++)
3831 {
3832 if ( strcmp(MParser->Data[D].Name, Src) == 0 )
3833 {
3834 void* _Temp = MParser->CallocF( strlen(New) + 1, 1 );
3835
3836 if (!_Temp)
3837 {
3838 return BPARSER_CALLOC_ERROR;
3839 }
3840
3841 // if calloc was to fail, we still preserve the name
3842 if (MParser->Data[D].Name)
3843 {
3844 MParser->FreeF(MParser->Data[D].Name);
3845 }
3846
3847 MParser->Data[D].Name = _Temp;
3848
3849 strcpy(MParser->Data[D].Name, New);
3850 return 1;
3851 }
3852 }
3854}
3855
3857{
3858 if (!Src)
3859 {
3860 return NULL;
3861 }
3862
3863 bparser_parser_t* _Dest = Dest;
3864
3865 if (!_Dest)
3866 {
3867 _Dest = bparser_init(Src->MallocF, Src->CallocF, Src->ReallocF, Src->FreeF);
3868
3869 if (!_Dest)
3870 {
3871 // check again, if _Dest is NULL, bparser_init failed
3872 return NULL;
3873 }
3874 }
3875
3876 memcpy(_Dest, Src, sizeof(bparser_parser_t));
3877 return _Dest;
3878}
3879
3880void* bparser_parser_deep_copy(bparser_parser_t* Src, bparser_parser_t* Dest, char* Error)
3881{
3882 char _Temp = 0;
3883 char* _E = (Error) ? Error : &_Temp;
3884
3885 if (!Src)
3886 {
3887 *_E = BPARSER_NO_PARSER;
3888 return NULL;
3889 }
3890
3891 // Before overwritting, make sure to free the pointer...
3892 if (Dest)
3893 {
3894 if (Dest->ReadOrder)
3895 {
3896 bparser_destroy_read_order(Dest->ReadOrder, Dest->ReadOrderMaxLength, Dest->FreeF);
3897 }
3898
3899 if (Dest->Data)
3900 {
3901 bparser_destroy_data(Dest->Data, Dest->DataCount, Dest->FreeF);
3902 }
3903 }
3904
3905 // deep copying a parser instance is essentially just shallow copying
3906 // and then deeply copying the RO and data array
3908
3909 if (!_Dest)
3910 {
3912 return NULL;
3913 }
3914
3915 if (Src->ReadOrder)
3916 {
3918 if ( !_RO )
3919 {
3921 return NULL;
3922 }
3923
3924 _Dest->ReadOrder = _RO;
3925 _Dest->ReadOrderLength = Src->ReadOrderLength;
3926 _Dest->ReadOrderMaxLength = Src->ReadOrderMaxLength;
3927 }
3928
3929 if (Src->Data)
3930 {
3932 if ( !_D )
3933 {
3935 return NULL;
3936 }
3937
3938 _Dest->Data = _D;
3939 _Dest->DataCount = Src->DataCount;
3940 }
3941
3942 return _Dest;
3943}
3944
3946{
3947 // THIS IS SUPPOSED TO BE && NOT || YOU STUPID FUCK @norbcodes
3948 if (Src && Dest)
3949 {
3950 if (Dest)
3951 {
3952 if (Dest->ReadOrder)
3953 {
3954 bparser_destroy_read_order(Dest->ReadOrder, Dest->ReadOrderMaxLength, Dest->FreeF);
3955 }
3956
3957 if (Dest->Data)
3958 {
3959 bparser_destroy_data(Dest->Data, Dest->DataCount, Dest->FreeF);
3960 }
3961 }
3962
3963 return memmove(Dest, Src, sizeof(bparser_parser_t));
3964 }
3965 return NULL;
3966}
3967
3968char bparser_set_override(bparser_parser_t* MParser, uint8_t Override)
3969{
3970 if (!MParser)
3971 {
3972 return BPARSER_NO_PARSER;
3973 }
3974
3975 if (Override >= BPARSER_OVERRIDE_ERROR && Override <= BPARSER_OVERRIDE_DO_NOTHING)
3976 {
3977 MParser->Override = Override;
3978 }
3979 else
3980 {
3981 return BPARSER_BAD_OVERRIDE;
3982 }
3983
3984 return 1;
3985}
3986
3987#endif // BPARSER_IMPLEMENTATION
3988
3989#undef _BPARSER_INIT_ARGS
3990
3991#ifdef __cplusplus
3992}
3993#endif // __cplusplus
3994
3995#endif // BPARSER_PARSER
#define BPARSER_SEEK_FROM_END
Enum value used to specify seeking from the end.
Definition parser.h:271
char bparser_read_null_str(bparser_parser_t *MParser, const char *Name)
Read a null-terminated string from the file.
#define BPARSER_FOPEN_ERROR
Error code for when fopen errors out in bparser_fread.
Definition parser.h:368
char bparser_read_utf8_null_str(bparser_parser_t *MParser, const char *Name)
Read an UTF8 null terminated string from the file.
char bparser_read_8_booleans(bparser_parser_t *MParser, const char *Name)
Read 8bits from the file and store each bit as boolean.
char bparser_check_magic_num(const uint8_t *Data, const uint8_t *MagicNum, size_t Length)
Check magic number.
void(* bparser_free_like_f)(void *ptr)
Shortcut for a custom callback for a free-like function.
Definition parser.h:811
size_t bparser_get_data_count(const bparser_parser_t *MParser)
Get how many data entries have been stored so far.
const char * bparser_error_str(char Error)
Translate BPARSER_*_ERROR codes into strings.
void * bparser_data_shallow_copy(const bparser_parser_t *MParser, bparser_data_t *Dest)
Shallowly copies the data array.
char bparser_read_utf8_fixed_len_str(bparser_parser_t *MParser, const char *Name, size_t Length)
Read an UTF8 string of specified length from the file.
#define BPARSER_OVERRIDE_SKIP
When a read rule has a name that is already used by some other, simply do not create it.
Definition parser.h:693
#define BPARSER_BAD_OVERRIDE
Error code for when bparser_set_override has been specified with an unknown override method.
Definition parser.h:537
char bparser_read_fixed_len_str(bparser_parser_t *MParser, const char *Name, size_t Length)
Read a string of specified length from the file.
void *(* bparser_malloc_like_f)(size_t size)
Shortcut for a custom callback for a malloc-like function.
Definition parser.h:817
#define BPARSER_UTF8_STR
Enum value for reading a null-terminated UTF8 string.
Definition parser.h:213
#define BPARSER_BOOLS
Enum value for a boolean array.
Definition parser.h:229
#define BPARSER_UINT8
Enum value for an uint8 value.
Definition parser.h:53
char bparser_read_2d_array(bparser_parser_t *MParser, const char *Name, size_t Cols, size_t Rows, uint8_t ItemType)
Read a 2D array of size NxM items of specified type.
#define BPARSER_SHORT_NAME
Error code for when a bparser_read_* function recieves a string shorter than 1 char for its' Name arg...
Definition parser.h:459
const bparser_data_t * bparser_get_data_at(const bparser_parser_t *MParser, size_t Indx)
Get the raw bparser_data_t object from the parser.
#define BPARSER_UTF8_F_STR
Enum value for reading a fixed length UTF8 string.
Definition parser.h:221
char bparser_read_unicode_from_utf8_fixed_str(bparser_parser_t *MParser, const char *Name, size_t Length)
Read unicode codepoints (uint32) from an UTF8 string of specified length from the file.
void(* bparser_bool_f)(BPARSER_BOOL_F_ARGS)
Shortcut for the function that runs as specified by bparser_read_bool_and_run.
Definition parser.h:738
#define BPARSER_NOTHING_TO_PARSE
Error code for when bparser_read's Size arg is zero.
Definition parser.h:523
void * bparser_set_free(bparser_parser_t *MParser, bparser_free_like_f Free)
Override the free function used internally by the parser.
#define BPARSER_BAD_REALLOC_METHOD
Error code for when bparser_parser_set_realloc_method is fed a bad / unknown realloc method.
Definition parser.h:417
#define BPARSER_NULL_NAME
Error code for when a bparser_read_* function recieves a NULL pointer for its' Name argument.
Definition parser.h:452
#define BPARSER_NO_BOOLS_TO_READ
Error code for _bparser_bool's argument A is equal to zero.
Definition parser.h:488
#define BPARSER_SPRINTF_ERROR
Error code for when sprintf fails.
Definition parser.h:310
#define BPARSER_BIG_ENDIAN
Used internally, tells us to read an integer in big endian mode.
Definition parser.h:558
#define BPARSER_NO_FUNC_PASSED
Error code for when bparser_read_bytes_and_run or bparser_read_bool_and_run have no function given.
Definition parser.h:303
#define BPARSER_UNKNOWN_READ_TYPE
Error code for when the parser encounters an unknown data type.
Definition parser.h:361
bparser_parser_t * bparser_init(bparser_malloc_like_f MallocLikeFunc, bparser_calloc_like_f CallocLikeFunc, bparser_realloc_like_f ReallocLikeFunc, bparser_free_like_f FreeLikeFunc)
Create a new parser instance.
#define BPARSER_UINT128
Enum value for an uint128 value.
Definition parser.h:93
#define BPARSER_BAD_INTEGRAL_TYPE
Error code for bparser_read_integral was given a bad integral type.
Definition parser.h:409
char bparser_read_array(bparser_parser_t *MParser, const char *Name, size_t Items, uint8_t ItemType)
Read an array with N items of specified type.
void bparser_use_little_endian(bparser_parser_t *MParser)
Instruct the parser to use little endian when reading multibyte integral values.
char bparser_check_magic_num_char(const uint8_t *Data, const char *MagicNum, size_t Length)
Check magic number.
#define BPARSER_OVERRIDE_DO_NOTHING
When a read rule has a name that is already used by some other, the library does not care....
Definition parser.h:700
void * bparser_set_realloc(bparser_parser_t *MParser, bparser_realloc_like_f Realloc)
Override the realloc function used internally by the parser.
#define BPARSER_SEEK_TO
Enum value used to specify seeking to a certain position.
Definition parser.h:247
#define BPARSER_NO_SEEK
Internal value, don't use.
Definition parser.h:278
char bparser_unwind(bparser_parser_t *MParser)
Seek to the end of the file.
void * bparser_data_deep_copy(const bparser_parser_t *MParser, bparser_data_t *Dest, char *Failure)
Deeply copies the data array.
void bparser_use_big_endian(bparser_parser_t *MParser)
Instruct the parser to use big endian when reading multibyte integral values.
#define BPARSER_N_BYTES
Enum value for a byte array.
Definition parser.h:157
#define BPARSER_NAME_IS_NOT_UNIQUE
Error code for when a name of a read rule that is about to be created is not unique.
Definition parser.h:481
#define BPARSER_UINT24
Enum value for an uint24 value.
Definition parser.h:69
#define BPARSER_FIXED_STR
Enum value for a string datatype of a set length.
Definition parser.h:165
#define BPARSER_SEEK_ERROR
Error code for when an invalid seeking mode is specified to bparser_seek.
Definition parser.h:401
#define BPARSER_REALLOC_FACTOR_TOO_SMALL
Error code for when bparser_parser_set_realloc_method N arg is smaller than 1.
Definition parser.h:424
char bparser_read_64_booleans(bparser_parser_t *MParser, const char *Name)
Read 64bits from the file and store each bit as boolean.
#define BPARSER_LITTLE_ENDIAN
Used internally, tells us to read an integer in little endian mode.
Definition parser.h:551
char bparser_rename(bparser_parser_t *MParser, const char *Src, const char *New)
Renames an object in the data array.
#define BPARSER_BACKWARD_SEEK_ERROR
Error code for when seeking backwards beyond the beginning of the file.
Definition parser.h:319
char bparser_set_override(bparser_parser_t *MParser, uint8_t Override)
Set custom override behaviour.
char bparser_read_bytes_and_run_sequential(bparser_parser_t *MParser, size_t NBytes, bparser_bytes_seq_f Func)
Read a specified amount of bytes and run a function on each one.
#define BPARSER_RO_ARRAY_ERROR
Error code for when reallocating the RO array failed.
Definition parser.h:289
#define BPARSER_UINT16
Enum value for an uint16 value.
Definition parser.h:61
void * bparser_read_order_shallow_copy(const bparser_parser_t *MParser, bparser_read_t *Dest)
Shallowly copies the RO array.
#define BPARSER_INT16
Enum value for an int16 value.
Definition parser.h:109
#define BPARSER_EMPTY_FILE
Error code for when bparser_fread tries to read an empty file.
Definition parser.h:530
void bparser_shallow_destroy(bparser_parser_t *MParser)
Destroys a shallow copy of a parser instance.
char bparser_read(bparser_parser_t *MParser, uint8_t *Data, size_t Size)
Read data and parse according to saved rules.
#define BPARSER_RENAME_NOT_FOUND
Error code for when bparser_rename cannot find a data object of name Src.
Definition parser.h:431
#define BPARSER_UNKNOWN_ENDIAN
Error code for when the parser encounters an unknown endianess.
Definition parser.h:352
#define BPARSER_FREAD_UNKNOWN_ERROR
Error code for when fread() errored out with an unknown reason.
Definition parser.h:509
#define BPARSER_BOOL_HANDLER_F_ARGS
Shortcut for argument list of bparser_bool_handler_f function. You can use it while making your own.
Definition parser.h:719
void bparser_destroy(bparser_parser_t *MParser)
Destroy a parser instance.
#define BPARSER_FREAD_EOF_ERROR
Error code for when fread errors out on an unexpected EOF in bparser_fread.
Definition parser.h:393
#define BPARSER_SEEK_BACKWARD
Enum value used to specify seeking backward.
Definition parser.h:263
char bparser_read_24_booleans(bparser_parser_t *MParser, const char *Name)
Read 24bits from the file and store each bit as boolean.
#define BPARSER_UINT32
Enum value for an uint32 value.
Definition parser.h:77
void * bparser_parser_deep_copy(bparser_parser_t *Src, bparser_parser_t *Dest, char *Error)
Deeply copies Src parser instance into Dest parser instance.
#define BPARSER_INT32
Enum value for an int32 value.
Definition parser.h:125
char(* bparser_bool_handler_f)(BPARSER_BOOL_HANDLER_F_ARGS)
Shortcut for handler function that controls whether bparser_bool_f runs.
Definition parser.h:732
void(* bparser_bytes_seq_f)(BPARSER_BYTES_SEQ_F_ARGS)
Shortcut for the function to run as specified by bparser_read_bytes_and_run_sequential.
Definition parser.h:712
#define BPARSER_REALLOC_METHOD_MULT
Tells the parser to calculate new size to realloc as: new_size = old_size * N a.k....
Definition parser.h:579
char bparser_read_bytes_and_run(bparser_parser_t *MParser, size_t NBytes, bparser_bytes_f Func)
Read a specified amount of bytes from the file and run a function on them.
#define BPARSER_PDC_INIT_ERROR
Error code for when bparser_init fails from within bparser_parser_deep_copy.
Definition parser.h:438
char bparser_read_unicode_from_utf8_null_str(bparser_parser_t *MParser, const char *Name)
Read unicode codepoints (uint32) from an UTF8 null terminated string from the file.
#define BPARSER_FTELL_ERROR
Error code for when ftell errors out in bparser_fread.
Definition parser.h:386
#define BPARSER_BOOL_F_ARGS
Shortcut for argument list of bparser_bool_f function. You can use it while making your own.
Definition parser.h:726
char bparser_read_unix_time(bparser_parser_t *MParser, const char *Name)
Read a 4 byte unsigned integer number and parse it as an Unix timestamp.
#define BPARSER_FSEEK_ERROR
Error code for when fseek errors out in bparser_fread.
Definition parser.h:377
#define BPARSER_FREAD_ERROR
Error code for when fread() errored out.
Definition parser.h:502
void * bparser_parser_shallow_copy(bparser_parser_t *Src, bparser_parser_t *Dest)
Shallowly copies Src parser instance into Dest parser instance.
char bparser_read_float(bparser_parser_t *MParser, const char *Name)
Read a float from the file.
char bparser_seek(bparser_parser_t *MParser, uint64_t Pos, uint8_t Mode)
Seek to a position in the file.
char bparser_fread(bparser_parser_t *MParser, const char *Filename)
Read file and parse according to saved rules.
#define BPARSER_UINT64
Enum value for an uint64 value.
Definition parser.h:85
void * bparser_set_calloc(bparser_parser_t *MParser, bparser_calloc_like_f Calloc)
Override the calloc function used internally by the parser.
void bparser_destroy_data(bparser_data_t *Array, size_t Length, bparser_free_like_f FreeCallback)
Unallocates a data (bparser_data_t) array.
#define BPARSER_CALLOC_ERROR
Error code for when calloc fails.
Definition parser.h:343
#define BPARSER_DOUBLE
Enum value for a double datatype.
Definition parser.h:181
void * bparser_set_malloc(bparser_parser_t *MParser, bparser_malloc_like_f Malloc)
Override the malloc function used internally by the parser.
void * bparser_read_order_deep_copy(const bparser_parser_t *MParser, bparser_read_t *Dest)
Deeply copies the RO array.
void *(* bparser_realloc_like_f)(void *ptr, size_t size)
Shortcut for a custom callback for a realloc-like function.
Definition parser.h:823
void *(* bparser_calloc_like_f)(size_t num, size_t size)
Shortcut for a custom callback for a calloc-like function.
Definition parser.h:805
char bparser_read_32_booleans(bparser_parser_t *MParser, const char *Name)
Read 32bits from the file and store each bit as boolean.
#define BPARSER_OVERRIDE_TRUE
When a read rule has a name that is already used by some other, override it.
Definition parser.h:686
char bparser_rewind(bparser_parser_t *MParser)
Seek to beginning of the file.
char bparser_read_double(bparser_parser_t *MParser, const char *Name)
Read a double from the file.
void bparser_destroy_read_order(bparser_read_t *Array, size_t Length, bparser_free_like_f FreeCallback)
Unallocates a read order (bparser_read_t) array.
#define BPARSER_ZERO_LENGTH
Error code for when an argument passed to a function is not of satisfactory length.
Definition parser.h:473
size_t bparser_get_read_order_count(const bparser_parser_t *MParser)
Get how many entries have been stored so far in the RO array.
#define BPARSER_PDC_RO_COPY_ERROR
Error code for when bparser_read_order_deep_copy fails from within bparser_parser_deep_copy.
Definition parser.h:445
char bparser_read_bytes(bparser_parser_t *MParser, const char *Name, size_t NBytes)
Read a specified amount of bytes from the file and store as a simple uint8 array.
char bparser_read_bool_and_run(bparser_parser_t *MParser, bparser_bool_handler_f HFunc, bparser_bool_f Func)
Read a single byte and run a function on it.
bparser_read_t * bparser_get_read_order_at(const bparser_parser_t *MParser, size_t Index)
Get an entry from RO array.
#define BPARSER_DEFAULT_ENDIAN
Use with bparser_read_integral, to use the currently set endianess of the parser.
Definition parser.h:565
#define BPARSER_NO_PARSER
Error code for when a function that changes or reads a parser instance, has no parser instance specif...
Definition parser.h:466
void * bparser_parser_move(bparser_parser_t *Src, bparser_parser_t *Dest)
Using memmove, moves a parser instance.
#define BPARSER_INT24
Enum value for an int24 value.
Definition parser.h:117
#define BPARSER_REALLOC_METHOD_PLUS
Tells the parser to calculate new size to realloc as: new_size = old_size + N.
Definition parser.h:572
char bparser_read_16_booleans(bparser_parser_t *MParser, const char *Name)
Read 16bits from the file and store each bit as boolean.
char bparser_read_integral(bparser_parser_t *MParser, const char *Name, uint8_t Type, uint8_t Endian)
Read an integral from the file.
#define BPARSER_BYTES_SEQ_F_ARGS
Shortcut for argument list of bparser_bytes_seq_f function. You can use it while making your own.
Definition parser.h:672
#define BPARSER_PDC_DATA_COPY_ERROR
Error code for when bparser_data_deep_copy fails from within bparser_parser_deep_copy.
Definition parser.h:495
#define BPARSER_UNICODE_FROM_UTF8_F_STR
Enum value for reading unicode codepoints from a fixed length UTF8 string.
Definition parser.h:205
#define BPARSER_OVERRIDE_ERROR
When a read rule has a name that is already used by some other, error out.
Definition parser.h:679
#define BPARSER_INT8
Enum value for an int8 value.
Definition parser.h:101
char bparser_parser_set_realloc_method(bparser_parser_t *MParser, double N, uint8_t ReallocMethod)
Set the realloc method.
#define BPARSER_BOOL_RUN
Enum value for reading a boolean and running a function if it's true.
Definition parser.h:237
#define BPARSER_UNICODE_FROM_UTF8_STR
Enum value for reading unicode codepoints from a null-terminated UTF8 string.
Definition parser.h:197
#define BPARSER_STR
Enum value for a string datatype.
Definition parser.h:149
#define BPARSER_SEEK_FORWARD
Enum value used to specify seeking forward.
Definition parser.h:255
#define BPARSER_SEEK_FROM_END_ERROR
Error code for when seeking from the end goes beyond the beginning of the file.
Definition parser.h:327
#define BPARSER_MALLOC_ERROR
Returned when malloc (or the user-defined function replacing malloc) fails.
Definition parser.h:296
#define BPARSER_FLOAT
Enum value for a float datatype.
Definition parser.h:173
#define BPARSER_BYTES_F_ARGS
Shortcut for argument list of bparser_bytes_f function. You can use it while making your own.
Definition parser.h:665
#define BPARSER_UNIX_TIME
Enum value for the unix timestamp.
Definition parser.h:189
#define BPARSER_INT128
Enum value for an int128 value.
Definition parser.h:141
#define BPARSER_INT64
Enum value for an int64 value.
Definition parser.h:133
#define BPARSER_NULL_DATA
Error code for when bparser_read's Data arg is null.
Definition parser.h:516
char bparser_read_128_booleans(bparser_parser_t *MParser, const char *Name)
Read 128bits from the file and store each bit as boolean.
void * bparser_get(const bparser_parser_t *MParser, const char *Name)
Get parsed data.
void(* bparser_bytes_f)(BPARSER_BYTES_F_ARGS)
Shortcut for the function to run as specified by bparser_read_bytes_and_run.
Definition parser.h:706
#define BPARSER_EOF_ERROR
Error code for when the parser reaches EOF.
Definition parser.h:335
A small struct that keeps track of the handler function and the actual function to run,...
Definition parser.h:745
Stores parsed data.
Definition parser.h:793
The parser.
Definition parser.h:832
Describes a read rule.
Definition parser.h:772
A small struct keeping track of the parsers position in the file.
Definition parser.h:756
Project version macros.