Develop and Download Open Source Software

Browse CVS Repository

Diff of /gikonavigoeson/gikonavi/GikoXMLDoc.pas

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.2.2.2 by yoffy, Thu Sep 9 16:20:33 2004 UTC revision 1.2.2.3 by yoffy, Fri Oct 8 05:44:52 2004 UTC
# Line 10  interface Line 10  interface
10  uses  uses
11  //==================================================  //==================================================
12    
13          Classes, SysUtils,          Classes, SysUtils, Windows,
14          YofUtils;          YofUtils;
15    
16  //==================================================  //==================================================
# Line 26  type Line 26  type
26          IXMLNode = class          IXMLNode = class
27          private          private
28                  FNodeName : string;                  FNodeName : string;
29                    FCapacity : Integer;
30                  FCount : Integer;                  FCount : Integer;
31                  FAttributeCount : Integer;                  FAttributeCount : Integer;
32                  FChildNodes : IXMLNode;                  FChildNodes : IXMLNode;
# Line 54  type Line 55  type
55          end;          end;
56    
57  function XMLCloseCheck(  function XMLCloseCheck(
58          var f : TFileStream;          var p                           : PChar;
59            const tail      : PChar;
60          var node : IXMLNode;          var node : IXMLNode;
         ch : char;  
61          out tag : string;          out tag : string;
62          out closed : boolean // 呼び出したルーチンが node を閉じるべきなら true          out closed : boolean // 呼び出したルーチンが node を閉じるべきなら true
63  ) : boolean; // ch をこのルーチンが処理したなら true  ) : boolean; // ch をこのルーチンが処理したなら true
64    
65  function XMLReadNode(  function XMLReadNode(
66          var f : TFileStream;          var p                           : PChar;
67            const tail      : PChar;
68          var node : IXMLNode          var node : IXMLNode
69  ) : string; // node 以外のノードが閉じられた場合のノード名  ) : string; // node 以外のノードが閉じられた場合のノード名
70    
# Line 75  procedure LoadXMLDocument( Line 77  procedure LoadXMLDocument(
77  const  const
78  //==================================================  //==================================================
79          kXMLWhite : TSysCharSet = [#0..#$20];          kXMLWhite : TSysCharSet = [#0..#$20];
80            kXMLNodeNameStop : TSysCharSet = [#0..#$20, '/', '>'];
81            kXMLAttributeNameStop : TSysCharSet = [#0..#$20, '=', '/', '>'];
82          kXMLDQuote : TSysCharSet = ['"'];          kXMLDQuote : TSysCharSet = ['"'];
83          kXMLTagStart : TSysCharSet = ['<'];          kXMLTagStart : TSysCharSet = ['<'];
84          kXMLTagEnd : TSysCharSet = ['>'];          kXMLTagEnd : TSysCharSet = ['>'];
# Line 90  begin Line 94  begin
94    
95          inherited;          inherited;
96    
97            FCapacity := 0;
98          FCount := 0;          FCount := 0;
99    
100  end;  end;
# Line 138  procedure IXMLNode.Add( node : IXMLNode Line 143  procedure IXMLNode.Add( node : IXMLNode
143  begin  begin
144    
145          Inc( FCount );          Inc( FCount );
146          SetLength( FNodes, FCount );          if FCount > FCapacity then begin
147                    FCapacity := FCapacity + (FCapacity shr 2) + 1;
148                    SetLength( FNodes, FCapacity );
149            end;
150    
151          FNodes[ FCount - 1 ] := node;          FNodes[ FCount - 1 ] := node;
152    
153  end;  end;
# Line 154  begin Line 163  begin
163          index := FAttributeCount;          index := FAttributeCount;
164          Inc( FAttributeCount );          Inc( FAttributeCount );
165          SetLength( FAttributes, FAttributeCount );          SetLength( FAttributes, FAttributeCount );
166    
167          FAttributes[ index ].Name := Name;          FAttributes[ index ].Name := Name;
168          FAttributes[ index ].Value := Value;          FAttributes[ index ].Value := Value;
169    
# Line 166  begin Line 176  begin
176    
177  end;  end;
178    
179  // untilSet になるまで飛ばす  {*!
180  procedure FileThruUntil(  \brief  tok を探す
181          var f : TFileStream;  \param  p                       探索開始位置
182          const untilSet : TSysCharSet  \param  tail    終了位置 + 1
183  );  \param  tok             探すキャラクタ
184  var  \return tok が最初に見つかった位置
185          ch : char;  *}
186    function AnsiStrTok(
187            p                       : PChar;
188            const tail      : PChar;
189            const tok : TSysCharSet
190    ) : PChar;
191  begin  begin
192    
193          while f.Position < f.Size do          while p < tail do
194          begin          begin
195                  f.ReadBuffer( ch, 1 );                  if p^ in tok then
                 if ch in untilSet then  
196                  begin                  begin
197                          f.Seek( -1, soFromCurrent );                          Break;
198                          exit;                  end else if p^ in kXMLKanji then
199                  end else if ch in kXMLKanji then                          p := p + 2
200                          f.Seek( 1, soFromCurrent );                  else
201                            Inc( p );
202          end;          end;
203    
204            Result := p;
205    
206  end;  end;
207    
208  // whileSet の間飛ばす  {*!
209  procedure FileThruWhile(  \brief  tok では無いキャラクタを探す
210          var f : TFileStream;  \param  p                       探索開始位置
211          const whileSet : TSysCharSet  \param  tail    終了位置 + 1
212  );  \param  tok             探すキャラクタ
213  var  \return tok ではないキャラクタが最初に見つかった位置
214          ch : char;  *}
215    function AnsiStrNonTok(
216            p                       : PChar;
217            const tail      : PChar;
218            const tok : TSysCharSet
219    ) : PChar;
220  begin  begin
221    
222          while f.Position < f.Size do          while p < tail do
223          begin          begin
224                  f.ReadBuffer( ch, 1 );                  if p^ in tok then
                 if ch in whileSet then  
225                  begin                  begin
226                          if ch in kXMLKanji then                          if p^ in kXMLKanji then
227                                  f.ReadBuffer( ch, 1 );                                  p := p + 2
228                            else
229                                    Inc( p );
230                  end else begin                  end else begin
231                          f.Seek( -1, soFromCurrent );                          Break;
                         exit;  
232                  end;                  end;
233          end;          end;
234    
235            Result := p;
236    
237  end;  end;
238    
239  function XMLCloseCheck(  function XMLCloseCheck(
240          var f : TFileStream;          var p : PChar;
241            const tail      : PChar;
242          var node : IXMLNode;          var node : IXMLNode;
         ch : char;  
243          out tag : string;          out tag : string;
244          out closed : boolean          out closed : boolean
245  ) : boolean; // ch をこのルーチンが処理したなら true  ) : boolean; // ch をこのルーチンが処理したなら true
246  var  var
247          last : Integer;          found           : PChar;
         tagLen : Integer;  
248  begin  begin
249    
250          closed := false;          closed := false;
251          Result := false;          Result := false;
252          tag := '';          tag := '';
253    
254          if ch = '>' then          case p^ of
255          begin          '>':
256                  // 開始タグの最後まで読んだ                  begin
257                  Result := true;                          // 開始タグの最後まで読んだ
258          end else if ch = '?' then                          Inc( p );       // '>' 飛ばし
259          begin                          Result := true;
260                  // <?xml?> みたいなやつ。よって無視                  end;
261                  FileThruUntil( f, kXMLTagEnd );  
262                  FileThruUntil( f, kXMLTagStart );          '?':
263                  f.Seek( 1, soFromCurrent );                  begin
264                  FileThruWhile( f, kXMLWhite );                          // <?xml?> みたいなやつ。よって無視
265                  //closed := true;                          p := AnsiStrTok( p, tail, kXMLTagEnd );
266                  Result := true;                          p := AnsiStrTok( p, tail, kXMLTagStart );
267          end else if ch = '/' then                          Inc( p );       // '<' 飛ばし
268          begin                          p := AnsiStrNonTok( p, tail, kXMLWhite );
269                  // タグ名を読み込んで返す                          //closed := true;
270                  last := f.Position;                          Result := true;
271                  FileThruUntil( f, kXMLTagEnd );                  end;
272                  tagLen := f.Position - last;  
273                  SetLength( tag, tagLen );          '/':
274                    begin
275                  f.Seek( last, soFromBeginning );                          // タグ名を読み込んで返す
276                  f.ReadBuffer( PChar( tag )^, tagLen );                          Inc( p );       // '/' 飛ばし
277                            found := AnsiStrTok( p, tail, kXMLTagEnd );
278                  f.Seek( f.Position + 1, soFromBeginning ); // '>' 飛ばし  //                      tag := Copy( p, 0, found - p ); // 何故か激遅
279                  closed := true;                          SetLength( tag, found - p );
280                  Result := true;                          CopyMemory( PChar( tag ), p, found - p );
281    
282                            p := found + 1; // '>' 飛ばし
283                            closed := true;
284                            Result := true;
285                    end;
286          end;          end;
287    
288  end;  end;
289    
290  function XMLReadNode(  function XMLReadNode(
291          var f : TFileStream;          var p : PChar;
292            const tail      : PChar;
293          var node : IXMLNode          var node : IXMLNode
294  ) : string; // node 以外のノードが閉じられた場合のノード名  ) : string; // node 以外のノードが閉じられた場合のノード名
295  var  var
296          child : IXMLNode;          child : IXMLNode;
297    
298          last : Integer;          found : PChar;
299          tag : string;          tag : string;
         tagLen : Integer;  
300    
301          isClosed : boolean;          isClosed : boolean;
302    
303            nodeName : string;
304          attributeName : string;          attributeName : string;
305          attributeValue : string;          attributeValue : string;
   
         ch : char;  
306  label  label
307          NextNode;          NextNode;
308  begin  begin
# Line 283  begin Line 310  begin
310                  // node の読み込み(1 ループにつき 1 ノード)                  // node の読み込み(1 ループにつき 1 ノード)
311                  node.ChildNodes := IXMLNode.Create;                  node.ChildNodes := IXMLNode.Create;
312    
313                  while f.Position < f.Size do                  while p < tail do
314                  begin                  begin
315                          // NodeName 読み込み                          // NodeName 読み込み
316                          FileThruWhile( f, kXMLWhite );                          p := AnsiStrNonTok( p, tail, kXMLWhite );
317    
318                          while f.Position < f.Size do                          while p < tail do
319                          begin                          begin
320                                  f.ReadBuffer( ch, 1 );                                  if XMLCloseCheck( p, tail, node, tag, isClosed ) then
   
                                 if XMLCloseCheck( f, node, ch, tag, isClosed ) then  
321                                  begin                                  begin
322                                          if isClosed then                                          if isClosed then
323                                          begin                                          begin
# Line 301  begin Line 326  begin
326                                          end;                                          end;
327    
328                                          goto NextNode;                                          goto NextNode;
329                                  end else if ch = '<' then                                  end else if p^ = '<' then
330                                  begin                                  begin
331                                          // 新規ノード                                          // 新規ノード
332                                            Inc( p );
333                                          child := IXMLNode.Create;                                          child := IXMLNode.Create;
334                                          tag := XMLReadNode( f, child );                                          tag := XMLReadNode( p, tail, child );
335                                          node.ChildNodes.Add( child );                                          node.ChildNodes.Add( child );
336    
337                                          // タグが閉じられた                                          // タグが閉じられた
# Line 318  begin Line 344  begin
344                                          end;                                          end;
345    
346                                          goto NextNode;                                          goto NextNode;
347                                  end else if ch in kXMLWhite then                                  end else if p^ in kXMLWhite then
348                                  begin                                  begin
349                                          // NodeName 完了                                          // NodeName 完了
350                                          break;                                          break;
351                                  end else begin                                  end else begin
352                                          node.NodeName := node.NodeName + ch;                                          found := AnsiStrTok( p, tail, kXMLNodeNameStop );
353                                            SetLength( nodeName, found - p );
354                                            CopyMemory( PChar( nodeName ), p, found - p );
355                                            node.NodeName := nodeName;
356    
357                                          if ch in kXMLKanji then                                          p := found;
                                         begin  
                                                 f.ReadBuffer( ch, 1 );  
                                                 node.NodeName := node.NodeName + ch;  
                                         end;  
358                                  end;                                  end;
359                          end;                          end;
360    
361                          // Attribute の読み込み                          // Attribute の読み込み
362                          while f.Position < f.Size do                          while p < tail do
363                          begin                          begin
364                                  // Attribute の名前を読み込み                                  // Attribute の名前を読み込み
365                                  attributeName := '';                                  attributeName := '';
366                                  attributeValue := '';                                  attributeValue := '';
367    
368                                  FileThruWhile( f, kXMLWhite );                                  p := AnsiStrNonTok( p, tail, kXMLWhite );
369    
370                                  while f.Position < f.Size do                                  while p < tail do
371                                  begin                                  begin
372                                          f.ReadBuffer( ch, 1 );                                          if XMLCloseCheck( p, tail, node, tag, isClosed ) then
   
                                         if XMLCloseCheck( f, node, ch, tag, isClosed ) then  
373                                          begin                                          begin
374                                                  if isClosed then                                                  if isClosed then
375                                                  begin                                                  begin
# Line 358  begin Line 381  begin
381    
382                                                  // 次のノードへ                                                  // 次のノードへ
383                                                  goto NextNode;                                                  goto NextNode;
384                                          end else if ch = '=' then                                          end else if p^ = '=' then
385                                          begin                                          begin
386                                                  // ここからは値が始まるので名前は終了                                                  // ここからは値が始まるので名前は終了
387                                                    Inc( p );
388                                                  break;                                                  break;
389                                          end else if ch in kXMLWhite then                                          end else if p^ in kXMLWhite then
390                                          begin                                          begin
391                                                  // Value が存在しない(規格外)ので次のノードへ                                                  // Value が存在しない(規格外)ので次のノードへ
392                                                  goto NextNode;                                                  goto NextNode;
393                                          end else begin                                          end else begin
394                                                  attributeName := attributeName + ch;                                                  found := AnsiStrTok( p, tail, kXMLAttributeNameStop );
395                                                    SetLength( attributeName, found - p );
396                                                    CopyMemory( PChar( attributeName ), p, found - p );
397    
398                                                  if ch in kXMLKanji then                                                  p := found;
                                                 begin  
                                                         f.ReadBuffer( ch, 1 );  
                                                         attributeName := attributeName + ch;  
                                                 end;  
399                                          end;                                          end;
400                                  end;                                  end;
401    
402                                  // Attribute の値を読み込み                                  // Attribute の値を読み込み
403                                  FileThruWhile( f, kXMLWhite );                                  p := AnsiStrNonTok( p, tail, kXMLWhite );
404    
405                                  while f.Position < f.Size do                                  while p < tail do
406                                  begin                                  begin
407                                          f.ReadBuffer( ch, 1 );                                          if XMLCloseCheck( p, tail, node, tag, isClosed ) then
   
                                         if XMLCloseCheck( f, node, ch, tag, isClosed ) then  
408                                          begin                                          begin
409                                                  if isClosed then                                                  if isClosed then
410                                                  begin                                                  begin
# Line 400  begin Line 420  begin
420    
421                                                  // 次のノードへ                                                  // 次のノードへ
422                                                  goto NextNode;                                                  goto NextNode;
423                                          end else if ch = '"' then                                          end else if p^ = '"' then
424                                          begin                                          begin
425                                                  // 値が "" で括られてるので(ていうか括られてなきゃいけないんだけど)                                                  // 値が "" で括られてるので(ていうか括られてなきゃいけないんだけど)
426                                                  // 値を一括読み込み                                                  // 値を一括読み込み
427                                                  last := f.Position;                                                  Inc( p );
428                                                  FileThruUntil( f, kXMLDQuote );                                                  found := AnsiStrTok( p, tail, kXMLDQuote );
429                                                  tagLen := f.Position - last;  //                                              attributeValue := Copy( p, 0, found - p );      // 何故か激遅
430                                                  SetLength( attributeValue, tagLen );                                                  SetLength( attributeValue, found - p );
431                                                    CopyMemory( PChar( attributeValue ), p, found - p );
                                                 f.Seek( last, soFromBeginning );  
                                                 f.ReadBuffer( PChar( attributeValue )^, tagLen );  
432    
433                                                  node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );                                                  node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );
434    
435                                                  // 値を読み終わったので終了                                                  // 値を読み終わったので終了
436                                                  f.Seek( f.Position + 1, soFromBeginning ); // '"' 飛ばし                                                  p := found + 1; // '"' 飛ばし
437                                                  break;                                                  break;
438                                          end else if ch in kXMLWhite then                                          end else if p^ in kXMLWhite then
439                                          begin                                          begin
440                                                  // 規格外だけどね                                                  // 規格外だけどね
441                                                  node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );                                                  node.AddAttribute( attributeName, HtmlDecode( attributeValue ) );
# Line 425  begin Line 443  begin
443                                                  goto NextNode;                                                  goto NextNode;
444                                          end else begin                                          end else begin
445                                                  // 規格外だけど一応取っておく                                                  // 規格外だけど一応取っておく
446                                                  attributeValue := attributeValue + ch;                                                  attributeValue := attributeValue + p^;
447    
448                                                  if ch in kXMLKanji then                                                  if p^ in kXMLKanji then
449                                                  begin                                                  begin
450                                                          f.ReadBuffer( ch, 1 );                                                          attributeValue := attributeValue + (p + 1)^;
451                                                          attributeValue := attributeValue + ch;                                                          p := p + 2;
452                                                    end else begin
453                                                            Inc( p );
454                                                  end;                                                  end;
455                                          end;                                          end;
456                                  end;                                  end;
# Line 449  procedure LoadXMLDocument( Line 469  procedure LoadXMLDocument(
469  type  type
470          xmlMode = ( xmlHoge );          xmlMode = ( xmlHoge );
471  var  var
472          xmlFile : TFileStream;          xmlFile : TMappedFile;
473            p                               : PChar;
474  begin  begin
475      //Result := IXMLDocument.Create;                  //Result := IXMLDocument.Create;
476          //doc := IXMLDocument.Create;          //doc := IXMLDocument.Create;
477    
478          xmlFile := TFileStream.Create( fileName, fmOpenRead );          xmlFile := TMappedFile.Create( fileName );
479    
480      try          try
481          XMLReadNode( xmlFile, IXMLNode( doc ) );                  p := xmlFile.Memory;
482          //XMLReadNode( xmlFile, IXMLNode( Result ) );                  XMLReadNode( p, p + xmlFile.Size, IXMLNode( doc ) );
483      finally                  //XMLReadNode( xmlFile, IXMLNode( Result ) );
484            finally
485                  xmlFile.Free;                  xmlFile.Free;
486      end;          end;
487    
488          //Result := doc;          //Result := doc;
489    

Legend:
Removed from v.1.2.2.2  
changed lines
  Added in v.1.2.2.3

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26