| 145 | |
| 146 | |
| 147 | void cMultipartParser::Parse(const char * a_Data, size_t a_Size) |
| 148 | { |
| 149 | // Skip parsing if invalid |
| 150 | if (!m_IsValid) |
| 151 | { |
| 152 | return; |
| 153 | } |
| 154 | |
| 155 | // Append to buffer, then parse it: |
| 156 | m_IncomingData.append(a_Data, a_Size); |
| 157 | for (;;) |
| 158 | { |
| 159 | if (m_EnvelopeParser.IsInHeaders()) |
| 160 | { |
| 161 | size_t BytesConsumed = m_EnvelopeParser.Parse(m_IncomingData.data(), m_IncomingData.size()); |
| 162 | if (BytesConsumed == AString::npos) |
| 163 | { |
| 164 | m_IsValid = false; |
| 165 | return; |
| 166 | } |
| 167 | if ((BytesConsumed == a_Size) && m_EnvelopeParser.IsInHeaders()) |
| 168 | { |
| 169 | // All the incoming data has been consumed and still waiting for more |
| 170 | return; |
| 171 | } |
| 172 | m_IncomingData.erase(0, BytesConsumed); |
| 173 | } |
| 174 | |
| 175 | // Search for boundary / boundary end: |
| 176 | size_t idxBoundary = m_IncomingData.find("\r\n--"); |
| 177 | if (idxBoundary == AString::npos) |
| 178 | { |
| 179 | // Boundary string start not present, present as much data to the part callback as possible |
| 180 | if (m_IncomingData.size() > m_Boundary.size() + 8) |
| 181 | { |
| 182 | size_t BytesToReport = m_IncomingData.size() - m_Boundary.size() - 8; |
| 183 | m_Callbacks.OnPartData(m_IncomingData.data(), BytesToReport); |
| 184 | m_IncomingData.erase(0, BytesToReport); |
| 185 | } |
| 186 | return; |
| 187 | } |
| 188 | if (idxBoundary > 0) |
| 189 | { |
| 190 | m_Callbacks.OnPartData(m_IncomingData.data(), idxBoundary); |
| 191 | m_IncomingData.erase(0, idxBoundary); |
| 192 | } |
| 193 | idxBoundary = 4; |
| 194 | size_t LineEnd = m_IncomingData.find("\r\n", idxBoundary); |
| 195 | if (LineEnd == AString::npos) |
| 196 | { |
| 197 | // Not a complete line yet, present as much data to the part callback as possible |
| 198 | if (m_IncomingData.size() > m_Boundary.size() + 8) |
| 199 | { |
| 200 | size_t BytesToReport = m_IncomingData.size() - m_Boundary.size() - 8; |
| 201 | m_Callbacks.OnPartData(m_IncomingData.data(), BytesToReport); |
| 202 | m_IncomingData.erase(0, BytesToReport); |
| 203 | } |
| 204 | return; |
no test coverage detected