OSDN Git Service

まちBBSで削除レスがあるレス番号とスレの件数がずれる不具合を修正
[gikonavigoeson/gikonavi.git] / YofUtils.pas
index f89ee6a..5988f86 100644 (file)
@@ -1,7 +1,10 @@
 unit YofUtils;
 
-{
-       HttpApp \82Ì\83N\83\8d\81[\83\93\82â\82»\82Ì\91¼\8eG\97p\8aÖ\90\94
+{!
+\file          YofUtils.pas
+\brief HttpApp \82Ì\83N\83\8d\81[\83\93\82â\82»\82Ì\91¼\8eG\97p\8aÖ\90\94
+
+$Id: YofUtils.pas,v 1.10 2004/10/09 15:06:19 yoffy Exp $
 }
 interface
 
@@ -9,8 +12,13 @@ interface
 uses
 //==================================================
 
-       Classes, SysUtils;
+       Classes, SysUtils,
+       Windows;
 
+{!
+\brief         ExtractHttpFields \82Ì\83N\83\8d\81[\83\93
+\warning       \82Æ\82è\82 \82¦\82¸\82Ì\91ã\97p\95i\82È\82Ì\82Å chrWhite \82ð\8dl\97\82µ\82Ä\82¢\82È\82¢\82±\82Æ\82É\92\8d\88Ó\81I\81I\81I
+}
 procedure ExtractHttpFields(
        const chrSep : TSysCharSet;
        const chrWhite : TSysCharSet;
@@ -31,15 +39,104 @@ function HttpEncode(
        const strValue : string
 ) : string;
 
+function HttpDecode(
+       const strValue : string
+) : string;
+
+{!
+\brief         MachiesMask \82Ì\83N\83\8d\81[\83\93
+\warning       \82Æ\82è\82 \82¦\82¸\82Ì\91ã\97p\95i\82È\82Ì\82Å [] \82ð\8eg\82Á\82½\90³\8bK\95\\8c»\82ð\8dl\97\82µ\82Ä\82¢\82È\82¢\82±\82Æ\82É\92\8d\88Ó\81I\81I\81I
+}
 function MatchesMask(
        const filename, mask : string
 ) : boolean;
 
-// \83\81\83^\83L\83\83\83\89\83N\83^\82ð\90³\8bK\95\\8c»\88µ\82¢\82É\82È\82ç\82È\82¢\82æ\82¤\82É\92u\8a·
+//! \83\81\83^\83L\83\83\83\89\83N\83^\82ð\90³\8bK\95\\8c»\88µ\82¢\82É\82È\82ç\82È\82¢\82æ\82¤\82É\92u\8a·
 function RegExpEncode(
        const text : string
 ) : string;
 
+{!
+\brief         \95\\8e¦\83\81\83b\83Z\81[\83W\82Ì\90®\8c`
+\param         msg                             \95\\8e¦\82·\82é\83\81\83b\83Z\81[\83W
+\param         elements        \92u\8a·\92P\8cê
+
+msg \82Ì\92\86\82Ì\92u\8a·\82³\82ê\82é\92P\8cê\82Í '^\94Ô\8d\86\82Å\95\\82³\82ê\81A
+elements \82Í\89ü\8ds\82É\82æ\82Á\82Ä\92P\8cê\95ª\82¯\82³\82ê\82Ü\82·\81B<br>
+
+<pre><code>
+elements := IntToStr( 10 ) + #10 + 'hoge';
+m := MessageStyle(
+       '^0 \8cÂ\82Ì\81g^1\81h\82ð\92u\8a·\82µ\82Ü\82µ\82½\81B',
+       elements );
+</code></pre>
+
+\82Å\8fo\97Í\82³\82ê\82é m \82Í\81u10 \8cÂ\82Ì\81ghoge\81h\82ð\92u\8a·\82µ\82Ü\82µ\82½\81B\81v\82Æ\82È\82è\82Ü\82·\81B
+}
+function MessageStyle(
+       const msg                               : string;
+       const elements  : string
+) : string; overload;
+
+function MessageStyle(
+       const msg                               : string;
+       const elements  : TStringList
+) : string; overload;
+
+{!
+\brief \89E\89ñ\93]\83V\83t\83g
+\param v               \89ñ\93]\82·\82é\92l
+\param n               \89ñ\93]\83r\83b\83g\90\94
+\return        Longword( (v shl (32 - n)) or (v shr n) ) \82Ì\92l
+}
+function ror( v, n : Longword ) : Longword; register;
+
+{!
+\brief         \95\8e\9a\97ñ\82Ì\83n\83b\83V\83\85\92l\82ð\8cv\8eZ
+\param         s               \95\8e\9a\97ñ
+\return                \83n\83b\83V\83\85\92l ( 4 byte )
+\warning  \91½\83o\83C\83g\82ð 4 byte \82É\8fk\82ß\82Ä\82¢\82é\82½\82ß\81A
+                                       \93¯\82\92l\82ð\8fo\97Í\82·\82é\95\8e\9a\97ñ\82Í\96³\8cÀ\82É\91\8dÝ\82µ\82Ü\82·\81B
+                                       \83R\83\93\83t\83\8a\83N\83g\82ª\8bN\82±\82ç\82È\82¢\8e\96\82ð\91O\92ñ\82É\82µ\82½\8bL\8fq\82Í\94ð\82¯\82Ä\82­\82¾\82³\82¢\81B
+
+\82±\82Ì\8aÖ\90\94\82Í\91½\83o\83C\83g\92·\82Ì\95\8e\9a\97ñ\82ð 4 byte \82É\8fk\82ß\82Ü\82·\81B<br>
+\82»\82Ì\89ß\92ö\82Å\81A'abcdefgh' \82Æ 'efghabcd' \82ª\93¯\82\92l\82É\82È\82ç\82È\82¢\82æ\82¤\82É\82·\82é\93\99\81A
+\91½\8f­\95Î\82è\82ð\8fÈ\82­\82æ\82¤\82É\8dl\97\82³\82ê\82Ü\82·\81B
+}
+function GetStringHash( const s : string ) : Longword;
+
+type
+       //! Mode \92l\82ª\82¨\82©\82µ\82¢
+       EMappedFileModeError = class( Exception );
+       //! \83}\83b\83s\83\93\83O\82É\8e¸\94s
+       EMappedFileMappingError = class( Exception );
+
+       //! \83\81\83\82\83\8a\83}\83b\83v\83h\81E\83t\83@\83C\83\8b \83N\83\89\83X
+       TMappedFile = class( TObject )
+       private
+               FFileHandle                     : THandle;
+               FMappingHandle  : THandle;
+               FSize                                           : Int64;
+               FViewAddress            : Pointer;
+       public
+               {!
+               \brief  \83\81\83\82\83\8a\83}\83b\83v\83h\83t\83@\83C\83\8b\82Ì\8dì\90¬
+               \param  filePath                \8aJ\82­\83t\83@\83C\83\8b\82Ì\83p\83X
+               \param  mode                            fmOpenRead (\83f\83t\83H\83\8b\83g) \82Ü\82½\82Í fmOpenReadWrite
+               \param  maximumSize     \83y\81[\83W\83T\83C\83Y\82Ì\8fã\8cÀ (0 \82È\82ç\8c»\8dÝ\82Ì\83t\83@\83C\83\8b\83T\83C\83Y)
+               }
+               constructor Create(
+                       const filePath  : string;
+                       mode                                            : Longword = fmOpenRead;
+                       maximumSize                     : Int64 = 0 );
+               destructor      Destroy; override;
+
+               //! \83T\83C\83Y\82Ì\8eæ\93¾
+               property                Size            : Int64                 read FSize;
+               //! \83A\83h\83\8c\83X\82Ì\8eæ\93¾
+               property                Memory  : Pointer               read FViewAddress;
+       end;
+
 //==================================================
 const
 //==================================================
@@ -49,7 +146,8 @@ const
 implementation
 //==================================================
 
-// \82Æ\82è\82 \82¦\82¸\82Ì\91ã\97p\95i\82È\82Ì\82Å chrWhite \82ð\8dl\97\82µ\82Ä\82¢\82È\82¢\82±\82Æ\82É\92\8d\88Ó\81I\81I\81I
+uses MojuUtils;
+
 procedure ExtractHttpFields(
        const chrSep : TSysCharSet;
        const chrWhite : TSysCharSet;
@@ -192,25 +290,87 @@ begin
 
 end;
 
-// \82Æ\82è\82 \82¦\82¸\82Ì\91ã\97p\95i\82È\82Ì\82Å [] \82ð\8eg\82Á\82½\90³\8bK\95\\8c»\82ð\8dl\97\82µ\82Ä\82¢\82È\82¢\82±\82Æ\82É\92\8d\88Ó\81I\81I\81I
+function       toupper(
+       ch : Longword
+) : Byte; Register;
+asm
+       mov     ecx, eax                // ecx = (ch - 'a')
+       sub     cl, 'a'
+       cmp     ecx, 26                 // edx = ecx < 26 (\8f¬\95\8e\9a\82È\82ç\83t\83\8b\83r\83b\83g)
+       sbb     edx, edx
+       and     edx, $20                // edx &= 0x20 (\8f¬\95\8e\9a\82È\82ç 0x20)
+       xor     eax, edx                // eax ^= edx
+end;
+
+function HttpDecode(
+       const strValue : string
+) : string;
+var
+       i : Integer;
+       strLen : Integer;
+       strResult : string;
+       b : Integer;
+begin
+
+       strLen := Length( strValue );
+       i := 1;
+
+       while i <= strLen do
+       begin
+
+               if '%' = strValue[ i ] then begin
+                       Inc( i );
+                       if strValue[ i ] in ['a' .. 'z', 'A' .. 'Z'] then
+                               b := (toupper( Longword( strValue[ i ] ) ) - 55) shl 4
+                       else
+                               b := (Byte( strValue[ i ] ) - Byte( '0' )) shl 4;
+                       Inc( i );
+                       if strValue[ i ] in ['a' .. 'z', 'A' .. 'Z'] then
+                               b := b or (toupper( Longword( strValue[ i ] ) ) - 55)
+                       else
+                               b := b or (Byte( strValue[ i ] ) - Byte( '0' ));
+
+                       strResult := strResult + Char( Byte( b ) );
+               end else begin
+                       strResult := strResult + strValue[ i ];
+               end;
+
+               Inc( i );
+
+       end;
+
+       Result := strResult;
+
+end;
+
 function MatchesMask(
        const filename, mask : string
        ) : boolean;
 var
        pName, pMask : Integer;
+       ptrName, ptrMask : PChar;
        nameLen, maskLen : Integer;
        chrUpMask : char;
+       delimiterPos : Integer;
 begin
 
        nameLen := Length( filename );
        maskLen := Length( mask );
+       ptrName := PChar( filename );
+       ptrMask := PChar( mask );
        pName := 0;
        pMask := 0;
+       delimiterPos := Pos( '\', string( ptrName + pName ) );
+       while delimiterPos > 0 do
+       begin
+               pName := pName + delimiterPos;
+               delimiterPos := Pos( '\', string( ptrName + pName ) );
+       end;
 
        while (pMask < maskLen) and (pName < nameLen) do
        begin
 
-               case mask[ pMask ] of
+               case ptrMask[ pMask ] of
                '?':
                        begin
                                // \82±\82Ì 1 \8e\9a\82Í\89½\82à\82µ\82È\82¢
@@ -226,8 +386,8 @@ begin
                                end;
 
                                // * \82Ì\8e\9f\82Ì\95\8e\9a\82ª\97\88\82é\82Ü\82Å\94ò\82Î\82·
-                               chrUpMask := upcase( mask[ pMask ] );
-                               while chrUpMask <> UpCase( filename[ pName ] ) do
+                               chrUpMask := upcase( ptrMask[ pMask ] );
+                               while chrUpMask <> UpCase( ptrName[ pName ] ) do
                                begin
                                        pName := pName + 1;
                                        if pName >= nameLen then
@@ -238,7 +398,7 @@ begin
                                end;
 
                                // * \82Ì\8e\9f\82Ì\95\8e\9a\82ª\8c©\82Â\82©\82ç\82È\82©\82Á\82½\82ç\8fI\97¹
-                               if chrUpMask <> UpCase( filename[ pName ] ) then
+                               if chrUpMask <> UpCase( ptrName[ pName ] ) then
                                begin
                                        Result := false;
                                        exit;
@@ -250,7 +410,7 @@ begin
                else
                        begin
                                // \82±\82Ì 1 \95\8e\9a\82ª\88á\82Á\82½\82ç\8fI\97¹
-                               if UpCase( mask[ pMask ] ) <> UpCase( filename[ pName ] ) then
+                               if UpCase( ptrMask[ pMask ] ) <> UpCase( ptrName[ pName ] ) then
                                begin
                                        Result := false;
                                        exit;
@@ -272,8 +432,6 @@ begin
 
 end;
 
-
-// \83\81\83^\83L\83\83\83\89\83N\83^\82ð\90³\8bK\95\\8c»\88µ\82¢\82É\82È\82ç\82È\82¢\82æ\82¤\82É\92u\8a·
 function RegExpEncode(
        const text : string
 ) : string;
@@ -300,4 +458,140 @@ begin
 
 end;
 
+function MessageStyle(
+       const msg                               : string;
+       const elements  : string
+) : string;
+var
+       list                                            : TStringList;
+begin
+
+       list := TStringList.Create;
+       try
+               list.Text := elements;
+               Result := MessageStyle( msg, list );
+       finally
+               list.Free;
+       end;
+
+end;
+
+function MessageStyle(
+       const msg                               : string;
+       const elements  : TStringList
+) : string;
+var
+       i                                                               : Integer;
+begin
+
+       Result := msg;
+       for i := elements.Count - 1 downto 0 do
+               Result := CustomStringReplace( Result, '^' + IntToStr( i ), elements[ i ], false );
+
+end;
+
+//==============================
+// ror
+//==============================
+function ror( v, n : Longword ) : Longword; register;
+asm
+       mov             cl, dl
+       ror             eax, cl
+end;
+
+//==============================
+// GetStringHash
+//==============================
+function GetStringHash( const s : string ) : Longword;
+var
+       l                               : Integer;
+       v                               : Longword;
+       p, tail : PChar;
+begin
+
+       l                       := Length( s );
+       p                       := PChar( s );
+       v                       := $87654321;
+       tail    := p + (l and $fffffffc);
+       while p < tail do begin
+               v       := PDword( p )^ + (v shl 2) * ($10000 - v);
+               p := p + 4;
+       end;
+       tail    := PChar( s ) + l;
+       while p < tail do begin
+               v := PByte( p )^ + (v shl 2) * ($10000 - v);
+               Inc( p );
+       end;
+
+       Result := v xor ((v shl 2) * ($10000 - v));
+
+end;
+
+{ TMappedFile }
+
+constructor TMappedFile.Create(
+       const filePath  : string;
+       mode                                            : Longword = fmOpenRead;
+       maximumSize                     : Int64 = 0 );
+var
+       dwFileDesiredAccess     : DWORD;
+       flProtect                                               : DWORD;
+       dwViewDesiredAccess     : DWORD;
+begin
+
+       case mode of
+       fmOpenRead:
+               begin
+                       dwFileDesiredAccess     := GENERIC_READ;
+                       flProtect                                               := PAGE_READONLY;
+                       dwViewDesiredAccess     := FILE_MAP_READ;
+               end;
+
+       fmOpenReadWrite:
+               begin
+                       dwFileDesiredAccess     := GENERIC_READ or GENERIC_WRITE;
+                       flProtect                                               := PAGE_READWRITE;
+                       dwViewDesiredAccess     := FILE_MAP_WRITE;
+               end;
+
+       else
+               raise EMappedFileModeError.Create( '\83t\83@\83C\83\8b\83I\81[\83v\83\93\82Ì\83\82\81[\83h\82ª\95s\90³\82Å\82·\81B' );
+       end;
+
+       FFileHandle := CreateFile(
+               PChar( filePath ), dwFileDesiredAccess, 0, nil, OPEN_ALWAYS,
+               FILE_ATTRIBUTE_NORMAL, 0 );
+       if FFileHandle = INVALID_HANDLE_VALUE then
+// for Delphi 7
+//             raise EFOpenError.Create( '\83t\83@\83C\83\8b\82Ì\83I\81[\83v\83\93\82É\8e¸\94s\82µ\82Ü\82µ\82½\81B' );
+               raise EMappedFileMappingError.Create( '\83t\83@\83C\83\8b\82Ì\83I\81[\83v\83\93\82É\8e¸\94s\82µ\82Ü\82µ\82½\81B' );
+/////////////
+
+       FSize := GetFileSize( FFileHandle, nil );
+       if FSize < maximumSize then
+               FSize := maximumSize;
+
+       FMappingHandle := CreateFileMapping(
+               FFileHandle, nil, flProtect,
+               DWORD( (maximumSize shr 32) and $ffffffff ),
+               DWORD( maximumSize and $ffffffff ),
+               nil );
+       if FFileHandle = INVALID_HANDLE_VALUE then
+               raise EMappedFileMappingError.Create( '\83t\83@\83C\83\8b\82Ì\83}\83b\83s\83\93\83O\82É\8e¸\94s\82µ\82Ü\82µ\82½\81B' );
+
+       FViewAddress := MapViewOfFile( FMappingHandle, dwViewDesiredAccess, 0, 0, 0 );
+       if FViewAddress = nil then
+               raise EMappedFileMappingError.Create( '\83t\83@\83C\83\8b\82Ì\83}\83b\83s\83\93\83O\82É\8e¸\94s\82µ\82Ü\82µ\82½\81B' );
+
+end;
+
+destructor     TMappedFile.Destroy;
+begin
+
+       UnmapViewOfFile( FViewAddress );
+       CloseHandle( FMappingHandle );
+       CloseHandle( FFileHandle );
+
+end;
+
 end.