/
YakuninAV
/
Convertors
Обзор
Документация
Войти
/
YakuninAV
/
Convertors
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Core/DBDSplitFormCorrection.pas
142 строки
4 KB
YakuninAV
begin with gitflick
31 июл 2026, 15:21
31 июл 2026, 15:21
1dc0fc6
Код
Авторство
О чём код?
unit DBDSplitFormCorrection; {$I mormot.defines.inc} interface uses {$IFDEF ISDELPHIXE2} System.Types, System.SysUtils, System.Classes {$ELSE} Types, SysUtils, Classes {$ENDIF} , mormot.core.base, mormot.core.os, mormot.core.buffers, mormot.core.zip ; const SharedString_FN = 'xl\SharedStrings.xml'; function SplitFormCorrector(const FileName: TFileName): Boolean; overload; function SplitFormCorrector(Stream: TStream): Integer; overload; function CorrectionSharedString(Src: RawUtf8; const pCnt: PInteger=nil): RawUtf8; implementation function SplitFormCorrector(const FileName: TFileName): Boolean; var i: Integer; rb: RawByteString; tmpF, fn, fs: TFileName; Writer: TZipWrite; Reader: TZipRead; begin try Result:=False; rb:=''; if (FileName<>'') and FileExists(FileName) then begin tmpF:=GetSystemPath(spTempFolder); tmpF:=TemporaryFileName; tmpF:=EnsureDirectoryExists(TemporaryFileName); fn:=tmpF+'1.zip'; fs:=tmpF+SharedString_FN; if CopyFile(FileName, fn, true) then begin Reader:=TZipRead.Create(fn); try i:=Reader.nameToIndex(SharedString_FN); if i>=0 then begin rb:=Reader.UnZip(i); Result:=rb<>''; end; Result:=Reader.UnZip(SharedString_FN, tmpF); finally Reader.Free; end; Result:=Result and FileExists(fs); if not Result then Exit; rb:=StringFromFile(fs); rb:=CorrectionSharedString(rb); Result:= (rb<>'') and FileFromString(rb, fs, true); if not Result then Exit; Writer:=TZipWrite.CreateFromIgnore(fn, [SharedString_FN]); try try Writer.AddDeflated(fs,true, 6, SharedString_FN); except Result:=False; end; finally Writer.Free; end; Result := Result and DeleteFile(FileName) and CopyFile(fn, FileName, TRUE); end; end; except Result:=False; end; if Result then DirectoryDelete(tmpF); end; function SplitFormCorrector(Stream: TStream): Integer; overload; var r,rr: RawByteString; iPos: Int64; cnt, sz: Integer; buf:TBytes; begin if Stream=nil then begin Result:=-1; Exit; end; if Stream.Size=0 then begin Result:=-2; Exit; end; iPos:=Stream.Position; Stream.Position:=0; SetLength(buf,Stream.Size); sz:=Stream.Size; Stream.ReadBuffer(Pointer(buf)^, sz); BytesToRawByteString(buf,r); if r<>'' then r:=CorrectionSharedString(r, @cnt); if cnt>0 then begin RawByteStringToBytes(r,buf); Stream.Position:=0; Stream.Write(Pointer(buf)^,Length(buf)); Stream.Size:=Length(buf); end; if iPos=0 then Stream.Position:=0; Result:=cnt; end; function CorrectionSharedString(Src: RawUtf8; const pCnt: PInteger=nil): RawUtf8; var p0,p: PUtf8Char; l,u,y,x,t,s: PtrUInt; f: Boolean; cnt: Integer; rr,rB,rE: RawUtf8; //u - начальный токен спец.строки - <d:r //p0 - начало буфера источника //s - смещение p0 от начала исходного текста //l - длина копирования begin Result:=''; rB:='<t'; rE:='</t>'; FastSetString(rr, Length(Src)); p0:=@src[1]; p:=@rr[1]; u:=PosEx('<d:r', Src ,1); //u - начальный токен спец.строки - <d:r s:=0; l:=u-1; cnt:=0; f:=True; y:=0; while u>0 do begin MoveByOne(p0,p, l); p:=p+l; y:=PosEx('</d:r>', src, u+4); //y - конечный токен спец.строки </d:r> f:=y>0; if not f then Break; t:=PosEx('<d:t', src, u+4); //t - начальный токен текста в спец строке <d:t f:=(t>0) and (t<y); if not f then Break; x:=PosEx('</d:t>', src, t); //x - конечный токен текста в спец строке </d:r> f:=(x>0) and (x<y); if not f then Break; t:=t+4; p0:=@src[t]; s:=p0-@src[1]; l:=x-t; MoveByOne(@rB[1],p,2); p:=p+2; MoveByOne(p0,p,l); p:=p+l; MoveByOne(@rE[1],p,4); p:=p+4; y:=y+6; p0:=@src[y]; s:=p0-@src[1]; u:=PosEx('<d:r', src, y); l:=u-s-1; Inc(cnt); end; if pCnt<>nil then pCnt^:=cnt; if f and (cnt=0) then Result:=src else if f then begin l:=Length(src)-y+1; MoveByOne(p0,p, l); Result:=Trim(rr); end; end; end.