+
+ std::string native_error_string(const PRUnichar * text)
+ {
+ std::string result;
+ PRInt32 text_len = 0;
+ while (text[text_len])
+ ++text_len;
+
+ nsCOMPtr<nsICharsetConverterManager> conv_manager;
+ nsCOMPtr<nsIUnicodeEncoder> encoder;
+ static const nsCID charset_converter_manager_cid =
+ NS_ICHARSETCONVERTERMANAGER_CID;
+ if (NS_SUCCEEDED(CallGetService<nsICharsetConverterManager>(
+ charset_converter_manager_cid,
+ getter_AddRefs(conv_manager)))
+ && NS_SUCCEEDED(conv_manager->GetUnicodeEncoder(
+ nl_langinfo(CODESET),
+ getter_AddRefs(encoder))))
+ {
+ encoder->SetOutputErrorBehavior(
+ nsIUnicodeEncoder::kOnError_Replace, NULL, PRUnichar('?'));
+
+ char buf[1000]; // Hopefully long enough for an error message
+
+ char * out = buf;
+ PRInt32 out_len = sizeof(buf);
+ encoder->Convert(text, &text_len, out, &out_len);
+ out += out_len;
+
+ out_len = sizeof(buf) - out_len;
+ encoder->Finish(out, &out_len);
+ out += out_len;
+
+ result.assign(buf, out);
+ }
+ else
+ {
+ // Convert to ASCII
+ result.resize(text_len);
+ for (PRInt32 i = 0; i != text_len; ++i)
+ result[i] = (text[i] < 0x80) ? text[i] : '?';
+ }
+
+ return result;
+ }