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);
}