eaabb964a9e0bb9f55a8f952deabbd9ecf29b8fc
1 // streaming file system (virtual)
2 {$MODE DELPHI}
3 {.$R-}
4 {.$DEFINE SFS_VOLDEBUG}
7 interface
9 uses
13 type
22 public
24 fPath: TSFSString; // ðàçäåëèòåëè êàòàëîãîâ -- "/"; êîðåíü íèêàê íå îáîçíà÷åí, åñëè íå ïóñòîå, îáÿçàíî çàâåðøàåòñÿ "/"
37 // âèðòóàëüíàÿ ôàéëîâàÿ ñèñòåìà. ÒÎËÜÊÎ ÄËß ×ÒÅÍÈß!
38 // òîì ÍÅ ÄÎËÆÅÍ óáèâàòüñÿ íèêàê èíà÷å, ÷åì ïðè ïîìîùè ôàáðèêè!
40 protected
46 // ïðèøèáèòü âñå ñòðóêòóðû.
47 // íå äîëæíà ïàäàòü, åñëè å¸ âûçûâàþò íåñêîëüêî ðàç.
50 // âûçûâàåòñÿ èç DoDirectoryRead() äëÿ çàïîëíåíèÿ ñïèñêà ôàéëîâ.
51 // ñ÷èòàåòñÿ, ÷òî âñå ìàãèêè óæå ïðîâåðåíû è ôàéë òî÷íî íàø.
52 // fFileName, fFileStream óæå óñòàíîâëåíû, fFiles ñîçäàí,
53 // â í¸ì, ñêîðåå âñåãî, íèêîãî íåò.
54 // ïîçèöèÿ ïîòîêà -- òà, ÷òî îñòàâèëà ôàáðèêà.
55 // ïðè îøèáêàõ êèäàòü èñêëþ÷åíèå, òîãäà òîì áóäåò ïðèáèò ôàáðèêîé.
56 // ðàçäåëèòåëè ïóòåé äîëæíû áûòü òîëüêî "/", êîðíåâîé "/" äîëæåí
57 // áûòü îïóùåí, ïóòè (åñëè íå ïóñòûå) äîëæíû çàâåðøàòüñÿ "/"!
58 // fName äîëæíî ñîäåðæàòü òîëüêî èìÿ, fPath -- òîëüêî ïóòü.
59 // â ïðèíöèïå, îá ýòîì ïîçàáîòèòñÿ DoDirectoryRead(), íî çà÷åì
60 // äàâàòü åìó ëèøíþþ ðàáîòó?
63 // íàéòè ôàéë, âåðíóòü åãî èíäåêñ â fFiles.
64 // ýòà ïðîöåäóðà ìîæåò ìåíÿòü fFiles!
65 // fPath -- â ïðàâèëüíîé ôîðìå, ñ "/", êîðíåâîé "/" óáèò, ôèíàëüíûé äîáàâëåí.
66 // åñëè ôàéë íå íàéäåí, âåðíóòü -1.
69 // âîçâðàùàåò êîëè÷åñòâî ôàéëîâ â fFiles
72 // âîçâðàùàåò ôàéë ñ èíäåêñîì index.
73 // ìîæåò âîçâðàùàòü NIL.
74 // íèêàêèõ ïàäåíèé íà íåïðàâèëüíûå èíäåêñû!
79 public
80 // pSt íå îáÿçàòåëüíî çàïîìèíàòü, åñëè îí íå íóæåí.
82 // fFileStream óíè÷òîæàòü íåëüçÿ, åñëè îí ðàâåí ïàðàìåòðó pSt êîíñòðóêòîðà.
85 // âûçûâàåò ReadDirectory().
86 // ýòà ïðîöåäóðà ñàìà ðàçáåð¸òñÿ ñ äóáëèêàòàìè èì¸í: ïîäîáàâëÿåò â
87 // êîíåö èì¸í-äóáëèêàòîâ ïîä÷¸ðêèâàíèå è äåñÿòè÷íûé íîìåð.
88 // òàêæå îíà íîðìàëèçóåò âèä èì¸í.
91 // ïðè îøèáêàõ êèäàòüñÿ èñêëþ÷åíèÿìè.
94 // åñëè íå ñìîãëî îòêóïîðèòü ôàéëî (èëè åù¸ ãäå îøèáëîñü), çàøâûðí¸ò èñêëþ÷åíèå.
98 // ìîæåò âîçâðàùàòü NIL.
99 // íèêàêèõ ïàäåíèé íà íåïðàâèëüíûå èíäåêñû!
103 // ôàáðèêà òîìîâ. âñå SFS ïðè ñòàðòå äîáàâëÿþò ñâîè ôàáðèêè.
104 // áëàãîäàðÿ ýòîìó ìîæíî ñîçäàâàòü ðàçíûå âñÿêèå SFS ñòàíäàðòíûì
105 // âûçîâîì ñòàíäàðòíîé ïðîöåäóðû.
106 // ôàáðèêà ÍÅ ÄÎËÆÍÀ óáèâàòüñÿ íèêàê èíà÷å, ÷åì ïðè ïîìîùè âûçîâà
107 // SFSUnregisterVolumeFactory()! ýòî ãàðàíòèðóåò, ÷òî äâèæîê
108 // ïåðåä ðàññòðåëîì îòäàñò åé âñå å¸ òîìà.
110 public
111 // åñëè äîáàâëÿåì ôàéë äàííûõ ôàéë ñ èìåíåì òèïà "zip:....", òî
112 // SFS èçâëå÷¸ò ýòî "zip" è ïåðåäàñò â ñèþ ôóíêöèþ.
113 // åæåëè ôóíêöèÿ âåðí¸ò ïðàâäó, òî SFS âûçîâåò Produce äëÿ äàííîãî
114 // ôàéëà. åñëè íè îäíà ôàáðèêà ïðåôèêñ íå ïðèçíàåò, òî ôàéë íå îòêðîþò.
115 // èñïîëüçóåòñÿ äëÿ ñêèïàíèÿ àâòîäåòåêòà.
116 // SFS ÍÅ Ñ×ÈÒÀÅÒ ÏÐÅÔÈÊÑÎÌ ÑÒÐÎÊÓ ÊÎÐÎ×Å ÒÐ¨Õ ÑÈÌÂÎËÎÂ!
118 // ïðîâåðÿåò, ìîæåò ëè ôàáðèêà ñäåëàòü òîì äëÿ äàííîãî ôàéëà.
119 // st -- îòêðûòûé äëÿ ÷òåíèÿ ôàéëîâé ïîòîê. óêàçàòåëü ÷òåíèÿ ñòîèò â íà÷àëå.
120 // ýòîò ïîòîê íåëüçÿ çàêðûâàòü!
121 // prefix: òî, ÷òî áûëî ïåðåäàíî â IsMyVolumePrefix() èëè ''.
122 // èñêëþ÷åíèå ñ÷èòàåòñÿ îøèáêîé, âîçâðàò NIL ñ÷èòàåòñÿ îøèáêîé.
123 function Produce (const prefix, fileName: TSFSString; st: TStream): TSFSVolume; virtual; abstract;
124 // êîãäà òîì áîëüøå íå íóæåí, îí áóäåò îòäàí ôàáðèêå íà ïåðåðàáîòêó.
125 // äàëåå äâèæîê íå áóäåò þçàòü ñåé òîì.
129 // "èòåðàòîð", âîçâðàùàåìûé SFSFileList()
131 protected
137 public
143 // ïðè íåïðàâèëüíîì èíäåêñå ìîë÷à âåðí¸ò NIL.
144 // ïðè ïðàâèëüíîì òîæå ìîæåò âåðíóòü NIL!
145 // î÷åíü íå ñîâåòóþ ìåíÿòü ñîäåðæèìîå ïîëó÷åííîãî êëàññà.
146 // êîíå÷íî, ÿ ìîã áû âîçâðàùàòü íîâóþ ñòðóêòóðó èëè íå÷òî ïîõîæåå,
147 // íî áëèí, åñëè òû èäèîò è íå óìååøü äàæå êîììåíòû ÷èòàòü, òî
148 // êàêîãî òû âîîáùå â ïðîãðàììèíã ïîëåç?
154 // ýòà ôóíêöèÿ àâòîìàòè÷åñêè ïðèáü¸ò factory.
157 // äîáàâèòü ñáîðíèê â ïîñòîÿííûé ñïèñîê.
158 // åñëè ñáîðíèê ñ òàêèì èìåíåì óæå îòêðûò, òî íå îòêðûâàåò åãî ïîâòîðíî.
159 // íèêîãäà íå êèäàåò èñêëþ÷åíèé.
160 // top: äîáàâèòü â íà÷àëî ñïèñêà ïîèñêà.
161 // âåðí¸ò ëîæü ïðè îøèáêå.
162 // ñïîñîáíî îòêðûâàòü ñáîðíèêè â ñáîðíèêàõ ïðè ïîìîùè êðóòûõ èì¸í a-la:
163 // "zip:pack0::pack:pack1::wad2:pack2".
164 // â äàëüíåéøåì ñëåäóåò îáðàùàòüñÿ ê ñáîðíèêó êàê "pack2::xxx".
165 // èëè ìîæíî íàïèñàòü:
166 // "zip:pack0::pack:pack1::wad2:pack2|datafile".
167 // è îáðàùàòüñÿ êàê "datafile::xxx".
168 // "||" ïðåîáðàçóþòñÿ â ïðîñòîé "|" è ðàçäåëèòåëåì íå ñ÷èòàþòñÿ.
169 // ïðèíèìàåòñÿ âî âíèìàíèå òîëüêî ïîñëåäíÿÿ òðóáà.
172 // äîáàâèòü ñáîðíèê âðåìåííî
175 // äîáàâèòü â ïîñòîÿííûé ñïèñîê ñáîðíèê èç ïîòîêà ds.
176 // åñëè âîçâðàùàåò èñòèíó, òî SFS ñòàíîâèòñÿ âëÿäåëüöåì ïîòîêà ds è ñàìà
177 // óãðîáèò ñåé ïîòîê ïî íåîáõîäèìîñòè.
178 // virtualName ñòàíîâèòñÿ èìåíåì ñáîðíèêà äëÿ îïåðàöèè îòêðûòèÿ ôàéëà òèïà
179 // "packfile:file.ext".
180 // åñëè êàêîé-íèáóäü ñáîðíèê ñ èìåíåì virtualName óæå îòêðûò, âåðí¸ò false.
181 // íèêîãäà íå êèäàåò èñêëþ÷åíèé.
182 // top: äîáàâèòü â íà÷àëî ñïèñêà ïîèñêà.
183 // âåðí¸ò ëîæü ïðè îøèáêå.
184 // îòêðûâàåò ñáîðíèê èç ïîòîêà. dataFileName -- ÂÈÐÒÓÀËÜÍÎÅ èìÿ.
185 // ò.å. íà ñàìîì äåëå òàêîãî ôàéëà ìîæåò è íå áûòü íà äèñêå.
186 function SFSAddSubDataFile (const virtualName: TSFSString; ds: TStream; top: Boolean=false): Boolean;
188 // øâûðÿåòñÿ èñêëþ÷åíèÿìè.
189 // åñëè fName íå èìååò óêàçàíèÿ íà ôàéë äàííûõ (ýòî òî, ÷òî îòäåëåíî îò
190 // îñòàëüíîãî èìåíè äâîåòî÷èåì), òî èùåì ñíà÷àëà ïî âñåì çàðåãèñòðèðîâàííûì
191 // ôàéëàì äàííûõ, ïîòîì â òåêóùåì êàòàëîãå, ïîòîì â êàòàëîãå, îòêóäà ñòàðòîâàëè.
192 // åñëè íè÷åãî íå íàøëè, êèäàåì èñêëþ÷åíèå.
195 // ïðè îøèáêå -- NIL, è íèêàêèõ èñêëþ÷åíèé.
198 // âîçâðàùàåò NIL ïðè îøèáêå.
199 // ïîñëå èñïîëüçîâàíèÿ, íàòóðàëüíî, èòåðàòîð íàäî ãðîõíóòü %-)
202 // çàïðåòèòü îñâîáîæäåíèå âðåìåííûõ òîìîâ (ìîæíî âûçûâàòü ðåêóðñèâíî)
205 // ðàçðåøèòü îñâîáîæäåíèå âðåìåííûõ òîìîâ (ìîæíî âûçûâàòü ðåêóðñèâíî)
208 // for completeness sake
213 // èãíîðèðóåò ðåãèñòð ñèìâîëîâ
216 // ðàçîáðàòü òîëñòîå èìÿ ôàéëà, âåðíóòü âèðòóàëüíîå èìÿ ïîñëåäíåãî ñïèñêà
217 // èëè ïóñòóþ ñòîðîêó, åñëè ñïèñêîâ íå áûëî.
220 // ïðåîáðàçîâàòü ÷èñëî â ñòðîêó, êðàñèâî ðàçáàâëÿÿ çàïÿòûìè
223 // `name` will be modified
224 // return `true` if file was found
227 // Wildcard matching
228 // this code is meant to allow wildcard pattern matches. tt is VERY useful
229 // for matching filename wildcard patterns. tt allows unix grep-like pattern
230 // comparisons, for instance:
231 //
232 // ? Matches any single characer
233 // + Matches any single characer or nothing
234 // * Matches any number of contiguous characters
235 // [abc] Matches a or b or c at that position
236 // [!abc] Matches anything but a or b or c at that position
237 // [a-e] Matches a through e at that position
238 //
239 // 'ma?ch.*' -Would match match.exe, mavch.dat, march.on, etc
240 // 'this [e-n]s a [!zy]est' -Would match 'this is a test', but would
241 // not match 'this as a yest'
242 //
247 // this will compare only last path element from sfspath
255 var
256 // ïðàâäà: ðàçðåøåíî èñêàòü ôàéëî íå òîëüêî â ôàéëàõ äàííûõ, íî è íà äèñêå.
258 // ïðàâäà: åñëè ôàéë íå ïðåôèêñîâàí, òî ñíà÷àëà èùåì ôàéëî íà äèñêå,
259 // ïîòîì â ôàéëàõ äàííûõ.
261 // ïðàâäà: äàæå äëÿ ïðåôèêñîâàíûõ ôàéëîâ ñíà÷àëà ïðîñìîòðèì äèñê
262 // (åñëè óñòàíîâëåí ôëàæîê sfsDiskFirst è sfsDiskEnabled).
264 // ñïèñîê äèñêîâûõ êàòàëîãîâ äëÿ ïîèñêà ôàéëà. åñëè ïóñò -- èùåì òîëüêî â
265 // òåêóùåì. êàòàëîãè ðàçäåëÿþòñÿ òðóáîé ("|").
266 // <currentdir> çàìåíÿåòñÿ íà òåêóùèé êàòàëîã (ñ çàâåðøàþùèì "/"),
267 // <exedir> çàìåíÿåòñÿ íà êàòàëîã, ãäå ñèäèò .EXE (ñ çàâåðøàþùèì "/").
271 implementation
273 uses
274 xstreams;
278 var
280 begin
284 begin
290 // `name` will be modified
292 var
295 begin
301 repeat
305 begin
308 exit;
317 const
318 // character defines
330 begin
331 result :=
339 function MatchMask (const pattern: TSFSString; p, pend: Integer; const text: TSFSString; t, tend: Integer): Boolean;
340 var
344 begin
345 // sanity checks
351 begin
353 begin
354 // no more text. check if there's no more chars in pattern (except "*" & "+")
359 exit;
362 WILD_CHAR_SINGLE: ;
363 WILD_CHAR_ESCAPE:
364 begin
369 WILD_CHAR_RANGE_OPEN:
370 begin
378 repeat
384 begin
388 begin
390 end
392 end
397 // skip the rest or the range
401 WILD_CHAR_SINGLE_OR_NONE:
402 begin
406 exit;
408 WILD_CHAR_MULTI:
409 begin
413 begin
417 exit;
428 begin
435 var
437 begin
443 begin
445 begin
447 begin
454 begin
464 type
470 fPermanent: Boolean; // èñòèíà -- íå áóäåò óãðîáëåíà, åñëè íå îñòàíåòñÿ íè îäíîãî îòêðûòîãî òîìà
471 // èñòèíà -- ýòîò òîì áûë ñîçäàí èç ïîòîêà è íå èìååò äèñêîâîãî ôàéëà, ïîòîìó ôàáðèêå áóäåò ïåðåäàíî íå èìÿ ñáîðíèêà, à ïóñòàÿ ñòðîêà
479 protected
482 public
488 var
495 var
499 begin
500 // collect garbage
503 begin
507 begin
508 // this volume probably can be removed
512 begin
514 begin
522 begin
523 {$IFDEF SFS_VOLDEBUG}writeln('000: destroying volume "', TVolumeInfo(volumes[f]).fPackName, '"');{$ENDIF}
527 continue;
535 begin
540 begin
543 begin
550 // ðàçáèòü èìÿ ôàéëà íà ÷àñòè: ïðåôèêñ ôàéëîâîé ñèñòåìû, èìÿ ôàéëà äàííûõ,
551 // ñîáñòâåííî èìÿ ôàéëà
552 // èìÿ âûãëÿäèò êàê:
553 // (("sfspfx:")?"datafile::")*"filename"
555 var
557 begin
560 begin
565 else
566 begin
572 // ñàéäýôôåêò: âûðåçàåò âèðòóàëüíîå èìÿ èç dataFile.
574 var
576 begin
579 begin
582 begin
584 else
585 begin
588 break;
595 // ðàçáèòü èìÿ ñáîðíèêà íà ÷àñòè: ïðåôèêñ ôàéëîâîé ñèñòåìû, èìÿ ôàéëà äàííûõ,
596 // âèðòóàëüíîå èìÿ. åñëè âèðòóàëüíîãî èìåíè íå äàíî, îíî áóäåò ðàâíî dataFile.
597 // èìÿ âûãëÿäèò êàê:
598 // [sfspfx:]datafile[|virtname]
599 // åñëè ïåðåä äâîåòî÷èåì ìåíüøå òð¸õ áóêâ, òî ýòî ñ÷èòàåòñÿ íå ïðåôèêñîì,
600 // à èìåíåì äèñêà.
602 var
604 begin
607 else
608 begin
615 // íàéòè ïðîèçâîäèòåëÿ äëÿ ýòîãî ôàéëà (åñëè ôàéë óæå îòêðûò).
616 // onlyPerm: òîëüêî "ïîñòîÿííûå" ïðîèçâîäèòåëè.
618 var
621 begin
624 begin
626 begin
629 begin
631 begin
633 exit;
642 // íàéòè èíôó äëÿ ýòîãî òîìà.
643 // õîðîøåå èìÿ, ïðàâäà? %-)
645 begin
648 begin
650 begin
658 begin
660 begin
662 end
663 else
664 begin
666 begin
668 end
669 else
670 begin
681 var
683 begin
684 //result := (AnsiCompareText(s0, s1) == 0);
688 begin
694 // this will compare only last path element from sfspath
696 {var
697 i: Integer;}
698 begin
700 (*
701 if not result and (length(sfspath) > 1) then
702 begin
703 i := length(sfspath);
704 while i > 1 do
705 begin
706 while (i > 1) and (sfspath[i-1] <> '/') do Dec(i);
707 if i <= 1 then exit;
708 writeln('{', sfspath, '} [', Copy(sfspath, i, length(sfspath)), '] : [', path, ']');
709 result := SFSStrEqu(Copy(sfspath, i, length(sfspath)), path);
710 end;
711 end;
712 *)
715 // adds '/' too
717 var
719 begin
723 begin
725 begin
727 continue;
730 begin
732 end
733 else
734 begin
743 var
745 begin
748 begin
750 begin
751 // avoid unnecessary string changes
758 var
761 begin
763 repeat
771 { TVolumeInfo }
773 var
776 begin
783 // òèïà ìóñîðîñáîðíèê: åñëè íàø ïîòîê áîëåå íèêåì íå þçàåòñÿ, òî óãðîáèòü åãî íàôèã
785 begin
789 begin
791 begin
794 begin
807 { TOwnedPartialStream }
810 begin
817 var
819 begin
822 begin
825 begin
828 begin
829 {$IFDEF SFS_VOLDEBUG}writeln('001: destroying volume "', TVolumeInfo(volumes[f]).fPackName, '"');{$ENDIF}
837 { TSFSFileInfo }
839 begin
850 begin
856 { TSFSVolume }
858 begin
867 begin
871 var
875 begin
882 begin
884 // normalize name & path
891 begin
892 // split path and name
905 begin
912 begin
918 begin
920 else
921 begin
924 begin
927 begin
937 begin
942 begin
944 else
945 begin
952 var
955 begin
957 // normalize name, find split position
961 begin
974 { TSFSFileList }
976 var
978 begin
988 var
990 begin
995 // óáü¸ì çàïèñü, åñëè îíà âðåìåííàÿ, è â íåé íåò áîëüøå íè÷åãî îòêðûòîãî
996 if (gcdisabled = 0) and not TVolumeInfo(volumes[f]).fPermanent and (TVolumeInfo(volumes[f]).fOpenedFilesCount < 1) then
997 begin
998 {$IFDEF SFS_VOLDEBUG}writeln('002: destroying volume "', TVolumeInfo(volumes[f]).fPackName, '"');{$ENDIF}
1005 begin
1010 begin
1017 var
1019 begin
1028 var
1031 begin
1036 begin
1037 if (volumes[c] <> nil) and (TVolumeInfo(volumes[c]).fFactory = factory) then volumes[c] := nil;
1044 function SFSAddDataFileEx (dataFileName: TSFSString; ds: TStream; top, permanent: Integer): Integer;
1045 // dataFileName ìîæåò èìåòü ïðåôèêñ òèïà "zip:" (ñì. âûøå: IsMyPrefix).
1046 // ìîæåò âûêèíóòü èñêëþ÷åíèå!
1047 // top:
1048 // <0: äîáàâèòü â íà÷àëî ñïèñêà ïîèñêà.
1049 // =0: íå ìåíÿòü.
1050 // >0: äîáàâèòü â êîíåö ñïèñêà ïîèñêà.
1051 // permanent:
1052 // <0: ñîçäàòü "âðåìåííûé" òîì.
1053 // =0: íå ìåíÿòü ôëàæîê ïîñòîÿíñòâà.
1054 // >0: ñîçäàòü "ïîñòîÿííûé" òîì.
1055 // åñëè ds <> nil, òî ñîçäà¸ò ñáîðíèê èç ïîòîêà. åñëè ñáîðíèê ñ èìåíåì
1056 // dataFileName óæå çàðåãèñòðèðîâàí, òî ïàäàåò íàôèã.
1057 // âîçâðàùàåò èíäåêñ â volumes.
1058 // óìååò äåëàòü ðåêóðñèþ.
1059 var
1067 begin
1070 begin
1071 // ðåêóðñèâíîå îòêðûòèå.
1072 // ðàçîáü¸ì dataFileName íà èìÿ ñáîðíèêà è îñòàòîê.
1073 // pfx áóäåò èìåíåì ñáîðíèêà, dataFileName -- îñòàòêîì.
1075 // ñíà÷àëà îòêðîåì ïåðâûé ñïèñîê...
1077 // ...òåïåðü ïðîäîëæèì ñ îñòàòêîì.
1078 // óçíàåì, êàêîå ôàéëî îòêðûâàòü.
1079 // âûêîâûðÿåì ïåðâûé "::" ïðåôèêñ (ýòî áóäåò èìÿ ôàéëà).
1082 // dataFileName õðàíèò îñòàòîê.
1083 // èçâëå÷¸ì èìÿ ôàéëà:
1085 // îòêðîåì ýòîò ôàéë
1087 try
1090 except
1092 // óäàëèì íåèñïîëüçóåìûé âðåìåííûé òîì.
1093 if (gcdisabled = 0) and not vi.fPermanent and (vi.fOpenedFilesCount < 1) then volumes[result] := nil;
1096 // óðà. îòêðûëè ôàéë. êèäàåì â âîçäóõ ÷åï÷èêè, ïðîäîëæàåì ðàçâëå÷åíèå.
1098 try
1101 except
1105 exit;
1108 // îáûêíîâåííîå íåðåêóðñèâíîå îòêðûòèå.
1113 begin
1120 exit;
1130 try
1132 begin
1137 try
1140 except
1146 except
1152 try
1154 begin
1157 end
1159 except
1175 function SFSAddSubDataFile (const virtualName: TSFSString; ds: TStream; top: Boolean=false): Boolean;
1176 var
1178 begin
1180 try
1184 except
1190 var
1192 begin
1193 try
1197 except
1203 var
1205 begin
1206 try
1210 except
1218 var
1221 begin
1224 begin
1235 begin
1240 end
1246 var
1254 // ïðîâåðèì, åñòü ëè ôàëî fn ãäå-òî íà äèñêàõ.
1255 var
1258 begin
1265 begin
1271 try
1273 exit;
1274 except
1279 begin
1286 begin
1287 // ïðåôèêñîâàíûé ôàéë
1289 begin
1297 try
1300 except
1302 if (gcdisabled = 0) and not vi.fPermanent and (vi.fOpenedFilesCount < 1) then volumes[f] := nil;
1305 exit;
1307 //Inc(vi.fOpenedFilesCount);
1309 exit;
1312 // íåïðåôèêñîâàíûé ôàéë
1314 begin
1318 // èùåì ïî âñåì ïåðìàíåíòíûì ïðåôèêñàì
1321 begin
1324 begin
1326 begin
1329 begin
1330 try
1333 //Inc(vi.fOpenedFilesCount);
1334 except
1348 begin
1349 try
1351 except
1357 var
1360 begin
1364 try
1366 except
1367 exit;
1371 try
1374 except
1375 if (gcdisabled = 0) and not vi.fPermanent and (vi.fOpenedFilesCount < 1) then volumes[f] := nil;
1380 // ////////////////////////////////////////////////////////////////////////// //
1381 // utils
1382 // `ch`: utf8 start
1383 // -1: invalid utf8
1385 begin
1397 var
1399 begin
1403 begin
1409 // check other sequence bytes
1411 begin
1421 // ////////////////////////////////////////////////////////////////////////// //
1422 const
1423 // TODO: move this to a separate file
1425 $0402,$0403,$201A,$0453,$201E,$2026,$2020,$2021,$20AC,$2030,$0409,$2039,$040A,$040C,$040B,$040F,
1426 $0452,$2018,$2019,$201C,$201D,$2022,$2013,$2014,$003F,$2122,$0459,$203A,$045A,$045C,$045B,$045F,
1427 $00A0,$040E,$045E,$0408,$00A4,$0490,$00A6,$00A7,$0401,$00A9,$0404,$00AB,$00AC,$00AD,$00AE,$0407,
1428 $00B0,$00B1,$0406,$0456,$0491,$00B5,$00B6,$00B7,$0451,$2116,$0454,$00BB,$0458,$0405,$0455,$0457,
1429 $0410,$0411,$0412,$0413,$0414,$0415,$0416,$0417,$0418,$0419,$041A,$041B,$041C,$041D,$041E,$041F,
1430 $0420,$0421,$0422,$0423,$0424,$0425,$0426,$0427,$0428,$0429,$042A,$042B,$042C,$042D,$042E,$042F,
1431 $0430,$0431,$0432,$0433,$0434,$0435,$0436,$0437,$0438,$0439,$043A,$043B,$043C,$043D,$043E,$043F,
1432 $0440,$0441,$0442,$0443,$0444,$0445,$0446,$0447,$0448,$0449,$044A,$044B,$044C,$044D,$044E,$044F
1433 );
1437 var
1439 begin
1440 (* The following encodings are valid, except for the 5 and 6 byte
1441 * combinations:
1442 * 0xxxxxxx
1443 * 110xxxxx 10xxxxxx
1444 * 1110xxxx 10xxxxxx 10xxxxxx
1445 * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
1446 * 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1447 * 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
1448 *)
1456 // mask out unused bits
1464 // now continue
1466 begin
1474 // done, try 1251
1476 // alas
1481 var
1483 begin
1487 begin
1498 initialization
1501 //finalization
1502 //volumes.Free(); // it fails for some reason... Runtime 217 (^C hit). wtf?!
1503 //factories.Free(); // not need to be done actually...