/* * Help Access Library * A Library to access the contents of Windows Help files. * * Copyright (C) 1995-2000 Bernd Herd, http://www.herdsoft.com * * 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 of * the License. * * 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, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* HASH.C --------------------------------------------- * * @doc * @module HASH.C | * Computes the Hash-Code for a given Context-String. * * ISTOPIC-Project. * *-----------------------------------------------------*/ #include #include #include #include #include #include "hlpacces.h" #define FAKTOR 0x2B void LOCAL nNameForHash(LPSTR buf, DWORD Hash); /* @func DWORD | HlpGenerateHashValue | * * Computes a Hash-Value representing a Context-String (#-Footnote) using * the same algorithm Windows Help uses internally. * * @rdesc The 32-Bit Hash Value * @parm LPCSTR | lpszHashString | Pointer to the context-Striong, for example "IDH_CONTENTS" */ DWORD WINAPI DLLEXP HlpGenerateHashValue(LPCSTR p) { static int InitFlag = 0; static char MapTable[256]; DWORD h = 0; if(!InitFlag) /* set up char translation table */ { int i; for(i = 'A'; i <= 'Z'; ++i) MapTable[i] = (i - 'A') + 0x11; for(i = 'a'; i <= 'z'; ++i) MapTable[i] = (i - 'a') + 0x11; for(i = '1'; i <= '9'; ++i) MapTable[i] = (i - '1') + 0x01; MapTable['0'] = 0x0A; MapTable['.'] = 0x0C; MapTable['_'] = 0x0D; InitFlag = 1; } while(*p) { char c = MapTable[(unsigned char) *p++]; if(!c) continue; h = h * FAKTOR + c; } return h; } static LPCSTR StartVal[] = { "", "Ind", "con", "ID_", "IDH", "KEY", "ID", "cn", NULL }; /* @func void | HlpCreateStringForHashValue | * * Creates a String that has the same Hash-Code and can be used * to Transfer hash-code data to Winhelp as a context-String * for example in JumpId()-Macros and "-i"-command line Parameter. * * @comm This Function is implemented in a rather slow manner, so * do not call it more often than needed. */ void WINAPI DLLEXP HlpCreateStringForHashValue( DWORD HashValue, // @parm Hash-Code that shall be decoded LPSTR Buffer) // @parm Buffer for the decoded hash-Value. Minimum Size is 20 Bytes. { int StartChar='A'; BOOL HashCodeMatch; LPCSTR *StartNext = StartVal; do { if (*StartNext) strcpy(Buffer, *StartNext++); else sprintf(Buffer, "%c", StartChar++); nNameForHash(Buffer, HashValue); // From Hans-Peter Dittrich: Try to find a String for the Hash-Value HashCodeMatch = HlpGenerateHashValue(Buffer) == HashValue; } while (!HashCodeMatch && StartChar <= 'Z'); } /* HlpNameForHash ----------------------------------------------* * From Hans-Peter-Diettrich: * * Searches for a string that represents the given Hash-Value * *--------------------------------------------------------------*/ static BYTE cQ[] = "\0" "1234567890\0" "._\0\0\0"; // \0 illegal in strings void LOCAL nNameForHash(LPSTR buf, DWORD Hash) { DWORD hsoll = Hash; DWORD HashCode = HlpGenerateHashValue(buf); int dig0 = strlen(buf); int i, ndig; for (ndig = 0; ndig < 15; ++ndig) { DWORD l = HashCode; // hash0; for (i = 0; i < ndig; ++i) l *= FAKTOR; l = hsoll - l; for (i = ndig; --i >= 0; ) // i = 0; i < ndig; ++i) { int c = (int)(l % FAKTOR); // last char first! if (c > 0x10) c = (c - 0x10) + '@' + ' '; // ' ' für small! else { c = cQ[c]; if (!c) break; } buf[i+dig0] = c; l /= FAKTOR; } if (i < 0 && !l) // Ziel erreicht { buf[dig0+ndig] = 0; // if (SendDlgItemMessage(hDlg, L_TEXT, LB_ADDSTRING, 0, (LONG)(LPSTR)buf) < 0) goto fertig; } } fertig: ; }