Page 1 of 1

SFTP ReadDirectory/EOF compile error using BCB5

Posted: Tue 15 Mar 2011 14:30
by gw
Hi!

here is a part of my code that i can't compile.
ScSFTPClient is the component that i placed on the form.

Code: Select all

Scclrclasses::TBytes Handle;

Handle = ScSFTPClient->OpenDirectory("Test");
try
{
  do
  {
     ScSFTPClient->ReadDirectory(Handle);
  } while (!(ScSFTPClient->EOF));
__finally {
  ScSFTPClient->CloseHandle(Handle);
}
Borland C++Builder 5 (Enterprise) won't compile the line with the EOF statement: Error: E2280 Member identifier expected.
Even if i use the popup list (where you can see all the functions and properties - and the EOF property is displayed there!).
If i use the 'Active' property instead (just for a test) it compiles ok.

Any idea what is wrong? Any help how to solve? Are there any more/better examples/demos written in C++ to check?

thanks
/gw

Update

Posted: Thu 17 Mar 2011 15:01
by gw
EOF' seems to be globally known in this unit (i believe by SecureBridge, not by me. Seems also to be the cause for my other problem - see my other post 'SFTP OnDirectoryList compile error using BCB5').
So if i change the code to this it compiles and works!

Code: Select all

Scclrclasses::TBytes Handle; 

Handle = ScSFTPClient->OpenDirectory("Test"); 
try 
{ 
  do 
  { 
     ScSFTPClient->ReadDirectory(Handle); 
  } while (!EOF); 
__finally { 
  ScSFTPClient->CloseHandle(Handle); 
}
Hope this will help other C++ programmers ;)
/gw

Posted: Mon 28 Mar 2011 09:54
by Dimon
To solve the problem you can add the following lines in the beginning of your cpp unit:

Code: Select all

#ifdef EOF
#undef EOF
#endif

Posted: Wed 06 Apr 2011 08:46
by gw
Hi!

I changed code to this:

Code: Select all

#ifdef EOF 
#undef EOF 
#endif

Scclrclasses::TBytes Handle; 

Handle = ScSFTPClient->OpenDirectory("Test"); 
try 
{ 
  do 
  { 
     ScSFTPClient->ReadDirectory(Handle); 
  } while (!(ScSFTPClient->EOF)); 
__finally { 
  ScSFTPClient->CloseHandle(Handle); 
}

void __fastcall TSftpForm::ScSFTPClientDirectoryList(TObject *Sender, 
      const AnsiString Path, const TBytes Handle, 
      TScSFTPFileInfo *FileInfo, bool EOF) 
{ 
  FilenameList->Add(FileInfo->Filename); 
}
Now it compiles without error, but when executed i get an runtime error in the 'ScSFTPClientDirectoryList' function.

I have it running with my workaround, just want to give a reply that there still seems to be a problem.

/gw

Posted: Wed 06 Apr 2011 08:59
by Dimon
Please give a more detailed description of the error that arises in the 'ScSFTPClientDirectoryList' function.

Posted: Wed 06 Apr 2011 09:33
by gw
It's an EAccessViolation.
I have 2 files in the remote directory.
So i get 3 events that work well (my 2 files and '.').
On the 4th event, that shouldn't occure, i get the access violation (since there's no (more) filename to read).
So for me it looks like the instruction:

Code: Select all

while (!(ScSFTPClient->EOF));
doesn't work right (doesn't recognize/set EOF).

Note:
I placed the

Code: Select all

#ifdef EOF
#undef EOF
#endif
right after the '#include' and '#pragma link' statements, so directly before the code of my SFTP unit beginns.

/gw

Posted: Wed 06 Apr 2011 14:23
by Dimon
The last OnDirectoryList event is arised with EOF equaled to True, and this means that the server has passed all the directory list. This behaviour is particularly useful in the NonBlocking mode.
At this case FileInfo is nil, and therefore to solve the problem you should use the following code:

Code: Select all

void __fastcall TSftpForm::ScSFTPClientDirectoryList(TObject *Sender, 
      const AnsiString Path, const TBytes Handle, 
      TScSFTPFileInfo *FileInfo, bool EOF) 
{ 
  if (FileInfo != NULL)
    FilenameList->Add(FileInfo->Filename); 
} 

Posted: Wed 06 Apr 2011 15:02
by gw
Ok, it was my fault - have overlooked this when viewing the 'SFTPClientFrame.pas' example.
Now it works :)
Can also be coded like this:

Code: Select all

void __fastcall TSftpForm::ScSFTPClientDirectoryList(TObject *Sender, 
      const AnsiString Path, const TBytes Handle, 
      TScSFTPFileInfo *FileInfo, bool EOF) 
{
  if (!EOF) 
    FilenameList->Add(FileInfo->Filename); 
}
thanks
/gw