--- parser3/src/main/pa_uue.C 2003/01/29 12:02:24 1.4.2.2 +++ parser3/src/main/pa_uue.C 2020/12/15 17:10:37 1.19 @@ -1,18 +1,18 @@ /** @file Parser: uuencoding impl. - Copyright(c) 2000,2001, 2003 ArtLebedev Group(http://www.artlebedev.com) + Copyright (c) 2001-2020 Art. Lebedev Studio (http://www.artlebedev.com) Author: Alexandr Petrosian (http://paf.design.ru) @todo setrlimit */ -static const char* IDENT_UUE_C="$Date: 2003/01/29 12:02:24 $"; - #include "pa_config_includes.h" #include "pa_uue.h" -#include "pa_value_includes.h" +#include "pa_memory.h" + +volatile const char * IDENT_PA_UUE_C="$Id: pa_uue.C,v 1.19 2020/12/15 17:10:37 moko Exp $" IDENT_PA_UUE_H; static unsigned char uue_table[64] = { '`', '!', '"', '#', '$', '%', '&', '\'', @@ -24,25 +24,27 @@ static unsigned char uue_table[64] = { 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', '[', '\\',']', '^', '_' }; -void pa_uuencode(Pool& pool, String& result, ConstStringPtr file_name, const VFile& vfile) { + +const char* pa_uuencode(const unsigned char* in, size_t in_size, const char* file_name) { + int count=45; + + size_t new_size = ((in_size / 3 + 1) * 4); + new_size += 2 * new_size / (count / 3 * 4) /*chars in line + new lines*/ + 2; + new_size += strlen(file_name) + 11/*header*/ + 6/*footer*/ + 1/*zero terminator*/; + + const char* result=new(PointerFreeGC) char[new_size]; + char* optr=(char*)result; + //header - result << "content-transfer-encoding: x-uuencode\n" << "\n"; - result << "begin 644 " << *file_name << "\n"; + optr += sprintf(optr, "begin 644 %s\n", file_name); //body - const unsigned char *in=(const unsigned char *)vfile.value_ptr(); - size_t in_length=vfile.value_size(); - - int count=45; - for(const unsigned char *itemp=in; itemp<(in+in_length); itemp+=count) { + for(const unsigned char *itemp=in; itemp<(in+in_size); itemp+=count) { int index; - if((itemp+count)>(in+in_length)) - count=in_length-(itemp-in); + if((itemp+count)>(in+in_size)) + count=in_size-(itemp-in); - char *buf=new(pool) char[MAX_STRING]; - char *optr=buf; - /* * for UU and XX, encode the number of bytes as first character */ @@ -76,12 +78,14 @@ void pa_uuencode(Pool& pool, String& res /* * end of line */ - *optr++ = '\n'; - *optr = 0; - result << buf; + *optr++ = '\n'; } //footer - result.APPEND_AS_IS((const char *)uue_table, 1/* one char */, 0, 0) << "\n" - "end\n"; + optr += sprintf(optr, "`\nend\n"); + + //throw Exception(PARSER_RUNTIME, 0, "%d %d %d", in_size, new_size, (size_t)(optr-result)); + assert((size_t)(optr-result) < new_size); + + return result; }