source: tools/WoWHeadLoader/UDBC.pas

Last change on this file was 606, checked in by maron, 10 years ago
  • Added: Tool for import text from wowhead.com (not complete, import quest working)
File size: 4.0 KB
Line 
1unit UDBC;
2
3{$mode Delphi}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Strings, Variants;
9
10const
11 HeaderSize = 20;
12 DBCSignature = $43424457;
13
14type
15 TDBCColumnType = (ctUInt32, ctSInt32, ctSingle, ctString, ctByte);
16
17 { TDBC }
18
19 TDBC = class
20 private
21 FileStream: TFileStream;
22 RecordCount: Integer;
23 FieldCount: Integer;
24 RecordSize: Integer;
25 StringBlockSize: Integer;
26 public
27 Cells: array of array of Variant;
28 ColumnFormat: array of TDBCColumnType;
29 function DetectColumnType(Column: Integer): TDBCColumnType;
30 procedure LoadFromFile(FileName: string);
31 procedure LoadColumnStrings(Column: Integer);
32 procedure SaveToFile(FileName: string);
33 procedure SetString(Row, Column: Integer; Text: AnsiString);
34 end;
35
36implementation
37
38{ TDBC }
39
40procedure TDBC.LoadFromFile(FileName: string);
41var
42 Signature: Cardinal;
43 Row, Col: Integer;
44begin
45 FileStream := TFileStream.Create(FileName, fmOpenRead);
46 with FileStream do begin
47 Signature := ReadDWord;
48 if Signature <> DBCSignature then
49 raise Exception.Create('DBC type mismatch.');
50
51 RecordCount := ReadDWord;
52 FieldCount := ReadDWord;
53 RecordSize := ReadDWord;
54 StringBlockSize := ReadDWord;
55
56 SetLength(Cells, RecordCount, FieldCount);
57 for Row := 0 to RecordCount - 1 do
58 for Col := 0 to FieldCount - 1 do begin
59 Cells[Row, Col] := ReadDWord;
60 end;
61 end;
62end;
63
64procedure TDBC.LoadColumnStrings(Column: Integer);
65var
66 Row: Integer;
67 Offset: Integer;
68 Text: AnsiString;
69 C: Char;
70begin
71 with FileStream do
72 for Row := 0 to RecordCount - 1 do begin
73 Offset := HeaderSize + RecordCount * RecordSize + Cells[Row, Column];
74 if Position <> Offset then Seek(Offset, soBeginning);
75
76 Text := '';
77 C := ' ';
78 while (C <> #0) do begin
79 C := Chr(ReadByte);
80 if C <> #0 then Text := Text + C;
81 end;
82 Cells[Row, Column] := Text;
83 end;
84end;
85
86procedure TDBC.SaveToFile(FileName: string);
87var
88 Row, Col: Integer;
89 Offset: Integer;
90 StringList: array of string;
91begin
92 if Assigned(FileStream) then FileStream.Free;
93 FileStream := TFileStream.Create(FileName, fmCreate);
94 with FileStream do begin
95 WriteDWord(DBCSignature);
96 WriteDWord(RecordCount);
97 WriteDWord(FieldCount);
98 WriteDWord(RecordSize);
99 WriteDWord(StringBlockSize);
100
101 Size := RecordSize * RecordCount;
102 SetLength(StringList, 0);
103 Offset := 1;
104 // Write cells
105 for Row := 0 to RecordCount - 1 do begin
106 for Col := 0 to FieldCount - 1 do begin
107 if VarIsStr(Cells[Row, Col]) then begin
108 //System.Write(IntToStr(Offset) + ': "' + Cells[Row, Col] + '", ');
109 WriteDWord(Offset);
110 Offset := Offset + Length(Cells[Row, Col]) + 1;
111 SetLength(StringList, Length(StringList) + 1);
112 StringList[High(StringList)] := Cells[Row, Col];
113 end else begin
114 //System.Write(IntToStr(Cells[Row, Col]) + ', ');
115 WriteDWord(Cells[Row, Col]);
116 end;
117 end;
118 //WriteLn;
119 end;
120
121 // Write strings
122 Offset := 1;
123 WriteByte(0);
124 for Row := 0 to Length(StringList) - 1 do begin
125 //WriteLn('Id: ' + IntToStr(Row) + ', Offset: ' + IntToStr(Offset) + ', "' + StringList[Row] + '"');
126 for Col := 1 to Length(StringList[Row]) do
127 WriteByte(Ord(StringList[Row][Col]));
128 WriteByte(0);
129 Offset := Offset + Length(StringList[Row]) + 1;
130 end;
131
132 // Update string block size
133 StringBlockSize := Offset;
134 Seek(16, soFromBeginning);
135 WriteDWord(StringBlockSize);
136 end;
137end;
138
139procedure TDBC.SetString(Row, Column: Integer; Text: AnsiString);
140begin
141 if VarIsStr(Cells[Row,Column]) then begin
142 StringBlockSize := StringBlockSize + strlen(Pchar(Text)) - strlen(Pchar(VarToStr(Cells[Row,Column])));
143 Cells[Row,Column] := Text;
144 end;
145end;
146
147function TDBC.DetectColumnType(Column: Integer): TDBCColumnType;
148//var
149// Row: Integer;
150begin
151(*
152 Result := ctString;
153 for Row := 0 to RecordCount - 1 do
154 if GetStringByOffset(Cells[Row, Column]) = '' then Result := ctInt32;
155 if Result = ctString then Exit;
156*)
157end;
158
159end.
Note: See TracBrowser for help on using the repository browser.