source: trunk/includes/dbc.php@ 234

Last change on this file since 234 was 234, checked in by maron, 16 years ago

V knihovně dbc zobrazování více informací při chybě, doplnění počtu a struktury dbc pro verzi 3.0.3 a 2.4.3, smazání nepotřebných sloupců se strukturou dbc souborů v tabulce group, změna načítání indexu textů z exportu podle verze

File size: 6.8 KB
Line 
1<?php
2
3include('stream.php');
4
5define('NOT_DBC_FILE', 'Není DBC soubor.');
6define('FIELD_COUNT_NOT_MATCH', 'Počet sloupců neodpovídá délce formátu.');
7define('RECORD_SIZE_NOT_MATCH', 'Velikost řádku neodpovídá zadanému formátu.');
8
9class DBCFile extends FileStream
10{
11 private $HeaderSize = 20;
12 private $Offsets;
13 private $StringOffset;
14 private $StringList = array();
15 private $StringListOffset = array();
16 private $Format;
17
18 private $RecordSize;
19 private $RecordCount;
20 private $StringBlockSize;
21 private $FieldCount;
22
23 public function OpenFile($FileName, $Format)
24 {
25 parent::OpenFile($FileName);
26
27 $this->Format = $Format;
28 if($this->ReadUint() != 0x43424457) die(NOT_DBC_FILE);
29
30 $this->RecordCount = $this->ReadUint();
31 $this->FieldCount = $this->ReadUint();
32 $this->RecordSize = $this->ReadUint();
33 $this->StringBlockSize = $this->ReadUint();
34
35 if(strlen($this->Format) != $this->FieldCount)
36 die(FIELD_COUNT_NOT_MATCH.' Počet v souboru:'.$this->FieldCount.' Počet v struktuře: '.strlen($Format));
37
38 $this->GenerateOffsetTable($Format);
39 if($this->Offsets[count($this->Offsets) - 1] != $this->RecordSize)
40 die(RECORD_SIZE_NOT_MATCH.$this->Offsets[count($this->Offsets) - 1].' <> '.$this->RecordSize);
41 }
42
43 public function CreateFile($FileName, $Format)
44 {
45 parent::CreateFile($FileName);
46
47 $this->WriteUint(0x43424457);
48
49 $this->StringList = array();
50 $this->StringOffset = 1;
51 $this->Format = $Format;
52 $this->GenerateOffsetTable($Format);
53 $this->FieldCount = strlen($Format);
54 $this->RecordCount = 0;
55 $this->RecordSize = $this->Offsets[count($this->Offsets) - 1];
56 $this->StringBlockSize = 0;
57
58 $this->WriteUint($this->RecordCount);
59 $this->WriteUint($this->FieldCount);
60 $this->WriteUint($this->RecordSize);
61 $this->WriteUint($this->StringBlockSize);
62 }
63
64 private function GenerateOffsetTable($Format)
65 {
66 $this->Offsets = array();
67 $this->Offsets[0] = 0;
68 for($I = 0; $I < strlen($Format); $I++)
69 {
70 $this->Offsets[$I + 1] = $this->Offsets[$I];
71 switch($Format[$I])
72 {
73 case "b":
74 case "X":
75 $this->Offsets[$I + 1] += 1;
76 break;
77 case "x":
78 case "u":
79 case "i":
80 case "f":
81 case "s":
82 $this->Offsets[$I + 1] += 4;
83 break;
84 }
85 }
86 }
87
88 private function SeekPosi($Row, $Column)
89 {
90 $Position = $this->HeaderSize + $Row * $this->RecordSize + $this->Offsets[$Column];
91 $this->Seek($Position);
92 }
93
94 public function GetByte($Row, $Column)
95 {
96 $this->SeekPosi($Row, $Column);
97 return($this->ReadByte());
98 }
99
100 public function GetUint($Row, $Column)
101 {
102 $this->SeekPosi($Row, $Column);
103 return($this->ReadUint());
104 }
105
106 public function GetInt($Row, $Column)
107 {
108 $this->SeekPosi($Row, $Column);
109 return($this->ReadInt());
110 }
111
112 public function GetFloat($Row, $Column)
113 {
114 $this->SeekPosi($Row, $Column);
115 return($this->ReadFloat());
116 }
117
118 public function SetByte($Row, $Column, $Value)
119 {
120 $this->SeekPosi($Row, $Column);
121 $this->WriteByte($Value);
122 }
123
124 public function SetUint($Row, $Column, $Value)
125 {
126 $this->SeekPosi($Row, $Column);
127 $this->WriteUint($Value);
128 }
129
130 public function SetInt($Row, $Column, $Value)
131 {
132 $this->SeekPosi($Row, $Column);
133 $this->WriteInt($Value);
134 }
135
136 public function SetFloat($Row, $Column, $Value)
137 {
138 $this->SeekPosi($Row, $Column);
139 $this->WriteFloat($Value);
140 }
141
142 public function GetString($Row, $Column)
143 {
144 $Offset = $this->GetUint($Row, $Column);
145
146 $Position = $this->HeaderSize + $this->RecordCount * $this->RecordSize + $Offset;
147 if($Position >= $this->GetSize()) return('');
148 $this->Seek($Position);
149
150 $String = '';
151 while(($Char = $this->ReadChar()) != "\0")
152 {
153 $String .= $Char;
154 }
155 return($String);
156 }
157
158 public function SetString($Row, $Column, $Value)
159 {
160 if(in_array($Value, $this->StringList))
161 {
162 $this->SetUint($Row, $Column, $this->StringListOffset[array_search($Value, $this->StringList)]);
163 } else
164 {
165 $this->SetUint($Row, $Column, $this->StringOffset);
166 $this->StringList[] = $Value;
167 $this->StringListOffset[] = $this->StringOffset;
168 $this->StringOffset += strlen($Value) + 1;
169 }
170 }
171
172 public function Commit()
173 {
174 $this->Seek(0);
175 $this->WriteUint(0x43424457);
176 $this->WriteUint($this->RecordCount);
177 $this->WriteUint($this->FieldCount);
178 $this->WriteUint($this->RecordSize);
179 $this->WriteUint($this->StringOffset);
180 $this->Seek($this->HeaderSize + $this->RecordCount * $this->RecordSize);
181 $this->WriteByte(0);
182 foreach($this->StringList as $Index => $Item)
183 {
184 $this->WriteString($Item);
185 }
186 }
187
188 public function GetLine($Row)
189 {
190 $Line = array();
191 for($I = 0; $I < $this->FieldCount; $I++)
192 {
193 switch($this->Format[$I])
194 {
195 case 'b':
196 $Line[$I] = $this->GetByte($Row, $I);
197 break;
198 case 'u':
199 $Line[$I] = $this->GetUint($Row, $I);
200 break;
201 case 'i':
202 $Line[$I] = $this->GetInt($Row, $I);
203 break;
204 case 'f':
205 $Line[$i] = $this->GetFloat($Row, $I);
206 break;
207 case 's':
208 $Line[$I] = $this->GetString($Row, $I);
209 break;
210 case 'x':
211 case 'X':
212 default:
213 break;
214 }
215 }
216 return($Line);
217 }
218
219 public function SetLine($Row, $Line)
220 {
221 for($I = 0; $I < $this->FieldCount; $I++)
222 {
223 switch($this->Format[$I])
224 {
225 case 'b':
226 $this->SetByte($Row, $I, $Line[$I]);
227 break;
228 case 'u':
229 $this->SetUint($Row, $I, $Line[$I]);
230 break;
231 case 'i':
232 $this->SetInt($Row, $I, $Line[$I]);
233 break;
234 case 'f':
235 $this->SetFloat($Row, $I, $Line[$i]);
236 break;
237 case 's':
238 $this->SetString($Row, $I, $Line[$I]);
239 break;
240 case 'x':
241 case 'X':
242 default:
243 break;
244 }
245 }
246 return($Line);
247 }
248
249 public function GetLineCols($Row, $Columns)
250 {
251 $Line = array();
252 for($I = 0; $I < count($Columns); $I++)
253 {
254 switch($this->Format[$Columns[$I]])
255 {
256 case 'b':
257 $Line[$I] = $this->GetByte($Row, $Columns[$I]);
258 break;
259 case 'u':
260 $Line[$I] = $this->GetUint($Row, $Columns[$I]);
261 break;
262 case 'i':
263 $Line[$I] = $this->GetInt($Row, $Columns[$I]);
264 break;
265 case 'f':
266 $Line[$i] = $this->GetFloat($Row, $Columns[$I]);
267 break;
268 case 's':
269 $Line[$I] = $this->GetString($Row, $Columns[$I]);
270 break;
271 case 'x':
272 case 'X':
273 default:
274 break;
275 }
276 }
277 return($Line);
278 }
279
280 public function GetRecordCount()
281 {
282 return($this->RecordCount);
283 }
284
285 public function SetRecordCount($Value)
286 {
287 $this->RecordCount = $Value;
288 }
289
290 public function GetFieldCount()
291 {
292 return($this->FieldCount);
293 }
294}
295
296?>
Note: See TracBrowser for help on using the repository browser.