/* * format a mime message - this is the recursive on, not intended * for external use. */ int mime_format_part (MIME *m, DBUF *b) { MIME *n; char boundary[100]; int bl; mime_size (m); dbuf_printf (b, "%s", m->headers); dbuf_write (b, m->body, m->len); if ((bl = mime_getBoundary (m, boundary, 100)) < 1) return (dbuf_size (b)); boundary[bl++] = '\n'; for (n = m->next; n != NULL; n = n->next) { debug ("adding next part at %d\n", dbuf_size (b)); dbuf_write (b, boundary, bl); mime_format_part (n, b); } debug ("adding final boundary at %d\n", dbuf_size (b)); dbuf_write (b, boundary, bl - 1); dbuf_write (b, "--\n", 4); debug ("final size is %d\n", dbuf_size (b)); debug ("actual size is %d (%d/%d)\n", strlen (dbuf_getbuf(b)), strlen (m->headers), strlen (dbuf_getbuf(b)) - strlen (m->headers)); return (dbuf_size (b)); }
static int do_decode_rle(deark *c, lctx *d, i64 pos1, dbuf *unc_pixels) { u8 b; i64 count; i64 k; u8 buf[8]; i64 pos = pos1; while(1) { if(pos >= c->infile->len) break; if(unc_pixels->len >= d->main_image.img_size_in_bytes) break; b = de_getbyte(pos); pos++; if(b & 0x80) { // RLE block count = (i64)(b - 0x80) + 1; de_read(buf, pos, d->bytes_per_pixel); pos += d->bytes_per_pixel; for(k=0; k<count; k++) { dbuf_write(unc_pixels, buf, d->bytes_per_pixel); } } else { // uncompressed block count = (i64)(b) + 1; dbuf_copy(c->infile, pos, count * d->bytes_per_pixel, unc_pixels); pos += count * d->bytes_per_pixel; } } de_dbg(c, "decompressed %d bytes to %d bytes", (int)(pos-pos1), (int)unc_pixels->len); return 1; }
static int copy_cbfn(struct de_bufferedreadctx *brctx, const u8 *buf, i64 buf_len) { dbuf *outf = (dbuf*)brctx->userdata; dbuf_write(outf, buf, buf_len); return 1; }
void dbuf_copy(dbuf *inf, i64 input_offset, i64 input_len, dbuf *outf) { u8 tmpbuf[256]; if(inf->btype==DBUF_TYPE_MEMBUF && (input_offset>=0) && (input_offset+input_len<=inf->len)) { // Fast path if the data to copy is all in memory dbuf_write(outf, &inf->membuf_buf[input_offset], input_len); return; } if(input_len<=(i64)sizeof(tmpbuf)) { // Fast path for small sizes dbuf_read(inf, tmpbuf, input_offset, input_len); dbuf_write(outf, tmpbuf, input_len); return; } dbuf_buffered_read(inf, input_offset, input_len, copy_cbfn, (void*)outf); }
// Emit a raw string. Does not force a paragraph to be open. // Updates pinfo->xpos (assumes 1 byte per char). // For xpos, handles the case where sz ends with a newline, but does not // handle internal newlines. static void do_emit_raw_sz(deark *c, lctx *d, struct para_info *pinfo, const char *sz) { size_t sz_len = de_strlen(sz); if(sz_len<1) return; dbuf_write(d->html_outf, (const u8*)sz, (i64)sz_len); if(sz[sz_len-1]=='\n') { pinfo->xpos = 0; } else { pinfo->xpos += (int)sz_len; } }
// TODO: Document and review whether the bi->total_size and // bi->size_of_headers_and_pal fields include the 14-byte fileheader. void de_fmtutil_generate_bmpfileheader(deark *c, dbuf *outf, const struct de_bmpinfo *bi, i64 file_size_override) { i64 file_size_to_write; dbuf_write(outf, (const u8*)"BM", 2); if(file_size_override) file_size_to_write = file_size_override; else file_size_to_write = 14 + bi->total_size; dbuf_writeu32le(outf, file_size_to_write); dbuf_write_zeroes(outf, 4); dbuf_writeu32le(outf, 14 + bi->size_of_headers_and_pal); }
void dbuf_write_run(dbuf *f, u8 n, i64 len) { u8 buf[1024]; i64 amt_left; i64 amt_to_write; de_memset(buf, n, (size_t)len<sizeof(buf) ? (size_t)len : sizeof(buf)); amt_left = len; while(amt_left > 0) { if((size_t)amt_left<sizeof(buf)) amt_to_write = amt_left; else amt_to_write = sizeof(buf); dbuf_write(f, buf, amt_to_write); amt_left -= amt_to_write; } }
void dbuf_write(dbuf *f, const u8 *m, i64 len) { if(f->len + len > f->max_len_hard) { do_on_dbuf_size_exceeded(f); } if(f->writecallback_fn) { f->writecallback_fn(f, m, len); } if(f->btype==DBUF_TYPE_NULL) { f->len += len; return; } else if(f->btype==DBUF_TYPE_OFILE || f->btype==DBUF_TYPE_STDOUT) { if(!f->fp) return; if(f->c->debug_level>=3) { de_dbg3(f->c, "writing %d bytes to %s", (int)len, f->name); } fwrite(m, 1, (size_t)len, f->fp); f->len += len; return; } else if(f->btype==DBUF_TYPE_MEMBUF) { if(f->c->debug_level>=3 && f->name) { de_dbg3(f->c, "appending %d bytes to membuf %s", (int)len, f->name); } membuf_append(f, m, len); return; } else if(f->btype==DBUF_TYPE_ODBUF) { dbuf_write(f->parent_dbuf, m, len); f->len += len; return; } de_err(f->c, "Internal: Invalid output file type (%d)", f->btype); de_fatalerror(f->c); }
// Caller must initialize *repeat_count. static void uncompress_line(deark *c, lctx *d, dbuf *unc_line, i64 pos1, i64 rownum, i64 *bytes_consumed, i64 *repeat_count) { i64 pos; u8 b0, b1; u8 val; i64 count; i64 k; i64 tmp_repeat_count; i64 unc_line_len_orig; *bytes_consumed = 0; pos = pos1; unc_line_len_orig = unc_line->len; while(1) { if(pos >= c->infile->len) break; if(unc_line->len - unc_line_len_orig >= d->rowspan_per_plane) break; b0 = de_getbyte(pos++); if(b0==0) { // Pattern run or scanline run b1 = de_getbyte(pos++); if(b1>0) { // pattern run de_read(d->pattern_buf, pos, d->patlen); pos += d->patlen; count = (i64)b1; for(k=0; k<count; k++) { dbuf_write(unc_line, d->pattern_buf, d->patlen); } } else { // (b1==0) scanline run u8 flagbyte; flagbyte = de_getbyte(pos); if(flagbyte==0xff) { pos++; tmp_repeat_count = (i64)de_getbyte(pos++); if(tmp_repeat_count == 0) { de_dbg(c, "row %d: bad repeat count", (int)rownum); } else { *repeat_count = tmp_repeat_count; } } else { de_dbg(c, "row %d: bad scanline run marker: 0x%02x", (int)rownum, (unsigned int)flagbyte); } } } else if(b0==0x80) { // "Uncompressed bit string" count = (i64)de_getbyte(pos++); dbuf_copy(c->infile, pos, count, unc_line); pos += count; } else { // "solid run" val = (b0&0x80) ? 0xff : 0x00; count = (i64)(b0 & 0x7f); dbuf_write_run(unc_line, val, count); } } *bytes_consumed = pos - pos1; }
void dbuf_writebyte(dbuf *f, u8 n) { dbuf_write(f, &n, 1); }