// // aegis - project change supervisor // Copyright (C) 2014 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 output_filter_base85::~output_filter_base85() { flush(); while (accumulator_nbytes) encode(0); if (column > 0) deeper_fputc('\n'); char buf[80]; snprintf ( buf, sizeof(buf), "xbtoa End N %lu %lx E %lx S %lx R %lx\n", content_length, content_length, check_xor, check_sum, check_rot ); deeper_fputs(buf); } output_filter_base85::output_filter_base85( const pointer &a_deeper ) : output_filter(a_deeper), accumulator(0), accumulator_nbytes(0), column(0), content_length(0), check_xor(0), check_sum(0), check_rot(0), bol(false) { deeper_fputs("xbtoa Begin\n"); } output::pointer output_filter_base85::create(const pointer &a_deeper) { return pointer(new output_filter_base85(a_deeper)); } #define MAXPERLINE 78 void output_filter_base85::char_out(unsigned char c) { deeper_fputc(c); ++column; if (column >= MAXPERLINE) { deeper_fputc('\n'); column = 0; } } void output_filter_base85::word_out(unsigned long word) { if (word == 0) { char_out('z'); } #if 0 else if (word == 0x20202020) { // If we are being conservative, we should not use this code, // because the very first btoa(1) did not use it. char_out('y'); } #endif else { unsigned char c5 = word % 85; word /= 85; unsigned char c4 = word % 85; word /= 85; unsigned char c3 = word % 85; word /= 85; unsigned char c2 = word % 85; word /= 85; assert(word < 83); unsigned char c1 = word; char_out('!' + c1); char_out('!' + c2); char_out('!' + c3); char_out('!' + c4); char_out('!' + c5); } } void output_filter_base85::encode(unsigned char c) { check_xor ^= c; check_sum += c + 1; check_rot = (check_rot << 1) | ((check_rot >> 31) & 1); check_rot = (check_rot + c) & 0xFFFFFFFF; accumulator |= c << ((3 - accumulator_nbytes) * 8); ++accumulator_nbytes; if (accumulator_nbytes >= 4) { word_out(accumulator); accumulator = 0; accumulator_nbytes = 0; } } void output_filter_base85::write_inner(const void *data, size_t size) { const char *start = (const char *)data; const char *end = start + size; const char *cp = start; content_length += size; while (cp < end) { unsigned char c = *cp++; encode(c); bol = (c == '\n'); } } nstring output_filter_base85::type_name(void) const { return ("base64 " + output_filter::type_name()); } void output_filter_base85::end_of_line_inner(void) { if (column > 0) { write_inner("\n", 1); } } long output_filter_base85::ftell_inner(void) const { return content_length; } // vim: set ts=8 sw=4 et :