CString TextCodecGtk::encode(const UChar* characters, size_t length, UnencodableHandling handling) { if (!length) return ""; if (m_iconvEncoder == reinterpret_cast<GIConv>(-1)) createIConvEncoder(); if (m_iconvEncoder == reinterpret_cast<GIConv>(-1)) return CString(); size_t count; GOwnPtr<GError> err; GOwnPtr<char> buffer; buffer.outPtr() = g_convert_with_iconv(reinterpret_cast<const char*>(characters), length * sizeof(UChar), m_iconvEncoder, 0, &count, &err.outPtr()); if (err) { LOG_ERROR("GIConv conversion error, Code %d: \"%s\"", err->code, err->message); return CString(); } return CString(buffer.get(), count); }
CString TextCodecGtk::encode(const UChar* characters, size_t length, UnencodableHandling handling) { if (!length) return ""; if (!m_iconvEncoder) createIConvEncoder(); if (!m_iconvEncoder) { LOG_ERROR("Error creating IConv encoder even though encoding was in table."); return CString(); } gsize bytesRead = 0; gsize bytesWritten = 0; const gchar* input = reinterpret_cast<const char*>(characters); gsize inputLength = length * sizeof(UChar); gchar buffer[ConversionBufferSize]; Vector<char> result; GOwnPtr<GError> error; size_t size = 0; do { g_converter_convert(G_CONVERTER(m_iconvEncoder.get()), input, inputLength, buffer, sizeof(buffer), G_CONVERTER_INPUT_AT_END, &bytesRead, &bytesWritten, &error.outPtr()); input += bytesRead; inputLength -= bytesRead; if (bytesWritten > 0) { result.grow(size + bytesWritten); memcpy(result.data() + size, buffer, bytesWritten); size += bytesWritten; } if (error && g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_INVALID_DATA)) { UChar codePoint = reinterpret_cast<const UChar*>(input)[0]; UnencodableReplacementArray replacement; int replacementLength = TextCodec::getUnencodableReplacement(codePoint, handling, replacement); // Consume the invalid character. input += sizeof(UChar); inputLength -= sizeof(UChar); // Append replacement string to result buffer. result.grow(size + replacementLength); memcpy(result.data() + size, replacement, replacementLength); size += replacementLength; error.clear(); } } while (inputLength && !error.get()); if (error) { LOG_ERROR("GIConv conversion error, Code %d: \"%s\"", error->code, error->message); return CString(); } return CString(result.data(), size); }