diff --git a/ChangeLog.txt b/ChangeLog.txt index 73a2d1a74b..df1ab6be61 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -10,6 +10,21 @@ * Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment */ +2014-01-22 02:44 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) + ; modifications taken from Viktor's branch. + + * include/hb.ch + + added hbserial.ch + + * src/rtl/base64c.c + + HB_BASE64ENCODE(): added second parameter to request + specific line length for the output. Line length + should be specified in visible characters (w/o the + 2 EOL bytes). EOL is fixed to CRLF. + https://en.wikipedia.org/wiki/Base64 + ; probably there exist more optimal implementations + ; (code slightly modified) + 2014-01-21 20:41 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl) * Makefile * config/* diff --git a/include/hb.ch b/include/hb.ch index 1475edbc94..b5b11323fe 100644 --- a/include/hb.ch +++ b/include/hb.ch @@ -55,6 +55,7 @@ #include "fileio.ch" #include "hbgtinfo.ch" #include "hbhash.ch" +#include "hbserial.ch" #include "inkey.ch" #include "setcurs.ch" diff --git a/src/rtl/base64c.c b/src/rtl/base64c.c index b27920198d..0f9bfc1d61 100644 --- a/src/rtl/base64c.c +++ b/src/rtl/base64c.c @@ -55,51 +55,64 @@ HB_FUNC( HB_BASE64ENCODE ) if( len > 0 ) { - HB_SIZE dst = ( 4 * ( ( len + 2 ) / 3 ) + 1 ) * sizeof( char ); + HB_SIZE lin = hb_parns( 2 ); + HB_SIZE dst = ( 4 * ( ( len + 2 ) / 3 ) + 1 ); + + if( lin <= 2 ) + lin = 0; + + if( lin ) + dst += ( ( dst + lin - 1 ) / lin ) * 2; + dst *= sizeof( char ); if( dst > len ) { const char * s = hb_parcx( 1 ); - char * t, * p; + HB_SIZE lln = lin; t = p = ( char * ) hb_xgrab( dst ); while( len-- > 0 ) { + #define ADD_EOL() do { if( --lln == 0 ) { *p++ = '\r'; *p++ = '\n'; lln = lin; } } while( 0 ) + #define ADD_CHAR( c ) do { *p++ = s_b64chars[ ( c ) & 0x3F ]; ADD_EOL(); } while( 0 ) + #define ADD_EQ() do { *p++ = '='; ADD_EOL(); } while( 0 ) static const char s_b64chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; int x, y; x = *s++; - - *p++ = s_b64chars[ ( x >> 2 ) & 0x3F ]; - + ADD_CHAR( x >> 2 ); if( len-- == 0 ) { - *p++ = s_b64chars[ ( x << 4 ) & 0x3F ]; - *p++ = '='; - *p++ = '='; + ADD_CHAR( x << 4 ); + ADD_EQ(); + ADD_EQ(); break; } + y = *s++; - - *p++ = s_b64chars[ ( ( x << 4 ) | ( ( y >> 4 ) & 0x0F ) ) & 0x3F ]; - + ADD_CHAR( ( x << 4 ) | ( ( y >> 4 ) & 0x0F ) ); if( len-- == 0 ) { - *p++ = s_b64chars[ ( y << 2 ) & 0x3F ]; - *p++ = '='; + ADD_CHAR( y << 2 ); + ADD_EQ(); break; } x = *s++; + ADD_CHAR( ( y << 2 ) | ( ( x >> 6 ) & 0x03 ) ); + ADD_CHAR( x ); + } - *p++ = s_b64chars[ ( ( y << 2 ) | ( ( x >> 6 ) & 3 ) ) & 0x3F ]; - *p++ = s_b64chars[ x & 0x3F ]; + if( lin && lin != lln ) + { + *p++ = '\r'; + *p++ = '\n'; } *p = '\0'; - hb_retc_buffer( t ); + hb_retclen_buffer( t, p - t ); } else hb_errRT_BASE( EG_STROVERFLOW, 9999, NULL, HB_ERR_FUNCNAME, HB_ERR_ARGS_BASEPARAMS );