实例介绍
【实例截图】
【核心代码】
{BTTorrent B编码(Bencoding)格式分析} unit DxBencoding; interface uses Classes,SysUtils,Generics.Collections; type (* Torrent文件格式 Multi-file Torrent 多文件 ├─announce ├─announce-list ├─comment ├─comment.utf-8 ├─creation date ├─encoding ├─info │ ├─files │ │ ├─length │ │ ├─path │ │ └─path.utf-8 │ ├─name │ ├─name.utf-8 │ ├─piece length │ ├─pieces │ ├─publisher │ ├─publisher-url │ ├─publisher-url.utf-8 │ └─publisher.utf-8 └─nodes Single-File Torrent 单文件 ├─announce ├─announce-list ├─comment ├─comment.utf-8 ├─creation date ├─encoding ├─info │ ├─length │ ├─name │ ├─name.utf-8 │ ├─piece length │ ├─pieces │ ├─publisher │ ├─publisher-url │ ├─publisher-url.utf-8 │ └─publisher.utf-8 └─nodes *) //B编码支持的数据类型 TDxBenValueTypes = (DBV_String,DBV_Int,DBV_List,DBV_Dictionary); //B编码的节点,类似于JSON节点, TDxBenValue = class private FParent: TDxBenValue; protected function GetType:TDxBenValueTypes; virtual; abstract; procedure Parser(str: string);virtual;abstract; function GetAsInteger: Integer;virtual;abstract; function GetAsString: string;virtual;abstract; function GetObject: TDxBenValue;virtual; public constructor Create;overload;virtual; constructor Create(str: string);overload;virtual; property ValueType: TDxBenValueTypes read GetType; function ToString: string;override; property Parent: TDxBenValue read FParent; property AsInteger: Integer read GetAsInteger; property AsString: string read GetAsString; property AsValueObject: TDxBenValue read GetObject; end; TDxBenInt = class(TDxBenValue) private FValue: Integer; protected function GetType:TDxBenValueTypes;override; function GetAsInteger: Integer;override; procedure Parser(str: string);override; function GetAsString: string;override; function GetObject: TDxBenValue;override; public constructor Create;override; function ToString: string;override; end; TDxBenString = class(TDxBenValue) private FValue: string; protected function GetType:TDxBenValueTypes;override; function GetAsString: string;override; function GetObject: TDxBenValue;override; function GetAsInteger: Integer;override; procedure Parser(str: string);override; public function ToString: string;override; end; TDxBenDictionary = class; TDxBenList = class(TDxBenValue) private FList: TList; function GetCount: Integer; function GetValues(index: Integer): TDxBenValue; protected procedure Parser(str: string);override; procedure ParserToList(var P: Pchar;List: TDxBenList); procedure ParserToDictionary(var p: PChar;Dict: TDxBenDictionary); function GetType:TDxBenValueTypes;override; function GetAsString: string;override; function GetObject: TDxBenValue;override; function GetAsInteger: Integer;override; public procedure Clear; constructor Create; override; constructor CreateFromString(str: string); destructor Destroy;override; function ToString: string;override; property Count: Integer read GetCount; property Values[index: Integer]: TDxBenValue read GetValues; end; TDxBenDictionary = class(TDxBenValue) private FDict: TDictionary<string,TDxBenValue>; function GetCount: Integer; function GetValues(Key: string): TDxBenValue; protected procedure ParserToList(var P: Pchar;List: TDxBenList); procedure ParserToDictionary(var p: PChar;Dict: TDxBenDictionary); procedure Parser(str: string);override; function GetType:TDxBenValueTypes;override; function GetAsString: string;override; function GetObject: TDxBenValue;override; function GetAsInteger: Integer;override; public procedure Clear; constructor Create;override; destructor Destroy;override; function ToString: string;override; property Count: Integer read GetCount; property Values[Key: string]: TDxBenValue read GetValues; end; TDxBtInfo = class(TDxBenDictionary) private function GetSingleFile: Boolean; function GetFiles: TDxBenList; function GetName: string; function GetNameUtf8: string; function Getpublisher: string; function GetpublisherUtf8: string; function Getpublisherurl: string; function GetpublisherurlUtf8: string; public property SingleFile: Boolean read GetSingleFile; property Files: TDxBenList read GetFiles; property Name: string read GetName; property NameUtf8: string read GetNameUtf8; property publisher: string read Getpublisher; property publisherUtf8: string read GetpublisherUtf8; property publisherurl: string read Getpublisherurl; property publisherurlUtf8: string read GetpublisherurlUtf8; end; TDxTorrentFile = class private FDict: TDxBenDictionary; procedure ParserStream(Stream: TStream;Dict: TDxBenDictionary);overload; procedure ParserStreamToList(Stream: TStream; List: TDxBenList); function GetComment: string; function GetEncoding: string; function GetCreator: string; function Getannounce: string; function Getannounce_list: TDxBenList; function GetBtInfo: TDxBtInfo; function GetCreateDate: TDateTime; public procedure Clear; constructor Create; destructor Destroy;override; procedure LoadFromFile(FileName: string); procedure LoadFromStream(Stream: TStream); property Comment: string read GetComment; property Encoding: string read GetEncoding; property Creator: string read GetCreator; property announce: string read Getannounce; property announce_list: TDxBenList read Getannounce_list; property BtInfo: TDxBtInfo read GetBtInfo; property CreateDate: TDateTime read GetCreateDate; end; implementation { TDxBenValue } constructor TDxBenValue.Create; begin FParent := nil; end; constructor TDxBenValue.Create(str: string); begin Create; Parser(str); end; function TDxBenValue.GetObject: TDxBenValue; begin Result := Self; end; function TDxBenValue.ToString: string; begin Result := ''; end; { TDxBenInt } constructor TDxBenInt.Create; begin inherited; FValue := 0; end; function TDxBenInt.GetAsInteger: Integer; begin Result := FValue; end; function TDxBenInt.GetAsString: string; begin Result := IntToStr(FValue); end; function TDxBenInt.GetObject: TDxBenValue; begin Result := Self; end; function TDxBenInt.GetType: TDxBenValueTypes; begin Result := DBV_Int; end; procedure TDxBenInt.Parser(str: string); var len: Integer; begin len := Length(str); if (UpperCase(str[1]) = 'I') and (UpperCase(str[len]) = 'E') then begin Str := Copy(str,2,len - 2); if not TryStrToInt(str,FValue) then raise Exception.Create('无效的B编码整数格式'); end else raise Exception.Create('无效的B编码整数格式'); end; function TDxBenInt.ToString: string; begin Result := 'i' inttostr(FValue) 'e'; end; { TDxBenString } function TDxBenString.GetAsInteger: Integer; begin raise Exception.Create('字符串类型数据'); end; function TDxBenString.GetAsString: string; begin Result := FValue; end; function TDxBenString.GetObject: TDxBenValue; begin Result := Self; end; function TDxBenString.GetType: TDxBenValueTypes; begin Result := DBV_String; end; procedure TDxBenString.Parser(str: string); var ipos: Integer; str1: string; begin FValue := ''; ipos := Pos(':',str); if ipos <= 1 then raise Exception.Create('无效的数据格式') else begin str1 := Copy(str,1,ipos - 1); if not TryStrToInt(str1,ipos) then raise Exception.Create('无效的数据格式'); FValue := Copy(str,ipos 1,ipos); end; end; function TDxBenString.ToString: string; var len: Integer; begin len := Length(FValue); if len > 0 then Result := IntToStr(len) ':' FValue else Result := ''; end; { TDxBenList } procedure TDxBenList.Clear; begin while FList.Count > 0 do begin TDxBenValue(FList[FList.Count - 1]).Free; FList.Delete(FList.Count - 1); end; end; constructor TDxBenList.Create; begin inherited; FList := TList.Create; end; constructor TDxBenList.CreateFromString(str: string); begin Create; Parser(str); end; destructor TDxBenList.Destroy; begin Clear; FList.Free; inherited; end; function TDxBenList.GetAsInteger: Integer; begin raise Exception.Create('列表不支持'); end; function TDxBenList.GetAsString: string; begin raise Exception.Create('列表不支持'); end; function TDxBenList.GetCount: Integer; begin Result := FList.Count; end; function TDxBenList.GetObject: TDxBenValue; begin Result := inherited; end; function TDxBenList.GetType: TDxBenValueTypes; begin Result := DBV_List; end; function TDxBenList.GetValues(index: Integer): TDxBenValue; begin if index in [0..FList.Count-1] then Result := FList[index] else Result := nil; end; procedure TDxBenList.Parser(str: string); var len: Integer; p: PChar; begin len := Length(str); Clear; if (UpperCase(str[1]) = 'L') and (UpperCase(str[len]) = 'E') then begin Str := Copy(str,2,len - 2); p := @str[1]; ParserToList(p,nil); end else raise Exception.Create('无效的B编码列表格式'); end; procedure TDxBenList.ParserToDictionary(var p: PChar; Dict: TDxBenDictionary); type TParserState = (PS_None,PS_Key,PS_Value); var t: Char; st: string; FInt: Integer; IntValue: TDxBenInt; ListValue: TDxBenList; StrValue: TDxBenString; DicValue: TDxBenDictionary; Parstate: TParserState; key: string; begin //开始解析 Parstate := PS_None; while p^ <> '' do begin t := P^; case t of 'i': begin //整数 if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); Inc(p); st := ''; while p^ <> 'e' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型i' st 'e'); IntValue := TDxBenInt.Create; IntValue.FValue := FInt; IntValue.FParent := Dict; Dict.FDict[Key] := IntValue; Inc(p); end; 'l': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); Inc(p); ListValue := TDxBenList.Create; ListValue.FParent := Dict; Dict.FDict[Key] := ListValue; ParserToList(p,ListValue); end; 'd': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); Inc(p); DicValue := TDxBenDictionary.Create; DicValue.FParent := Dict; Dict.FDict[Key] := DicValue; ParserToDictionary(p,DicValue); end; 'e': begin if Parstate = PS_Value then Parstate := PS_None else if Parstate = PS_None then Break; end; else begin st := ''; while p^ <> ':' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型' st); //读取字符串 Inc(p); if StrLen(p) < FInt then raise Exception.Create('字符串解析长度不够'); SetLength(st,Fint); Move(p^,Pointer(St)^,FInt*Sizeof(Char)); Inc(p,Fint); if Parstate = PS_None then begin key := st; if Dict.FDict.ContainsKey(st) then raise Exception.Create('字典存在重复信息'); Dict.FDict.Add(st,nil); Parstate := PS_Value; end else if Parstate = PS_Value then begin StrValue := TDxBenString.Create; StrValue.FParent := Dict; StrValue.FValue := st; Dict.FDict[Key] := StrValue; end; end; end; end; end; procedure TDxBenList.ParserToList(var P: PChar; List: TDxBenList); var t: Char; st: string; FInt: Integer; IntValue: TDxBenInt; ListValue: TDxBenList; StrValue: TDxBenString; DicValue: TDxBenDictionary; begin //开始解析 while p^ <> '' do begin t := P^; case t of 'i': begin //是一个整数 Inc(p); st := ''; while p^ <> 'e' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型i' st 'e'); IntValue := TDxBenInt.Create; IntValue.FValue := FInt; if List = nil then begin IntValue.FParent := Self; FList.Add(IntValue); end else begin IntValue.FParent := List; List.FList.Add(IntValue) end; Inc(p); end; 'l': begin //列表 Inc(p); ListValue := TDxBenList.Create; if List = nil then begin ListValue.FParent := Self; FList.Add(ListValue); end else begin ListValue.FParent := List; List.FList.Add(ListValue) end; ParserToList(p,ListValue); end; 'd': begin //字典 Inc(p); DicValue := TDxBenDictionary.Create; if List = nil then begin DicValue.FParent := Self; FList.Add(DicValue); end else begin DicValue.FParent := List; List.FList.Add(DicValue) end; ParserToDictionary(p,DicValue); end; 'e': Break;//结束了 else begin //字符串 st := ''; while p^ <> ':' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型' st); //读取字符串 Inc(p); if StrLen(p) < FInt then raise Exception.Create('字符串解析长度不够'); StrValue := TDxBenString.Create; SetLength(StrValue.FValue,Fint); Move(p^,Pointer(StrValue.FValue)^,FInt*Sizeof(Char)); if List = nil then begin StrValue.FParent := Self; FList.Add(StrValue); end else begin StrValue.FParent := List; List.FList.Add(StrValue) end; Inc(p,Fint); end; end; end; end; function TDxBenList.ToString: string; var i: Integer; V: TDxBenValue; begin for i := 0 to FList.Count - 1 do begin V := FList[i]; Result := Result V.ToString; end; end; { TDxBenDictionary } procedure TDxBenDictionary.Clear; var Pair: TPair<string,TDxBenValue>; begin for Pair in FDict do begin Pair.Value.Free; end; FDict.Clear; end; constructor TDxBenDictionary.Create; begin FDict := TDictionary<string,TDxBenValue>.Create; end; destructor TDxBenDictionary.Destroy; begin Clear; FDict.Free; inherited; end; function TDxBenDictionary.GetAsInteger: Integer; begin raise Exception.Create('字典不支持'); end; function TDxBenDictionary.GetAsString: string; begin raise Exception.Create('字典不支持'); end; function TDxBenDictionary.GetCount: Integer; begin Result := FDict.Count; end; function TDxBenDictionary.GetObject: TDxBenValue; begin Result := Self; end; function TDxBenDictionary.GetType: TDxBenValueTypes; begin Result := DBV_Dictionary; end; function TDxBenDictionary.GetValues(Key: string): TDxBenValue; begin if FDict.ContainsKey(Key) then Result := FDict[Key] else Result := nil; end; procedure TDxBenDictionary.Parser(str: string); var len: Integer; p: PChar; begin len := Length(str); Clear; if (UpperCase(str[1]) = 'D') and (UpperCase(str[len]) = 'E') then begin Str := Copy(str,2,len - 2); p := @str[1]; ParserToDictionary(p,Self); end else raise Exception.Create('无效的B编码字典格式'); end; procedure TDxBenDictionary.ParserToDictionary(var p: PChar; Dict: TDxBenDictionary); type TParserState = (PS_None,PS_Key,PS_Value); var t: Char; st: string; FInt: Integer; IntValue: TDxBenInt; ListValue: TDxBenList; StrValue: TDxBenString; DicValue: TDxBenDictionary; Parstate: TParserState; key: string; begin //开始解析 Parstate := PS_None; while p^ <> '' do begin t := P^; case t of 'i': begin //整数 if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); Inc(p); st := ''; while p^ <> 'e' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型i' st 'e'); IntValue := TDxBenInt.Create; IntValue.FValue := FInt; IntValue.FParent := Dict; Dict.FDict[Key] := IntValue; Inc(p); Parstate := PS_None; end; 'l': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); Inc(p); ListValue := TDxBenList.Create; ListValue.FParent := Dict; Dict.FDict[Key] := ListValue; ParserToList(p,ListValue); Parstate := PS_None; end; 'd': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); Inc(p); DicValue := TDxBenDictionary.Create; DicValue.FParent := Dict; Dict.FDict[Key] := DicValue; ParserToDictionary(p,DicValue); Parstate := PS_None; end; 'e': begin if Parstate = PS_Value then Parstate := PS_None else if Parstate = PS_None then Break; end; else begin st := ''; while p^ <> ':' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型' st); //读取字符串 Inc(p); if StrLen(p) < FInt then raise Exception.Create('字符串解析长度不够'); SetLength(st,Fint); Move(p^,Pointer(St)^,FInt*Sizeof(Char)); Inc(p,Fint); if Parstate = PS_None then begin key := st; if Dict.FDict.ContainsKey(st) then raise Exception.Create('字典存在重复信息'); Dict.FDict.Add(st,nil); Parstate := PS_Value; end else if Parstate = PS_Value then begin StrValue := TDxBenString.Create; StrValue.FParent := Dict; StrValue.FValue := st; Dict.FDict[Key] := StrValue; Parstate := PS_None; end; end; end; end; end; procedure TDxBenDictionary.ParserToList(var P: Pchar; List: TDxBenList); var t: Char; st: string; FInt: Integer; IntValue: TDxBenInt; ListValue: TDxBenList; StrValue: TDxBenString; DicValue: TDxBenDictionary; begin //开始解析 while p^ <> '' do begin t := P^; case t of 'i': begin //是一个整数 Inc(p); st := ''; while p^ <> 'e' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型i' st 'e'); IntValue := TDxBenInt.Create; IntValue.FValue := FInt; IntValue.FParent := List; List.FList.Add(IntValue); Inc(p); end; 'l': begin //列表 Inc(p); ListValue := TDxBenList.Create; ListValue.FParent := List; List.FList.Add(ListValue); ParserToList(p,ListValue); end; 'd': begin //字典 Inc(p); DicValue := TDxBenDictionary.Create; DicValue.FParent := List; List.FList.Add(DicValue); ParserToDictionary(p,DicValue); end; 'e': Break;//结束了 else begin //字符串 st := ''; while p^ <> ':' do begin if not CharInSet(p^, ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st p^; Inc(p); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型' st); //读取字符串 Inc(p); if StrLen(p) < FInt then raise Exception.Create('字符串解析长度不够'); StrValue := TDxBenString.Create; SetLength(StrValue.FValue,Fint); Move(p^,Pointer(StrValue.FValue)^,FInt*Sizeof(Char)); StrValue.FParent := List; List.FList.Add(StrValue); Inc(p,Fint); end; end; end; end; function TDxBenDictionary.ToString: string; begin end; { TDxTorrentFile } procedure TDxTorrentFile.Clear; begin FDict.Clear; end; constructor TDxTorrentFile.Create; begin inherited; FDict := TDxBenDictionary.Create; end; destructor TDxTorrentFile.Destroy; begin FDict.Free; inherited; end; function TDxTorrentFile.Getannounce: string; var F: TDxBenValue; begin F := FDict.Values['announce']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxTorrentFile.Getannounce_list: TDxBenList; begin Result := TDxBenList(FDict.Values['announce-list']); end; function TDxTorrentFile.GetBtInfo: TDxBtInfo; begin Result := TDxBtInfo(FDict.Values['info']); end; function TDxTorrentFile.GetComment: string; begin if FDict.FDict.ContainsKey('comment') then begin if CompareText(Encoding,'utf-8') = 0 then Result := UTF8Decode(FDict.Values['comment'].AsString) else result := FDict.Values['comment'].AsString end else result := ''; end; function SpanOfNowAndThen(const ANow, AThen: TDateTime): TDateTime; begin if ANow < AThen then Result := AThen - ANow else Result := ANow - AThen; end; function SecondSpan(const ANow, AThen: TDateTime): Double; begin Result := SecsPerDay * SpanOfNowAndThen(ANow, AThen); end; function TDxTorrentFile.GetCreateDate: TDateTime; var F: TDxBenValue; V: Double; begin F := FDict.Values['creation date']; if F <> nil then begin //是从1970年1月1日00:00:00到现在的秒数 Result := F.AsInteger; //V := StrToDate('1970-01-01');//25569 V := SecondSpan(Now,25569); V := (V - Result) / SecsPerDay; Result := Now - V end else Result := 0; end; function TDxTorrentFile.GetCreator: string; var F: TDxBenValue; begin F := FDict.Values['created by']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxTorrentFile.GetEncoding: string; begin if FDict.Values['encoding'] <> nil then Result := FDict.Values['encoding'].AsString else result := ''; end; procedure TDxTorrentFile.LoadFromFile(FileName: string); var F: TFileStream; begin F := TFileStream.Create(FileName,fmOpenRead); LoadFromStream(F); F.Free; end; procedure TDxTorrentFile.LoadFromStream(Stream: TStream); var c: Byte; begin Clear; Stream.ReadBuffer(c,1); if Char(c) = 'd' then ParserStream(Stream,FDict); end; procedure TDxTorrentFile.ParserStreamToList(Stream: TStream; List: TDxBenList); var t: Byte; st: Ansistring; FInt: Integer; IntValue: TDxBenInt; ListValue: TDxBenList; StrValue: TDxBenString; DicValue: TDxBenDictionary; begin while Stream.Position <> Stream.Size do begin Stream.ReadBuffer(t,SizeOf(t)); case Char(t) of 'i': begin //是一个整数 st := ''; Stream.ReadBuffer(t,SizeOf(t)); while Char(t) <> 'e' do begin if not CharInSet(Char(t), ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st Char(t); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型i' st 'e'); IntValue := TDxBenInt.Create; IntValue.FValue := FInt; IntValue.FParent := List; List.FList.Add(IntValue); end; 'l': begin //列表 ListValue := TDxBenList.Create; ListValue.FParent := List; List.FList.Add(ListValue); ParserStreamToList(Stream,ListValue); end; 'd': begin DicValue := TDxBenDictionary.Create; DicValue.FParent := List; List.FList.Add(DicValue); ParserStream(Stream,DicValue); end; 'e': Break; else begin st := ''; while Char(t) <> ':' do begin if not CharInSet(Char(t), ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st Char(t); Stream.ReadBuffer(t,SizeOf(t)); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型' st); //读取字符串 if Stream.Size - Stream.Position < FInt then raise Exception.Create('字符串解析长度不够'); SetLength(st,Fint); Stream.ReadBuffer(Pointer(st)^,Fint); StrValue := TDxBenString.Create; if CompareText(Encoding,'utf-8') = 0 then StrValue.FValue := UTF8Decode(st) else StrValue.FValue := st; StrValue.FParent := List; List.FList.Add(StrValue); end; end; end; end; procedure TDxTorrentFile.ParserStream(Stream: TStream;Dict: TDxBenDictionary); type TParserState = (PS_None,PS_Key,PS_Value); var t: Byte; st: Ansistring; FInt: Integer; IntValue: TDxBenInt; ListValue: TDxBenList; StrValue: TDxBenString; DicValue: TDxBenDictionary; Parstate: TParserState; key: string; begin Parstate := PS_None; while Stream.Position < Stream.Size do begin Stream.ReadBuffer(t,SizeOf(t)); case Char(t) of 'i': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); st := ''; Stream.ReadBuffer(t,SizeOf(t)); while Char(t) <> 'e' do begin if not CharInSet(Char(t), ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st Char(t); Stream.ReadBuffer(t,SizeOf(t)); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型i' st 'e'); IntValue := TDxBenInt.Create; IntValue.FValue := FInt; IntValue.FParent := Dict; Dict.FDict[Key] := IntValue; Parstate := PS_None; end; 'l': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); ListValue := TDxBenList.Create; ListValue.FParent := Dict; Dict.FDict[Key] := ListValue; ParserStreamToList(Stream,ListValue); Parstate := PS_None; end; 'd': begin if Parstate <> PS_Value then raise Exception.Create('B编码字典的Key必须是字符串!'); DicValue := TDxBenDictionary.Create; DicValue.FParent := Dict; Dict.FDict[Key] := DicValue; ParserStream(stream,DicValue); Parstate := PS_None; end; 'e': begin if Parstate = PS_Value then Parstate := PS_None else if Parstate = PS_None then Break; end; else begin st := ''; while Char(t) <> ':' do begin if not CharInSet(Char(t), ['-','0'..'9']) then raise Exception.Create('无效的数据类型'); st := st Char(t); Stream.ReadBuffer(t,SizeOf(t)); end; if not TryStrToInt(st,FInt) then raise Exception.Create('无效的数据类型' st); if Stream.Size - Stream.Position < FInt then raise Exception.Create('字符串解析长度不够'); SetLength(st,Fint); Stream.ReadBuffer(Pointer(st)^,Fint); if Parstate = PS_None then begin key := st; if Dict.FDict.ContainsKey(st) then raise Exception.Create('字典存在重复信息'); Dict.FDict.Add(st,nil); Parstate := PS_Value; end else if Parstate = PS_Value then begin StrValue := TDxBenString.Create; StrValue.FParent := Dict; if CompareText(Encoding,'utf-8') = 0 then StrValue.FValue := UTF8Decode(st) else StrValue.FValue := st; Dict.FDict[Key] := StrValue; Parstate := PS_None; end; end; end; end; end; { TDxBtInfo } function TDxBtInfo.GetFiles: TDxBenList; begin Result := TDxBenList(Values['files']) end; function TDxBtInfo.GetName: string; var F: TDxBenValue; begin F := Values['name']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxBtInfo.GetNameUtf8: string; var F: TDxBenValue; begin F := Values['name.utf-8']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxBtInfo.Getpublisher: string; var F: TDxBenValue; begin F := Values['publisher']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxBtInfo.Getpublisherurl: string; var F: TDxBenValue; begin F := Values['publisher-url']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxBtInfo.GetpublisherurlUtf8: string; var F: TDxBenValue; begin F := Values['publisher-url.utf8']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxBtInfo.GetpublisherUtf8: string; var F: TDxBenValue; begin F := Values['publisher.utf-8']; if F <> nil then Result := F.AsString else Result := ''; end; function TDxBtInfo.GetSingleFile: Boolean; begin Result := Files = nil; end; end.
标签: 种子
网友评论
小贴士
感谢您为本站写下的评论,您的评论对其它用户来说具有重要的参考价值,所以请认真填写。
- 类似“顶”、“沙发”之类没有营养的文字,对勤劳贡献的楼主来说是令人沮丧的反馈信息。
- 相信您也不想看到一排文字/表情墙,所以请不要反馈意义不大的重复字符,也请尽量不要纯表情的回复。
- 提问之前请再仔细看一遍楼主的说明,或许是您遗漏了。
- 请勿到处挖坑绊人、招贴广告。既占空间让人厌烦,又没人会搭理,于人于己都无利。
关于好例子网
本站旨在为广大IT学习爱好者提供一个非营利性互相学习交流分享平台。本站所有资源都可以被免费获取学习研究。本站资源来自网友分享,对搜索内容的合法性不具有预见性、识别性、控制性,仅供学习研究,请务必在下载后24小时内给予删除,不得用于其他任何用途,否则后果自负。基于互联网的特殊性,平台无法对用户传输的作品、信息、内容的权属或合法性、安全性、合规性、真实性、科学性、完整权、有效性等进行实质审查;无论平台是否已进行审查,用户均应自行承担因其传输的作品、信息、内容而可能或已经产生的侵权或权属纠纷等法律责任。本站所有资源不代表本站的观点或立场,基于网友分享,根据中国法律《信息网络传播权保护条例》第二十二与二十三条之规定,若资源存在侵权或相关问题请联系本站客服人员,点此联系我们。关于更多版权及免责申明参见 版权及免责申明
支持(0) 盖楼(回复)