* @brief Formats an array of strings, similar to the `repr` method of Python lists. * Will output an object that looks like `sz.Str(['item1', 'item2... ])`, potentially * dropping the last few entries. */
| 6682 | * dropping the last few entries. |
| 6683 | */ |
| 6684 | static PyObject *Strs_repr(Strs *self) { |
| 6685 | get_string_at_offset_t getter = str_at_offset_getter(self); |
| 6686 | if (!getter) { |
| 6687 | PyErr_SetString(PyExc_TypeError, "Unknown Strs kind"); |
| 6688 | return NULL; |
| 6689 | } |
| 6690 | |
| 6691 | char repr_buffer[1024]; |
| 6692 | sz_ptr_t repr_buffer_ptr = &repr_buffer[0]; |
| 6693 | sz_cptr_t const repr_buffer_end = repr_buffer_ptr + 1024; |
| 6694 | |
| 6695 | // Start of the array |
| 6696 | sz_copy(repr_buffer_ptr, "sz.Strs([", 9); |
| 6697 | repr_buffer_ptr += 9; |
| 6698 | |
| 6699 | sz_size_t count = Strs_len(self); |
| 6700 | PyObject *parent_string; |
| 6701 | |
| 6702 | // In the worst case, we must have enough space for `...', ...])` |
| 6703 | // That's extra 11 bytes of content. |
| 6704 | sz_cptr_t non_fitting_array_tail = "... ])"; |
| 6705 | int const non_fitting_array_tail_length = 6; |
| 6706 | |
| 6707 | // If the whole string doesn't fit, even before the `non_fitting_array_tail` tail, |
| 6708 | // we need to add `, '` separator of 3 bytes. |
| 6709 | for (sz_size_t i = 0; i < count && repr_buffer_ptr + (non_fitting_array_tail_length + 3) < repr_buffer_end; i++) { |
| 6710 | sz_cptr_t cstr_start = NULL; |
| 6711 | sz_size_t cstr_length = 0; |
| 6712 | getter(self, i, count, &parent_string, &cstr_start, &cstr_length); |
| 6713 | |
| 6714 | if (i > 0) { *(repr_buffer_ptr++) = ',', *(repr_buffer_ptr++) = ' '; } |
| 6715 | |
| 6716 | // Check if the string contains valid UTF-8 |
| 6717 | int did_fit; |
| 6718 | repr_buffer_ptr = sz_utf8_valid(cstr_start, cstr_length) |
| 6719 | ? export_escaped_unquoted_to_utf8_buffer( |
| 6720 | cstr_start, cstr_length, repr_buffer_ptr, |
| 6721 | repr_buffer_end - repr_buffer_ptr - non_fitting_array_tail_length, &did_fit) |
| 6722 | : export_escaped_unquoted_to_binary_buffer( |
| 6723 | cstr_start, cstr_length, repr_buffer_ptr, |
| 6724 | repr_buffer_end - repr_buffer_ptr - non_fitting_array_tail_length, &did_fit); |
| 6725 | |
| 6726 | // If it didn't fit, let's put an ellipsis |
| 6727 | if (!did_fit) { |
| 6728 | sz_copy(repr_buffer_ptr, non_fitting_array_tail, non_fitting_array_tail_length); |
| 6729 | repr_buffer_ptr += non_fitting_array_tail_length; |
| 6730 | return PyUnicode_FromStringAndSize(repr_buffer, repr_buffer_ptr - repr_buffer); |
| 6731 | } |
| 6732 | } |
| 6733 | |
| 6734 | // Close the array |
| 6735 | *(repr_buffer_ptr++) = ']', *(repr_buffer_ptr++) = ')'; |
| 6736 | return PyUnicode_FromStringAndSize(repr_buffer, repr_buffer_ptr - repr_buffer); |
| 6737 | } |
| 6738 | |
| 6739 | /** |
| 6740 | * @brief Array to string conversion method, that concatenates all the strings in the array. |
nothing calls this directly
no test coverage detected
searching dependent graphs…