[vlc-devel] [PATCH 6/8] stream_ReadLine: simplify flow and variable types
Pierre Ynard
linkfanel at yahoo.fr
Wed Oct 21 05:29:33 CEST 2020
No functional change
diff --git a/src/input/stream.c b/src/input/stream.c
index 98ce6da..6cb3bea 100644
--- a/src/input/stream.c
+++ b/src/input/stream.c
@@ -188,7 +188,8 @@ char *vlc_stream_ReadLine( stream_t *s )
{
stream_priv_t *priv = (stream_priv_t *)s;
char *p_line = NULL;
- int i_line = 0, i_read = 0;
+ size_t i_line = 0;
+ bool b_data = false;
/* Let's fail quickly if this is a readdir access */
if( s->pf_read == NULL && s->pf_block == NULL )
@@ -244,9 +245,8 @@ char *vlc_stream_ReadLine( stream_t *s )
for( ;; )
{
- char *psz_eol;
- const uint8_t *p_data;
- int i_data;
+ const uint8_t *p_data, *psz_eol;
+ ssize_t i_data;
/* Probe new data */
i_data = vlc_stream_Peek( s, &p_data, STREAM_PROBE_LINE );
@@ -270,6 +270,9 @@ char *vlc_stream_ReadLine( stream_t *s )
i_data = i_data - ( i_data % priv->text.char_width );
/* Check if there is an EOL */
+ /* FIXME: <CR> behavior varies depending on where buffer
+ boundaries happen to fall; a <CR><LF> across the boundary
+ creates a bogus empty line. */
if( priv->text.char_width == 1 )
{
/* UTF-8: 0A <LF> */
@@ -290,7 +293,7 @@ char *vlc_stream_ReadLine( stream_t *s )
{
if( U16_AT( p ) == eol )
{
- psz_eol = (char *)p + 1;
+ psz_eol = p;
break;
}
}
@@ -302,7 +305,7 @@ char *vlc_stream_ReadLine( stream_t *s )
{
if( U16_AT( p ) == eol )
{
- psz_eol = (char *)p + 1;
+ psz_eol = p;
break;
}
}
@@ -310,88 +313,81 @@ char *vlc_stream_ReadLine( stream_t *s )
}
if( psz_eol )
- {
- i_data = (psz_eol - (char *)p_data) + 1;
- p_line = realloc_or_free( p_line,
- i_line + i_data + priv->text.char_width ); /* add \0 */
- if( !p_line )
- goto error;
- i_data = vlc_stream_Read( s, &p_line[i_line], i_data );
- if( i_data <= 0 ) break; /* Hmmm */
- i_line += i_data - priv->text.char_width; /* skip \n */;
- i_read += i_data;
-
- /* We have our line */
- break;
- }
+ i_data = (psz_eol - p_data) + priv->text.char_width;
/* Read data (+1 for easy \0 append) */
p_line = realloc_or_free( p_line,
i_line + i_data + priv->text.char_width );
if( !p_line )
- goto error;
+ return NULL;
i_data = vlc_stream_Read( s, &p_line[i_line], i_data );
- if( i_data <= 0 ) break; /* Hmmm */
+ if( i_data < priv->text.char_width ) break; /* Hmmm */
i_line += i_data;
- i_read += i_data;
+ b_data = true;
+
+ if( psz_eol )
+ {
+ i_line -= priv->text.char_width; /* skip \n */;
+ /* We have our line */
+ break;
+ }
- if( i_read >= STREAM_LINE_MAX )
+ if( i_line >= STREAM_LINE_MAX )
{
msg_Err( s, "line too long, exceeding %zu bytes",
(size_t) STREAM_LINE_MAX );
- goto error;
+ free( p_line );
+ return NULL;
}
}
- if( i_read > 0 )
+ if( !b_data ) /* We failed to read any data, probably EOF */
+ return NULL;
+
+ if( priv->text.char_width > 1 )
{
- if( priv->text.char_width > 1 )
+ size_t i_new_line = 0;
+ size_t i_in = 0, i_out = 0;
+ const char * p_in = NULL;
+ char * p_out = NULL;
+ char * psz_new_line = NULL;
+
+ /* iconv */
+ /* UTF-8 needs at most 150% of the buffer as many as UTF-16 */
+ i_new_line = i_line * 3 / 2 + 1;
+ psz_new_line = malloc( i_new_line );
+ if( psz_new_line == NULL )
{
- int i_new_line = 0;
- size_t i_in = 0, i_out = 0;
- const char * p_in = NULL;
- char * p_out = NULL;
- char * psz_new_line = NULL;
-
- /* iconv */
- /* UTF-8 needs at most 150% of the buffer as many as UTF-16 */
- i_new_line = i_line * 3 / 2 + 1;
- psz_new_line = malloc( i_new_line );
- if( psz_new_line == NULL )
- goto error;
- i_in = (size_t)i_line;
- i_out = (size_t)i_new_line;
- p_in = p_line;
- p_out = psz_new_line;
-
- if( vlc_iconv( priv->text.conv, &p_in, &i_in, &p_out, &i_out ) == (size_t)-1 )
- {
- msg_Err( s, "conversion error: %s", vlc_strerror_c( errno ) );
- msg_Dbg( s, "original: %d, in %zu, out %zu", i_line, i_in, i_out );
- /* Reset state */
- size_t r = vlc_iconv( priv->text.conv, NULL, NULL, NULL, NULL );
- VLC_UNUSED( r );
- }
free( p_line );
- p_line = psz_new_line;
- i_line = (size_t)i_new_line - i_out; /* does not include \0 */
+ return NULL;
}
+ i_in = i_line;
+ i_out = i_new_line;
+ p_in = p_line;
+ p_out = psz_new_line;
- /* Remove trailing LF/CR */
- while( i_line >= 1 &&
- (p_line[i_line - 1] == '\r' || p_line[i_line - 1] == '\n') )
- i_line--;
+ if( vlc_iconv( priv->text.conv, &p_in, &i_in, &p_out, &i_out ) == VLC_ICONV_ERR )
+ {
+ msg_Err( s, "conversion error: %s", vlc_strerror_c( errno ) );
+ msg_Dbg( s, "original: %zu, in %zu, out %zu", i_line, i_in, i_out );
+ /* Reset state */
+ size_t r = vlc_iconv( priv->text.conv, NULL, NULL, NULL, NULL );
+ VLC_UNUSED( r );
+ }
+ free( p_line );
+ p_line = psz_new_line;
+ i_line = i_new_line - i_out; /* does not include \0 */
+ }
- /* Make sure the \0 is there */
- p_line[i_line] = '\0';
+ /* Remove trailing LF/CR */
+ while( i_line >= 1 &&
+ (p_line[i_line - 1] == '\r' || p_line[i_line - 1] == '\n') )
+ i_line--;
- return p_line;
- }
+ /* Make sure the \0 is there */
+ p_line[i_line] = '\0';
-error:
- /* We failed to read any data, probably EOF */
- free( p_line );
- return NULL;
+ return p_line;
}
static ssize_t vlc_stream_CopyBlock(block_t **restrict pp,
--
Pierre Ynard
"Une âme dans un corps, c'est comme un dessin sur une feuille de papier."
More information about the vlc-devel
mailing list