//--------------------------------------------------------------------------- #include #pragma hdrstop #include "Common.h" #include "FileBuffer.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //--------------------------------------------------------------------------- char * __fastcall EOLToStr(TEOLType EOLType) { switch (EOLType) { case eolLF: return "\n"; case eolCRLF: return "\r\n"; case eolCR: return "\r"; default: assert(false); return ""; } } //--------------------------------------------------------------------------- __fastcall TFileBuffer::TFileBuffer() { FMemory = new TMemoryStream(); FSize = 0; } //--------------------------------------------------------------------------- __fastcall TFileBuffer::~TFileBuffer() { delete FMemory; } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::SetSize(int value) { if (FSize != value) { FMemory->Size = value; FSize = value; } } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::SetPosition(int value) { FMemory->Position = value; } //--------------------------------------------------------------------------- int __fastcall TFileBuffer::GetPosition() const { return (int)FMemory->Position; } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::SetMemory(TMemoryStream * value) { if (FMemory != value) { if (FMemory) delete FMemory; FMemory = value; } } //--------------------------------------------------------------------------- DWORD __fastcall TFileBuffer::ReadStream(TStream * Stream, const DWORD Len, bool ForceLen) { Size = Position + Len; // C++5 // FMemory->SetSize(FMemory->Position + Len); DWORD Result; if (ForceLen) { Stream->ReadBuffer(Data + Position, Len); Result = Len; } else { Result = Stream->Read(Data + Position, Len); } if (Result != Len) { Size = Size - Len + Result; } FMemory->Seek(Len, soFromCurrent); return Result; } //--------------------------------------------------------------------------- DWORD __fastcall TFileBuffer::ReadFile(const HANDLE File, const DWORD Len, bool ForceLen) { DWORD Result; TStream *Stream = NULL; try { Stream = new THandleStream((THandle)File); Result = ReadStream(Stream, Len, ForceLen); } __finally { delete Stream; } return Result; } //--------------------------------------------------------------------------- DWORD __fastcall TFileBuffer::LoadFile(const HANDLE File, const DWORD Len, bool ForceLen) { FMemory->Seek(0, soFromBeginning); return ReadFile(File, Len, ForceLen); } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::Convert(char * Source, char * Dest, int Params) { assert(strlen(Source) <= 2); assert(strlen(Dest) <= 2); bool RemoveCtrlZ = ((Params & cpRemoveCtrlZ) != 0); if (strcmp(Source, Dest) == 0) { return; } char * Ptr = Data; // one character source EOL if (!Source[1]) { for (int Index = 0; Index < Size; Index++) { if (*Ptr == Source[0]) { *Ptr = Dest[0]; if (Dest[1]) { Insert(Index+1, Dest+1, 1); Index++; Ptr = Data + Index; } } // this should fix LF -> CR/LF conversion "bug" on CR/FL files, // which led to CR/CR/FL else if (*Ptr == Dest[0] || *Ptr == Dest[1]) { Delete(Index, 1); Index--; Ptr = Data + Index; } Ptr++; } } // two character source EOL else { int Index; for (Index = 0; Index < Size - 1; Index++) { if ((*Ptr == Source[0]) && (*(Ptr+1) == Source[1])) { *Ptr = Dest[0]; if (Dest[1]) { *(Ptr+1) = Dest[1]; Index++; Ptr++; } else { Delete(Index+1, 1); Ptr = Data + Index; } } Ptr++; } if ((Index < Size) && (*Ptr == Source[0])) { Delete(Index, 1); } } if (RemoveCtrlZ && (Size > 0) && ((*(Data + Size - 1)) == '\x1A')) { Delete(Size-1, 1); } } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::Convert(TEOLType Source, TEOLType Dest, int Params) { Convert(EOLToStr(Source), EOLToStr(Dest), Params); } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::Convert(char * Source, TEOLType Dest, int Params) { Convert(Source, EOLToStr(Dest), Params); } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::Convert(TEOLType Source, char * Dest, int Params) { Convert(EOLToStr(Source), Dest, Params); } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::Insert(int Index, const char * Buf, int Len) { Size += Len; memmove(Data + Index + Len, Data + Index, Size - Index - Len); memmove(Data + Index, Buf, Len); } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::Delete(int Index, int Len) { memmove(Data + Index, Data + Index + Len, Size - Index - Len); Size -= Len; } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::WriteToStream(TStream * Stream, const DWORD Len) { Stream->WriteBuffer(Data + Position, Len); FMemory->Seek(Len, soFromCurrent); } //--------------------------------------------------------------------------- void __fastcall TFileBuffer::WriteToFile(const HANDLE File, const DWORD Len) { TStream *Stream = NULL; try { Stream = new THandleStream((THandle)File); WriteToStream(Stream, Len); } __finally { delete Stream; } }