static ssize_t i_stream_base64_encoder_read(struct istream_private *stream) { struct base64_encoder_istream *bstream = (struct base64_encoder_istream *)stream; size_t pre_count, post_count, size; int ret; do { ret = i_stream_read_parent(stream); if (ret <= 0) return ret; (void)i_stream_get_data(stream->parent, &size); } while (size < 4 && !stream->parent->eof); /* encode as many lines as fits into destination buffer */ pre_count = stream->pos - stream->skip; while (i_stream_base64_try_encode_line(bstream)) ; post_count = stream->pos - stream->skip; if (pre_count == post_count) { i_assert(stream->buffer_size - stream->pos < 4); return -2; } i_assert(post_count > pre_count); return post_count - pre_count; }
static ssize_t i_stream_base64_encoder_read(struct istream_private *stream) { struct base64_encoder_istream *bstream = (struct base64_encoder_istream *)stream; size_t pre_count, post_count; int ret; do { ret = i_stream_read_parent(stream); if (ret == 0) return 0; if (ret < 0) { if (i_stream_get_data_size(stream->parent) == 0) return -1; /* add the final partial block */ } /* encode as many lines as fits into destination buffer */ pre_count = stream->pos - stream->skip; while ((ret = i_stream_base64_try_encode_line(bstream)) > 0) ; post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); if (ret < 0 && pre_count == post_count) return ret; i_assert(post_count > pre_count); return post_count - pre_count; }
static ssize_t i_stream_base64_decoder_read(struct istream_private *stream) { struct base64_decoder_istream *bstream = (struct base64_decoder_istream *)stream; const unsigned char *data; size_t pre_count, post_count, size; int ret; do { ret = i_stream_read_parent(stream); if (ret <= 0) { if (ret < 0 && stream->istream.stream_errno == 0 && i_stream_get_data_size(stream->parent) > 0) { /* base64 input with a partial block */ data = i_stream_get_data(stream->parent, &size); io_stream_set_error(&stream->iostream, "base64 input ends with a partial block: 0x%s", binary_to_hex(data, size)); stream->istream.stream_errno = EINVAL; } return ret; } /* encode as many blocks as fits into destination buffer */ pre_count = stream->pos - stream->skip; while ((ret = i_stream_base64_try_decode_block(bstream)) > 0) ; post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); if (ret < 0 && pre_count == post_count) return ret; i_assert(post_count > pre_count); return post_count - pre_count; }
static ssize_t i_stream_nonuls_read(struct istream_private *stream) { struct nonuls_istream *nstream = (struct nonuls_istream *)stream; const unsigned char *data, *p; size_t i, size, avail_size; int ret; if ((ret = i_stream_read_parent(stream)) <= 0) return ret; data = i_stream_get_data(stream->parent, &size); if (!i_stream_try_alloc(stream, size, &avail_size)) return -2; if (size > avail_size) size = avail_size; i_assert(size > 0); p = memchr(data, '\0', size); if (p == NULL) { /* no NULs in this block */ memcpy(stream->w_buffer+stream->pos, data, size); } else { i = p-data; memcpy(stream->w_buffer+stream->pos, data, i); for (; i < size; i++) { stream->w_buffer[stream->pos+i] = data[i] == '\0' ? nstream->replace_chr : data[i]; } } stream->pos += size; i_stream_skip(stream->parent, size); return size; }
static ssize_t i_stream_qp_decoder_read(struct istream_private *stream) { struct qp_decoder_istream *bstream = (struct qp_decoder_istream *)stream; const unsigned char *data; size_t pre_count, post_count, size; int ret; size_t prev_size = 0; do { ret = i_stream_read_parent(stream, &prev_size); if (ret <= 0) { if (ret != -1 || stream->istream.stream_errno != 0) return 0; ret = i_stream_qp_try_decode_input(bstream, TRUE); if (ret == 0) { /* ended with =[whitespace] but without LF */ stream->istream.eof = TRUE; return -1; } /* partial qp input */ i_assert(ret < 0); data = i_stream_get_data(stream->parent, &size); io_stream_set_error(&stream->iostream, "quoted-printable input ends with a partial block: 0x%s", binary_to_hex(data, size)); stream->istream.stream_errno = EINVAL; return -1; } /* encode as much data as fits into destination buffer */ pre_count = stream->pos - stream->skip; while ((ret = i_stream_qp_try_decode_input(bstream, FALSE)) > 0) ; post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); if (ret < 0) return ret; i_assert(post_count > pre_count); return post_count - pre_count; }
static ssize_t i_stream_qp_decoder_read(struct istream_private *stream) { struct qp_decoder_istream *bstream = (struct qp_decoder_istream *)stream; size_t pre_count, post_count; int ret; size_t prev_size = 0; do { ret = i_stream_read_parent(stream, &prev_size); if (ret <= 0) { if (ret != -1 || stream->istream.stream_errno != 0) return 0; ret = i_stream_qp_try_decode_input(bstream, TRUE); if (ret == 0) { /* ended with =[whitespace] but without LF */ stream->istream.eof = TRUE; return -1; } /* partial qp input */ i_assert(ret < 0); stream->istream.stream_errno = EINVAL; return -1; } /* encode as much data as fits into destination buffer */ pre_count = stream->pos - stream->skip; while ((ret = i_stream_qp_try_decode_input(bstream, FALSE)) > 0) ; post_count = stream->pos - stream->skip; } while (ret == 0 && pre_count == post_count); if (ret < 0) return ret; i_assert(post_count > pre_count); return post_count - pre_count; }