/* PSPP - a program for statistical analysis.
- Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+ Copyright (C) 2010, 2011, 2012, 2013, 2014 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <errno.h>
#include <fcntl.h>
#include <iconv.h>
+#include <limits.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include "libpspp/cast.h"
#include "libpspp/compiler.h"
#include "libpspp/encoding-guesser.h"
+#include "libpspp/i18n.h"
#include "gl/c-strcase.h"
#include "gl/localcharset.h"
goto error;
encoding = encoding_guess_head_encoding (fromcode, is->buffer, is->length);
- if (!strcmp (encoding, "UTF-8"))
- is->state = S_UTF8;
+ if (is_encoding_utf8 (encoding))
+ {
+ unsigned int bom_len;
+
+ is->state = S_UTF8;
+ bom_len = encoding_guess_bom_length (encoding, is->buffer, is->length);
+ is->head += bom_len;
+ is->length -= bom_len;
+ }
else
{
if (encoding_guess_encoding_is_auto (fromcode)
&& !strcmp (encoding, "ASCII"))
- is->state = S_AUTO;
+ {
+ is->state = S_AUTO;
+ encoding = encoding_guess_parse_encoding (fromcode);
+ }
else
is->state = S_CONVERT;
- is->converter = iconv_open ("UTF-8",
- encoding_guess_parse_encoding (fromcode));
+ is->converter = iconv_open ("UTF-8", encoding);
if (is->converter == (iconv_t) -1)
goto error;
}
is->head = is->buffer;
/* Read more input. */
- n = read (is->fd, is->buffer + is->length,
- U8_ISTREAM_BUFFER_SIZE - is->length);
- if (n > 0)
- is->length += n;
+ n = 0;
+ do
+ {
+ ssize_t retval = read (is->fd, is->buffer + is->length,
+ U8_ISTREAM_BUFFER_SIZE - is->length);
+ if (retval > 0)
+ {
+ n += retval;
+ is->length += retval;
+ }
+ else if (retval == 0)
+ return n;
+ else if (errno != EINTR)
+ return n > 0 ? n : -1;
+ }
+ while (is->length < U8_ISTREAM_BUFFER_SIZE);
return n;
}
char **inbufp, size_t *inbytesleft,
char **outbufp, size_t *outbytesleft)
{
- size_t n = iconv (converter, inbufp, inbytesleft, outbufp, outbytesleft);
+ size_t n = iconv (converter, (ICONV_CONST char **) inbufp, inbytesleft,
+ outbufp, outbytesleft);
return n == SIZE_MAX ? errno : 0;
}