source: trunk/Demo/Packages/Common/UURI.pas

Last change on this file was 60, checked in by chronos, 12 years ago
File size: 8.7 KB
Line 
1unit UURI;
2
3// Date: 2011-04-04
4
5{$mode delphi}
6
7interface
8
9uses
10 Classes, SysUtils;
11
12const
13 URIPathSeparator = '/';
14
15type
16
17 { TPath }
18
19 TPath = class
20 private
21 function GetAsString: string;
22 procedure SetAsString(AValue: string);
23 public
24 Items: TStringList;
25 IsAbsolute: Boolean;
26 DirSeparator: string;
27 procedure Assign(Source: TPath);
28 constructor Create;
29 destructor Destroy; override;
30 property AsString: string read GetAsString write SetAsString;
31 end;
32
33 { TFileName }
34
35 TFileNamePart = (fnpDrive, fnpDirectory, fnpName, fnpExtension);
36 TFileNameParts = set of TFileNamePart;
37
38 TFileName = class
39 private
40 public
41 Drive: string;
42 Directory: TPath;
43 Name: string;
44 Extension: string;
45 function Combine(Parts: TFileNameParts = [fnpDrive, fnpDirectory, fnpName, fnpExtension]): string;
46 procedure Parse(AValue: string);
47 procedure Assign(Source: TFileName);
48 constructor Create;
49 destructor Destroy; override;
50 end;
51
52 { TURI }
53
54 TURI = class(TPersistent)
55 private
56 function GetAsString: string;
57 procedure SetAsString(Value: string);
58 public
59 Scheme: string;
60 Authority: string;
61 Path: TFileName;
62 Query: string;
63 Fragment: string;
64 constructor Create;
65 procedure Clear;
66 destructor Destroy; override;
67 procedure Assign(Source: TPersistent); override;
68 property AsString: string read GetAsString write SetAsString;
69 end;
70
71 { TURL }
72
73 TURL = class(TURI)
74 private
75 function GetAsString: string;
76 procedure SetAsString(Value: string);
77 public
78 UserName: string;
79 Password: string;
80 Host: string;
81 Port: Word;
82 constructor Create;
83 destructor Destroy; override;
84 property AsString: string read GetAsString write SetAsString;
85 end;
86
87implementation
88
89function LeftCutString(var Source: string; out Output: string; Delimiter: string; Allowed: string = ''): Boolean;
90var
91 I, J: Integer;
92 Matched: Boolean;
93begin
94 I := 1;
95 Matched := True;
96 while (I < Length(Source)) and Matched do begin
97 Matched := True;
98 if (Source[I] = Delimiter) then Matched := False;
99 //for J := 1 to Length(Allowed) do
100 // if Source[I] = Allowed[J] then Matched := True;
101 if Matched then Inc(I);
102 end;
103 if (Delimiter = Copy(Source, I, Length(Delimiter))) or (I = Length(Source)) then begin
104 Output := Copy(Source, 1, I - 1);
105 Delete(Source, 1, Length(Output) + Length(Delimiter));
106 Result := True;
107 end else begin
108 Output := '';
109 Result := False;
110 end;
111end;
112
113function RightCutString(var Source: string; out Output: string; Delimiter: string; Allowed: string = ''): Boolean;
114var
115 I, J: Integer;
116 Matched: Boolean;
117begin
118 I := Length(Source);
119 Matched := True;
120 while (I > 0) and Matched do begin
121 Matched := True;
122 if (Source[I] = Delimiter) then Matched := False;
123 //for J := 1 to Length(Allowed) do
124 // if Source[I] = Allowed[J] then Matched := True;
125 if Matched then Dec(I);
126 end;
127 if (Delimiter = Copy(Source, I - Length(Delimiter) + 1, Length(Delimiter))) or (I = 0) then begin
128 Output := Copy(Source, I + 1, Length(Source) - I);
129 Delete(Source, I, Length(Output) + Length(Delimiter));
130 Result := True;
131 end else begin
132 Output := '';
133 Result := False;
134 end;
135end;
136
137{ TPath }
138
139function TPath.GetAsString: string;
140var
141 I: Integer;
142begin
143 if IsAbsolute then Result := DirSeparator
144 else Result := '';
145 for I := 0 to Items.Count - 1 do
146 Result := Result + Items[I] + DirSeparator;
147end;
148
149procedure TPath.SetAsString(AValue: string);
150var
151 Name: string;
152begin
153 Items.Clear;
154 if Length(AValue) > 0 then begin
155 if AValue[1] = DirSeparator then begin
156 IsAbsolute := True;
157 Delete(AValue, 1, 1);
158 end else IsAbsolute := False;
159 while Pos(DirSeparator, AValue) > 0 do begin
160 Name := Copy(AValue, 1, Pos(DirSeparator, AValue) - 1);
161 Delete(AValue, 1, Pos(DirSeparator, AValue));
162 Items.Add(Name);
163 end;
164 if Length(AValue) > 0 then
165 Items.Add(AValue);
166 end else IsAbsolute := False;
167end;
168
169procedure TPath.Assign(Source: TPath);
170begin
171 IsAbsolute := Source.IsAbsolute;
172 Items.Assign(Source.Items);
173 DirSeparator := Source.DirSeparator;
174end;
175
176constructor TPath.Create;
177begin
178 Items := TStringList.Create;
179 DirSeparator := DirectorySeparator;
180end;
181
182destructor TPath.Destroy;
183begin
184 Items.Free;
185 inherited Destroy;
186end;
187
188{ TURI }
189
190function TURI.GetAsString: string;
191begin
192 Result := '';
193 if Scheme <> '' then Result := Scheme + ':';
194 if Path.Combine <> '' then begin
195 Result := Result + '//' + Authority;
196 if Scheme = 'file' then Result := Result + URIPathSeparator;
197 Result := Result + Path.Combine;
198 end;
199 if Query <> '' then Result := Result + '?' + Query;
200 if Fragment <> '' then Result := Result + '#' + Fragment;
201end;
202
203procedure TURI.SetAsString(Value: string);
204var
205 HostAddr: string;
206 HostPort: string;
207begin
208 LeftCutString(Value, Scheme, ':');
209 if Copy(Value, 1, 2) = '//' then begin
210 Value := Copy(Value, 3, Length(Value));
211 LeftCutString(Value, Authority, URIPathSeparator);
212 end;
213 RightCutString(Value, Fragment, '#');
214 RightCutString(Value, Query, '?', '=&');
215 //if Scheme = 'file' then Delete(Value, 1, 1); // Remove beginning slash
216 Path.Parse(Value);
217end;
218
219constructor TURI.Create;
220begin
221 Path := TFileName.Create;
222 Path.Directory.DirSeparator := URIPathSeparator;
223end;
224
225procedure TURI.Clear;
226begin
227 Scheme := '';
228 Authority := '';
229 Path.Parse('');
230 Fragment := '';
231 Query := '';
232end;
233
234destructor TURI.Destroy;
235begin
236 Path.Free;
237 inherited Destroy;
238end;
239
240procedure TURI.Assign(Source: TPersistent);
241begin
242 if Source is TURI then begin
243 Scheme := TURI(Source).Scheme;
244 Authority := TURI(Source).Authority;
245 Path.Assign(TURI(Source).Path);
246 Fragment := TURI(Source).Fragment;
247 Query := TURI(Source).Query;
248 end else inherited Assign(Source);
249end;
250
251{ TURL }
252
253function TURL.GetAsString: string;
254begin
255 Result := '';
256 if Scheme <> '' then Result := Scheme + '://';
257 if UserName <> '' then begin
258 Result := Result + UserName;
259 if UserName <> '' then Result := Result + ':' + Password;
260 Result := Result + '@';
261 end;
262 if Host <> '' then Result := Result + Host;
263 if Port <> 0 then Result := Result + ':' + IntToStr(Port);
264 if Path.Combine <> '' then Result := Result + Path.Combine;
265 if Query <> '' then Result := Result + '?' + Query;
266 if Fragment <> '' then Result := Result + '#' + Fragment;
267end;
268
269procedure TURL.SetAsString(Value: string);
270var
271 HostAddr: string;
272 HostPort: string;
273 TempPath: string;
274begin
275 LeftCutString(Value, Scheme, '://');
276 if LeftCutString(Value, UserName, ':') then LeftCutString(Value, Password, '@')
277 else LeftCutString(Value, UserName, '@');
278 RightCutString(Value, Fragment, '#');
279 RightCutString(Value, Query, '?', '=&');
280 if LeftCutString(Value, HostAddr, ':', '.') then begin
281 LeftCutString(Value, HostPort, '');
282 Port := StrToInt(HostPort);
283 end else LeftCutString(Value, HostAddr, '', '.');
284 Host := HostAddr;
285 LeftCutString(Value, TempPath, '', URIPathSeparator + '.');
286 Path.Parse(TempPath);
287end;
288
289constructor TURL.Create;
290begin
291
292end;
293
294destructor TURL.Destroy;
295begin
296 inherited Destroy;
297end;
298
299{ TFileName }
300
301function TFileName.Combine(Parts: TFileNameParts): string;
302begin
303 Result := '';
304 if (fnpDrive in Parts) and (Drive <> '') then Result := Result + Drive;
305 if (fnpDirectory in Parts) and (Directory.AsString <> '') then
306 Result := Result + Directory.AsString;
307 if (fnpName in Parts) then Result := Result + Name;
308 if (fnpExtension in Parts) and (Extension <> '') then
309 Result := Result + Extension;
310end;
311
312procedure TFileName.Parse(AValue: string);
313begin
314 if Pos(ExtensionSeparator, AValue) > 0 then begin
315 RightCutString(AValue, Extension, ExtensionSeparator);
316 Extension := ExtensionSeparator + Extension;
317 end else Extension := '';
318 if Pos(Directory.DirSeparator, AValue) > 0 then
319 RightCutString(AValue, Name, Directory.DirSeparator)
320 else begin
321 Name := AValue;
322 AValue := '';
323 end;
324 if Pos(DriveSeparator, AValue) > 0 then begin
325 LeftCutString(AValue, Drive, DriveSeparator);
326 Drive := Drive + DriveSeparator;
327 end else Drive := '';
328 Directory.AsString := AValue;
329end;
330
331procedure TFileName.Assign(Source: TFileName);
332begin
333 Name := Source.Name;
334 Extension := Source.Extension;
335 Drive := Source.Drive;
336 Directory.Assign(Source.Directory);
337end;
338
339constructor TFileName.Create;
340begin
341 Directory := TPath.Create;
342end;
343
344destructor TFileName.Destroy;
345begin
346 Directory.Free;
347 inherited Destroy;
348end;
349
350
351end.
352
Note: See TracBrowser for help on using the repository browser.