| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 | //---------------------------------------------------------------------------#include <vcl.h>#pragma hdrstop#include "Common.h"#include "FileBuffer.h"//---------------------------------------------------------------------------#pragma package(smart_init)//---------------------------------------------------------------------------const wchar_t * EOLTypeNames = L"LF;CRLF;CR";//---------------------------------------------------------------------------char * __fastcall EOLToStr(TEOLType EOLType){  switch (EOLType) {    case eolLF: return "\n";    case eolCRLF: return "\r\n";    case eolCR: return "\r";    default: DebugFail(); 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){  DWORD Result;  try  {    Size = Position + Len;    // C++5    // FMemory->SetSize(FMemory->Position + Len);    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(Result, soCurrent);  }  catch(EReadError &)  {    RaiseLastOSError();  }  return Result;}//---------------------------------------------------------------------------DWORD __fastcall TFileBuffer::LoadStream(TStream * Stream, const DWORD Len, bool ForceLen){  FMemory->Seek(0, soFromBeginning);  return ReadStream(Stream, Len, ForceLen);}//---------------------------------------------------------------------------void __fastcall TFileBuffer::Convert(char * Source, char * Dest, int Params,  bool & Token){  DebugAssert(strlen(Source) <= 2);  DebugAssert(strlen(Dest) <= 2);  if (FLAGSET(Params, cpRemoveBOM) && (Size >= 3) &&      (memcmp(Data, Bom, sizeof(Bom)) == 0))  {    Delete(0, 3);  }  if (FLAGSET(Params, cpRemoveCtrlZ) && (Size > 0) && ((*(Data + Size - 1)) == '\x1A'))  {    Delete(Size-1, 1);  }  if (strcmp(Source, Dest) == 0)  {    return;  }  char * Ptr = Data;  // one character source EOL  if (!Source[1])  {    bool PrevToken = Token;    Token = false;    for (int Index = 0; Index < Size; Index++)    {      // EOL already in destination format, make sure to pass it unmodified      if ((Index < Size - 1) && (*Ptr == Dest[0]) && (*(Ptr+1) == Dest[1]))      {        Index++;        Ptr++;      }      // last buffer ended with the first char of destination 2-char EOL format,      // which got expanded to full destination format.      // now we got the second char, so get rid of it.      else if ((Index == 0) && PrevToken && (*Ptr == Dest[1]))      {        Delete(Index, 1);      }      // we are ending with the first char of destination 2-char EOL format,      // append the second char and make sure we strip it from the next buffer, if any      else if ((*Ptr == Dest[0]) && (Index == Size - 1) && Dest[1])      {        Token = true;        Insert(Index+1, Dest+1, 1);        Index++;        Ptr = Data + Index;      }      else if (*Ptr == Source[0])      {        *Ptr = Dest[0];        if (Dest[1])        {          Insert(Index+1, Dest+1, 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);    }  }}//---------------------------------------------------------------------------void __fastcall TFileBuffer::Convert(TEOLType Source, TEOLType Dest, int Params,  bool & Token){  Convert(EOLToStr(Source), EOLToStr(Dest), Params, Token);}//---------------------------------------------------------------------------void __fastcall TFileBuffer::Convert(char * Source, TEOLType Dest, int Params,  bool & Token){  Convert(Source, EOLToStr(Dest), Params, Token);}//---------------------------------------------------------------------------void __fastcall TFileBuffer::Convert(TEOLType Source, char * Dest, int Params,  bool & Token){  Convert(EOLToStr(Source), Dest, Params, Token);}//---------------------------------------------------------------------------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){  try  {    Stream->WriteBuffer(Data + Position, Len);    FMemory->Seek(Len, soCurrent);  }  catch(EWriteError &)  {    RaiseLastOSError();  }}//---------------------------------------------------------------------------void __fastcall TFileBuffer::WriteToOut(TTransferOutEvent OnTransferOut, TObject * Sender, const DWORD Len){  OnTransferOut(Sender, reinterpret_cast<const unsigned char *>(Data) + Position, Len);  FMemory->Seek(Len, soCurrent);}//---------------------------------------------------------------------------//---------------------------------------------------------------------------__fastcall TSafeHandleStream::TSafeHandleStream(int AHandle) :  THandleStream(AHandle){}//---------------------------------------------------------------------------int __fastcall TSafeHandleStream::Read(void * Buffer, int Count){  int Result = FileRead(FHandle, Buffer, Count);  if (Result == -1)  {    RaiseLastOSError();  }  return Result;}//---------------------------------------------------------------------------int __fastcall TSafeHandleStream::Write(const void * Buffer, int Count){  int Result = FileWrite(FHandle, Buffer, Count);  if (Result == -1)  {    RaiseLastOSError();  }  return Result;}//---------------------------------------------------------------------------int __fastcall TSafeHandleStream::Read(System::DynamicArray<System::Byte> Buffer, int Offset, int Count){  DebugFail(); // untested  int Result = FileRead(FHandle, Buffer, Offset, Count);  if (Result == -1)  {    RaiseLastOSError();  }  return Result;}//---------------------------------------------------------------------------int __fastcall TSafeHandleStream::Write(const System::DynamicArray<System::Byte> Buffer, int Offset, int Count){  // This is invoked for example by TIniFileStorage::Flush  int Result = FileWrite(FHandle, Buffer, Offset, Count);  if (Result == -1)  {    RaiseLastOSError();  }  return Result;}
 |