1 // streaming file system (virtual)
2 {$MODE DELPHI}
3 {.$R-}
6 interface
8 uses
12 type
21 public
23 fPath: TSFSString; // ðàçäåëèòåëè êàòàëîãîâ -- "/"; êîðåíü íèêàê íå îáîçíà÷åí, åñëè íå ïóñòîå, îáÿçàíî çàâåðøàåòñÿ "/"
36 // âèðòóàëüíàÿ ôàéëîâàÿ ñèñòåìà. ÒÎËÜÊÎ ÄËß ×ÒÅÍÈß!
37 // òîì ÍÅ ÄÎËÆÅÍ óáèâàòüñÿ íèêàê èíà÷å, ÷åì ïðè ïîìîùè ôàáðèêè!
39 protected
45 // ïðèøèáèòü âñå ñòðóêòóðû.
46 // íå äîëæíà ïàäàòü, åñëè å¸ âûçûâàþò íåñêîëüêî ðàç.
49 // âûçûâàåòñÿ èç DoDirectoryRead() äëÿ çàïîëíåíèÿ ñïèñêà ôàéëîâ.
50 // ñ÷èòàåòñÿ, ÷òî âñå ìàãèêè óæå ïðîâåðåíû è ôàéë òî÷íî íàø.
51 // fFileName, fFileStream óæå óñòàíîâëåíû, fFiles ñîçäàí,
52 // â í¸ì, ñêîðåå âñåãî, íèêîãî íåò.
53 // ïîçèöèÿ ïîòîêà -- òà, ÷òî îñòàâèëà ôàáðèêà.
54 // ïðè îøèáêàõ êèäàòü èñêëþ÷åíèå, òîãäà òîì áóäåò ïðèáèò ôàáðèêîé.
55 // ðàçäåëèòåëè ïóòåé äîëæíû áûòü òîëüêî "/", êîðíåâîé "/" äîëæåí
56 // áûòü îïóùåí, ïóòè (åñëè íå ïóñòûå) äîëæíû çàâåðøàòüñÿ "/"!
57 // fName äîëæíî ñîäåðæàòü òîëüêî èìÿ, fPath -- òîëüêî ïóòü.
58 // â ïðèíöèïå, îá ýòîì ïîçàáîòèòñÿ DoDirectoryRead(), íî çà÷åì
59 // äàâàòü åìó ëèøíþþ ðàáîòó?
62 // íàéòè ôàéë, âåðíóòü åãî èíäåêñ â fFiles.
63 // ýòà ïðîöåäóðà ìîæåò ìåíÿòü fFiles!
64 // fPath -- â ïðàâèëüíîé ôîðìå, ñ "/", êîðíåâîé "/" óáèò, ôèíàëüíûé äîáàâëåí.
65 // åñëè ôàéë íå íàéäåí, âåðíóòü -1.
68 // âîçâðàùàåò êîëè÷åñòâî ôàéëîâ â fFiles
71 // âîçâðàùàåò ôàéë ñ èíäåêñîì index.
72 // ìîæåò âîçâðàùàòü NIL.
73 // íèêàêèõ ïàäåíèé íà íåïðàâèëüíûå èíäåêñû!
78 public
79 // pSt íå îáÿçàòåëüíî çàïîìèíàòü, åñëè îí íå íóæåí.
81 // fFileStream óíè÷òîæàòü íåëüçÿ, åñëè îí ðàâåí ïàðàìåòðó pSt êîíñòðóêòîðà.
84 // âûçûâàåò ReadDirectory().
85 // ýòà ïðîöåäóðà ñàìà ðàçáåð¸òñÿ ñ äóáëèêàòàìè èì¸í: ïîäîáàâëÿåò â
86 // êîíåö èì¸í-äóáëèêàòîâ ïîä÷¸ðêèâàíèå è äåñÿòè÷íûé íîìåð.
87 // òàêæå îíà íîðìàëèçóåò âèä èì¸í.
90 // ïðè îøèáêàõ êèäàòüñÿ èñêëþ÷åíèÿìè.
93 // åñëè íå ñìîãëî îòêóïîðèòü ôàéëî (èëè åù¸ ãäå îøèáëîñü), çàøâûðí¸ò èñêëþ÷åíèå.
97 // ìîæåò âîçâðàùàòü NIL.
98 // íèêàêèõ ïàäåíèé íà íåïðàâèëüíûå èíäåêñû!
102 // ôàáðèêà òîìîâ. âñå SFS ïðè ñòàðòå äîáàâëÿþò ñâîè ôàáðèêè.
103 // áëàãîäàðÿ ýòîìó ìîæíî ñîçäàâàòü ðàçíûå âñÿêèå SFS ñòàíäàðòíûì
104 // âûçîâîì ñòàíäàðòíîé ïðîöåäóðû.
105 // ôàáðèêà ÍÅ ÄÎËÆÍÀ óáèâàòüñÿ íèêàê èíà÷å, ÷åì ïðè ïîìîùè âûçîâà
106 // SFSUnregisterVolumeFactory()! ýòî ãàðàíòèðóåò, ÷òî äâèæîê
107 // ïåðåä ðàññòðåëîì îòäàñò åé âñå å¸ òîìà.
109 public
110 // åñëè äîáàâëÿåì ôàéë äàííûõ ôàéë ñ èìåíåì òèïà "zip:....", òî
111 // SFS èçâëå÷¸ò ýòî "zip" è ïåðåäàñò â ñèþ ôóíêöèþ.
112 // åæåëè ôóíêöèÿ âåðí¸ò ïðàâäó, òî SFS âûçîâåò Produce äëÿ äàííîãî
113 // ôàéëà. åñëè íè îäíà ôàáðèêà ïðåôèêñ íå ïðèçíàåò, òî ôàéë íå îòêðîþò.
114 // èñïîëüçóåòñÿ äëÿ ñêèïàíèÿ àâòîäåòåêòà.
115 // SFS ÍÅ Ñ×ÈÒÀÅÒ ÏÐÅÔÈÊÑÎÌ ÑÒÐÎÊÓ ÊÎÐÎ×Å ÒÐ¨Õ ÑÈÌÂÎËÎÂ!
117 // ïðîâåðÿåò, ìîæåò ëè ôàáðèêà ñäåëàòü òîì äëÿ äàííîãî ôàéëà.
118 // st -- îòêðûòûé äëÿ ÷òåíèÿ ôàéëîâé ïîòîê. óêàçàòåëü ÷òåíèÿ ñòîèò â íà÷àëå.
119 // ýòîò ïîòîê íåëüçÿ çàêðûâàòü!
120 // prefix: òî, ÷òî áûëî ïåðåäàíî â IsMyVolumePrefix() èëè ''.
121 // èñêëþ÷åíèå ñ÷èòàåòñÿ îøèáêîé, âîçâðàò NIL ñ÷èòàåòñÿ îøèáêîé.
122 function Produce (const prefix, fileName: TSFSString; st: TStream): TSFSVolume; virtual; abstract;
123 // êîãäà òîì áîëüøå íå íóæåí, îí áóäåò îòäàí ôàáðèêå íà ïåðåðàáîòêó.
124 // äàëåå äâèæîê íå áóäåò þçàòü ñåé òîì.
128 // "èòåðàòîð", âîçâðàùàåìûé SFSFileList()
130 protected
136 public
142 // ïðè íåïðàâèëüíîì èíäåêñå ìîë÷à âåðí¸ò NIL.
143 // ïðè ïðàâèëüíîì òîæå ìîæåò âåðíóòü NIL!
144 // î÷åíü íå ñîâåòóþ ìåíÿòü ñîäåðæèìîå ïîëó÷åííîãî êëàññà.
145 // êîíå÷íî, ÿ ìîã áû âîçâðàùàòü íîâóþ ñòðóêòóðó èëè íå÷òî ïîõîæåå,
146 // íî áëèí, åñëè òû èäèîò è íå óìååøü äàæå êîììåíòû ÷èòàòü, òî
147 // êàêîãî òû âîîáùå â ïðîãðàììèíã ïîëåç?
153 // ýòà ôóíêöèÿ àâòîìàòè÷åñêè ïðèáü¸ò factory.
156 // äîáàâèòü ñáîðíèê â ïîñòîÿííûé ñïèñîê.
157 // åñëè ñáîðíèê ñ òàêèì èìåíåì óæå îòêðûò, òî íå îòêðûâàåò åãî ïîâòîðíî.
158 // íèêîãäà íå êèäàåò èñêëþ÷åíèé.
159 // top: äîáàâèòü â íà÷àëî ñïèñêà ïîèñêà.
160 // âåðí¸ò ëîæü ïðè îøèáêå.
161 // ñïîñîáíî îòêðûâàòü ñáîðíèêè â ñáîðíèêàõ ïðè ïîìîùè êðóòûõ èì¸í a-la:
162 // "zip:pack0::pack:pack1::wad2:pack2".
163 // â äàëüíåéøåì ñëåäóåò îáðàùàòüñÿ ê ñáîðíèêó êàê "pack2::xxx".
164 // èëè ìîæíî íàïèñàòü:
165 // "zip:pack0::pack:pack1::wad2:pack2|datafile".
166 // è îáðàùàòüñÿ êàê "datafile::xxx".
167 // "||" ïðåîáðàçóþòñÿ â ïðîñòîé "|" è ðàçäåëèòåëåì íå ñ÷èòàþòñÿ.
168 // ïðèíèìàåòñÿ âî âíèìàíèå òîëüêî ïîñëåäíÿÿ òðóáà.
171 // äîáàâèòü â ïîñòîÿííûé ñïèñîê ñáîðíèê èç ïîòîêà ds.
172 // åñëè âîçâðàùàåò èñòèíó, òî SFS ñòàíîâèòñÿ âëÿäåëüöåì ïîòîêà ds è ñàìà
173 // óãðîáèò ñåé ïîòîê ïî íåîáõîäèìîñòè.
174 // virtualName ñòàíîâèòñÿ èìåíåì ñáîðíèêà äëÿ îïåðàöèè îòêðûòèÿ ôàéëà òèïà
175 // "packfile:file.ext".
176 // åñëè êàêîé-íèáóäü ñáîðíèê ñ èìåíåì virtualName óæå îòêðûò, âåðí¸ò false.
177 // íèêîãäà íå êèäàåò èñêëþ÷åíèé.
178 // top: äîáàâèòü â íà÷àëî ñïèñêà ïîèñêà.
179 // âåðí¸ò ëîæü ïðè îøèáêå.
180 // îòêðûâàåò ñáîðíèê èç ïîòîêà. dataFileName -- ÂÈÐÒÓÀËÜÍÎÅ èìÿ.
181 // ò.å. íà ñàìîì äåëå òàêîãî ôàéëà ìîæåò è íå áûòü íà äèñêå.
182 function SFSAddSubDataFile (const virtualName: TSFSString; ds: TStream; top: Boolean=false): Boolean;
184 // øâûðÿåòñÿ èñêëþ÷åíèÿìè.
185 // åñëè fName íå èìååò óêàçàíèÿ íà ôàéë äàííûõ (ýòî òî, ÷òî îòäåëåíî îò
186 // îñòàëüíîãî èìåíè äâîåòî÷èåì), òî èùåì ñíà÷àëà ïî âñåì çàðåãèñòðèðîâàííûì
187 // ôàéëàì äàííûõ, ïîòîì â òåêóùåì êàòàëîãå, ïîòîì â êàòàëîãå, îòêóäà ñòàðòîâàëè.
188 // åñëè íè÷åãî íå íàøëè, êèäàåì èñêëþ÷åíèå.
191 // ïðè îøèáêå -- NIL, è íèêàêèõ èñêëþ÷åíèé.
194 // âîçâðàùàåò NIL ïðè îøèáêå.
195 // ïîñëå èñïîëüçîâàíèÿ, íàòóðàëüíî, èòåðàòîð íàäî ãðîõíóòü %-)
199 // èãíîðèðóåò ðåãèñòð ñèìâîëîâ
202 // ðàçîáðàòü òîëñòîå èìÿ ôàéëà, âåðíóòü âèðòóàëüíîå èìÿ ïîñëåäíåãî ñïèñêà
203 // èëè ïóñòóþ ñòîðîêó, åñëè ñïèñêîâ íå áûëî.
206 // ïðåîáðàçîâàòü ÷èñëî â ñòðîêó, êðàñèâî ðàçáàâëÿÿ çàïÿòûìè
209 // `name` will be modified
210 // return `true` if file was found
213 // Wildcard matching
214 // this code is meant to allow wildcard pattern matches. tt is VERY useful
215 // for matching filename wildcard patterns. tt allows unix grep-like pattern
216 // comparisons, for instance:
217 //
218 // ? Matches any single characer
219 // + Matches any single characer or nothing
220 // * Matches any number of contiguous characters
221 // [abc] Matches a or b or c at that position
222 // [!abc] Matches anything but a or b or c at that position
223 // [a-e] Matches a through e at that position
224 //
225 // 'ma?ch.*' -Would match match.exe, mavch.dat, march.on, etc
226 // 'this [e-n]s a [!zy]est' -Would match 'this is a test', but would
227 // not match 'this as a yest'
228 //
233 // this will compare only last path element from sfspath
241 var
242 // ïðàâäà: ðàçðåøåíî èñêàòü ôàéëî íå òîëüêî â ôàéëàõ äàííûõ, íî è íà äèñêå.
244 // ïðàâäà: åñëè ôàéë íå ïðåôèêñîâàí, òî ñíà÷àëà èùåì ôàéëî íà äèñêå,
245 // ïîòîì â ôàéëàõ äàííûõ.
247 // ïðàâäà: äàæå äëÿ ïðåôèêñîâàíûõ ôàéëîâ ñíà÷àëà ïðîñìîòðèì äèñê
248 // (åñëè óñòàíîâëåí ôëàæîê sfsDiskFirst è sfsDiskEnabled).
250 // ñïèñîê äèñêîâûõ êàòàëîãîâ äëÿ ïîèñêà ôàéëà. åñëè ïóñò -- èùåì òîëüêî â
251 // òåêóùåì. êàòàëîãè ðàçäåëÿþòñÿ òðóáîé ("|").
252 // <currentdir> çàìåíÿåòñÿ íà òåêóùèé êàòàëîã (ñ çàâåðøàþùèì "/"),
253 // <exedir> çàìåíÿåòñÿ íà êàòàëîã, ãäå ñèäèò .EXE (ñ çàâåðøàþùèì "/").
257 implementation
259 uses
260 xstreams;
264 var
266 begin
270 begin
276 // `name` will be modified
278 var
281 begin
287 repeat
291 begin
294 exit;
303 const
304 // character defines
316 begin
317 result :=
325 function MatchMask (const pattern: TSFSString; p, pend: Integer; const text: TSFSString; t, tend: Integer): Boolean;
326 var
330 begin
331 // sanity checks
337 begin
339 begin
340 // no more text. check if there's no more chars in pattern (except "*" & "+")
345 exit;
348 WILD_CHAR_SINGLE: ;
349 WILD_CHAR_ESCAPE:
350 begin
355 WILD_CHAR_RANGE_OPEN:
356 begin
364 repeat
370 begin
374 begin
376 end
378 end
383 // skip the rest or the range
387 WILD_CHAR_SINGLE_OR_NONE:
388 begin
392 exit;
394 WILD_CHAR_MULTI:
395 begin
399 begin
403 exit;
414 begin
421 var
423 begin
429 begin
431 begin
433 begin
440 begin
450 type
456 fPermanent: Boolean; // èñòèíà -- íå áóäåò óãðîáëåíà, åñëè íå îñòàíåòñÿ íè îäíîãî îòêðûòîãî òîìà
457 // èñòèíà -- ýòîò òîì áûë ñîçäàí èç ïîòîêà è íå èìååò äèñêîâîãî ôàéëà, ïîòîìó ôàáðèêå áóäåò ïåðåäàíî íå èìÿ ñáîðíèêà, à ïóñòàÿ ñòðîêà
465 protected
468 public
474 var
479 // ðàçáèòü èìÿ ôàéëà íà ÷àñòè: ïðåôèêñ ôàéëîâîé ñèñòåìû, èìÿ ôàéëà äàííûõ,
480 // ñîáñòâåííî èìÿ ôàéëà
481 // èìÿ âûãëÿäèò êàê:
482 // (("sfspfx:")?"datafile::")*"filename"
484 var
486 begin
489 begin
494 else
495 begin
501 // ñàéäýôôåêò: âûðåçàåò âèðòóàëüíîå èìÿ èç dataFile.
503 var
505 begin
508 begin
511 begin
513 else
514 begin
517 break;
524 // ðàçáèòü èìÿ ñáîðíèêà íà ÷àñòè: ïðåôèêñ ôàéëîâîé ñèñòåìû, èìÿ ôàéëà äàííûõ,
525 // âèðòóàëüíîå èìÿ. åñëè âèðòóàëüíîãî èìåíè íå äàíî, îíî áóäåò ðàâíî dataFile.
526 // èìÿ âûãëÿäèò êàê:
527 // [sfspfx:]datafile[|virtname]
528 // åñëè ïåðåä äâîåòî÷èåì ìåíüøå òð¸õ áóêâ, òî ýòî ñ÷èòàåòñÿ íå ïðåôèêñîì,
529 // à èìåíåì äèñêà.
531 var
533 begin
536 else
537 begin
544 // íàéòè ïðîèçâîäèòåëÿ äëÿ ýòîãî ôàéëà (åñëè ôàéë óæå îòêðûò).
545 // onlyPerm: òîëüêî "ïîñòîÿííûå" ïðîèçâîäèòåëè.
547 var
550 begin
553 begin
555 begin
558 begin
560 begin
562 exit;
571 // íàéòè èíôó äëÿ ýòîãî òîìà.
572 // õîðîøåå èìÿ, ïðàâäà? %-)
574 begin
577 begin
579 begin
587 begin
589 begin
591 end
592 else
593 begin
595 begin
597 end
598 else
599 begin
610 var
612 begin
613 //result := (AnsiCompareText(s0, s1) == 0);
617 begin
623 // this will compare only last path element from sfspath
625 {var
626 i: Integer;}
627 begin
629 (*
630 if not result and (length(sfspath) > 1) then
631 begin
632 i := length(sfspath);
633 while i > 1 do
634 begin
635 while (i > 1) and (sfspath[i-1] <> '/') do Dec(i);
636 if i <= 1 then exit;
637 writeln('{', sfspath, '} [', Copy(sfspath, i, length(sfspath)), '] : [', path, ']');
638 result := SFSStrEqu(Copy(sfspath, i, length(sfspath)), path);
639 end;
640 end;
641 *)
644 // adds '/' too
646 var
648 begin
652 begin
654 begin
656 continue;
659 begin
661 end
662 else
663 begin
672 var
674 begin
677 begin
679 begin
680 // avoid unnecessary string changes
687 var
690 begin
692 repeat
700 { TVolumeInfo }
702 var
705 begin
712 // òèïà ìóñîðîñáîðíèê: åñëè íàø ïîòîê áîëåå íèêåì íå þçàåòñÿ, òî óãðîáèòü åãî íàôèã
714 begin
718 begin
720 begin
723 begin
736 { TOwnedPartialStream }
739 begin
746 var
748 begin
751 begin
754 begin
762 { TSFSFileInfo }
764 begin
775 begin
781 { TSFSVolume }
783 begin
792 begin
796 var
800 begin
807 begin
809 // normalize name & path
816 begin
817 // split path and name
830 begin
837 begin
843 begin
845 else
846 begin
849 begin
852 begin
862 begin
867 begin
869 else
870 begin
877 var
880 begin
882 // normalize name, find split position
886 begin
899 { TSFSFileList }
901 var
903 begin
913 var
915 begin
920 // óáü¸ì çàïèñü, åñëè îíà âðåìåííàÿ, è â íåé íåò áîëüøå íè÷åãî îòêðûòîãî
927 begin
932 begin
939 var
941 begin
950 var
953 begin
958 begin
966 function SFSAddDataFileEx (dataFileName: TSFSString; ds: TStream; top, permanent: Integer): Integer;
967 // dataFileName ìîæåò èìåòü ïðåôèêñ òèïà "zip:" (ñì. âûøå: IsMyPrefix).
968 // ìîæåò âûêèíóòü èñêëþ÷åíèå!
969 // top:
970 // <0: äîáàâèòü â íà÷àëî ñïèñêà ïîèñêà.
971 // =0: íå ìåíÿòü.
972 // >0: äîáàâèòü â êîíåö ñïèñêà ïîèñêà.
973 // permanent:
974 // <0: ñîçäàòü "âðåìåííûé" òîì.
975 // =0: íå ìåíÿòü ôëàæîê ïîñòîÿíñòâà.
976 // >0: ñîçäàòü "ïîñòîÿííûé" òîì.
977 // åñëè ds <> nil, òî ñîçäà¸ò ñáîðíèê èç ïîòîêà. åñëè ñáîðíèê ñ èìåíåì
978 // dataFileName óæå çàðåãèñòðèðîâàí, òî ïàäàåò íàôèã.
979 // âîçâðàùàåò èíäåêñ â volumes.
980 // óìååò äåëàòü ðåêóðñèþ.
981 var
989 begin
992 begin
993 // ðåêóðñèâíîå îòêðûòèå.
994 // ðàçîáü¸ì dataFileName íà èìÿ ñáîðíèêà è îñòàòîê.
995 // pfx áóäåò èìåíåì ñáîðíèêà, dataFileName -- îñòàòêîì.
997 // ñíà÷àëà îòêðîåì ïåðâûé ñïèñîê...
999 // ...òåïåðü ïðîäîëæèì ñ îñòàòêîì.
1000 // óçíàåì, êàêîå ôàéëî îòêðûâàòü.
1001 // âûêîâûðÿåì ïåðâûé "::" ïðåôèêñ (ýòî áóäåò èìÿ ôàéëà).
1004 // dataFileName õðàíèò îñòàòîê.
1005 // èçâëå÷¸ì èìÿ ôàéëà:
1007 // îòêðîåì ýòîò ôàéë
1009 try
1012 except
1014 // óäàëèì íåèñïîëüçóåìûé âðåìåííûé òîì.
1018 // óðà. îòêðûëè ôàéë. êèäàåì â âîçäóõ ÷åï÷èêè, ïðîäîëæàåì ðàçâëå÷åíèå.
1020 try
1023 except
1027 exit;
1030 // îáûêíîâåííîå íåðåêóðñèâíîå îòêðûòèå.
1035 begin
1042 exit;
1052 try
1054 begin
1059 try
1062 except
1068 except
1074 try
1076 begin
1079 end
1081 except
1099 var
1101 begin
1103 try
1107 except
1113 var
1115 begin
1116 try
1120 except
1127 var
1130 begin
1133 begin
1144 begin
1149 end
1155 var
1163 // ïðîâåðèì, åñòü ëè ôàëî fn ãäå-òî íà äèñêàõ.
1164 var
1167 begin
1174 begin
1180 try
1182 exit;
1183 except
1188 begin
1195 begin
1196 // ïðåôèêñîâàíûé ôàéë
1198 begin
1206 try
1209 except
1214 exit;
1216 //Inc(vi.fOpenedFilesCount);
1218 exit;
1221 // íåïðåôèêñîâàíûé ôàéë
1223 begin
1227 // èùåì ïî âñåì ïåðìàíåíòíûì ïðåôèêñàì
1230 begin
1233 begin
1235 begin
1238 begin
1239 try
1242 //Inc(vi.fOpenedFilesCount);
1243 except
1257 begin
1258 try
1260 except
1266 var
1269 begin
1273 try
1275 except
1276 exit;
1280 try
1283 except
1289 // ////////////////////////////////////////////////////////////////////////// //
1290 // utils
1291 // `ch`: utf8 start
1292 // -1: invalid utf8
1294 begin
1306 var
1308 begin
1312 begin
1318 // check other sequence bytes
1320 begin
1330 // ////////////////////////////////////////////////////////////////////////// //
1331 const
1332 // TODO: move this to a separate file
1334 $0402,$0403,$201A,$0453,$201E,$2026,$2020,$2021,$20AC,$2030,$0409,$2039,$040A,$040C,$040B,$040F,
1335 $0452,$2018,$2019,$201C,$201D,$2022,$2013,$2014,$003F,$2122,$0459,$203A,$045A,$045C,$045B,$045F,
1336 $00A0,$040E,$045E,$0408,$00A4,$0490,$00A6,$00A7,$0401,$00A9,$0404,$00AB,$00AC,$00AD,$00AE,$0407,
1337 $00B0,$00B1,$0406,$0456,$0491,$00B5,$00B6,$00B7,$0451,$2116,$0454,$00BB,$0458,$0405,$0455,$0457,
1338 $0410,$0411,$0412,$0413,$0414,$0415,$0416,$0417,$0418,$0419,$041A,$041B,$041C,$041D,$041E,$041F,
1339 $0420,$0421,$0422,$0423,$0424,$0425,$0426,$0427,$0428,$0429,$042A,$042B,$042C,$042D,$042E,$042F,
1340 $0430,$0431,$0432,$0433,$0434,$0435,$0436,$0437,$0438,$0439,$043A,$043B,$043C,$043D,$043E,$043F,
1341 $0440,$0441,$0442,$0443,$0444,$0445,$0446,$0447,$0448,$0449,$044A,$044B,$044C,$044D,$044E,$044F
1342 );
1346 var
1348 begin
1349 (* The following encodings are valid, except for the 5 and 6 byte
1350 * combinations:
1351 * 0xxxxxxx
1352 * 110xxxxx 10xxxxxx
1353 * 1110xxxx 10xxxxxx 10xxxxxx
1354 * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1355 * 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1356 * 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1357 *)
1365 // mask out unused bits
1373 // now continue
1375 begin
1383 // done, try 1251
1385 // alas
1390 var
1392 begin
1396 begin
1407 initialization
1410 //finalization
1411 //volumes.Free(); // it fails for some reason... Runtime 217 (^C hit). wtf?!
1412 //factories.Free(); // not need to be done actually...