亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? tntformatstrutils.pas

?? TNTUniCtrlsWithExceptions UniCode 國際化語言
?? PAS
字號:

{*****************************************************************************}
{                                                                             }
{    Tnt Delphi Unicode Controls                                              }
{      http://www.tntware.com/delphicontrols/unicode/                         }
{        Version: 2.3.0                                                       }
{                                                                             }
{    Copyright (c) 2002-2007, Troy Wolbrink (troy.wolbrink@tntware.com)       }
{                                                                             }
{*****************************************************************************}

unit TntFormatStrUtils;

{$INCLUDE TntCompilers.inc}

interface

// this unit provides functions to work with format strings

uses
  TntSysUtils;

function GetCanonicalFormatStr(const _FormatString: WideString): WideString;
{$IFNDEF COMPILER_9_UP}
function ReplaceFloatingArgumentsInFormatString(const _FormatString: WideString;
  const Args: array of const
    {$IFDEF COMPILER_7_UP}; FormatSettings: PFormatSettings{$ENDIF}): WideString;
{$ENDIF}
procedure CompareFormatStrings(FormatStr1, FormatStr2: WideString);
function FormatStringsAreCompatible(FormatStr1, FormatStr2: WideString): Boolean;

type
  EFormatSpecError = class(ETntGeneralError);

implementation

uses
  SysUtils, Math, TntClasses;

resourcestring
  SInvalidFormatSpecifier = 'Invalid Format Specifier: %s';
  SMismatchedArgumentTypes = 'Argument types for index %d do not match. (%s <> %s)';
  SMismatchedArgumentCounts = 'Number of format specifiers do not match.';

type
  TFormatSpecifierType = (fstInteger, fstFloating, fstPointer, fstString);

function GetFormatSpecifierType(const FormatSpecifier: WideString): TFormatSpecifierType;
var
  LastChar: WideChar;
begin
  LastChar := TntWideLastChar(FormatSpecifier);
  case LastChar of
    'd', 'D', 'u', 'U', 'x', 'X':
      result := fstInteger;
    'e', 'E', 'f', 'F', 'g', 'G', 'n', 'N', 'm', 'M':
      result := fstFloating;
    'p', 'P':
      result := fstPointer;
    's', 'S':
      result := fstString
    else
      raise ETntInternalError.CreateFmt('Internal Error: Unexpected format type (%s)', [LastChar]);
  end;
end;

type
  TFormatStrParser = class(TObject)
  private
    ParsedString: TBufferedWideString;
    PFormatString: PWideChar;
    LastIndex: Integer;
    ExplicitCount: Integer;
    ImplicitCount: Integer;
    procedure RaiseInvalidFormatSpecifier;
    function ParseChar(c: WideChar): Boolean;
    procedure ForceParseChar(c: WideChar);
    function ParseDigit: Boolean;
    function ParseInteger: Boolean;
    procedure ForceParseType;
    function PeekDigit: Boolean;
    function PeekIndexSpecifier(out Index: Integer): Boolean;
  public
    constructor Create(const _FormatString: WideString);
    destructor Destroy; override;
    function ParseFormatSpecifier: Boolean;
  end;

constructor TFormatStrParser.Create(const _FormatString: WideString);
begin
  inherited Create;
  PFormatString := PWideChar(_FormatString);
  ExplicitCount := 0;
  ImplicitCount := 0;
  LastIndex := -1;
  ParsedString := TBufferedWideString.Create;
end;

destructor TFormatStrParser.Destroy;
begin
  FreeAndNil(ParsedString);
  inherited;
end;

procedure TFormatStrParser.RaiseInvalidFormatSpecifier;
begin
  raise EFormatSpecError.CreateFmt(SInvalidFormatSpecifier, [ParsedString.Value + PFormatString]);
end;

function TFormatStrParser.ParseChar(c: WideChar): Boolean;
begin
  result := False;
  if PFormatString^ = c then begin
    result := True;
    ParsedString.AddChar(c);
    Inc(PFormatString);
  end;
end;

procedure TFormatStrParser.ForceParseChar(c: WideChar);
begin
  if not ParseChar(c) then
    RaiseInvalidFormatSpecifier;
end;

function TFormatStrParser.PeekDigit: Boolean;
begin
  result := False;
  if  (PFormatString^ <> #0)
  and (PFormatString^ >= '0')
  and (PFormatString^ <= '9') then
    result := True;
end;

function TFormatStrParser.ParseDigit: Boolean;
begin
  result := False;
  if PeekDigit then begin
    result := True;
    ForceParseChar(PFormatString^);
  end;
end;

function TFormatStrParser.ParseInteger: Boolean;
const
  MAX_INT_DIGITS = 6;
var
  digitcount: integer;
begin
  digitcount := 0;
  While ParseDigit do begin
    inc(digitcount);
  end;
  result := (digitcount > 0);
  if digitcount > MAX_INT_DIGITS then
    RaiseInvalidFormatSpecifier;
end;

procedure TFormatStrParser.ForceParseType;
begin
  if PFormatString^ = #0 then
    RaiseInvalidFormatSpecifier;

  case PFormatString^ of
    'd', 'u', 'x', 'e', 'f', 'g', 'n', 'm', 'p', 's',
    'D', 'U', 'X', 'E', 'F', 'G', 'N', 'M', 'P', 'S':
  begin
    // do nothing
  end
  else
    RaiseInvalidFormatSpecifier;
  end;
  ForceParseChar(PFormatString^);
end;

function TFormatStrParser.PeekIndexSpecifier(out Index: Integer): Boolean;
var
  SaveParsedString: WideString;
  SaveFormatString: PWideChar;
begin
  SaveParsedString := ParsedString.Value;
  SaveFormatString := PFormatString;
  try
    ParsedString.Clear;
    Result := False;
    Index := -1;
    if ParseInteger then begin
      Index := StrToInt(ParsedString.Value);
      if ParseChar(':') then
        Result := True;
    end;
  finally
    ParsedString.Clear;
    ParsedString.AddString(SaveParsedString);
    PFormatString := SaveFormatString;
  end;
end;

function TFormatStrParser.ParseFormatSpecifier: Boolean;
var
  ExplicitIndex: Integer;
begin
  Result := False;
  // Parse entire format specifier
  ForceParseChar('%');
  if (PFormatString^ <> #0)
  and (not ParseChar(' '))
  and (not ParseChar('%')) then begin
    if PeekIndexSpecifier(ExplicitIndex) then begin
      Inc(ExplicitCount);
      LastIndex := Max(LastIndex, ExplicitIndex);
    end else begin
      Inc(ImplicitCount);
      Inc(LastIndex);
      ParsedString.AddString(IntToStr(LastIndex));
      ParsedString.AddChar(':');
    end;
    if ParseChar('*') then
    begin
      Inc(ImplicitCount);
      Inc(LastIndex);
      ParseChar(':');
    end else if ParseInteger then
      ParseChar(':');
    ParseChar('-');
    if ParseChar('*') then begin
      Inc(ImplicitCount);
      Inc(LastIndex);
    end else
      ParseInteger;
    if ParseChar('.') then begin
      if not ParseChar('*') then
        ParseInteger;
    end;
    ForceParseType;
    Result := True;
  end;
end;

//-----------------------------------

function GetCanonicalFormatStr(const _FormatString: WideString): WideString;
var
  PosSpec: Integer;
begin
  with TFormatStrParser.Create(_FormatString) do
  try
    // loop until no more '%'
    PosSpec := Pos('%', PFormatString);
    While PosSpec <> 0 do begin
      try
        // delete everything up until '%'
        ParsedString.AddBuffer(PFormatString, PosSpec - 1);
        Inc(PFormatString, PosSpec - 1);
        // parse format specifier
        ParseFormatSpecifier;
      finally
        PosSpec := Pos('%', PFormatString);
      end;
    end;
    if ((ExplicitCount = 0) and (ImplicitCount = 1)) {simple expression}
    or ((ExplicitCount > 0) and (ImplicitCount = 0)) {nothing converted} then
      result := _FormatString {original}
    else
      result := ParsedString.Value + PFormatString;
  finally
    Free;
  end;
end;

{$IFNDEF COMPILER_9_UP}
function ReplaceFloatingArgumentsInFormatString(const _FormatString: WideString;
  const Args: array of const
    {$IFDEF COMPILER_7_UP}; FormatSettings: PFormatSettings{$ENDIF}): WideString;
{ This function replaces floating point format specifiers with their actual formatted values.
  It also adds index specifiers so that the other format specifiers don't lose their place.
  The reason for this is that WideFormat doesn't correctly format floating point specifiers.
  See QC#4254. }
var
  Parser: TFormatStrParser;
  PosSpec: Integer;
  Output: TBufferedWideString;
begin
  Output := TBufferedWideString.Create;
  try
    Parser := TFormatStrParser.Create(_FormatString);
    with Parser do
    try
      // loop until no more '%'
      PosSpec := Pos('%', PFormatString);
      While PosSpec <> 0 do begin
        try
          // delete everything up until '%'
          Output.AddBuffer(PFormatString, PosSpec - 1);
          Inc(PFormatString, PosSpec - 1);
          // parse format specifier
          ParsedString.Clear;
          if (not ParseFormatSpecifier)
          or (GetFormatSpecifierType(ParsedString.Value) <> fstFloating) then
            Output.AddBuffer(ParsedString.BuffPtr, MaxInt)
          {$IFDEF COMPILER_7_UP}
          else if Assigned(FormatSettings) then
            Output.AddString(Format{TNT-ALLOW Format}(ParsedString.Value, Args, FormatSettings^))
          {$ENDIF}
          else
            Output.AddString(Format{TNT-ALLOW Format}(ParsedString.Value, Args));
        finally
          PosSpec := Pos('%', PFormatString);
        end;
      end;
      Output.AddString(PFormatString);
    finally
      Free;
    end;
    Result := Output.Value;
  finally
    Output.Free;
  end;
end;
{$ENDIF}

procedure GetFormatArgs(const _FormatString: WideString; FormatArgs: TTntStrings);
var
  PosSpec: Integer;
begin
  with TFormatStrParser.Create(_FormatString) do
  try
    FormatArgs.Clear;
    // loop until no more '%'
    PosSpec := Pos('%', PFormatString);
    While PosSpec <> 0 do begin
      try
        // delete everything up until '%'
        Inc(PFormatString, PosSpec - 1);
        // add format specifier to list
        ParsedString.Clear;
        if ParseFormatSpecifier then
          FormatArgs.Add(ParsedString.Value);
      finally
        PosSpec := Pos('%', PFormatString);
      end;
    end;
  finally
    Free;
  end;
end;

function GetExplicitIndex(const FormatSpecifier: WideString): Integer;
var
  IndexStr: WideString;
  PosColon: Integer;
begin
  result := -1;
  PosColon := Pos(':', FormatSpecifier);
  if PosColon <> 0 then begin
    IndexStr := Copy(FormatSpecifier, 2, PosColon - 2);
    result := StrToInt(IndexStr);
  end;
end;

function GetMaxIndex(FormatArgs: TTntStrings): Integer;
var
  i: integer;
  RunningIndex: Integer;
  ExplicitIndex: Integer;
begin
  result := -1;
  RunningIndex := -1;
  for i := 0 to FormatArgs.Count - 1 do begin
    ExplicitIndex := GetExplicitIndex(FormatArgs[i]);
    if ExplicitIndex <> -1 then
      RunningIndex := ExplicitIndex
    else
      inc(RunningIndex);
    result := Max(result, RunningIndex);
  end;
end;

procedure UpdateTypeList(FormatArgs, TypeList: TTntStrings);
var
  i: integer;
  f: WideString;
  SpecType: TFormatSpecifierType;
  ExplicitIndex: Integer;
  MaxIndex: Integer;
  RunningIndex: Integer;
begin
  // set count of TypeList to accomodate maximum index
  MaxIndex := GetMaxIndex(FormatArgs);
  TypeList.Clear;
  for i := 0 to MaxIndex do
    TypeList.Add('');

  // for each arg...
  RunningIndex := -1;
  for i := 0 to FormatArgs.Count - 1 do begin
    f := FormatArgs[i];
    ExplicitIndex := GetExplicitIndex(f);
    SpecType := GetFormatSpecifierType(f);

    // determine running arg index
    if ExplicitIndex <> -1 then
      RunningIndex := ExplicitIndex
    else
      inc(RunningIndex);

    if TypeList[RunningIndex] <> '' then begin
      // already exists in list, check for compatibility
      if TypeList.Objects[RunningIndex] <> TObject(SpecType) then
        raise EFormatSpecError.CreateFmt(SMismatchedArgumentTypes,
          [RunningIndex, TypeList[RunningIndex], f]);
    end else begin
      // not in list so update it
      TypeList[RunningIndex] := f;
      TypeList.Objects[RunningIndex] := TObject(SpecType);
    end;
  end;
end;

procedure CompareFormatStrings(FormatStr1, FormatStr2: WideString);
var
  ArgList1: TTntStringList;
  ArgList2: TTntStringList;
  TypeList1: TTntStringList;
  TypeList2: TTntStringList;
  i: integer;
begin
  ArgList1 := nil;
  ArgList2 := nil;
  TypeList1 := nil;
  TypeList2 := nil;
  try
    ArgList1 := TTntStringList.Create;
    ArgList2 := TTntStringList.Create;
    TypeList1 := TTntStringList.Create;
    TypeList2 := TTntStringList.Create;

    GetFormatArgs(FormatStr1, ArgList1);
    UpdateTypeList(ArgList1, TypeList1);

    GetFormatArgs(FormatStr2, ArgList2);
    UpdateTypeList(ArgList2, TypeList2);

    if TypeList1.Count <> TypeList2.Count then
      raise EFormatSpecError.Create(SMismatchedArgumentCounts + CRLF + CRLF + '> ' + FormatStr1 + CRLF + '> ' + FormatStr2);

    for i := 0 to TypeList1.Count - 1 do begin
      if TypeList1.Objects[i] <> TypeList2.Objects[i] then begin
        raise EFormatSpecError.CreateFmt(SMismatchedArgumentTypes,
          [i, TypeList1[i], TypeList2[i]]);
      end;
    end;

  finally
    ArgList1.Free;
    ArgList2.Free;
    TypeList1.Free;
    TypeList2.Free;
  end;
end;

function FormatStringsAreCompatible(FormatStr1, FormatStr2: WideString): Boolean;
var
  ArgList1: TTntStringList;
  ArgList2: TTntStringList;
  TypeList1: TTntStringList;
  TypeList2: TTntStringList;
  i: integer;
begin
  ArgList1 := nil;
  ArgList2 := nil;
  TypeList1 := nil;
  TypeList2 := nil;
  try
    ArgList1 := TTntStringList.Create;
    ArgList2 := TTntStringList.Create;
    TypeList1 := TTntStringList.Create;
    TypeList2 := TTntStringList.Create;

    GetFormatArgs(FormatStr1, ArgList1);
    UpdateTypeList(ArgList1, TypeList1);

    GetFormatArgs(FormatStr2, ArgList2);
    UpdateTypeList(ArgList2, TypeList2);

    Result := (TypeList1.Count = TypeList2.Count);
    if Result then begin
      for i := 0 to TypeList1.Count - 1 do begin
        if TypeList1.Objects[i] <> TypeList2.Objects[i] then begin
          Result := False;
          break;
        end;
      end;
    end;
  finally
    ArgList1.Free;
    ArgList2.Free;
    TypeList1.Free;
    TypeList2.Free;
  end;
end;

end.

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲一区二区三区四区在线| 精品盗摄一区二区三区| 日本午夜精品一区二区三区电影| 国产亚洲欧洲997久久综合| 欧美人妇做爰xxxⅹ性高电影| 国产999精品久久久久久绿帽| 国产精品888| 97精品久久久午夜一区二区三区| 国产剧情一区二区| 99久久免费精品| 色综合久久99| 91色porny在线视频| 波多野结衣中文字幕一区二区三区| 99热精品国产| 67194成人在线观看| 欧美大片在线观看一区| 欧美videos大乳护士334| 国产精品午夜在线| 亚洲一区二区三区三| 蜜臀av国产精品久久久久| 国产高清一区日本| 国产精品一区二区男女羞羞无遮挡 | 亚洲免费观看视频| 亚洲电影在线播放| 国内偷窥港台综合视频在线播放| 国产精品免费看片| 国产精品久久久久久久久果冻传媒| 日韩一区二区三区视频在线观看| 久久综合丝袜日本网| 国产视频一区不卡| 天天操天天色综合| 成人午夜av电影| 欧美一区二区免费观在线| 国产精品激情偷乱一区二区∴| 亚洲mv大片欧洲mv大片精品| 中文字幕欧美国产| 日韩电影免费在线| 免费人成网站在线观看欧美高清| 99视频有精品| 久久久久久一二三区| 玉足女爽爽91| 国产激情一区二区三区四区| 91精品国产日韩91久久久久久| 久久综合九色综合97_久久久| 亚洲自拍偷拍综合| 成人av资源在线| 久久品道一品道久久精品| 视频一区在线播放| 在线一区二区三区做爰视频网站| 久久久久久**毛片大全| 日韩电影免费在线观看网站| 中文字幕在线一区免费| 国产老妇另类xxxxx| 日韩片之四级片| 五月开心婷婷久久| 在线免费观看不卡av| 国产精品久久久久久亚洲毛片 | 欧美另类高清zo欧美| 国产精品成人免费精品自在线观看| 精品在线一区二区三区| 91精品一区二区三区久久久久久 | 久久99精品久久久| 日韩一区二区三区高清免费看看| 亚洲日本在线看| a亚洲天堂av| 中文字幕一区二区视频| 成人高清伦理免费影院在线观看| 欧美激情在线免费观看| 国产馆精品极品| 国产欧美精品一区| www.在线欧美| 亚洲免费视频成人| 精品视频全国免费看| 五月天久久比比资源色| 欧美精品日韩一区| 日韩一二在线观看| 精品一区二区三区在线观看| 日韩精品资源二区在线| 久久99九九99精品| 国产精品天干天干在观线 | 一区二区在线观看免费 | 成人永久免费视频| 亚洲视频 欧洲视频| 在线亚洲一区观看| 天堂久久久久va久久久久| 欧美一区二区三区免费在线看| 天堂一区二区在线| 7777精品伊人久久久大香线蕉| 麻豆久久久久久| 欧美极品美女视频| 在线观看视频一区| 精品一区二区三区在线播放 | 亚洲国产精品激情在线观看| 99国产精品视频免费观看| 亚洲一区二三区| 日韩免费电影网站| 99综合电影在线视频| 午夜久久久久久久久| 久久久久久影视| 欧美视频在线一区二区三区 | 日本韩国欧美国产| 麻豆精品视频在线| 自拍偷拍亚洲综合| 蜜桃视频第一区免费观看| 国产欧美日韩激情| 欧美日韩亚洲综合一区| 国产精品中文欧美| 亚洲国产精品久久久男人的天堂| 2023国产精品| 色屁屁一区二区| 国产风韵犹存在线视精品| 亚洲欧美另类图片小说| 精品国产乱码久久久久久影片| 91同城在线观看| 国产一区二区视频在线| 一级特黄大欧美久久久| 国产欧美中文在线| 91精品国产91久久综合桃花 | 日本亚洲最大的色成网站www| 日本一区免费视频| 日韩欧美国产一二三区| 在线观看亚洲精品| 成人ar影院免费观看视频| 国内偷窥港台综合视频在线播放| 亚洲一区视频在线观看视频| 日本一区二区三区久久久久久久久不| 欧美人妖巨大在线| 欧美色视频在线观看| 一本色道久久综合狠狠躁的推荐 | 久久午夜羞羞影院免费观看| 欧美日韩一区三区四区| 一本色道久久综合亚洲aⅴ蜜桃| 国产精品你懂的在线| 欧美一区二区三区啪啪| 欧美性大战久久久久久久| 91视视频在线直接观看在线看网页在线看 | 国产亚洲精品免费| 日韩无一区二区| 777色狠狠一区二区三区| 欧美日韩一区二区三区免费看| 91丝袜高跟美女视频| av一区二区不卡| 成人激情文学综合网| 成人高清视频在线| 91在线视频免费观看| 国产一区二区三区在线观看精品| 老司机午夜精品| 亚洲美女免费视频| 亚洲男女一区二区三区| 国产日韩一级二级三级| 国产欧美精品一区| 久久精品网站免费观看| 国产日韩欧美一区二区三区综合| 久久精品亚洲精品国产欧美kt∨| 国产亚洲va综合人人澡精品| 欧美国产一区在线| 亚洲欧洲韩国日本视频| 亚洲人成网站在线| 性欧美疯狂xxxxbbbb| 日韩电影在线观看网站| 久久99精品久久久久久| 成人做爰69片免费看网站| 91麻豆高清视频| 欧美群妇大交群的观看方式| 日韩欧美一卡二卡| 99久久精品国产毛片| 成人免费视频播放| 在线观看一区不卡| 精品捆绑美女sm三区| 国产精品免费av| 亚洲一区二区三区小说| 美女在线一区二区| 成人免费视频视频| 欧美日韩亚洲综合一区| 久久亚洲一区二区三区四区| 国产精品福利一区| 首页综合国产亚洲丝袜| 国产精品一区二区在线播放 | 日韩电影在线观看电影| 国产成人免费视频网站| 在线观看91视频| 久久久另类综合| 午夜精品福利视频网站| 国产成人av电影在线| 欧美日韩视频在线第一区| 久久久亚洲午夜电影| 亚洲成人精品影院| 成人的网站免费观看| 欧美一区二区性放荡片| 亚洲天堂a在线| 久久99久久99| 欧美日韩国产一级片| 欧美—级在线免费片| 免费高清在线一区| 91国内精品野花午夜精品| 欧美极品少妇xxxxⅹ高跟鞋| 日韩福利视频网| 欧美性猛交xxxx乱大交退制版| 精品国产乱码久久久久久老虎| 欧美影视一区在线|