See ChangeLog: Sun Jan 17 11:04:33 CET 1999 Werner Koch
[gnupg.git] / g10 / textfilter.c
1 /* textfilter.c
2  *      Copyright (C) 1998 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <assert.h>
27
28 #include "errors.h"
29 #include "iobuf.h"
30 #include "memory.h"
31 #include "util.h"
32 #include "filter.h"
33 #include "i18n.h"
34
35
36 #define MAX_LINELEN 20000
37
38
39 /****************
40  * The filter is used to make canonical text: Lines are terminated by
41  * CR, LF, trailing white spaces are removed.
42  */
43 int
44 text_filter( void *opaque, int control,
45              IOBUF a, byte *buf, size_t *ret_len)
46 {
47     size_t size = *ret_len;
48     text_filter_context_t *tfx = opaque;
49     int rc=0;
50
51     if( control == IOBUFCTRL_UNDERFLOW ) {
52         size_t len = 0;
53         unsigned maxlen;
54
55         assert( size > 10 );
56         size -= 2;  /* reserve 2 bytes to append CR,LF */
57         while( !rc && len < size ) {
58             int lf_seen;
59
60             while( len < size && tfx->buffer_pos < tfx->buffer_len )
61                 buf[len++] = tfx->buffer[tfx->buffer_pos++];
62             if( len >= size )
63                 continue;
64
65             /* read the next line */
66             maxlen = MAX_LINELEN;
67             tfx->buffer_pos = 0;
68             tfx->buffer_len = iobuf_read_line( a, &tfx->buffer,
69                                                &tfx->buffer_size, &maxlen );
70             if( !maxlen )
71                 tfx->truncated++;
72             if( !tfx->buffer_len ) {
73                 if( !len )
74                     rc = -1; /* eof */
75                 break;
76             }
77             lf_seen = tfx->buffer[tfx->buffer_len-1] == '\n';
78             tfx->buffer_len = trim_trailing_ws( tfx->buffer, tfx->buffer_len );
79             if( lf_seen ) {
80                 tfx->buffer[tfx->buffer_len++] = '\r';
81                 tfx->buffer[tfx->buffer_len++] = '\n';
82             }
83         }
84
85         *ret_len = len;
86     }
87     else if( control == IOBUFCTRL_DESC )
88         *(char**)buf = "text_filter";
89     else if( control == IOBUFCTRL_FREE ) {
90         if( tfx->truncated )
91             log_error(_("can't handle text lines longer than %d characters\n"),
92                         MAX_LINELEN );
93         m_free( tfx->buffer );
94         tfx->buffer = NULL;
95     }
96     return rc;
97 }
98
99
100