| 12 | } |
| 13 | |
| 14 | bool TextStreamPlugin::handleIncompleteComponent( |
| 15 | const std::string& buffer, size_t componentStartPos, |
| 16 | const std::string& surfaceId, const std::string& version, |
| 17 | std::vector<ProtocolStreamExtractor::ParseResult>& outResults) { |
| 18 | |
| 19 | // Condition 1: "component":"Text" has appeared |
| 20 | if (!isPartialTextComponent(buffer, componentStartPos)) { |
| 21 | return false; |
| 22 | } |
| 23 | |
| 24 | // Condition 2: "text":"... has appeared and the value string is not yet closed |
| 25 | size_t textStart = findInlineTextValueStart(buffer, componentStartPos); |
| 26 | if (textStart == std::string::npos) { |
| 27 | // "text" not found, not yet arrived, or is a data binding {"path":"..."} |
| 28 | return false; |
| 29 | } |
| 30 | |
| 31 | // Check whether the text value is already closed (no streaming needed if so) |
| 32 | size_t closePos = 0; |
| 33 | if (isStringValueClosed(buffer, textStart, closePos)) { |
| 34 | // text value is complete; let the normal logic handle it |
| 35 | return false; |
| 36 | } |
| 37 | |
| 38 | // Enter Text component streaming mode |
| 39 | _isComponentStreaming = true; |
| 40 | _componentStart = componentStartPos; |
| 41 | _textValueStart = textStart; |
| 42 | |
| 43 | // Cache the component id (raw JSON-encoded) |
| 44 | _cachedComponentId = extractRawStringValue(buffer.substr(_componentStart), "\"id\""); |
| 45 | |
| 46 | // Deliver the first partial content immediately (using the text field) |
| 47 | std::string partialJson = constructPartialJson(buffer, _componentStart, "\"}"); |
| 48 | if (!partialJson.empty()) { |
| 49 | ProtocolStreamExtractor::ParseResult result; |
| 50 | result.type = ProtocolStreamExtractor::ParseResult::Type::ComponentUpdate; |
| 51 | result.componentJson = partialJson; |
| 52 | result.surfaceId = surfaceId; |
| 53 | result.version = version; |
| 54 | outResults.emplace_back(std::move(result)); |
| 55 | } |
| 56 | |
| 57 | // Compute the end position of the sent content (accounting for trailing backslash trimming) |
| 58 | size_t trailingBackslashes = 0; |
| 59 | for (size_t i = buffer.length(); i > _textValueStart; ) { |
| 60 | i--; |
| 61 | if (buffer[i] == '\\') { |
| 62 | trailingBackslashes++; |
| 63 | } else { |
| 64 | break; |
| 65 | } |
| 66 | } |
| 67 | _lastSentContentEnd = (trailingBackslashes % 2 != 0) |
| 68 | ? buffer.length() - 1 |
| 69 | : buffer.length(); |
| 70 | |
| 71 | return true; // Plugin takes over |
no test coverage detected