diff --git a/examplescripts/perfect5000.js b/examplescripts/perfect5000.js new file mode 100644 index 0000000..4e5a9d8 --- /dev/null +++ b/examplescripts/perfect5000.js @@ -0,0 +1,42 @@ + +// Some simple testing of new, eval and some string stuff. + +// constructor -- expression array initialization +function ExprArray(n,v) +{ + // Initializes n values to v coerced to a string. + for (var i = 0; i < n; i++) { + this[i] = "" + v; + } +} + + +// Print the perfect numbers up to n and the sum expression for n's divisors. +function perfect(n) +{ + trace("The perfect numbers up to " + n + " are:"); + + // We build sumOfDivisors[i] to hold a string expression for + // the sum of the divisors of i, excluding i itself. + var sumOfDivisors = new ExprArray(n+1,1); + for (var divisor = 2; divisor <= n; divisor++) { + for (var j = divisor + divisor; j <= n; j += divisor) { + sumOfDivisors[j] += " + " + divisor; + } + // At this point everything up to 'divisor' has its sumOfDivisors + // expression calculated, so we can determine whether it's perfect + // already by evaluating. + if (eval(sumOfDivisors[divisor]) == divisor) { + trace("" + divisor + " = " + sumOfDivisors[divisor]); + } + } + trace("That's all."); +} + + +trace("\nA number is 'perfect' if it is equal to the sum of its"); +trace("divisors (excluding itself).\n"); +var st=(new Date()).valueOf(); +perfect(5000); + var et=(new Date()).valueOf(); + trace(et-st,' milliseconds'); \ No newline at end of file diff --git a/src/BESENConstants.pas b/src/BESENConstants.pas index 9200bd3..3b88c45 100644 --- a/src/BESENConstants.pas +++ b/src/BESENConstants.pas @@ -31,6 +31,12 @@ unit BESENConstants; {$i BESEN.inc} + +{$define THRhash} +{$define THRhash2} + + + interface uses Math; diff --git a/src/BESENDateUtils.pas b/src/BESENDateUtils.pas index 6d06de4..e10594e 100644 --- a/src/BESENDateUtils.pas +++ b/src/BESENDateUtils.pas @@ -632,7 +632,7 @@ function BESENParseISOTime(s:TBESENString):TBESENDate; result:=double(pointer(@BESENDoubleNaN)^); exit; end; - result:=BESENMakeDay(StrToIntDef(copy(ss,1,4),0),StrToIntDef(copy(ss,5+(1*Offset),2),0),StrToIntDef(copy(ss,7+(2*Offset),2),0)); + result:=BESENMakeDay(StrToIntDef(copy(ss,1,4),0),StrToIntDef(copy(ss,5+(Offset),2),0),StrToIntDef(copy(ss,7+(Offset+Offset),2),0)); end; function ParseTime(const ss:TBESENString):TBESENDate; var s,ms:TBESENString; @@ -667,9 +667,10 @@ function BESENParseISOTime(s:TBESENString):TBESENDate; exit; end; Hours:=StrToIntDef(copy(s,1,2),100); - Minutes:=StrToIntDef(copy(s,3+(1*Offset),2),100); + //Minutes:=StrToIntDef(copy(s,3+(1*Offset),2),100); + Minutes:=StrToIntDef(copy(s,3+(Offset),2),100); if WithSeconds then begin - Seconds:=StrToIntDef(copy(s,5+(2*Offset),2),100); + Seconds:=StrToIntDef(copy(s,5+(Offset+Offset),2),100); end else begin Seconds:=0; if length(ms)>0 then begin diff --git a/src/BESENDeclarativeEnvironmentRecord.pas b/src/BESENDeclarativeEnvironmentRecord.pas index b3c8e72..b57d225 100644 --- a/src/BESENDeclarativeEnvironmentRecord.pas +++ b/src/BESENDeclarativeEnvironmentRecord.pas @@ -108,7 +108,9 @@ constructor TBESENDeclarativeEnvironmentRecord.Create(AInstance:TObject); FillChar(HashBuckets,sizeof(TBESENDeclarativeEnvironmentRecordHashBuckets),#0); First:=nil; Last:=nil; + HashSize:=256; + HashSizeMask:=HashSize-1; HashedItems:=0; HashBucketsUsed:=0; @@ -155,7 +157,9 @@ procedure TBESENDeclarativeEnvironmentRecord.Clear; First:=nil; Last:=nil; LastUsedItem:=nil; + HashSize:=256; + HashSizeMask:=HashSize-1; HashedItems:=0; HashBucketsUsed:=0; @@ -215,7 +219,9 @@ procedure TBESENDeclarativeEnvironmentRecord.GrowAndRehashIfNeeded; HashBucketsUsed:=0; Item:=First; while assigned(Item) do begin + Hash:=BESENHashKey(Item^.Key) and HashSizeMask; + Item^.Hash:=Hash; if assigned(HashBuckets[Hash].HashLast) then begin HashBuckets[Hash].HashLast^.HashNext:=Item; diff --git a/src/BESENHashMap.pas b/src/BESENHashMap.pas index 637ddde..3d6a1d3 100644 --- a/src/BESENHashMap.pas +++ b/src/BESENHashMap.pas @@ -176,7 +176,9 @@ procedure TBESENHashMap.GrowAndRehashIfNeeded; function TBESENHashMap.GetKey(const Key:TBESENString;Hash:TBESENHash=0):PBESENHashMapItem; begin + if assigned(LastUsedItem) and (LastUsedItem^.Key=Key) then begin + result:=LastUsedItem; Hash:=result^.Hash; end else begin @@ -185,9 +187,12 @@ function TBESENHashMap.GetKey(const Key:TBESENString;Hash:TBESENHash=0):PBESENHa end; Hash:=Hash and HashSizeMask; result:=HashBuckets[Hash].HashFirst; + while assigned(result) and (result^.Key<>Key) do begin result:=result^.HashNext; end; + + end; if assigned(result) then begin LastUsedItem:=result; diff --git a/src/BESENHashUtils.pas b/src/BESENHashUtils.pas index cc0ff21..52642bd 100644 --- a/src/BESENHashUtils.pas +++ b/src/BESENHashUtils.pas @@ -33,7 +33,12 @@ interface -uses BESENConstants,BESENTypes; +uses BESENConstants,BESENTypes +{$ifdef THRhash} +,thrHashUtils +{$endif} +; + function BESENHashKey(const Key:TBESENString):TBESENHash; function BESENDoubleHash(Hash:TBESENHash):TBESENHash; @@ -41,6 +46,11 @@ function BESENDoubleHash(Hash:TBESENHash):TBESENHash; implementation function BESENHashKey(const Key:TBESENString):TBESENHash; +{$ifdef THRhash} +begin + result:=thrHashKey(key); +end; +{$else} {$ifdef PurePascal} var i,h:longword; begin @@ -146,6 +156,7 @@ function BESENHashKey(const Key:TBESENString):TBESENHash; {$endif} {$endif} {$endif} +{$endif} function BESENDoubleHash(Hash:TBESENHash):TBESENHash; begin diff --git a/src/BESENLexer.pas b/src/BESENLexer.pas index 27242c6..6d26dfe 100644 --- a/src/BESENLexer.pas +++ b/src/BESENLexer.pas @@ -161,13 +161,18 @@ TBESENLexer=class(TBESENBaseObject) implementation -uses {$ifdef BESENEmbarcaderoNextGen}System.Character,{$endif}BESEN,BESENRegExp,BESENErrors,BESENNumberUtils; +uses {$ifdef BESENEmbarcaderoNextGen}System.Character,{$endif}BESEN,BESENRegExp,BESENErrors,BESENNumberUtils +{$ifdef THRhash} +,thrHashUtils +{$endif} +; type TKeywordToken=ltkBREAK..ltkYIELD; TKeyword=TKeywordToken; TKeywords=array of TKeyword; + TKeywordsHash=array of TBESENHash; const KeywordNames:array[TKeywordToken] of TBESENUTF16STRING= (// Used keywords @@ -189,6 +194,10 @@ implementation Keywords:TKeywords=nil; +{$ifdef THRhash2} + KeywordsHash:TKeywordsHash=nil; +{$endif} + constructor TBESENLexer.Create(AInstance:TObject); begin inherited Create(AInstance); @@ -550,12 +559,61 @@ procedure TBESENLexer.GetToken(var AResult:TBESENLexerToken); s:=''; end; + + function FindKeyword(const Name:TBESENUTF16STRING):TBESENLexerTokenType; var LowIndex,HighIndex,MiddleIndex:integer; + {$ifdef THRhash2} + aHash: TBESENHash; + aHash1: TBESENHash; + {$endif} begin result:=lttIDENTIFIER; LowIndex:=0; HighIndex:=length(Keywords)-1; + + {$ifdef THRhash2} + aHash:=thrHashKey(Name); + while LowIndex<=HighIndex do begin + case (HighIndex-LowIndex)+1 of + 1:begin + if KeywordsHash[ + Keywords[LowIndex] + ]=aHash then begin + result:=Keywords[LowIndex]; + end; + end; + 2:begin + if KeywordsHash[ + Keywords[LowIndex] + ]=aHash then begin + result:=Keywords[LowIndex]; + end else if KeywordsHash[ + Keywords[HighIndex] + ]=aHash then begin + result:=Keywords[HighIndex]; + end; + end; + else begin + MiddleIndex:=(LowIndex+HighIndex) div 2; + + aHash1 :=KeywordsHash[ Keywords[MiddleIndex] ]; + + if aHash1=aHash then begin + result:=Keywords[MiddleIndex]; + end else if LowIndex<>HighIndex then begin + if aHash1>aHash then begin + HighIndex:=MiddleIndex-1; + end else begin + LowIndex:=MiddleIndex+1; + end; + continue; + end; + end; + end; + break; + end; + {$else} while LowIndex<=HighIndex do begin case (HighIndex-LowIndex)+1 of 1:begin @@ -586,6 +644,8 @@ procedure TBESENLexer.GetToken(var AResult:TBESENLexerToken); end; break; end; + + {$endif} end; begin AResult.Name:=''; @@ -1370,13 +1430,47 @@ procedure InitKeywords; var kt:TKeywordToken; i:integer; k:TKeyword; + sz:integer; begin - SetLength(Keywords,(integer(high(TKeywordToken))-integer(low(TKeywordToken)))+1); + sz:=(integer(high(TKeywordToken))-integer(low(TKeywordToken)))+1; + + SetLength(Keywords,sz); + +{$ifdef THRhash2} + //tigra: add hash calc of keys + SetLength(KeywordsHash,sz); +{$endif} + i:=0; for kt:=low(TKeywordToken) to high(TKeywordToken) do begin Keywords[i]:=kt; + +{$ifdef THRhash2} + //tigra: calc hash and store + KeywordsHash[i]:=thrHashKey(KeywordNames[kt]); + {$endif} inc(i); end; + + //sort keywords by keywordNames + + {$ifdef THRhash2} + i:=0; + while (i+1)KeywordsHash[Keywords[i+1]] then begin + k:=Keywords[i]; + Keywords[i]:=Keywords[i+1]; + Keywords[i+1]:=k; + if i>0 then begin + dec(i); + end else begin + inc(i); + end; + end else begin + inc(i); + end; + end; + {$else} i:=0; while (i+1)KeywordNames[Keywords[i+1]] then begin @@ -1392,11 +1486,16 @@ procedure InitKeywords; inc(i); end; end; + {$endif} + end; procedure DoneKeywords; begin SetLength(Keywords,0); +{$ifdef THRhash2} + SetLength(KeywordsHash,0); +{$endif} end; procedure InitBESEN; diff --git a/src/BESENObject.pas b/src/BESENObject.pas index 51460af..141ebe5 100644 --- a/src/BESENObject.pas +++ b/src/BESENObject.pas @@ -496,7 +496,9 @@ constructor TBESENObjectPropertyContainer.Create(AInstance:TObject;ASorted:boole Last:=nil; EnumeratorFirst:=nil; EnumeratorLast:=nil; + HashSize:=256; + HashSizeMask:=HashSize-1; HashedItems:=0; HashBucketsUsed:=0; @@ -544,7 +546,9 @@ procedure TBESENObjectPropertyContainer.Clear; end; First:=nil; Last:=nil; + HashSize:=256; + HashSizeMask:=HashSize-1; HashedItems:=0; HashBucketsUsed:=0; diff --git a/src/BESENParser.pas b/src/BESENParser.pas index 3b6e486..7fe3f65 100644 --- a/src/BESENParser.pas +++ b/src/BESENParser.pas @@ -295,7 +295,9 @@ function TBESENParser.Parse(IsFunction,IsJSON:boolean):TBESENASTNode; OldToken:=CurrentToken; NextToken; if NextIsSemicolon then begin - if (length(OldToken.StringValue)=10) and (copy(Lexer.Source,OldToken.OldPosition,10)='use strict') then begin + if (length(OldToken.StringValue)=10) then begin + + if (copy(Lexer.Source,OldToken.OldPosition,10)='use strict') then begin if UseStrictAlreadyParsed then begin AddWarning('"use strict"/''use strict'' already seen!'); end else begin @@ -311,6 +313,8 @@ function TBESENParser.Parse(IsFunction,IsJSON:boolean):TBESENASTNode; end; end; end; + + end; FirstDirective:=false; end else begin IsDirectivePrologue:=false; diff --git a/src/BESENStringUtils.pas b/src/BESENStringUtils.pas index 52a88e0..5741b17 100644 --- a/src/BESENStringUtils.pas +++ b/src/BESENStringUtils.pas @@ -761,7 +761,8 @@ function BESENEncodeBase64(s:TBESENANSISTRING):TBESENANSISTRING; if l>1 then begin SetLength(result,l-1); end else begin - result:=BESENAnsiTrim(result); + //result:=BESENAnsiTrim(result); + result:=Trim(result); end; end; end; @@ -782,7 +783,7 @@ function BESENDequote(s:TBESENANSISTRING):TBESENANSISTRING; s:=s+#13#10; end; end; - p:=BESENANSIPosChar('=',s); + p:=Pos('=',s); while p>0 do begin encode:=ansichar(byte((pos(s[p+1],hexa) shl 4) or pos(s[p+2],hexa))); if encode=#0 then begin @@ -790,13 +791,13 @@ function BESENDequote(s:TBESENANSISTRING):TBESENANSISTRING; end; result:=result+copy(s,1,p-1)+encode; delete(s,1,p+2); - p:=BESENANSIPosChar('=',s); + p:=Pos('=',s); end; result:=result+s; - p:=BESENANSIPosChar('_',result); + p:=Pos('_',result); while p>0 do begin result[p]:=' '; - p:=BESENANSIPosChar('_',result); + p:=Pos('_',result); end; end; end; @@ -1190,7 +1191,7 @@ function BESENEncodeString(Value:TBESENANSISTRING;CharFrom:TBESENCharset;CharTo: inc(i); if c='-' then begin break; - end else if (c='=') or (BESENANSIPosChar(c,BESENBase64Chars)<1) then begin + end else if (c='=') or (Pos(c,BESENBase64Chars)<1) then begin dec(i); break; end; @@ -1243,7 +1244,7 @@ function BESENEncodeString(Value:TBESENANSISTRING;CharFrom:TBESENCharset;CharTo: end; end; s:=BESENEncodeBase64(s); - j:=BESENANSIPosChar('=',s); + j:=Pos('=',s); if j>0 then begin s:=copy(s,1,j-1); end; @@ -1402,60 +1403,60 @@ function BESENEncodeString(Value:TBESENANSISTRING;CharFrom:TBESENCharset;CharTo: function BESENGetCodePage(Value:TBESENANSISTRING):TBESENCharset; begin - Value:=BESENANSIUpperCase(Value); - if BESENANSIPos('ISO-8859-10',Value)>0 then begin + Value:=UpperCase(Value); + if Pos('ISO-8859-10',Value)>0 then begin result:=ISO_8859_10; - end else if BESENANSIPos('ISO-8859-1',Value)>0 then begin + end else if Pos('ISO-8859-1',Value)>0 then begin result:=ISO_8859_1; - end else if BESENANSIPos('ISO-8859-2',Value)>0 then begin + end else if Pos('ISO-8859-2',Value)>0 then begin result:=ISO_8859_2; - end else if BESENANSIPos('ISO-8859-3',Value)>0 then begin + end else if Pos('ISO-8859-3',Value)>0 then begin result:=ISO_8859_3; - end else if BESENANSIPos('ISO-8859-4',Value)>0 then begin + end else if Pos('ISO-8859-4',Value)>0 then begin result:=ISO_8859_4; - end else if BESENANSIPos('ISO-8859-5',Value)>0 then begin + end else if Pos('ISO-8859-5',Value)>0 then begin result:=ISO_8859_5; - end else if BESENANSIPos('ISO-8859-6',Value)>0 then begin + end else if Pos('ISO-8859-6',Value)>0 then begin result:=ISO_8859_6; - end else if BESENANSIPos('ISO-8859-7',Value)>0 then begin + end else if Pos('ISO-8859-7',Value)>0 then begin result:=ISO_8859_7; - end else if BESENANSIPos('ISO-8859-8',Value)>0 then begin + end else if Pos('ISO-8859-8',Value)>0 then begin result:=ISO_8859_8; - end else if BESENANSIPos('ISO-8859-9',Value)>0 then begin + end else if Pos('ISO-8859-9',Value)>0 then begin result:=ISO_8859_9; - end else if (BESENANSIPos('WINDOWS-1250',Value)>0) or (BESENANSIPos('X-CP1250',Value)>0) then begin + end else if (Pos('WINDOWS-1250',Value)>0) or (Pos('X-CP1250',Value)>0) then begin result:=CP1250; - end else if (BESENANSIPos('WINDOWS-1251',Value)>0) or (BESENANSIPos('X-CP1251',Value)>0) then begin + end else if (Pos('WINDOWS-1251',Value)>0) or (Pos('X-CP1251',Value)>0) then begin result:=CP1251; - end else if (BESENANSIPos('WINDOWS-1252',Value)>0) or (BESENANSIPos('X-CP1252',Value)>0) then begin + end else if (Pos('WINDOWS-1252',Value)>0) or (Pos('X-CP1252',Value)>0) then begin result:=CP1252; - end else if (BESENANSIPos('WINDOWS-1253',Value)>0) or (BESENANSIPos('X-CP1253',Value)>0) then begin + end else if (Pos('WINDOWS-1253',Value)>0) or (Pos('X-CP1253',Value)>0) then begin result:=CP1253; - end else if (BESENANSIPos('WINDOWS-1254',Value)>0) or (BESENANSIPos('X-CP1254',Value)>0) then begin + end else if (Pos('WINDOWS-1254',Value)>0) or (Pos('X-CP1254',Value)>0) then begin result:=CP1254; - end else if (BESENANSIPos('WINDOWS-1255',Value)>0) or (BESENANSIPos('X-CP1255',Value)>0) then begin + end else if (Pos('WINDOWS-1255',Value)>0) or (Pos('X-CP1255',Value)>0) then begin result:=CP1255; - end else if (BESENANSIPos('WINDOWS-1256',Value)>0) or (BESENANSIPos('X-CP1256',Value)>0) then begin + end else if (Pos('WINDOWS-1256',Value)>0) or (Pos('X-CP1256',Value)>0) then begin result:=CP1256; - end else if (BESENANSIPos('WINDOWS-1257',Value)>0) or (BESENANSIPos('X-CP1257',Value)>0) then begin + end else if (Pos('WINDOWS-1257',Value)>0) or (Pos('X-CP1257',Value)>0) then begin result:=CP1257; - end else if (BESENANSIPos('WINDOWS-1258',Value)>0) or (BESENANSIPos('X-CP1258',Value)>0) then begin + end else if (Pos('WINDOWS-1258',Value)>0) or (Pos('X-CP1258',Value)>0) then begin result:=CP1258; - end else if BESENANSIPos('KOI8-R',Value)>0 then begin + end else if Pos('KOI8-R',Value)>0 then begin result:=KOI8_R; - end else if BESENANSIPos('UTF-7',Value)>0 then begin + end else if Pos('UTF-7',Value)>0 then begin result:=UTF_7; - end else if BESENANSIPos('UTF-8',Value)>0 then begin + end else if Pos('UTF-8',Value)>0 then begin result:=UTF_8; - end else if BESENANSIPos('UTF-16',Value)>0 then begin + end else if Pos('UTF-16',Value)>0 then begin result:=UTF_16; - end else if BESENANSIPos('UTF-32',Value)>0 then begin + end else if Pos('UTF-32',Value)>0 then begin result:=UTF_32; - end else if BESENANSIPos('UCS-4',Value)>0 then begin + end else if Pos('UCS-4',Value)>0 then begin result:=UCS_4; - end else if BESENANSIPos('UCS-2',Value)>0 then begin + end else if Pos('UCS-2',Value)>0 then begin result:=UCS_2; - end else if BESENANSIPos('UNICODE',Value)>0 then begin + end else if Pos('UNICODE',Value)>0 then begin result:=UCS_2; end else begin result:=ISO_8859_1; @@ -1546,11 +1547,11 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; cs:TBESENCharset; begin result:=''; - us:=BESENANSIUpperCase(s); - p1:=BESENANSIPos('=?ISO',us); + us:=UpperCase(s); + p1:=Pos('=?ISO',us); while p1>0 do begin q:=copy(s,p1+2,length(s)); - p2:=BESENANSIPosChar('?',q); + p2:=Pos('?',q); if (p2=0) or (p2>=length(q)-2) or (q[p2+2]<>'?') then begin break; end; @@ -1558,7 +1559,7 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; cs:=BESENGetCodePage(e); encode:=TBESENCHAR(upcase(TBESENCHAR(q[p2+1]))); q:=copy(q,p2+3,length(q)); - p3:=BESENANSIPos('?=',q); + p3:=Pos('?=',q); if p3=0 then begin break; end; @@ -1575,18 +1576,18 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; inc(p1,2+p2+2+p3); delete(s,1,p1); delete(us,1,p1); - p1:=BESENANSIPos('=?ISO',us); + p1:=Pos('=?ISO',us); end; - p1:=BESENANSIPos('=?UTF-7',us); + p1:=Pos('=?UTF-7',us); while p1>0 do begin q:=copy(s,p1+2,length(s)); - p2:=BESENANSIPosChar('?',q); + p2:=Pos('?',q); if (p2=0) or (p2>=length(q)-2) or (q[p2+2]<>'?') then begin break; end; encode:=TBESENCHAR(upcase(TBESENCHAR(q[p2+1]))); q:=copy(q,p2+3,length(q)); - p3:=BESENANSIPos('?=',q); + p3:=Pos('?=',q); if p3=0 then begin break; end; @@ -1603,18 +1604,18 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; inc(p1,2+p2+2+p3); delete(s,1,p1); delete(us,1,p1); - p1:=BESENANSIPos('=?UTF-7',us); + p1:=Pos('=?UTF-7',us); end; - p1:=BESENANSIPos('=?UTF-8',us); + p1:=Pos('=?UTF-8',us); while p1>0 do begin q:=copy(s,p1+2,length(s)); - p2:=BESENANSIPosChar('?',q); + p2:=Pos('?',q); if (p2=0) or (p2>=length(q)-2) or (q[p2+2]<>'?') then begin break; end; encode:=TBESENCHAR(upcase(TBESENCHAR(q[p2+1]))); q:=copy(q,p2+3,length(q)); - p3:=BESENANSIPos('?=',q); + p3:=Pos('?=',q); if p3=0 then begin break; end; @@ -1630,12 +1631,12 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; inc(p1,2+p2+2+p3); delete(s,1,p1); delete(us,1,p1); - p1:=BESENANSIPos('=?UTF-8',us); + p1:=Pos('=?UTF-8',us); end; - p1:=BESENANSIPos('=?',us); + p1:=Pos('=?',us); while p1>0 do begin q:=copy(s,p1+2,length(s)); - p2:=BESENANSIPosChar('?',q); + p2:=Pos('?',q); if (p2=0) or (p2>=length(q)-2) or (q[p2+2]<>'?') then begin break; end; @@ -1645,12 +1646,12 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; result:=result+'=?'; delete(s,1,p1); delete(us,1,p1); - p1:=BESENANSIPos('=?',us); + p1:=Pos('=?',us); continue; end; encode:=TBESENCHAR(upcase(TBESENCHAR(q[p2+1]))); q:=copy(q,p2+3,length(q)); - p3:=BESENANSIPos('?=',q); + p3:=Pos('?=',q); if p3=0 then begin break; end; @@ -1667,7 +1668,7 @@ function BESENISOToUTF8(s:TBESENANSISTRING):TBESENANSISTRING; inc(p1,2+p2+2+p3); delete(s,1,p1); delete(us,1,p1); - p1:=BESENANSIPos('=?',us); + p1:=Pos('=?',us); end; result:=result+BESENEncodeString(s,ISO_8859_1,UTF_8); end; diff --git a/src/thrHashUtils.pas b/src/thrHashUtils.pas new file mode 100644 index 0000000..2124c69 --- /dev/null +++ b/src/thrHashUtils.pas @@ -0,0 +1,42 @@ +unit thrHashUtils; + +interface + +uses BESENTypes; + +function thrHashKey(const Key:TBESENString):TBESENHash; + +implementation + +(* +implementation of h*31 + *s simple and fast hashing function + +uint32_t X31_hash_string(const char *s) +{ + + khint_t h = *s; + for (++s ; *s; ++s) h = (h << 5) - h + *s; + return h; +} + +*) + + +function thrHashKey(const Key:TBESENString):TBESENHash; +var i,h:longword; +begin + if length(key)<1 then + begin + result:=0; + exit; + end; + + h:=ord(Key[1]); + for i:=2 to length(Key) do begin + h:=(h shl 5) - h + ord(Key[i]); + end; + + result:=h; +end; + +end.