unsigned int mz_quoted_printable_encode_close (const unsigned char *inbuf, unsigned int inlen, unsigned char *outbuf, int *state, unsigned int *save) { register unsigned char *outptr = outbuf; int last; if (inlen > 0) outptr += mz_quoted_printable_encode_step(inbuf, inlen, outptr, state, save); last = *state; if (last != -1) { /* space/tab must be encoded if its the last character on the line */ if (is_qpsafe(last) && !is_blank(last)) { *outptr++ = last; } else { *outptr++ = '='; *outptr++ = tohex[(last >> 4) & 0xf]; *outptr++ = tohex[last & 0xf]; } } *outptr++ = '\n'; *save = 0; *state = -1; return (outptr - outbuf); }
/// qpencode_file() // Encodes a whole file using the quoted-printable format defined in // RFC 2045 (page 19) long qpencode_file(FILE *in, FILE *out) { unsigned char inbuffer[QPENC_BUF+1]; // we read out data in ~4096 byte chunks unsigned char outbuffer[QPENC_BUF+5];// the output buffer should not be more than // the input buffer with an additional space // for 5 chars which could be used during // encoding. unsigned char *iptr; unsigned char *optr = outbuffer; unsigned char c; int last = -1; long encoded_chars = 0; int line_len = 0; BOOL eof_reached = FALSE; size_t read; ENTER(); while(eof_reached == FALSE) { // read in 4096 byte chunks read = fread(inbuffer, 1, QPENC_BUF, in); // on a short item count we check for a potential // error and return immediatly. if(read != QPENC_BUF) { if(feof(in) != 0) { D(DBF_MIME, "EOF file at %ld", ftell(in)); eof_reached = TRUE; // we found an EOF // if the last read was zero we can exit immediatly if(read == 0) break; } else { E(DBF_MIME, "error on reading data!"); // an error occurred, lets return -1 RETURN(-1); return -1; } } // let us now parse through the inbuffer and encode it according // to RFC 2045 iptr = inbuffer; while(read) { // decrease the read number and increase // out input buffer pointer c = *iptr++; read--; if(c == '\n') { // check if the previous char is a linear whitespace and // if so we have to put a soft break right before the // newline if(last != -1 && (last == ' ' || last == '\t')) { *optr++ = '='; *optr++ = '\n'; } *optr++ = '\n'; // reset the line_len counter line_len = 0; last = -1; } // we encode the current char if: // 1) it is an unsafe safe // 2) it is an upcoming "From " at the start of a line else if(!is_qpsafe(c) || (last == -1 && c == 'F' && strncmp((char *)iptr, "rom ", 4) == 0)) { // before we can encode the data we have to check // whether there is enough space left on the line // or if we have to put it on the next line if(line_len+3 >= QP_LINELEN-1) // one space for the trailing '=' { *optr++ = '='; *optr++ = '\n'; // reset the line_len counter line_len = 0; } // now put out the encoded char *optr++ = '='; *optr++ = basis_hex[(c >> 4) & 0xF]; *optr++ = basis_hex[c & 0xF]; // increase the line_len counter line_len += 3; // count the number of encoded chars encoded_chars++; } else { // so this char seems to be safe to be directly placed // in the output buffer without any encoding. We just // have to check whether this line is going to be longer // than the limit if(line_len+1 >= QP_LINELEN-1) // one space for the trailing '=' { *optr++ = '='; *optr++ = '\n'; // reset the line_len counter line_len = 0; } *optr++ = c; // increase the line_len counter line_len++; } // let us now check if our outbuffer is filled up so that we can write // out the data to our out stream. if(optr-outbuffer >= QPENC_BUF) { size_t todo = optr-outbuffer; // now we do a binary write of the data if(fwrite(outbuffer, 1, todo, out) != todo) { E(DBF_MIME, "error on writing data!"); // an error must have occurred. RETURN(-1); return -1; } // now reset the outbuffer and stuff optr = outbuffer; } last = c; } }