* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General
- * Public License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
- * Boston, MA 02111-1307, USA.
+ * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#include "config.h"
+#include "gcharsetconverter.h"
+
#include <errno.h>
-#include "gcontenttypeprivate.h"
-#include "gcharsetconverter.h"
-#include "glib.h"
#include "ginitable.h"
#include "gioerror.h"
#include "glibintl.h"
-#include "gioalias.h"
enum {
PROP_0,
* Since: 2.24
**/
GCharsetConverter *
-g_charset_converter_new (const gchar *to_charset,
- const gchar *from_charset,
- GError **error)
+g_charset_converter_new (const gchar *to_charset,
+ const gchar *from_charset,
+ GError **error)
{
GCharsetConverter *conv;
}
static GConverterResult
-g_charset_converter_convert (GConverter *converter,
- const void *inbuf,
- gsize inbuf_size,
- void *outbuf,
- gsize outbuf_size,
- GConverterFlags flags,
- gsize *bytes_read,
- gsize *bytes_written,
- GError **error)
+g_charset_converter_convert (GConverter *converter,
+ const void *inbuf,
+ gsize inbuf_size,
+ void *outbuf,
+ gsize outbuf_size,
+ GConverterFlags flags,
+ gsize *bytes_read,
+ gsize *bytes_written,
+ GError **error)
{
GCharsetConverter *conv;
gsize res;
gchar *inbufp, *outbufp;
gsize in_left, out_left;
int errsv;
+ gboolean reset;
conv = G_CHARSET_CONVERTER (converter);
return G_CONVERTER_ERROR;
}
- /* Iconv never produces output with no input, so handle this
- specially */
- if (inbuf_size == 0)
- {
- if (flags & G_CONVERTER_INPUT_AT_END)
- return G_CONVERTER_FINISHED;
-
- if (flags & G_CONVERTER_FLUSH)
- return G_CONVERTER_FLUSHED;
-
- g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT,
- _("Incomplete multibyte sequence in input"));
- return G_CONVERTER_ERROR;
- }
-
inbufp = (char *)inbuf;
outbufp = (char *)outbuf;
in_left = inbuf_size;
out_left = outbuf_size;
+ reset = FALSE;
- res = g_iconv (conv->iconv,
- &inbufp, &in_left,
- &outbufp, &out_left);
+ /* if there is not input try to flush the data */
+ if (inbuf_size == 0)
+ {
+ if (flags & G_CONVERTER_INPUT_AT_END ||
+ flags & G_CONVERTER_FLUSH)
+ {
+ reset = TRUE;
+ }
+ else
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT,
+ _("Incomplete multibyte sequence in input"));
+ return G_CONVERTER_ERROR;
+ }
+ }
+
+ if (reset)
+ /* call g_iconv with NULL inbuf to cleanup shift state */
+ res = g_iconv (conv->iconv,
+ NULL, &in_left,
+ &outbufp, &out_left);
+ else
+ res = g_iconv (conv->iconv,
+ &inbufp, &in_left,
+ &outbufp, &out_left);
*bytes_read = inbufp - (char *)inbuf;
*bytes_written = outbufp - (char *)outbuf;
ok:
ret = G_CONVERTER_CONVERTED;
- if (in_left == 0 &&
+ if (reset &&
(flags & G_CONVERTER_INPUT_AT_END))
- ret = G_CONVERTER_FINISHED;
- else if (in_left == 0 &&
+ ret = G_CONVERTER_FINISHED;
+ else if (reset &&
(flags & G_CONVERTER_FLUSH))
- ret = G_CONVERTER_FLUSHED;
+ ret = G_CONVERTER_FLUSHED;
}
return ret;
}
static gboolean
-g_charset_converter_initable_init (GInitable *initable,
- GCancellable *cancellable,
- GError **error)
+g_charset_converter_initable_init (GInitable *initable,
+ GCancellable *cancellable,
+ GError **error)
{
GCharsetConverter *conv;
return FALSE;
}
- conv->iconv =
- g_iconv_open (conv->to, conv->from);
+ conv->iconv = g_iconv_open (conv->to, conv->from);
- if (conv->iconv == NULL)
+ if (conv->iconv == (GIConv)-1)
{
if (errno == EINVAL)
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
{
iface->init = g_charset_converter_initable_init;
}
-
-#define __G_CHARSET_CONVERTER_C__
-#include "gioaliasdef.c"