diff options
author | Werner Koch <[email protected]> | 1998-02-04 18:54:31 +0000 |
---|---|---|
committer | Werner Koch <[email protected]> | 1998-02-04 18:54:31 +0000 |
commit | 9886ad8098ea1a128e07be54eaf8f24d73795aa2 (patch) | |
tree | 22e597c9f6384b0399abd049c0fd1c64d3d623eb /g10/textfilter.c | |
parent | Fixed a few bugs (diff) | |
download | gnupg-9886ad8098ea1a128e07be54eaf8f24d73795aa2.tar.gz gnupg-9886ad8098ea1a128e07be54eaf8f24d73795aa2.zip |
armor rewritten, but still buggy
Diffstat (limited to 'g10/textfilter.c')
-rw-r--r-- | g10/textfilter.c | 134 |
1 files changed, 84 insertions, 50 deletions
diff --git a/g10/textfilter.c b/g10/textfilter.c index e57b429e8..4734fe4ca 100644 --- a/g10/textfilter.c +++ b/g10/textfilter.c @@ -32,6 +32,69 @@ #include "filter.h" + + +static int +read_line( byte *buf, size_t *r_buflen, IOBUF a ) +{ + int c; + int rc = 0; + byte *p; + size_t buflen; + int no_lf=0; + size_t n; + + buflen = *r_buflen; + assert(buflen >= 20 ); + buflen -= 3; /* leave some room for CR,LF and one extra */ + + for(c=0, n=0; n < buflen && (c=iobuf_get2(a)) != -1 && c != '\n'; ) + buf[n++] = c; + buf[n] = 0; + if( c == -1 ) + rc = -1; + else if( c != '\n' ) { + IOBUF b = iobuf_temp(); + while( (c=iobuf_get2(a)) != -1 && c != '\n' ) { + iobuf_put(b,c); + if( c != ' ' && c != '\t' && c != '\r' ) + break; + } + if( c == '\n' ) { /* okay we can skip the rest of the line */ + iobuf_close(b); + } + else { + iobuf_unget_and_close_temp(a,b); + no_lf = 1; + } + } + + if( !no_lf ) { + /* append CR,LF after removing trailing wspaces */ + for(p=buf+n-1; n; n--, p-- ) { + assert( *p != '\n' ); + if( *p != ' ' && *p != '\t' && *p != '\r' ) { + p[1] = '\r'; + p[2] = '\n'; + n += 2; + break; + } + } + if( !n ) { + buf[0] = '\r'; + buf[1] = '\n'; + n = 2; + } + } + + + *r_buflen = n; + return rc; +} + + + + /**************** * The filter is used to make canonical text: Lines are terminated by * CR, LF, trailing white spaces are removed. @@ -42,60 +105,31 @@ text_filter( void *opaque, int control, { size_t size = *ret_len; text_filter_context_t *tfx = opaque; - int i, c, rc=0; - byte *p; + int rc=0; + size_t len, n, nn; if( control == IOBUFCTRL_UNDERFLOW ) { - for(i=0; i < size; i++ ) { - if( !tfx->linelen && !tfx->eof ) { /* read a complete line */ - for(;;) { - if( (c = iobuf_get(a)) == -1 ) { - tfx->eof=1; - break; - } - if( c == '\n' ) - break; - if( tfx->linelen >= tfx->linesize ) { - tfx->linesize += 500; - tfx->line = m_realloc( tfx->line, tfx->linesize ); - } - tfx->line[tfx->linelen++] = c; - } - /* remove trailing white spaces */ - p = tfx->line + tfx->linelen - 1; - for( ; p >= tfx->line; p--, tfx->linelen-- ) { - if( *p != ' ' && *p == '\t' && *p != '\r' ) - break; - } - if( tfx->linelen+2 >= tfx->linesize ) { - tfx->linesize += 10; - tfx->line = m_realloc( tfx->line, tfx->linesize ); - } - tfx->line[tfx->linelen++] = '\r'; - tfx->line[tfx->linelen++] = '\n'; - tfx->pos=0; + assert( size > 30 ); + len = 0; + while( !rc && len < size ) { + if( tfx->idx < tfx->len ) { /* flush the last buffer */ + n = tfx->len; + for(nn=tfx->idx; len < size && nn < n ; nn++ ) + buf[len++] = tfx->buf[nn]; + tfx->idx = nn; + continue; } - if( tfx->pos < tfx->linelen ) - buf[i] = tfx->line[tfx->pos++]; - else if( tfx->eof ) - break; - else - tfx->linelen = 0; + if( tfx->eof ) { + rc = -1; + continue; + } + n = DIM(tfx->buf); + tfx->idx = 0; + if( read_line( tfx->buf, &n, a ) == -1 ) + tfx->eof = 1; + tfx->len = n; } - if( !i ) - rc = -1; - *ret_len = i; - } - else if( control == IOBUFCTRL_INIT ) { - tfx->linesize = 500; - tfx->line = m_alloc(tfx->linesize); - tfx->linelen = 0; - tfx->pos = 0; - tfx->eof = 0; - } - else if( control == IOBUFCTRL_FREE ) { - m_free( tfx->line ); - tfx->line = NULL; + *ret_len = len; } else if( control == IOBUFCTRL_DESC ) *(char**)buf = "text_filter"; |