Changeset 11 for ProtocolBuffers


Ignore:
Timestamp:
Oct 20, 2009, 11:06:34 AM (15 years ago)
Author:
george
Message:
  • Modified: Definition tree is now separated from data. This was needed for implementation of repeated fields.
Location:
ProtocolBuffers
Files:
1 added
6 edited

Legend:

Unmodified
Added
Removed
  • ProtocolBuffers/Demo.lpi

    r10 r11  
    99      <Icon Value="0"/>
    1010      <UseXPManifest Value="True"/>
    11       <ActiveEditorIndexAtStart Value="0"/>
     11      <ActiveEditorIndexAtStart Value="2"/>
    1212    </General>
    1313    <VersionInfo>
     
    3333      </Item1>
    3434    </RequiredPackages>
    35     <Units Count="10">
     35    <Units Count="13">
    3636      <Unit0>
    3737        <Filename Value="Demo.lpr"/>
     
    4040        <CursorPos X="23" Y="11"/>
    4141        <TopLine Value="1"/>
    42         <EditorIndex Value="6"/>
    43         <UsageCount Value="34"/>
    44         <Loaded Value="True"/>
     42        <UsageCount Value="41"/>
    4543      </Unit0>
    4644      <Unit1>
     
    5048        <ResourceBaseClass Value="Form"/>
    5149        <UnitName Value="UMainForm"/>
    52         <CursorPos X="19" Y="137"/>
    53         <TopLine Value="124"/>
     50        <CursorPos X="1" Y="186"/>
     51        <TopLine Value="154"/>
    5452        <EditorIndex Value="0"/>
    55         <UsageCount Value="34"/>
     53        <UsageCount Value="41"/>
    5654        <Loaded Value="True"/>
    5755      </Unit1>
     
    6058        <IsPartOfProject Value="True"/>
    6159        <UnitName Value="UProtocolBuffers"/>
    62         <CursorPos X="30" Y="223"/>
    63         <TopLine Value="217"/>
    64         <EditorIndex Value="1"/>
    65         <UsageCount Value="34"/>
     60        <CursorPos X="43" Y="165"/>
     61        <TopLine Value="146"/>
     62        <EditorIndex Value="2"/>
     63        <UsageCount Value="41"/>
    6664        <Loaded Value="True"/>
    6765      </Unit2>
     
    7169        <UnitName Value="UMemoryStreamEx"/>
    7270        <CursorPos X="3" Y="60"/>
    73         <TopLine Value="56"/>
    74         <EditorIndex Value="2"/>
    75         <UsageCount Value="34"/>
     71        <TopLine Value="27"/>
     72        <EditorIndex Value="5"/>
     73        <UsageCount Value="41"/>
    7674        <Loaded Value="True"/>
    7775      </Unit3>
    7876      <Unit4>
    7977        <Filename Value="..\..\..\Programy\Lazarus_0.9.27\fpc\2.2.4\source\rtl\objpas\classes\classesh.inc"/>
    80         <CursorPos X="15" Y="806"/>
    81         <TopLine Value="790"/>
    82         <EditorIndex Value="5"/>
    83         <UsageCount Value="16"/>
    84         <Loaded Value="True"/>
     78        <CursorPos X="14" Y="277"/>
     79        <TopLine Value="228"/>
     80        <UsageCount Value="17"/>
    8581      </Unit4>
    8682      <Unit5>
     
    8985        <CursorPos X="20" Y="4"/>
    9086        <TopLine Value="1"/>
    91         <EditorIndex Value="4"/>
    92         <UsageCount Value="32"/>
     87        <EditorIndex Value="7"/>
     88        <UsageCount Value="39"/>
    9389        <Loaded Value="True"/>
    9490        <SyntaxHighlighter Value="None"/>
     
    9894        <IsPartOfProject Value="True"/>
    9995        <UnitName Value="UParser"/>
    100         <CursorPos X="66" Y="26"/>
    101         <TopLine Value="2"/>
    102         <EditorIndex Value="3"/>
    103         <UsageCount Value="31"/>
     96        <CursorPos X="1" Y="12"/>
     97        <TopLine Value="1"/>
     98        <EditorIndex Value="6"/>
     99        <UsageCount Value="38"/>
    104100        <Loaded Value="True"/>
    105101      </Unit6>
     
    109105        <CursorPos X="19" Y="2336"/>
    110106        <TopLine Value="2476"/>
    111         <UsageCount Value="11"/>
     107        <UsageCount Value="10"/>
    112108      </Unit7>
    113109      <Unit8>
    114110        <Filename Value="..\..\..\Programy\Lazarus_0.9.27\lcl\include\treeview.inc"/>
    115         <CursorPos X="1" Y="358"/>
    116         <TopLine Value="342"/>
    117         <UsageCount Value="10"/>
     111        <CursorPos X="41" Y="3711"/>
     112        <TopLine Value="3702"/>
     113        <EditorIndex Value="1"/>
     114        <UsageCount Value="12"/>
     115        <Loaded Value="True"/>
    118116      </Unit8>
    119117      <Unit9>
     
    121119        <CursorPos X="47" Y="533"/>
    122120        <TopLine Value="530"/>
    123         <UsageCount Value="10"/>
     121        <UsageCount Value="9"/>
    124122      </Unit9>
     123      <Unit10>
     124        <Filename Value="..\..\..\Programy\Lazarus_0.9.27\fpc\2.2.4\source\rtl\inc\objpash.inc"/>
     125        <CursorPos X="21" Y="160"/>
     126        <TopLine Value="144"/>
     127        <EditorIndex Value="4"/>
     128        <UsageCount Value="15"/>
     129        <Loaded Value="True"/>
     130      </Unit10>
     131      <Unit11>
     132        <Filename Value="..\..\..\Programy\Lazarus_0.9.27\fpc\2.2.4\source\rtl\inc\objpas.inc"/>
     133        <CursorPos X="12" Y="150"/>
     134        <TopLine Value="147"/>
     135        <UsageCount Value="9"/>
     136      </Unit11>
     137      <Unit12>
     138        <Filename Value="Readme.txt"/>
     139        <IsPartOfProject Value="True"/>
     140        <CursorPos X="19" Y="1"/>
     141        <TopLine Value="1"/>
     142        <EditorIndex Value="3"/>
     143        <UsageCount Value="27"/>
     144        <Loaded Value="True"/>
     145        <SyntaxHighlighter Value="None"/>
     146      </Unit12>
    125147    </Units>
    126148    <JumpHistory Count="30" HistoryIndex="29">
    127149      <Position1>
    128150        <Filename Value="UProtocolBuffers.pas"/>
    129         <Caret Line="158" Column="1" TopLine="142"/>
     151        <Caret Line="216" Column="1" TopLine="199"/>
    130152      </Position1>
    131153      <Position2>
    132154        <Filename Value="UProtocolBuffers.pas"/>
    133         <Caret Line="159" Column="1" TopLine="143"/>
     155        <Caret Line="219" Column="1" TopLine="202"/>
    134156      </Position2>
    135157      <Position3>
    136158        <Filename Value="UProtocolBuffers.pas"/>
    137         <Caret Line="160" Column="1" TopLine="144"/>
     159        <Caret Line="221" Column="1" TopLine="204"/>
    138160      </Position3>
    139161      <Position4>
    140162        <Filename Value="UProtocolBuffers.pas"/>
    141         <Caret Line="161" Column="1" TopLine="145"/>
     163        <Caret Line="222" Column="1" TopLine="205"/>
    142164      </Position4>
    143165      <Position5>
    144166        <Filename Value="UProtocolBuffers.pas"/>
    145         <Caret Line="162" Column="1" TopLine="146"/>
     167        <Caret Line="223" Column="1" TopLine="206"/>
    146168      </Position5>
    147169      <Position6>
    148170        <Filename Value="UProtocolBuffers.pas"/>
    149         <Caret Line="165" Column="1" TopLine="149"/>
     171        <Caret Line="224" Column="1" TopLine="207"/>
    150172      </Position6>
    151173      <Position7>
    152174        <Filename Value="UProtocolBuffers.pas"/>
    153         <Caret Line="166" Column="1" TopLine="150"/>
     175        <Caret Line="225" Column="1" TopLine="208"/>
    154176      </Position7>
    155177      <Position8>
    156178        <Filename Value="UProtocolBuffers.pas"/>
    157         <Caret Line="159" Column="1" TopLine="143"/>
     179        <Caret Line="226" Column="1" TopLine="209"/>
    158180      </Position8>
    159181      <Position9>
    160182        <Filename Value="UProtocolBuffers.pas"/>
    161         <Caret Line="160" Column="1" TopLine="144"/>
     183        <Caret Line="229" Column="1" TopLine="212"/>
    162184      </Position9>
    163185      <Position10>
    164186        <Filename Value="UProtocolBuffers.pas"/>
    165         <Caret Line="161" Column="1" TopLine="145"/>
     187        <Caret Line="233" Column="1" TopLine="216"/>
    166188      </Position10>
    167189      <Position11>
    168190        <Filename Value="UProtocolBuffers.pas"/>
    169         <Caret Line="172" Column="1" TopLine="156"/>
     191        <Caret Line="234" Column="1" TopLine="217"/>
    170192      </Position11>
    171193      <Position12>
    172194        <Filename Value="UProtocolBuffers.pas"/>
    173         <Caret Line="173" Column="1" TopLine="157"/>
     195        <Caret Line="235" Column="1" TopLine="218"/>
    174196      </Position12>
    175197      <Position13>
    176198        <Filename Value="UProtocolBuffers.pas"/>
    177         <Caret Line="159" Column="1" TopLine="143"/>
     199        <Caret Line="242" Column="1" TopLine="225"/>
    178200      </Position13>
    179201      <Position14>
    180         <Filename Value="UProtocolBuffers.pas"/>
    181         <Caret Line="160" Column="1" TopLine="144"/>
     202        <Filename Value="UMainForm.pas"/>
     203        <Caret Line="173" Column="21" TopLine="161"/>
    182204      </Position14>
    183205      <Position15>
    184206        <Filename Value="UProtocolBuffers.pas"/>
    185         <Caret Line="161" Column="1" TopLine="145"/>
     207        <Caret Line="222" Column="5" TopLine="212"/>
    186208      </Position15>
    187209      <Position16>
    188210        <Filename Value="UProtocolBuffers.pas"/>
    189         <Caret Line="162" Column="1" TopLine="146"/>
     211        <Caret Line="168" Column="42" TopLine="151"/>
    190212      </Position16>
    191213      <Position17>
    192214        <Filename Value="UProtocolBuffers.pas"/>
    193         <Caret Line="165" Column="1" TopLine="149"/>
     215        <Caret Line="172" Column="64" TopLine="151"/>
    194216      </Position17>
    195217      <Position18>
    196218        <Filename Value="UProtocolBuffers.pas"/>
    197         <Caret Line="166" Column="1" TopLine="150"/>
     219        <Caret Line="171" Column="40" TopLine="155"/>
    198220      </Position18>
    199221      <Position19>
    200         <Filename Value="Demo.lpr"/>
    201         <Caret Line="10" Column="75" TopLine="1"/>
     222        <Filename Value="UMainForm.pas"/>
     223        <Caret Line="186" Column="1" TopLine="169"/>
    202224      </Position19>
    203225      <Position20>
    204         <Filename Value="UMainForm.pas"/>
    205         <Caret Line="107" Column="11" TopLine="92"/>
     226        <Filename Value="UProtocolBuffers.pas"/>
     227        <Caret Line="158" Column="3" TopLine="153"/>
    206228      </Position20>
    207229      <Position21>
    208230        <Filename Value="UProtocolBuffers.pas"/>
    209         <Caret Line="132" Column="42" TopLine="118"/>
     231        <Caret Line="162" Column="1" TopLine="151"/>
    210232      </Position21>
    211233      <Position22>
    212234        <Filename Value="UProtocolBuffers.pas"/>
    213         <Caret Line="128" Column="1" TopLine="112"/>
     235        <Caret Line="163" Column="1" TopLine="146"/>
    214236      </Position22>
    215237      <Position23>
    216238        <Filename Value="UProtocolBuffers.pas"/>
    217         <Caret Line="129" Column="1" TopLine="113"/>
     239        <Caret Line="166" Column="1" TopLine="149"/>
    218240      </Position23>
    219241      <Position24>
    220242        <Filename Value="UProtocolBuffers.pas"/>
    221         <Caret Line="132" Column="22" TopLine="114"/>
     243        <Caret Line="167" Column="1" TopLine="150"/>
    222244      </Position24>
    223245      <Position25>
    224246        <Filename Value="UProtocolBuffers.pas"/>
    225         <Caret Line="128" Column="1" TopLine="112"/>
     247        <Caret Line="168" Column="1" TopLine="151"/>
    226248      </Position25>
    227249      <Position26>
    228250        <Filename Value="UProtocolBuffers.pas"/>
    229         <Caret Line="129" Column="1" TopLine="113"/>
     251        <Caret Line="163" Column="1" TopLine="146"/>
    230252      </Position26>
    231253      <Position27>
    232254        <Filename Value="UProtocolBuffers.pas"/>
    233         <Caret Line="130" Column="1" TopLine="114"/>
     255        <Caret Line="166" Column="1" TopLine="149"/>
    234256      </Position27>
    235257      <Position28>
    236258        <Filename Value="UProtocolBuffers.pas"/>
    237         <Caret Line="132" Column="12" TopLine="120"/>
     259        <Caret Line="170" Column="1" TopLine="153"/>
    238260      </Position28>
    239261      <Position29>
    240262        <Filename Value="UProtocolBuffers.pas"/>
    241         <Caret Line="185" Column="24" TopLine="181"/>
     263        <Caret Line="171" Column="1" TopLine="154"/>
    242264      </Position29>
    243265      <Position30>
    244266        <Filename Value="UProtocolBuffers.pas"/>
    245         <Caret Line="316" Column="5" TopLine="302"/>
     267        <Caret Line="172" Column="1" TopLine="155"/>
    246268      </Position30>
    247269    </JumpHistory>
  • ProtocolBuffers/UMainForm.lrs

    r9 r11  
    1 { Toto je automaticky generovaný zdrojový soubor lazarusu }
    2 
    31LazarusResources.Add('TMainForm','FORMDATA',[
    42  'TPF0'#9'TMainForm'#8'MainForm'#4'Left'#3#254#0#6'Height'#3#190#1#3'Top'#3#150
  • ProtocolBuffers/UMainForm.pas

    r10 r11  
    2828    procedure DisplayStream(Stream: TStream);
    2929    procedure DisplayTree(ProtocolBuffer: TProtocolBuffer; TreeView: TTreeView);
    30     procedure MessageToNode(PBMessage: TPBMessageItem; Node: TTreeNode);
     30    procedure ListToNode(PBRepeated: TPBRepeatedItem; Node: TTreeNode;
     31      Definition: TPBDefinition);
     32    procedure MessageToNode(PBMessage: TPBMessageItem; Node: TTreeNode;
     33      Definition: TPBDefinition);
    3134  public
    3235  end;
     
    7073var
    7174  Stream: TMemoryStreamEx;
    72   NewItem: TPBItem;
     75  NewItem: TPBDefinition;
    7376  PB: TProtocolBuffer;
    7477begin
     
    7679  PB := TProtocolBuffer.Create;
    7780  with PB do begin
    78     with BaseMessage do begin
     81    with Definition do begin
    7982      Name := 'SampleMessage';
    80       NewItem := TPBIntegerItem.Create;
    81       with TPBIntegerItem(NewItem) do begin
     83      NewItem := TPBDefinition.Create;
     84      with TPBDefinition(NewItem) do begin
    8285        Name := 'Height';
    8386        Tag := 1;
    84         Value := 12;
    85       end;
    86       Items.Add(NewItem);
    87       NewItem := TPBStringItem.Create;
    88       with TPBStringItem(NewItem) do begin
     87        ItemType := itInteger;
     88      end;
     89      Items.Add(NewItem);
     90
     91      NewItem := TPBDefinition.Create;
     92      with TPBDefinition(NewItem) do begin
    8993        Name := 'Name';
    9094        Tag := 2;
    91         Value := 'John Doe';
    92       end;
    93       Items.Add(NewItem);
    94       NewItem := TPBIntegerItem.Create;
    95       with TPBIntegerItem(NewItem) do begin
     95        ItemType := itString;
     96        ItemMode := imOptional;
     97      end;
     98      Items.Add(NewItem);
     99
     100      NewItem := TPBDefinition.Create;
     101      with TPBDefinition(NewItem) do begin
    96102        Name := 'Age';
    97103        Tag := 3;
    98         Value := 45;
    99       end;
    100       Items.Add(NewItem);
    101       NewItem := TPBMessageItem.Create;
    102       Items.Add(NewItem);
    103       with TPBMessageItem(Items[Items.Count - 1]) do begin
     104        ItemType := itInteger;
     105        ItemMode := imOptional;
     106      end;
     107      Items.Add(NewItem);
     108
     109      NewItem := TPBDefinition.Create;
     110      Items.Add(NewItem);
     111      with TPBDefinition(Items[Items.Count - 1]) do begin
    104112        Name := 'Address';
    105113        Tag := 5;
    106         NewItem := TPBIntegerItem.Create;
    107         with TPBIntegerItem(NewItem) do begin
     114        ItemType := itMessage;
     115        NewItem := TPBDefinition.Create;
     116        ItemMode := imOptional;
     117        with TPBDefinition(NewItem) do begin
    108118          Name := 'Street';
    109119          Tag := 1;
    110           Value := 67;
     120          ItemType := itString;
     121          ItemMode := imOptional;
    111122        end;
    112123        Items.Add(NewItem);
    113124      end;
    114125    end;
     126    BaseMessage.Clear(Definition);
     127    TPBIntegerItem(PB.BaseMessage.Items[0]).Value := 12;
     128    TPBStringItem(TPBMessageItem(PB.BaseMessage.Items[3]).
     129      Items[0]).Value := 'Vsetínská';
    115130    DisplayTree(PB, TreeView1);
    116131    SaveToStream(Stream);
     
    123138  PB := TProtocolBuffer.Create;
    124139  with PB do begin
    125     with BaseMessage do begin
     140    with Definition do begin
    126141      Name := 'SampleMessage';
    127       NewItem := TPBIntegerItem.Create;
    128       with TPBIntegerItem(NewItem) do begin
     142      NewItem := TPBDefinition.Create;
     143      with TPBDefinition(NewItem) do begin
    129144        Name := 'Height';
    130145        Tag := 1;
    131       end;
    132       Items.Add(NewItem);
    133       NewItem := TPBStringItem.Create;
    134       with TPBStringItem(NewItem) do begin
     146        ItemType := itInteger;
     147        DefaultInteger := 32;
     148      end;
     149      Items.Add(NewItem);
     150
     151      NewItem := TPBDefinition.Create;
     152      with TPBDefinition(NewItem) do begin
    135153        Name := 'Name';
    136154        Tag := 2;
    137         Value := '';
    138       end;
    139       Items.Add(NewItem);
    140       NewItem := TPBIntegerItem.Create;
    141       with TPBIntegerItem(NewItem) do begin
    142         Name := 'Weight';
     155        ItemType := itString;
     156        DefaultString := 'Billy Joe';
     157      end;
     158      Items.Add(NewItem);
     159
     160      NewItem := TPBDefinition.Create;
     161      with TPBDefinition(NewItem) do begin
     162        Name := 'Work';
    143163        Tag := 4;
    144       end;
    145       Items.Add(NewItem);
    146       NewItem := TPBMessageItem.Create;
    147       Items.Add(NewItem);
    148       with TPBMessageItem(Items[Items.Count - 1]) do begin
     164        ItemType := itString;
     165        DefaultString := 'EasyCompany';
     166      end;
     167      Items.Add(NewItem);
     168
     169      NewItem := TPBDefinition.Create;
     170      Items.Add(NewItem);
     171      with TPBDefinition(Items[Items.Count - 1]) do begin
    149172        Name := 'Address';
    150173        Tag := 5;
    151         NewItem := TPBIntegerItem.Create;
    152         with TPBIntegerItem(NewItem) do begin
     174        ItemType := itMessage;
     175        NewItem := TPBDefinition.Create;
     176        with TPBDefinition(NewItem) do begin
    153177          Name := 'Street';
    154178          Tag := 1;
     179          ItemType := itString;
     180          DefaultString := 'Ruská';
    155181        end;
    156182        Items.Add(NewItem);
    157183      end;
    158184    end;
     185    BaseMessage.Clear(Definition);
    159186    LoadFromStream(Stream);
    160187    DisplayTree(PB, TreeView2);
     
    188215    Items.Clear;
    189216    TopItem := Items.Add(nil, 'message');
    190     MessageToNode(ProtocolBuffer.BaseMessage, TopItem);
     217    MessageToNode(ProtocolBuffer.BaseMessage, TopItem, ProtocolBuffer.Definition);
    191218    TopItem.Expand(True);
    192219    EndUpdate;
     
    194221end;
    195222
    196 procedure TMainForm.MessageToNode(PBMessage: TPBMessageItem; Node: TTreeNode);
     223procedure TMainForm.ListToNode(PBRepeated: TPBRepeatedItem; Node: TTreeNode;
     224  Definition: TPBDefinition);
    197225var
    198226  I: Integer;
    199227  NewNode: TTreeNode;
    200228begin
    201   for I := 0 to PBMessage.Items.Count - 1 do begin
     229  for I := 0 to Definition.Items.Count - 1 do
     230  with TPBDefinition(Definition) do begin
    202231    NewNode := Node.Owner.AddChild(Node, '');
    203     if TPBItem(PBMessage.Items[I]) is TPBStringItem then begin
    204       NewNode.Text := IntToStr(TPBItem(PBMessage.Items[I]).Tag) + ': string ' +
    205         TPBItem(PBMessage.Items[I]).Name + ' = ' +
     232    if ItemType = itString then begin
     233      NewNode.Text := IntToStr(Tag) + ': string ' + Name + ' = ' +
     234        TPBStringItem(PBRepeated.Items[I]).Value;
     235    end else
     236    if ItemType = itInteger then begin
     237      NewNode.Text := IntToStr(Tag) + ': uint32 ' + Name + ' = ' +
     238        IntToStr(TPBIntegerItem(PBRepeated.Items[I]).Value);
     239    end else
     240    if ItemType = itMessage then begin
     241      NewNode.Text := IntToStr(Tag) + ': message ' + Name;
     242      MessageToNode(TPBMessageItem(PBRepeated.Items[I]), NewNode, Definition);
     243    end;
     244  end;
     245end;
     246
     247procedure TMainForm.MessageToNode(PBMessage: TPBMessageItem; Node: TTreeNode;
     248  Definition: TPBDefinition);
     249var
     250  I: Integer;
     251  NewNode: TTreeNode;
     252begin
     253  for I := 0 to Definition.Items.Count - 1 do
     254  with TPBDefinition(Definition.Items[I]) do begin
     255    NewNode := Node.Owner.AddChild(Node, '');
     256    if ItemMode = imRepeated then begin
     257      NewNode.Text := 'repeated';
     258      ListToNode(TPBRepeatedItem(PBMessage.Items[I]), NewNode, Definition.Items[I]);
     259    end else
     260    if ItemType = itString then begin
     261      NewNode.Text := IntToStr(Tag) + ': string ' + Name + ' = ' +
    206262        TPBStringItem(PBMessage.Items[I]).Value;
    207263    end else
    208     if TPBItem(PBMessage.Items[I]) is TPBIntegerItem then begin
    209       NewNode.Text := IntToStr(TPBItem(PBMessage.Items[I]).Tag) + ': uint32 ' +
    210         TPBItem(PBMessage.Items[I]).Name + ' = ' +
     264    if ItemType = itInteger then begin
     265      NewNode.Text := IntToStr(Tag) + ': uint32 ' + Name + ' = ' +
    211266        IntToStr(TPBIntegerItem(PBMessage.Items[I]).Value);
    212267    end else
    213     if TPBItem(PBMessage.Items[I]) is TPBMessageItem then begin
    214       NewNode.Text := IntToStr(TPBItem(PBMessage.Items[I]).Tag) + ': message ' +
    215         TPBItem(PBMessage.Items[I]).Name;
    216       MessageToNode(TPBMessageItem(PBMessage.Items[I]), NewNode);
    217     end;
    218 
     268    if ItemType = itMessage then begin
     269      NewNode.Text := IntToStr(Tag) + ': message ' + Name;
     270      MessageToNode(TPBMessageItem(PBMessage.Items[I]), NewNode, Definition.Items[I]);
     271    end;
    219272  end;
    220273end;
  • ProtocolBuffers/UParser.pas

    r8 r11  
    99
    1010type
    11 
    1211  { TParser }
    13 
    1412  TParser = class
    1513    WhiteSpaces: string;
  • ProtocolBuffers/UProtocolBuffers.pas

    r10 r11  
    1 // http://code.google.com/intl/cs/apis/protocolbuffers/docs/overview.html
     1// Specification: http://code.google.com/intl/cs/apis/protocolbuffers/docs/overview.html
    22unit UProtocolBuffers;
    33
     
    77
    88uses
    9   Classes, SysUtils;
     9  Classes, SysUtils, Dialogs;
    1010
    1111type
    1212  TPBItemMode = (imRequired, imOptional, imRepeated);
    13   TPBItemType = (itVariant, it64bit, itLengthDelimited, itStartGroup,
    14     itEndGroup, it32bit);
     13  TPBWireType = (wtVariant, wt64bit, wtLengthDelimited, wtStartGroup,
     14    wtEndGroup, wt32bit);
     15  TPBItemType = (itInteger, itString, itMessage, itFloat, itDouble, itBlock);
    1516
    1617  TPBEnumeration = class
    1718  end;
    1819
    19   { TPBItem }
    20   TPBItem = class
     20  { TPBDefinition }
     21  TPBDefinition = class
     22  private
     23    function GetWireType: TPBWireType;
     24  public
    2125    Name: string;
    2226    Tag: Integer;
    2327    ItemType: TPBItemType;
    2428    ItemMode: TPBItemMode;
     29    Items: TList; // TList<TPBDefinition>
     30    DefaultString: string;
     31    DefaultInteger: Integer;
     32    constructor Create;
     33    destructor Destroy; override;
     34    function SearchItemByTag(Tag: Integer): Integer;
     35    property WireType: TPBWireType read GetWireType;
     36  end;
     37
     38  { TPBItemHead }
     39  TPBItemHead = record
     40    Tag: Integer;
     41    WireType: TPBWireType;
     42  end;
     43
     44  { TPBItem }
     45  TPBItem = class
    2546    procedure SaveVariantToStream(Stream: TStream; Value: Integer);
    2647    function LoadVariantFromStream(Stream: TStream): Integer;
    2748    procedure SaveLengthDelimitedToStream(Stream: TStream; Block: TStream);
    2849    procedure LoadLengthDelimitedFromStream(Stream: TStream; Block: TStream);
    29     procedure SaveHeadToStream(Stream: TStream);
    30     procedure LoadHeadFromStream(Stream: TStream);
    31     procedure SaveToStream(Stream: TStream); virtual;
    32     procedure LoadFromStream(Stream: TStream); virtual;
     50    procedure SaveHeadToStream(Stream: TStream; Definition: TPBDefinition);
     51    function LoadHeadFromStream(Stream: TStream; Definition: TPBDefinition): TPBItemHead;
     52    procedure SaveToStream(Stream: TStream; Definition: TPBDefinition); virtual;
     53    procedure LoadFromStream(Stream: TStream; Definition: TPBDefinition); virtual;
     54    procedure Clear(Definition: TPBDefinition); virtual;
     55    procedure Assign(Source: TPBItem); virtual;
    3356  end;
    3457
     
    3861  TPBStringItem = class(TPBItem)
    3962    Value: string;
    40     procedure SaveToStream(Stream: TStream); override;
    41     procedure LoadFromStream(Stream: TStream); override;
     63    procedure SaveToStream(Stream: TStream; Definition: TPBDefinition); override;
     64    procedure LoadFromStream(Stream: TStream; Definition: TPBDefinition); override;
    4265    constructor Create;
     66    procedure Assign(Source: TPBItem); override;
    4367  end;
    4468
     
    4670  TPBIntegerItem = class(TPBItem)
    4771    Value: Integer;
    48     procedure SaveToStream(Stream: TStream); override;
    49     procedure LoadFromStream(Stream: TStream); override;
     72    procedure SaveToStream(Stream: TStream; Definition: TPBDefinition); override;
     73    procedure LoadFromStream(Stream: TStream; Definition: TPBDefinition); override;
    5074    constructor Create;
     75    procedure Assign(Source: TPBItem); override;
    5176  end;
    5277
     
    5479  TPBMessageItem = class(TPBItem)
    5580    GenerateHead: Boolean;
    56     Items: TList; // TList<TPBItem>;
    57     function SearchItemByTag(Tag: Integer): TPBItem;
    58     procedure SaveToStream(Stream: TStream); override;
    59     procedure LoadFromStream(Stream: TStream); override;
     81    Items: TList; // TList<TList<TPBItem>>;
     82    procedure Clear(Definition: TPBDefinition); override;
     83    procedure SaveToStream(Stream: TStream; Definition: TPBDefinition); override;
     84    procedure LoadFromStream(Stream: TStream; Definition: TPBDefinition); override;
    6085    constructor Create;
    6186    destructor Destroy; override;
     87    procedure Assign(Source: TPBItem); override;
     88  end;
     89
     90  { TPBRepeatedItem }
     91
     92  TPBRepeatedItem = class(TPBItem)
     93    Items: TList;
     94    procedure Clear(Definition: TPBDefinition); override;
     95    procedure SaveToStream(Stream: TStream; Definition: TPBDefinition); override;
     96    procedure LoadFromStream(Stream: TStream; Definition: TPBDefinition); override;
     97    constructor Create;
     98    destructor Destroy; override;
     99    procedure Assign(Source: TPBItem); override;
    62100  end;
    63101
    64102  { TProtocolBuffer }
    65103  TProtocolBuffer = class
     104    Definition: TPBDefinition;
    66105    BaseMessage: TPBMessageItem;
    67106    procedure LoadFromStream(Stream: TStream);
     
    82121begin
    83122  BaseMessage.GenerateHead := False;
    84   BaseMessage.LoadFromStream(Stream);
     123  BaseMessage.LoadFromStream(Stream, Definition);
    85124end;
    86125
     
    88127begin
    89128  BaseMessage.GenerateHead := False;
    90   BaseMessage.SaveToStream(Stream);
     129  BaseMessage.SaveToStream(Stream, Definition);
    91130end;
    92131
     
    99138begin
    100139  BaseMessage := TPBMessageItem.Create;
     140  Definition := TPBDefinition.Create;
     141  Definition.ItemType := itMessage;
    101142end;
    102143
    103144destructor TProtocolBuffer.Destroy;
    104145begin
    105   if Assigned(BaseMessage) then BaseMessage.Free;
     146  Definition.Destroy;
     147  BaseMessage.Free;
    106148  inherited Destroy;
    107149end;
     
    109151{ TPBMessageItem }
    110152
    111 function TPBMessageItem.SearchItemByTag(Tag: Integer): TPBItem;
    112 var
    113   I: Integer;
    114 begin
    115   I := 0;
    116   while (I < Items.Count) and (TPBItem(Items[I]).Tag <> Tag) do Inc(I);
    117   if I < Items.Count then Result := Items[I]
    118     else Result := nil;
    119 end;
    120 
    121 procedure TPBMessageItem.SaveToStream(Stream: TStream);
    122 var
    123   I: Integer;
     153procedure TPBMessageItem.Clear(Definition: TPBDefinition);
     154var
     155  I: Integer;
     156  Q: Integer;
     157begin
     158  for I := 0 to Items.Count - 1 do
     159    TPBItem(Items[I]).Clear(Definition);
     160  Items.Clear;
     161  Items.Count := Definition.Items.Count;
     162  for I := 0 to Items.Count - 1 do begin
     163    if TPBDefinition(Definition.Items[I]).ItemMode = imRepeated then
     164      Items[I] := TPBRepeatedItem.Create
     165    else
     166    if TPBDefinition(Definition.Items[I]).ItemType = itInteger then begin
     167      Items[I] := TPBIntegerItem.Create;
     168      TPBIntegerItem(Items[I]).Value := TPBDefinition(Definition.Items[I]).DefaultInteger;
     169    end else
     170    if TPBDefinition(Definition.Items[I]).ItemType = itString then begin
     171      Items[I] := TPBStringItem.Create;
     172      TPBStringItem(Items[I]).Value := TPBDefinition(Definition.Items[I]).DefaultString;
     173    end else
     174    if TPBDefinition(Definition.Items[I]).ItemType = itMessage then begin
     175      Items[I] := TPBMessageItem.Create;
     176      TPBMessageItem(Items[I]).Clear(Definition.Items[I]);
     177    end;
     178  end;
     179end;
     180
     181procedure TPBMessageItem.SaveToStream(Stream: TStream; Definition: TPBDefinition);
     182var
     183  I: Integer;
     184  Q: Integer;
    124185  TempStream: TMemoryStream;
    125186begin
     
    127188  // Generate message content to temporary stream
    128189  TempStream := TMemoryStream.Create;
    129   for I := 0 to Items.Count - 1 do
    130     TPBItem(Items[I]).SaveToStream(TempStream);
    131   // if head is used than write lenght-delimited head type with block byte length
     190  if Items.Count <> Definition.Items.Count then
     191    raise Exception.Create('Definition and value items count mismatch.');
     192  for I := 0 to Definition.Items.Count - 1 do
     193    TPBItem(Items[I]).SaveToStream(TempStream, Definition.Items[I]);
     194
     195  // If head is used than write lenght-delimited head type with block byte length
    132196  if GenerateHead then begin
    133     SaveHeadToStream(Stream);
     197    SaveHeadToStream(Stream, Definition);
    134198    SaveVariantToStream(Stream, TempStream.Size);
    135199  end;
     
    139203end;
    140204
    141 procedure TPBMessageItem.LoadFromStream(Stream: TStream);
     205procedure TPBMessageItem.LoadFromStream(Stream: TStream; Definition: TPBDefinition);
    142206var
    143207  I: Integer;
    144208  TempItem: TPBItem;
    145   SearchItem: TPBItem;
     209  ItemIndex: Integer;
    146210  EndIndex: Integer;
    147211  TempStream: TMemoryStream;
     212  ItemHead: TPBItemHead;
     213  NewItem: TPBItem;
    148214begin
    149215  inherited;
     
    156222
    157223  TempItem := TPBItem.Create;
     224  Clear(Definition);
    158225  while Stream.Position < EndIndex do begin
    159     TempItem.LoadHeadFromStream(Stream);
    160     SearchItem := SearchItemByTag(TempItem.Tag);
    161     if Assigned(SearchItem) then begin
    162       if SearchItem.ItemType <> TempItem.ItemType then
    163         raise Exception.Create('Bad type for item "' + SearchItem.Name +
    164           '" with tag ' + IntToStr(SearchItem.Tag));
    165       if SearchItem is TPBIntegerItem then
    166         TPBIntegerItem(SearchItem).LoadFromStream(Stream)
    167       else if SearchItem is TPBStringItem then
    168         TPBStringItem(SearchItem).LoadFromStream(Stream)
    169       else if SearchItem is TPBMessageItem then
    170         TPBMessageItem(SearchItem).LoadFromStream(Stream);
     226    ItemHead := TempItem.LoadHeadFromStream(Stream, Definition);
     227    ItemIndex := Definition.SearchItemByTag(ItemHead.Tag);
     228    if ItemIndex <> -1 then
     229      with TPBDefinition(Definition.Items[ItemIndex]) do begin
     230        if WireType <> ItemHead.WireType then
     231          raise Exception.Create('Bad type for item "' + TPBDefinition(Definition.Items[ItemIndex]).Name +
     232            '" with tag ' + IntToStr(ItemHead.Tag));
     233        if ItemType = itInteger then begin
     234          NewItem := TPBIntegerItem.Create;
     235          TPBIntegerItem(NewItem).LoadFromStream(Stream, Definition.Items[ItemIndex]);
     236        end else
     237        if TPBDefinition(Definition.Items[ItemIndex]).ItemType = itString then begin
     238          NewItem := TPBStringItem.Create;
     239          TPBStringItem(NewItem).LoadFromStream(Stream, Definition.Items[ItemIndex])
     240        end else
     241        if TPBDefinition(Definition.Items[ItemIndex]).ItemType = itMessage then begin
     242          NewItem := TPBMessageItem.Create;
     243          TPBMessageItem(NewItem).LoadFromStream(Stream, Definition.Items[ItemIndex]);
     244        end;
     245
     246        if ItemMode = imRepeated then begin
     247          TPBRepeatedItem(Items[ItemIndex]).Items.Add(NewItem);
     248        end else begin
     249          TPBItem(Self.Items[ItemIndex]).Assign(NewItem);
     250          NewItem.Free;
     251        end;
    171252    end else begin
    172       if TempItem.ItemType = itVariant then
     253      // Skip item data
     254      if ItemHead.WireType = wtVariant then
    173255        TempItem.LoadVariantFromStream(Stream)
    174       else if TempItem.ItemType = itLengthDelimited then
     256      else if ItemHead.WireType = wtLengthDelimited then
    175257        TempItem.LoadLengthDelimitedFromStream(Stream, TempStream);
    176258    end;
     
    181263constructor TPBMessageItem.Create;
    182264begin
    183   ItemType := itLengthDelimited;
    184265  Items := TList.Create;
    185266  GenerateHead := True;
     
    194275  Items.Free;
    195276  inherited Destroy;
     277end;
     278
     279procedure TPBMessageItem.Assign(Source: TPBItem);
     280var
     281  I: Integer;
     282begin
     283  if Source is TPBMessageItem then begin
     284    GenerateHead := TPBMessageItem(Source).GenerateHead;
     285    for I := 0 to Items.Count - 1 do
     286      TPBItem(Items[I]).Assign(TPBMessageItem(Source).Items[I]);
     287  end;
    196288end;
    197289
     
    215307end;
    216308
    217 procedure TPBItem.SaveHeadToStream(Stream: TStream);
     309procedure TPBItem.SaveHeadToStream(Stream: TStream; Definition: TPBDefinition);
    218310var
    219311  ByteIndex: Byte;
     
    221313begin
    222314  with TMemoryStreamEx(Stream) do begin
    223     Data := ((Tag and $f) shl 3) or (Integer(ItemType) and $7);
     315    Data := ((Definition.Tag and $f) shl 3) or (Integer(Definition.WireType) and $7);
    224316    ByteIndex := 0;
    225     while Tag > (1 shl (ByteIndex * 7 + 4)) do begin
     317    while Definition.Tag > (1 shl (ByteIndex * 7 + 4)) do begin
    226318      WriteByte(Data or $80);
    227       Data := (Tag shr (ByteIndex * 7 + 4)) and $7f;
     319      Data := (Definition.Tag shr (ByteIndex * 7 + 4)) and $7f;
    228320      Inc(ByteIndex);
    229321    end;
     
    232324end;
    233325
    234 procedure TPBItem.LoadHeadFromStream(Stream: TStream);
     326function TPBItem.LoadHeadFromStream(Stream: TStream; Definition: TPBDefinition): TPBItemHead;
    235327var
    236328  Data: Byte;
     
    238330begin
    239331  Data := TMemoryStreamEx(Stream).ReadByte;
    240   ItemType := TPBItemType(Data and 3);
    241   Tag := (Data shr 3) and $f;
     332  Result.WireType := TPBWireType(Data and 3);
     333  Result.Tag := (Data shr 3) and $f;
    242334  ByteIndex := 0;
    243335  while Data > $7f do begin
    244336    Data := TMemoryStreamEx(Stream).ReadByte;
    245     Tag := Tag or ((Data and $7f) shl (ByteIndex * 7 + 4));
     337    Result.Tag := Result.Tag or ((Data and $7f) shl (ByteIndex * 7 + 4));
    246338    Inc(ByteIndex);
    247339  end;
    248340end;
    249341
    250 procedure TPBItem.SaveToStream(Stream: TStream);
    251 begin
    252 
    253 end;
    254 
    255 procedure TPBItem.LoadFromStream(Stream: TStream);
     342procedure TPBItem.SaveToStream(Stream: TStream; Definition: TPBDefinition);
     343begin
     344
     345end;
     346
     347procedure TPBItem.LoadFromStream(Stream: TStream; Definition: TPBDefinition);
     348begin
     349
     350end;
     351
     352procedure TPBItem.Clear(Definition: TPBDefinition);
     353begin
     354
     355end;
     356
     357procedure TPBItem.Assign(Source: TPBItem);
    256358begin
    257359
     
    291393{ TPBIntegerItem }
    292394
    293 procedure TPBIntegerItem.SaveToStream(Stream: TStream);
    294 begin
    295   inherited;
    296   SaveHeadToStream(Stream);
     395procedure TPBIntegerItem.SaveToStream(Stream: TStream; Definition: TPBDefinition);
     396begin
     397  inherited;
     398  SaveHeadToStream(Stream, Definition);
    297399  SaveVariantToStream(Stream, Value);
    298400end;
    299401
    300 procedure TPBIntegerItem.LoadFromStream(Stream: TStream);
     402procedure TPBIntegerItem.LoadFromStream(Stream: TStream; Definition: TPBDefinition);
    301403begin
    302404  inherited;
     
    306408constructor TPBIntegerItem.Create;
    307409begin
    308   ItemType := itVariant;
     410end;
     411
     412procedure TPBIntegerItem.Assign(Source: TPBItem);
     413begin
     414  if Source is TPBIntegerItem then
     415    Value := TPBIntegerItem(Source).Value;
    309416end;
    310417
    311418{ TPBStringItem }
    312419
    313 procedure TPBStringItem.SaveToStream(Stream: TStream);
    314 begin
    315   inherited;
    316   SaveHeadToStream(Stream);
     420procedure TPBStringItem.SaveToStream(Stream: TStream; Definition: TPBDefinition);
     421begin
     422  inherited;
     423  SaveHeadToStream(Stream, Definition);
    317424  SaveVariantToStream(Stream, Length(Value));
    318   TMemoryStreamEx(Stream).Write(Value[1], Length(Value));
    319 end;
    320 
    321 procedure TPBStringItem.LoadFromStream(Stream: TStream);
     425  if Length(Value) > 0 then
     426    TMemoryStreamEx(Stream).Write(Value[1], Length(Value));
     427end;
     428
     429procedure TPBStringItem.LoadFromStream(Stream: TStream; Definition: TPBDefinition);
    322430begin
    323431  inherited;
    324432  SetLength(Value, LoadVariantFromStream(Stream));
    325   TMemoryStreamEx(Stream).Read(Value[1], Length(Value));
     433  if Length(Value) > 0 then
     434    TMemoryStreamEx(Stream).Read(Value[1], Length(Value));
    326435end;
    327436
    328437constructor TPBStringItem.Create;
    329438begin
    330   ItemType := itLengthDelimited;
     439end;
     440
     441procedure TPBStringItem.Assign(Source: TPBItem);
     442begin
     443  if Source is TPBStringItem then
     444    Value := TPBStringItem(Source).Value;
     445  inherited Assign(Source);
     446end;
     447
     448{ TPBDefinition }
     449
     450function TPBDefinition.SearchItemByTag(Tag: Integer): Integer;
     451var
     452  I: Integer;
     453begin
     454  I := 0;
     455  while (I < Items.Count) and (TPBDefinition(Items[I]).Tag <> Tag) do Inc(I);
     456  if I < Items.Count then Result := I
     457    else Result := -1;
     458end;
     459
     460function TPBDefinition.GetWireType: TPBWireType;
     461begin
     462  case ItemType of
     463    itInteger: Result := wtVariant;
     464    itFloat: Result := wt64bit;
     465    itDouble: Result := wt32bit;
     466    itString: Result := wtLengthDelimited;
     467    itMessage: Result := wtLengthDelimited;
     468  end;
     469end;
     470
     471constructor TPBDefinition.Create;
     472begin
     473  Items := TList.Create;
     474end;
     475
     476destructor TPBDefinition.Destroy;
     477var
     478  I: Integer;
     479begin
     480  for I := 0 to Items.Count - 1 do
     481    TPBDefinition(Items[I]).Destroy;
     482  Items.Free;
     483  inherited Destroy;
     484end;
     485
     486{ TPBRepeatedItem }
     487
     488procedure TPBRepeatedItem.Clear(Definition: TPBDefinition);
     489var
     490  I: Integer;
     491begin
     492  for I := 0 to Items.Count - 1 do
     493    TPBItem(Items[I]).Free;
     494  inherited;
     495end;
     496
     497procedure TPBRepeatedItem.SaveToStream(Stream: TStream;
     498  Definition: TPBDefinition);
     499var
     500  I: Integer;
     501begin
     502  for I := 0 to Items.Count - 1 do begin
     503    TPBItem(Items[I]).SaveToStream(Stream, Definition);
     504  end;
     505end;
     506
     507procedure TPBRepeatedItem.LoadFromStream(Stream: TStream;
     508  Definition: TPBDefinition);
     509begin
     510  inherited LoadFromStream(Stream, Definition);
     511end;
     512
     513constructor TPBRepeatedItem.Create;
     514begin
     515  Items := TList.Create;
     516end;
     517
     518destructor TPBRepeatedItem.Destroy;
     519var
     520  I: Integer;
     521begin
     522  for I := 0 to Items.Count - 1 do
     523    TPBItem(Items[I]).Free;
     524  Items.Free;
     525  inherited Destroy;
     526end;
     527
     528procedure TPBRepeatedItem.Assign(Source: TPBItem);
     529var
     530  I: Integer;
     531begin
     532  if Source is TPBRepeatedItem then begin
     533    for I := 0 to Items.Count - 1 do
     534      TPBItem(Items[I]).Assign(TPBRepeatedItem(Source).Items[I]);
     535  end;
     536  inherited Assign(Source);
    331537end;
    332538
Note: See TracChangeset for help on using the changeset viewer.