* @brief Exports a string to a UTF-8 buffer, escaping single quotes. * @param[in] cstr The input string to export. * @param[in] cstr_length The length of the input string. * @param[out] buffer The output buffer to write to. * @param[in] buffer_length The size of the output buffer. * @param[out] did_fit Populated with 1 if the string is fully exported, 0 if it didn't fit, -1 if invalid U
| 6579 | * @return Pointer to the end of the written data in the buffer, or buffer position where error occurred. |
| 6580 | */ |
| 6581 | sz_cptr_t export_escaped_unquoted_to_utf8_buffer(sz_cptr_t cstr, sz_size_t cstr_length, // |
| 6582 | sz_ptr_t buffer, sz_size_t buffer_length, // |
| 6583 | int *did_fit) { |
| 6584 | sz_cptr_t const cstr_end = cstr + cstr_length; |
| 6585 | sz_ptr_t buffer_ptr = buffer; |
| 6586 | *did_fit = 1; |
| 6587 | |
| 6588 | // Validate UTF-8 first |
| 6589 | if (!sz_utf8_valid(cstr, cstr_length)) { |
| 6590 | *did_fit = -1; // Signal UTF-8 error |
| 6591 | return buffer_ptr; |
| 6592 | } |
| 6593 | |
| 6594 | // First pass: calculate required buffer size (input already validated) |
| 6595 | sz_size_t required_bytes = 2; // Opening and closing quotes |
| 6596 | sz_cptr_t scan_ptr = cstr; |
| 6597 | while (scan_ptr < cstr_end) { |
| 6598 | sz_rune_t rune; |
| 6599 | sz_rune_length_t rune_length; |
| 6600 | sz_rune_parse(scan_ptr, &rune, &rune_length); |
| 6601 | |
| 6602 | if (rune_length == 1 && *scan_ptr == '\'') { required_bytes += 2; } // Escaped quote: \' |
| 6603 | else { required_bytes += rune_length; } // Normal rune |
| 6604 | scan_ptr += rune_length; |
| 6605 | } |
| 6606 | |
| 6607 | // Check if we have enough buffer space |
| 6608 | if (required_bytes > buffer_length) { |
| 6609 | *did_fit = 0; |
| 6610 | return buffer_ptr; |
| 6611 | } |
| 6612 | |
| 6613 | // Second pass: actually write to buffer |
| 6614 | *(buffer_ptr++) = '\''; // Opening quote |
| 6615 | |
| 6616 | while (cstr < cstr_end) { |
| 6617 | sz_rune_t rune; |
| 6618 | sz_rune_length_t rune_length; |
| 6619 | sz_rune_parse(cstr, &rune, &rune_length); |
| 6620 | |
| 6621 | if (rune_length == 1 && *cstr == '\'') { |
| 6622 | *(buffer_ptr++) = '\\'; |
| 6623 | *(buffer_ptr++) = '\''; |
| 6624 | } |
| 6625 | else { |
| 6626 | sz_copy(buffer_ptr, cstr, rune_length); |
| 6627 | buffer_ptr += rune_length; |
| 6628 | } |
| 6629 | cstr += rune_length; |
| 6630 | } |
| 6631 | |
| 6632 | *(buffer_ptr++) = '\''; // Closing quote |
| 6633 | return buffer_ptr; |
| 6634 | } |
| 6635 | |
| 6636 | /** |
| 6637 | * @brief Exports a binary string to a buffer in Python bytes representation (b'\\x..'). |
no test coverage detected
searching dependent graphs…