// // aegis - project change supervisor // Copyright (C) 2001-2006, 2008 Peter Miller // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation; either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, see // . // #include #include #include static char etab[] = "`!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_"; output_uuencode::~output_uuencode() { // // Make sure all buffered data has been passed to our write_inner // method. // flush(); if (begun) { while (residual_bits > 0) { if (residual_bits < 6) { // fake a NUL character residual_value <<= 8; residual_bits += 8; } residual_bits -= 6; int n = (residual_value >> residual_bits); n &= 0x3F; obuf[opos++] = etab[n]; } if (ipos) { obuf[0] = etab[ipos]; obuf[opos++] = '\n'; deeper->write(obuf, opos); ipos = 0; opos = 1; // The length character } deeper->fputs("`\nend\n"); } } output_uuencode::output_uuencode(const output::pointer &arg) : deeper(arg), residual_value(0), residual_bits(0), opos(1), // The length character ipos(0), pos(0), bol(true), begun(false) { // // Figure out what to call ourself, // discarding any ".uu*" suffix. // nstring fn = deeper->filename(); const char *cp1 = fn.c_str(); const char *cp2 = strrchr(cp1, '/'); if (cp2) ++cp2; else cp2 = cp1; const char *cp3 = strstr(cp2, ".uu"); if (cp3) file_name = nstring(cp1, cp3 - cp1); else file_name = fn; } output::pointer output_uuencode::create(const output::pointer &arg) { return pointer(new output_uuencode(arg)); } void output_uuencode::write_inner(const void *p, size_t len) { if (!begun) { begun = true; deeper->fputs("begin 644 "); deeper->fputs(file_name); deeper->fputc('\n'); } const unsigned char *data = (const unsigned char *)p; if (len > 0) bol = (data[len - 1] == '\n'); pos += len; while (len > 0) { unsigned char c = *data++; --len; residual_value = (residual_value << 8) | c; ++ipos; residual_bits += 8; for (;;) { residual_bits -= 6; int n = (residual_value >> residual_bits); n &= 0x3F; obuf[opos++] = etab[n]; if (residual_bits == 0 && opos > 60) { obuf[0] = etab[ipos]; obuf[opos++] = '\n'; deeper->write(obuf, opos); opos = 1; // The length character ipos = 0; } if (residual_bits < 6) break; } } } nstring output_uuencode::filename() const { return file_name; } long output_uuencode::ftell_inner() const { return pos; } int output_uuencode::page_width() const { return 80; } int output_uuencode::page_length() const { return 66; } void output_uuencode::end_of_line_inner() { if (!bol) fputc('\n'); } const char * output_uuencode::type_name() const { return "uuencode"; }