Skip to content

Commit ebb6769

Browse files
committed
Add streaming parsing demo
1 parent 09cb671 commit ebb6769

4 files changed

Lines changed: 127 additions & 1 deletion

File tree

.github/workflows/c-cpp.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@ jobs:
4141
working-directory: ./build
4242
run: ./demo_cpp
4343

44+
- name: Run C++ streaming demo
45+
working-directory: ./build
46+
run: ./demo_stream
47+
4448
- name: Compare demo outputs
4549
working-directory: ./build
4650
run: |

CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,15 @@ add_executable(demo_cpp
3333
demo.cpp
3434
)
3535

36+
# C++17 demo
37+
add_executable(demo_stream
38+
demo_stream.cpp
39+
)
40+
3641
# Link demo to library
3742
target_link_libraries(demo PRIVATE ini_parser)
3843
target_link_libraries(demo_cpp PRIVATE ini_parser)
44+
target_link_libraries(demo_stream PRIVATE ini_parser)
3945

4046
# Google Test configuration
4147
find_package(GTest REQUIRED)

demo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
@url github.com/diffstorm
1010
@license MIT License
1111
*/
12+
#include "ini_parser.h"
1213
#include <iostream>
1314
#include <cstring>
14-
#include "ini_parser.h"
1515

1616
int main()
1717
{

demo_stream.cpp

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
/**
2+
@brief INI Parser Library
3+
4+
A lightweight, single-header, speed and safety focused INI file parsing library written in C with C++ compatibility. Designed for simplicity and portability, this parser provides a low-footprint solution to decode INI format.
5+
6+
@date 2025-05-12
7+
@version 1.0
8+
@author Eray Ozturk | erayozturk1@gmail.com
9+
@url github.com/diffstorm
10+
@license MIT License
11+
*/
12+
#include "ini_parser.h"
13+
#include <iostream>
14+
#include <map>
15+
#include <vector>
16+
#include <cstring>
17+
18+
// Structure to collect parsing results
19+
typedef struct
20+
{
21+
std::map<std::string, std::map<std::string, std::string>> sections;
22+
std::vector<std::string> comments;
23+
std::vector<std::string> errors;
24+
std::string current_section;
25+
} ParserState;
26+
27+
// Handler function prototype
28+
bool parsing_handler(ini_eventtype_t type,
29+
const char *section,
30+
const char *key,
31+
const char *value,
32+
void *userdata);
33+
34+
int main()
35+
{
36+
const char *ini_content =
37+
"; Main configuration file\n"
38+
"[network]\n"
39+
"host = 127.0.0.1\n"
40+
"port = 8080\n"
41+
"[database]\n"
42+
"user = admin\n"
43+
"pass = secret\n"
44+
"[invalid_section\n" // Missing closing bracket
45+
"key = value\n";
46+
ParserState state;
47+
state.current_section = INI_LINE_SECTION;
48+
size_t length = strlen(ini_content);
49+
bool success = ini_parse_stream(ini_content, length, parsing_handler, &state);
50+
// Display results
51+
std::cout << "Parsing " << (success ? "completed" : "aborted") << "\n\n";
52+
std::cout << "Comments (" << state.comments.size() << "):\n";
53+
54+
for(const auto &comment : state.comments)
55+
{
56+
std::cout << " " << comment << "\n";
57+
}
58+
59+
std::cout << "\nErrors (" << state.errors.size() << "):\n";
60+
61+
for(const auto &error : state.errors)
62+
{
63+
std::cout << " " << error << "\n";
64+
}
65+
66+
std::cout << "\nParsed data:\n";
67+
68+
for(const auto& [section, values] : state.sections)
69+
{
70+
std::cout << "[" << section << "]\n";
71+
72+
for(const auto& [key, val] : values)
73+
{
74+
std::cout << " " << key << " = " << val << "\n";
75+
}
76+
}
77+
78+
return 0;
79+
}
80+
81+
bool parsing_handler(ini_eventtype_t type,
82+
const char *section,
83+
const char *key,
84+
const char *value,
85+
void *userdata)
86+
{
87+
ParserState *state = static_cast<ParserState *>(userdata);
88+
89+
switch(type)
90+
{
91+
case INI_EVENT_SECTION:
92+
state->current_section = section;
93+
state->sections[section]; // Create empty section
94+
break;
95+
96+
case INI_EVENT_KEY_VALUE:
97+
{
98+
const char *actual_section = state->current_section.c_str();
99+
state->sections[actual_section][key] = value;
100+
break;
101+
}
102+
103+
case INI_EVENT_COMMENT:
104+
state->comments.push_back(value);
105+
break;
106+
107+
case INI_EVENT_ERROR:
108+
state->errors.push_back(value);
109+
return false; // Abort parsing on first error
110+
111+
default:
112+
break;
113+
}
114+
115+
return true;
116+
}

0 commit comments

Comments
 (0)