diff --git a/harbour/ChangeLog b/harbour/ChangeLog index fb3fc5b0b5..9f83ac6757 100644 --- a/harbour/ChangeLog +++ b/harbour/ChangeLog @@ -8,6 +8,43 @@ 2002-12-01 13:30 UTC+0100 Foo Bar */ +2007-03-31 12:40 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) + * harbour/include/Makefile + + harbour/include/hbchksum.h + * harbour/source/rtl/Makefile + + harbour/source/rtl/hbadler.c + + harbour/source/rtl/hbcrc.c + + harbour/source/rtl/hbmd5.c + + added functions to calculate different checksums + HB_ADLER( [, ] ) -> + HB_CRC32( [, ] ) -> + HB_CRC16( [, ] ) -> + HB_CRC ( [, ] [, ] ) -> + HB_CRCCT( [, ] [, ] ) -> + HB_MD5( ) -> + HB_MD5FILE( ) -> + HB_CRC() is general CRC function which can be used for any polynomial + given as second argument, f.e.: 0x104C11DB7 is CRC32 polynomial, + 0x18005 -> CRC16, 0x11021 -> CRC16 X.26, 0x1393 -> CRC12, 0x101 -> LCR8 + HB_CRCCT() makes exactly the same job but it uses broken algorithm. + Unfortunately it seems that this broken version is widely used by many + other projects, f.e. HB_CRCCT() gives exactly the same results as + COM_CRC() from CT3. Generated results are usually "good enough" but + if you do not need compatibility with some other tools which uses + broken CRC algorithm then I suggest to not use it. + HB_ADLER() is ADLER32 check sum - this function gives the same results + as HB_CHECKSUM in xHarbour. + HB_MD5*() functions are from Dmitry V. Korzhov code modified a + little bit by me for other then x86@32 machines files and buffers + longer then 2^32. I also fixed possible problems with wrong results + in some cases. + + * harbour/source/compiler/hbmain.c + * increase number of optimization passes + + * harbour/source/pp/ppcore.c + * cleaned C compiler warning + 2007-03-30 18:50 UTC+0200 Przemyslaw Czerpak (druzus/at/priv.onet.pl) * harbour/source/pp/ppcore.c + added support for multiline string concatenated by ';' diff --git a/harbour/include/Makefile b/harbour/include/Makefile index 10bacf36e8..31b7096f86 100644 --- a/harbour/include/Makefile +++ b/harbour/include/Makefile @@ -16,6 +16,7 @@ C_HEADERS=\ hbapiitm.h \ hbapilng.h \ hbapirdd.h \ + hbchksum.h \ hbcomp.h \ hbcompdf.h \ hbdate.h \ diff --git a/harbour/include/hbchksum.h b/harbour/include/hbchksum.h new file mode 100644 index 0000000000..3d4047f1b9 --- /dev/null +++ b/harbour/include/hbchksum.h @@ -0,0 +1,65 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * header files for functions to calculate different checksums + * + * Copyright 2007 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + * 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 2, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbapi.h" + +HB_EXTERN_BEGIN + +HB_EXPORT ULONG hb_adler32( ULONG adler, const BYTE *buf, ULONG len ); +HB_EXPORT ULONG hb_crc16( ULONG crc, const BYTE *buf, ULONG len ); +HB_EXPORT ULONG hb_crc32( ULONG crc, const BYTE *buf, ULONG len ); +HB_EXPORT HB_ULONG hb_crc( HB_ULONG crc, const BYTE * buf, ULONG len, HB_ULONG poly ); +HB_EXPORT HB_ULONG hb_crcct( HB_ULONG crc, const BYTE * buf, ULONG len, HB_ULONG poly ); +HB_EXPORT void hb_md5( BYTE * ucData, ULONG ulLen, BYTE * ucDigest ); +HB_EXPORT void hb_md5file( FHANDLE hFile, BYTE * ucDigest ); + +HB_EXTERN_END diff --git a/harbour/source/compiler/hbmain.c b/harbour/source/compiler/hbmain.c index d1b0e18a6d..e0efd0aa12 100644 --- a/harbour/source/compiler/hbmain.c +++ b/harbour/source/compiler/hbmain.c @@ -3511,11 +3511,11 @@ static void hb_compOptimizeJumps( HB_COMP_DECL ) hb_compOptimizePCode( HB_COMP_PARAM, HB_COMP_PARAM->functions.pLast ); hb_compCodeTraceMarkDead( HB_COMP_PARAM, HB_COMP_PARAM->functions.pLast ); - for( iPass = 0; iPass < 3 && !HB_COMP_PARAM->fExit; ++iPass ) + for( iPass = 0; iPass < 4 && !HB_COMP_PARAM->fExit; ++iPass ) { LONG lOffset; - if( iPass == 2 && fLineStrip ) + if( iPass == 3 && fLineStrip ) { hb_compStripFuncLines( HB_COMP_PARAM->functions.pLast ); fLineStrip = FALSE; @@ -3814,7 +3814,7 @@ static void hb_compOptimizeJumps( HB_COMP_DECL ) HB_COMP_PARAM->functions.pLast->pNOOPs = NULL; HB_COMP_PARAM->functions.pLast->iNOOPs = 0; - if( iPass == 0 ) + if( iPass <= 1 ) { hb_compOptimizePCode( HB_COMP_PARAM, HB_COMP_PARAM->functions.pLast ); } diff --git a/harbour/source/pp/ppcore.c b/harbour/source/pp/ppcore.c index 0cdfdd1e4d..93a556f297 100644 --- a/harbour/source/pp/ppcore.c +++ b/harbour/source/pp/ppcore.c @@ -304,11 +304,13 @@ static void hb_membufFlush( PHB_MEM_BUFFER pBuffer ) pBuffer->ulLen = 0; } +#ifdef HB_PP_MULTILINE_STRING static void hb_membufRemove( PHB_MEM_BUFFER pBuffer, ULONG ulLeft ) { if( ulLeft < pBuffer->ulLen ) pBuffer->ulLen = ulLeft; } +#endif static ULONG hb_membufLen( PHB_MEM_BUFFER pBuffer ) { diff --git a/harbour/source/rtl/Makefile b/harbour/source/rtl/Makefile index 32e01e5fd1..14743a5951 100644 --- a/harbour/source/rtl/Makefile +++ b/harbour/source/rtl/Makefile @@ -48,6 +48,9 @@ C_SOURCES=\ gtfunc.c \ gx.c \ hardcr.c \ + hbadler.c \ + hbcrc.c \ + hbmd5.c \ hbffind.c \ hbgtcore.c \ hbinet.c \ diff --git a/harbour/source/rtl/hbadler.c b/harbour/source/rtl/hbadler.c new file mode 100644 index 0000000000..e981d7a603 --- /dev/null +++ b/harbour/source/rtl/hbadler.c @@ -0,0 +1,96 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * adler32 checksum function + * + * Copyright 2007 Przemyslaw Czerpak + * www - http://www.harbour-project.org + * + * Algorithm taken from adler32.c Copyright (C) 1995-2002 Mark Adler + * + * 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 2, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbapi.h" +#include "hbapierr.h" +#include "hbchksum.h" + +#define BASE 65521 /* largest prime smaller than 65536 */ +#define NMAX 5552 /* largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */ + +HB_EXPORT ULONG hb_adler32( ULONG adler, const BYTE *buf, ULONG len ) +{ + ULONG s1 = adler & 0xffff; + ULONG s2 = ( adler >> 16 ) & 0xffff; + + if( buf && len ) + { + do + { + int i = len < NMAX ? len : NMAX; + len -= i; + do + { + s1 += ( UCHAR ) *buf++; + s2 += s1; + } + while( --i ); + s1 %= BASE; + s2 %= BASE; + } + while( len ); + } + + return ( s2 << 16 ) | s1; +} + +HB_FUNC( HB_ADLER32 ) +{ + char * szString = hb_parc( 1 ); + + if( szString ) + hb_retnint( hb_adler32( ( ULONG ) hb_parnl( 2 ), ( BYTE * ) szString, hb_parclen( 1 ) ) ); + else + hb_errRT_BASE( EG_ARG, 3012, NULL, &hb_errFuncName, HB_ERR_ARGS_BASEPARAMS ); +} diff --git a/harbour/source/rtl/hbcrc.c b/harbour/source/rtl/hbcrc.c new file mode 100644 index 0000000000..4e98254f80 --- /dev/null +++ b/harbour/source/rtl/hbcrc.c @@ -0,0 +1,279 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * CRC checksum functions + * + * Copyright 2007 Przemyslaw Czerpak + * + * 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 2, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +#include "hbapi.h" +#include "hbapierr.h" +#include "hbchksum.h" + +/* X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 */ +/* 0x104C11DB7 => 0xEDB88320 */ +static const ULONG crc32_tab[ 256 ] = { + 0x00000000L, 0x77073096L, 0xEE0E612CL, 0x990951BAL, 0x076DC419L, + 0x706AF48FL, 0xE963A535L, 0x9E6495A3L, 0x0EDB8832L, 0x79DCB8A4L, + 0xE0D5E91EL, 0x97D2D988L, 0x09B64C2BL, 0x7EB17CBDL, 0xE7B82D07L, + 0x90BF1D91L, 0x1DB71064L, 0x6AB020F2L, 0xF3B97148L, 0x84BE41DEL, + 0x1ADAD47DL, 0x6DDDE4EBL, 0xF4D4B551L, 0x83D385C7L, 0x136C9856L, + 0x646BA8C0L, 0xFD62F97AL, 0x8A65C9ECL, 0x14015C4FL, 0x63066CD9L, + 0xFA0F3D63L, 0x8D080DF5L, 0x3B6E20C8L, 0x4C69105EL, 0xD56041E4L, + 0xA2677172L, 0x3C03E4D1L, 0x4B04D447L, 0xD20D85FDL, 0xA50AB56BL, + 0x35B5A8FAL, 0x42B2986CL, 0xDBBBC9D6L, 0xACBCF940L, 0x32D86CE3L, + 0x45DF5C75L, 0xDCD60DCFL, 0xABD13D59L, 0x26D930ACL, 0x51DE003AL, + 0xC8D75180L, 0xBFD06116L, 0x21B4F4B5L, 0x56B3C423L, 0xCFBA9599L, + 0xB8BDA50FL, 0x2802B89EL, 0x5F058808L, 0xC60CD9B2L, 0xB10BE924L, + 0x2F6F7C87L, 0x58684C11L, 0xC1611DABL, 0xB6662D3DL, 0x76DC4190L, + 0x01DB7106L, 0x98D220BCL, 0xEFD5102AL, 0x71B18589L, 0x06B6B51FL, + 0x9FBFE4A5L, 0xE8B8D433L, 0x7807C9A2L, 0x0F00F934L, 0x9609A88EL, + 0xE10E9818L, 0x7F6A0DBBL, 0x086D3D2DL, 0x91646C97L, 0xE6635C01L, + 0x6B6B51F4L, 0x1C6C6162L, 0x856530D8L, 0xF262004EL, 0x6C0695EDL, + 0x1B01A57BL, 0x8208F4C1L, 0xF50FC457L, 0x65B0D9C6L, 0x12B7E950L, + 0x8BBEB8EAL, 0xFCB9887CL, 0x62DD1DDFL, 0x15DA2D49L, 0x8CD37CF3L, + 0xFBD44C65L, 0x4DB26158L, 0x3AB551CEL, 0xA3BC0074L, 0xD4BB30E2L, + 0x4ADFA541L, 0x3DD895D7L, 0xA4D1C46DL, 0xD3D6F4FBL, 0x4369E96AL, + 0x346ED9FCL, 0xAD678846L, 0xDA60B8D0L, 0x44042D73L, 0x33031DE5L, + 0xAA0A4C5FL, 0xDD0D7CC9L, 0x5005713CL, 0x270241AAL, 0xBE0B1010L, + 0xC90C2086L, 0x5768B525L, 0x206F85B3L, 0xB966D409L, 0xCE61E49FL, + 0x5EDEF90EL, 0x29D9C998L, 0xB0D09822L, 0xC7D7A8B4L, 0x59B33D17L, + 0x2EB40D81L, 0xB7BD5C3BL, 0xC0BA6CADL, 0xEDB88320L, 0x9ABFB3B6L, + 0x03B6E20CL, 0x74B1D29AL, 0xEAD54739L, 0x9DD277AFL, 0x04DB2615L, + 0x73DC1683L, 0xE3630B12L, 0x94643B84L, 0x0D6D6A3EL, 0x7A6A5AA8L, + 0xE40ECF0BL, 0x9309FF9DL, 0x0A00AE27L, 0x7D079EB1L, 0xF00F9344L, + 0x8708A3D2L, 0x1E01F268L, 0x6906C2FEL, 0xF762575DL, 0x806567CBL, + 0x196C3671L, 0x6E6B06E7L, 0xFED41B76L, 0x89D32BE0L, 0x10DA7A5AL, + 0x67DD4ACCL, 0xF9B9DF6FL, 0x8EBEEFF9L, 0x17B7BE43L, 0x60B08ED5L, + 0xD6D6A3E8L, 0xA1D1937EL, 0x38D8C2C4L, 0x4FDFF252L, 0xD1BB67F1L, + 0xA6BC5767L, 0x3FB506DDL, 0x48B2364BL, 0xD80D2BDAL, 0xAF0A1B4CL, + 0x36034AF6L, 0x41047A60L, 0xDF60EFC3L, 0xA867DF55L, 0x316E8EEFL, + 0x4669BE79L, 0xCB61B38CL, 0xBC66831AL, 0x256FD2A0L, 0x5268E236L, + 0xCC0C7795L, 0xBB0B4703L, 0x220216B9L, 0x5505262FL, 0xC5BA3BBEL, + 0xB2BD0B28L, 0x2BB45A92L, 0x5CB36A04L, 0xC2D7FFA7L, 0xB5D0CF31L, + 0x2CD99E8BL, 0x5BDEAE1DL, 0x9B64C2B0L, 0xEC63F226L, 0x756AA39CL, + 0x026D930AL, 0x9C0906A9L, 0xEB0E363FL, 0x72076785L, 0x05005713L, + 0x95BF4A82L, 0xE2B87A14L, 0x7BB12BAEL, 0x0CB61B38L, 0x92D28E9BL, + 0xE5D5BE0DL, 0x7CDCEFB7L, 0x0BDBDF21L, 0x86D3D2D4L, 0xF1D4E242L, + 0x68DDB3F8L, 0x1FDA836EL, 0x81BE16CDL, 0xF6B9265BL, 0x6FB077E1L, + 0x18B74777L, 0x88085AE6L, 0xFF0F6A70L, 0x66063BCAL, 0x11010B5CL, + 0x8F659EFFL, 0xF862AE69L, 0x616BFFD3L, 0x166CCF45L, 0xA00AE278L, + 0xD70DD2EEL, 0x4E048354L, 0x3903B3C2L, 0xA7672661L, 0xD06016F7L, + 0x4969474DL, 0x3E6E77DBL, 0xAED16A4AL, 0xD9D65ADCL, 0x40DF0B66L, + 0x37D83BF0L, 0xA9BCAE53L, 0xDEBB9EC5L, 0x47B2CF7FL, 0x30B5FFE9L, + 0xBDBDF21CL, 0xCABAC28AL, 0x53B39330L, 0x24B4A3A6L, 0xBAD03605L, + 0xCDD70693L, 0x54DE5729L, 0x23D967BFL, 0xB3667A2EL, 0xC4614AB8L, + 0x5D681B02L, 0x2A6F2B94L, 0xB40BBE37L, 0xC30C8EA1L, 0x5A05DF1BL, + 0x2D02EF8DL +}; + +/* X^16+X^15+X^2+X^0 */ +/* 0x18005 => 0xA001 */ +static ULONG crc16_tab[] = +{ + 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, + 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, + 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, + 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, + 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, + 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, + 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, + 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, + 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, + 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, + 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, + 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, + 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, + 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, + 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, + 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, + 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, + 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, + 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, + 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, + 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, + 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, + 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, + 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, + 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, + 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, + 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, + 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, + 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, + 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, + 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, + 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 +}; + + +HB_EXPORT ULONG hb_crc32( ULONG crc, const BYTE *buf, ULONG len ) +{ + crc ^= 0xffffffffL; + if( buf && len ) + { + do + crc = crc32_tab[ ( crc ^ *buf++ ) & 0xFF ] ^ ( crc >> 8 ); + while( --len ); + } + return crc ^ 0xffffffffL; +} + +HB_EXPORT ULONG hb_crc16( ULONG crc, const BYTE *buf, ULONG len ) +{ + crc ^= 0xffff; + if( buf && len ) + { + do + crc = crc16_tab[ ( crc ^ *buf++ ) & 0xFF ] ^ ( crc >> 8 ); + while( --len ); + } + return crc ^ 0xffff; +} + +HB_EXPORT HB_ULONG hb_crc( HB_ULONG crc, const BYTE * buf, ULONG len, HB_ULONG poly ) +{ + if( buf && len ) + { + HB_ULONG mask = 1, revp = 0; + + while( poly > 1 ) + { + mask <<= 1; + revp <<= 1; + if( poly & 1 ) + revp |= 1; + poly >>= 1; + } + crc ^= --mask; + do + { + HB_ULONG b = ( crc ^ ( UCHAR ) * buf++ ) & 0xFF; + int i = 8; + do + b = b & 1 ? revp ^ ( b >> 1 ) : b >> 1; + while( --i ); + crc = b ^ ( crc >> 8 ); + } + while( --len ); + crc ^= mask; + } + return crc; +} + +HB_EXPORT HB_ULONG hb_crcct( HB_ULONG crc, const BYTE * buf, ULONG len, HB_ULONG poly ) +{ + if( buf && len ) + { + HB_ULONG mask, revp = poly; + int bits = 0; + + while( revp >>= 1 ) + ++bits; + mask = 1 << ( bits - 1 ); + bits -= 8; + do + { + int i = 8; + crc ^= ( HB_ULONG ) * buf++ << bits; + do + crc = crc & mask ? poly ^ ( crc << 1 ) : crc << 1; + while( --i ); + } + while( --len ); + crc &= ( mask << 1 ) - 1; + } + return crc; +} + +HB_FUNC( HB_CRC32 ) +{ + char * szString = hb_parc( 1 ); + + if( szString ) + hb_retnint( hb_crc32( ( ULONG ) hb_parnl( 2 ), ( BYTE * ) szString, hb_parclen( 1 ) ) ); + else + hb_errRT_BASE( EG_ARG, 3012, NULL, &hb_errFuncName, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_CRC16 ) +{ + char * szString = hb_parc( 1 ); + + if( szString ) + hb_retnint( hb_crc16( ( ULONG ) hb_parnl( 2 ), ( BYTE * ) szString, hb_parclen( 1 ) ) ); + else + hb_errRT_BASE( EG_ARG, 3012, NULL, &hb_errFuncName, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_CRC ) +{ + char * szString = hb_parc( 1 ); + + if( szString ) + { + HB_ULONG ulPolynomial = ( HB_ULONG ) hb_parnint( 3 ); + if( ulPolynomial == 0 ) + ulPolynomial = 0x11021; + hb_retnint( hb_crc( ( HB_ULONG ) hb_parnint( 2 ), ( BYTE * ) szString, hb_parclen( 1 ), ulPolynomial ) ); + } + else + hb_errRT_BASE( EG_ARG, 3012, NULL, &hb_errFuncName, HB_ERR_ARGS_BASEPARAMS ); +} + +HB_FUNC( HB_CRCCT ) +{ + char * szString = hb_parc( 1 ); + + if( szString ) + { + HB_ULONG ulPolynomial = ( HB_ULONG ) hb_parnint( 3 ); + if( ulPolynomial == 0 ) + ulPolynomial = 0x11021; + hb_retnint( hb_crcct( ( HB_ULONG ) hb_parnint( 2 ), ( BYTE * ) szString, hb_parclen( 1 ), ulPolynomial ) ); + } + else + hb_errRT_BASE( EG_ARG, 3012, NULL, &hb_errFuncName, HB_ERR_ARGS_BASEPARAMS ); +} diff --git a/harbour/source/rtl/hbmd5.c b/harbour/source/rtl/hbmd5.c new file mode 100644 index 0000000000..1011c11443 --- /dev/null +++ b/harbour/source/rtl/hbmd5.c @@ -0,0 +1,410 @@ +/* + * $Id$ + */ + +/* + * Harbour Project source code: + * Harbour MD5 Support + * + * Copyright 2004 Dmitry V. Korzhov + * + * Copyright 2007 Przemyslaw Czerpak + * updated and for current Harbour code, other then x86@32 machines, + * files and buffers longer then 2^32 and some fixes + * + * www - http://www.harbour-project.org + * + * 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 2, 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 software; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, + * Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/). + * + * As a special exception, the Harbour Project gives permission for + * additional uses of the text contained in its release of Harbour. + * + * The exception is that, if you link the Harbour libraries with other + * files to produce an executable, this does not by itself cause the + * resulting executable to be covered by the GNU General Public License. + * Your use of that executable is in no way restricted on account of + * linking the Harbour library code into it. + * + * This exception does not however invalidate any other reasons why + * the executable file might be covered by the GNU General Public License. + * + * This exception applies only to the code released by the Harbour + * Project under the name Harbour. If you copy code from other + * Harbour Project or Free Software Foundation releases into a copy of + * Harbour, as the General Public License permits, the exception does + * not apply to the code that you add in this way. To avoid misleading + * anyone as to the status of such modified files, you must delete + * this exception notice from them. + * + * If you write modifications of your own for Harbour, it is your choice + * whether to permit this exception to apply to your modifications. + * If you do not wish that, delete this exception notice. + * + */ + +/* +MD5 digest (based on RFC 1321 only). [x]Harbour implementation + +PRG functions: + + HB_MD5( ) -> + Calculates RFC 1321 MD5 digest (128-bit checksum) + Parameters: + - string variable to calculate MD5 + Returns: + ASCII hex MD5 digest as 32-byte string + empty string on error + + HB_MD5FILE( ) -> + Calculates RFC 1321 MD5 digest (128-bit checksum) of a file contents + (file size is limited by OS limits only) + Parameters: + - file name + Returns: + ASCII hex MD5 digest as 32-byte string + empty string on error + +C functions: + + void hb_md5( BYTE * data, ULONG datalen, BYTE * digest ) + Parameters: + data - input byte stream + datalen - input stream length + digest - raw (unformatted) MD5 digest buffer + (at least 16 bytes long) + + void hb_md5file( FHANDLE hFile, BYTE * digest ) + Parameters: + hFile - file handle + digest - raw (unformatted) MD5 digest buffer + (at least 16 bytes long) + +*/ + +#include "hbapi.h" +#include "hbapifs.h" +#include "hbchksum.h" + +/* MD5 buffer */ +typedef struct +{ + UINT32 accum[ 4 ]; + BYTE buf[ 64 ]; +} MD5_BUF; + +/* + Pseudofunctions; + A[x] - accumulators[4] + T[x] - Value table[64] + X[x] - buffer[16] +*/ +#define ROTL(x,n) ((x << n) | (x >> (32 - n))) +#define PF1(a,b,c,d,k,s,i) \ + A[a] = A[a] + ((A[b] & A[c]) | ((~A[b]) & A[d])) + X[k] + T[i]; \ + A[a] = ROTL(A[a], s) + A[b] +#define PF2(a,b,c,d,k,s,i) \ + A[a] = A[a] + ((A[b] & A[d]) | (A[c] & (~A[d]))) + X[k] + T[i]; \ + A[a] = ROTL(A[a], s) + A[b] +#define PF3(a,b,c,d,k,s,i) \ + A[a] = A[a] + (A[b] ^ A[c] ^ A[d]) + X[k] + T[i]; \ + A[a] = ROTL(A[a], s) + A[b] +#define PF4(a,b,c,d,k,s,i) \ + A[a] = A[a] + (A[c] ^(A[b] | (~A[d]))) + X[k] + T[i]; \ + A[a] = ROTL(A[a], s) + A[b] + +/* Defines for file ops */ +#define MAX_FBUF 0x20000 /* file read buffer size, MUST be 64*n */ + +/* Static data */ +static UINT32 T[ 64 ] = { + 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, + 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, + 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, + 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, + 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, + 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, + 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, + 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, + 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, + 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, + 0x289b7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, + 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, + 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, + 0x655b59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, + 0x6Fa87E4F, 0xFE2CE6e0, 0xA3014314, 0x4E0811A1, + 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 +}; + +static BYTE pad[ 64 ] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static void hb_md5go( MD5_BUF * md5 ) +{ + UINT32 X[ 16 ], A[ 4 ]; + BYTE * ptr; + int i; + + /* copy accumulators first */ + memcpy( A, md5->accum, sizeof( A ) ); + + /* fill buffer */ + for( i = 0, ptr = md5->buf; i < 16; i++, ptr += 4 ) + X[ i ] = HB_GET_LE_UINT32( ptr ); + + /* process buffer */ + PF1( 0, 1, 2, 3, 0, 7, 0 ); + PF1( 3, 0, 1, 2, 1, 12, 1 ); + PF1( 2, 3, 0, 1, 2, 17, 2 ); + PF1( 1, 2, 3, 0, 3, 22, 3 ); + PF1( 0, 1, 2, 3, 4, 7, 4 ); + PF1( 3, 0, 1, 2, 5, 12, 5 ); + PF1( 2, 3, 0, 1, 6, 17, 6 ); + PF1( 1, 2, 3, 0, 7, 22, 7 ); + PF1( 0, 1, 2, 3, 8, 7, 8 ); + PF1( 3, 0, 1, 2, 9, 12, 9 ); + PF1( 2, 3, 0, 1, 10, 17, 10 ); + PF1( 1, 2, 3, 0, 11, 22, 11 ); + PF1( 0, 1, 2, 3, 12, 7, 12 ); + PF1( 3, 0, 1, 2, 13, 12, 13 ); + PF1( 2, 3, 0, 1, 14, 17, 14 ); + PF1( 1, 2, 3, 0, 15, 22, 15 ); + PF2( 0, 1, 2, 3, 1, 5, 16 ); + PF2( 3, 0, 1, 2, 6, 9, 17 ); + PF2( 2, 3, 0, 1, 11, 14, 18 ); + PF2( 1, 2, 3, 0, 0, 20, 19 ); + PF2( 0, 1, 2, 3, 5, 5, 20 ); + PF2( 3, 0, 1, 2, 10, 9, 21 ); + PF2( 2, 3, 0, 1, 15, 14, 22 ); + PF2( 1, 2, 3, 0, 4, 20, 23 ); + PF2( 0, 1, 2, 3, 9, 5, 24 ); + PF2( 3, 0, 1, 2, 14, 9, 25 ); + PF2( 2, 3, 0, 1, 3, 14, 26 ); + PF2( 1, 2, 3, 0, 8, 20, 27 ); + PF2( 0, 1, 2, 3, 13, 5, 28 ); + PF2( 3, 0, 1, 2, 2, 9, 29 ); + PF2( 2, 3, 0, 1, 7, 14, 30 ); + PF2( 1, 2, 3, 0, 12, 20, 31 ); + PF3( 0, 1, 2, 3, 5, 4, 32 ); + PF3( 3, 0, 1, 2, 8, 11, 33 ); + PF3( 2, 3, 0, 1, 11, 16, 34 ); + PF3( 1, 2, 3, 0, 14, 23, 35 ); + PF3( 0, 1, 2, 3, 1, 4, 36 ); + PF3( 3, 0, 1, 2, 4, 11, 37 ); + PF3( 2, 3, 0, 1, 7, 16, 38 ); + PF3( 1, 2, 3, 0, 10, 23, 39 ); + PF3( 0, 1, 2, 3, 13, 4, 40 ); + PF3( 3, 0, 1, 2, 0, 11, 41 ); + PF3( 2, 3, 0, 1, 3, 16, 42 ); + PF3( 1, 2, 3, 0, 6, 23, 43 ); + PF3( 0, 1, 2, 3, 9, 4, 44 ); + PF3( 3, 0, 1, 2, 12, 11, 45 ); + PF3( 2, 3, 0, 1, 15, 16, 46 ); + PF3( 1, 2, 3, 0, 2, 23, 47 ); + PF4( 0, 1, 2, 3, 0, 6, 48 ); + PF4( 3, 0, 1, 2, 7, 10, 49 ); + PF4( 2, 3, 0, 1, 14, 15, 50 ); + PF4( 1, 2, 3, 0, 5, 21, 51 ); + PF4( 0, 1, 2, 3, 12, 6, 52 ); + PF4( 3, 0, 1, 2, 3, 10, 53 ); + PF4( 2, 3, 0, 1, 10, 15, 54 ); + PF4( 1, 2, 3, 0, 1, 21, 55 ); + PF4( 0, 1, 2, 3, 8, 6, 56 ); + PF4( 3, 0, 1, 2, 15, 10, 57 ); + PF4( 2, 3, 0, 1, 6, 15, 58 ); + PF4( 1, 2, 3, 0, 13, 21, 59 ); + PF4( 0, 1, 2, 3, 4, 6, 60 ); + PF4( 3, 0, 1, 2, 11, 10, 61 ); + PF4( 2, 3, 0, 1, 2, 15, 62 ); + PF4( 1, 2, 3, 0, 9, 21, 63 ); + + /* Update accumulators */ + md5->accum[ 0 ] += A[ 0 ]; + md5->accum[ 1 ] += A[ 1 ]; + md5->accum[ 2 ] += A[ 2 ]; + md5->accum[ 3 ] += A[ 3 ]; +} + +static void hb_md5accinit( UINT32 accum[] ) +{ + /* fill initial accumulator state */ + accum[ 0 ] = 0x67452301; + accum[ 1 ] = 0xEFCDAB89; + accum[ 2 ] = 0x98BADCFE; + accum[ 3 ] = 0x10325476; +} + +static void hb_md5val( UINT32 accum[], BYTE * md5val ) +{ + int i, n; + + for( i = 0; i < 4; i++ ) + { + for( n = 0; n < 4; n++ ) + *md5val++ = ( BYTE ) ( accum[ i ] >> ( n << 3 ) ) & 0xFF; + } +} + +static void hb_md5digest( BYTE * md5val, char * digest ) +{ + int i, b; + + for( i = 0; i < 16; i++ ) + { + b = ( md5val[ i ] >> 4 ) & 0x0F; + *digest++ = b + ( b > 9 ? 'a' - 10 : '0' ); + b = md5val[ i ] & 0x0F; + *digest++ = b + ( b > 9 ? 'a' - 10 : '0' ); + } +} + +HB_EXPORT void hb_md5( BYTE * ucData, ULONG ulLen, BYTE * ucDigest ) +{ + UCHAR buf[ 128 ]; + MD5_BUF md5; + int i, n; + + /* perform startup procedures */ + hb_md5accinit( md5.accum ); + /* count full 512bit blocks in data*/ + n = ulLen >> 6; + /* process full blocks */ + for( i = 0; i < n; i++, ucData += 64 ) + { + memcpy( md5.buf, ucData, 64 ); + hb_md5go( &md5 ); + } + /* prepare additional block(s) */ + n = ulLen & 63; + if( n ) + memcpy( buf, ucData, n ); + memcpy( buf + n, pad, 64 ); + /* count bits length */ + i = 56; + if( n > 56 ) + { + i += 64; + memcpy( md5.buf, buf, 64 ); + hb_md5go( &md5 ); + } + buf[ i++ ] = ( BYTE ) ( ulLen << 3 ) & 0xF8; + ulLen >>= 5; + for( n = 7; n; --n ) + { + buf[ i++ ] = ( BYTE ) ulLen & 0xFF; + ulLen >>= 8; + } + memcpy( md5.buf, buf + i - 64, 64 ); + hb_md5go( &md5 ); + /* write digest */ + hb_md5val( md5.accum, ucDigest ); +} + +HB_EXPORT void hb_md5file( FHANDLE hFile, BYTE * ucDigest ) +{ + MD5_BUF md5; + ULONG n; + int i; + HB_FOFFSET flen = 0; + UCHAR buf[ 128 ], * readbuf = ( UCHAR * ) hb_xgrab( MAX_FBUF ); + + hb_md5accinit( md5.accum ); + n = hb_fsReadLarge( hFile, readbuf, MAX_FBUF ); + flen += n; + while( n == MAX_FBUF ) + { + for( i = 0; i < ( MAX_FBUF >> 6 ); i++ ) + { + memcpy( md5.buf, readbuf + ( i << 6 ), 64 ); + hb_md5go( &md5 ); + } + n = hb_fsReadLarge( hFile, readbuf, MAX_FBUF ); + flen += n; + } + hb_fsClose( hFile ); + i = 0; + while( n > 64 ) + { + memcpy( md5.buf, readbuf + i, 64 ); + hb_md5go( &md5 ); + i += 64; + n -= 64; + } + if( n ) + memcpy( buf, readbuf + i, n ); + memcpy( buf + n, pad, 64 ); + i = 56; + if( n > 56 ) + { + i += 64; + memcpy( md5.buf, buf, 64 ); + hb_md5go( &md5 ); + } + buf[ i++ ] = ( BYTE ) ( flen << 3 ) & 0xF8; + flen >>= 5; + for( n = 7; n; --n ) + { + buf[ i++ ] = ( BYTE ) flen & 0xFF; + flen >>= 8; + } + memcpy( md5.buf, buf + i - 64, 64 ); + hb_md5go( &md5 ); + hb_md5val( md5.accum, ucDigest ); + hb_xfree( readbuf ); +} + +HB_FUNC( HB_MD5 ) +{ + char * pszStr = hb_parc( 1 ); + + if( pszStr ) + { + ULONG ulLen = hb_parclen( 1 ); + BYTE dststr[ 16 ]; + char digest[ 33 ]; + + hb_md5( ( BYTE * ) pszStr, ulLen, dststr ); + hb_md5digest( dststr, digest ); + hb_retclen( digest, 32 ); + } + else + hb_retc( NULL ); /* return empty string on wrong call */ +} + +HB_FUNC( HB_MD5FILE ) +{ + char * pszFile = hb_parc( 1 ); + + if( pszFile ) + { + FHANDLE hFile = hb_fsOpen( ( BYTE * ) pszFile, FO_READ ); + + if( hFile != FS_ERROR ) + { + BYTE dststr[ 16 ]; + char digest[ 33 ]; + + hb_md5file( hFile, dststr ); + hb_md5digest( dststr, digest ); + hb_retclen( digest, 32 ); + return; + } + } + hb_retc( NULL ); /* return empty string on wrong call */ +}