Logo Pico-Framework A web-first embedded framework for C++
Loading...
Searching...
No Matches
ChunkedDecoder.cpp
Go to the documentation of this file.
2#include <sstream>
3
4void ChunkedDecoder::feed(const std::string& data, size_t maxLength) {
5 buffer += data;
6 parseChunks(maxLength);
7}
8
9bool ChunkedDecoder::feedToFile(const std::string& data,
10 std::function<bool(const char* data, size_t len)> writeFn,
11 size_t maxLength)
12{
13 buffer += data;
14 std::istringstream stream(buffer);
15 std::string line;
16 truncated = false;
17
18 while (std::getline(stream, line)) {
19 if (line.empty()) continue;
20
21 int chunkSize = 0;
22 std::istringstream chunkHeader(line);
23 chunkHeader >> std::hex >> chunkSize;
24
25 if (chunkSize == 0) {
26 complete = true;
27 buffer.clear();
28 return true;
29 }
30
31 if ((int)stream.rdbuf()->in_avail() < chunkSize + 2) {
32 return true; // wait for more input
33 }
34
35 char* chunkData = new char[chunkSize];
36 stream.read(chunkData, chunkSize);
37
38 size_t available = maxLength - totalDecoded;
39 size_t toWrite = std::min((size_t)chunkSize, available);
40
41 if (!writeFn(chunkData, toWrite)) {
42 delete[] chunkData;
43 return false;
44 }
45
46 delete[] chunkData;
47 totalDecoded += toWrite;
48
49 if (chunkSize > (int)available) {
50 truncated = true;
51 complete = true;
52 return true;
53 }
54
55 std::getline(stream, line); // Consume CRLF
56 }
57
58 buffer.clear();
59 return true;
60}
61
62
64 return decoded;
65}
66
68 return complete;
69}
70
71void ChunkedDecoder::parseChunks(size_t maxLength) {
72 std::istringstream stream(buffer);
73 std::string line;
74 std::string tempDecoded;
75 truncated = false;
76
77 while (std::getline(stream, line)) {
78 if (line.empty()) continue;
79
80 int chunkSize = 0;
81 std::istringstream chunkHeader(line);
82 chunkHeader >> std::hex >> chunkSize;
83
84 if (chunkSize == 0) {
85 complete = true;
86 break;
87 }
88
89 char* chunk = new char[chunkSize];
90 stream.read(chunk, chunkSize);
91
92 size_t remaining = maxLength - tempDecoded.size();
93 if (chunkSize > remaining) {
94 tempDecoded.append(chunk, remaining);
95 truncated = true;
96 delete[] chunk;
97 break;
98 }
99
100 tempDecoded.append(chunk, chunkSize);
101 delete[] chunk;
102
103 std::getline(stream, line); // Consume CRLF
104 }
105
106 decoded = std::move(tempDecoded);
107}
std::string buffer
std::string decoded
void parseChunks(size_t maxLength)
void feed(const std::string &data, size_t maxLength=MAX_HTTP_BODY_LENGTH)
std::string getDecoded()
bool isComplete() const
bool feedToFile(const std::string &data, std::function< bool(const char *data, size_t len)> writeFn, size_t maxLength=MAX_HTTP_BODY_LENGTH)
Feed data to the decoder, writing it to a file using the provided write function.