Info Posted June 13, 2011 Share Posted June 13, 2011 expandcollapse popup#ifndef FTP_H #define FTP_H #include <string> #include <vector> #include <wininet.h> //you will also need to link to wininet.lib enum FTP_SIZE_TYPE { FTP_SIZE_BYTE, FTP_SIZE_KB, FTP_SIZE_MB, FTP_SIZE_GB }; class ftp { public: ftp(const std::string& agentName="ftp"); ~ftp(); bool Connect(const std::string& host, const std::string& username="", const std::string& password="", INTERNET_PORT port=INTERNET_DEFAULT_FTP_PORT, bool passive=false); bool Disconnect(); bool GetConnectionState() const; bool List(std::vector<WIN32_FIND_DATA>& vec, const std::string& rootDir="") const; bool DownloadFile(const std::string& remoteFile, const std::string& localFile, bool overwrite = false) const; bool UploadFile(const std::string& localFile, const std::string& remoteFile) const; DWORD GetFileSize(const std::string& remoteFile, FTP_SIZE_TYPE type=FTP_SIZE_BYTE) const; bool CreateDirectory(const std::string& remoteDir); bool DeleteFile(const std::string& remoteFile); bool DeleteDirectory(const std::string& remoteDir); bool RenameFile(const std::string& remoteFile, const std::string& newFile); //both parameters must containt full path private: HINTERNET m_hInternet; HINTERNET m_hConnection; bool m_bConnected; ftp(const ftp& other); // copy ctor ftp& operator=(const ftp& other); // asignment operator }; ftp::ftp(const std::string& agentName/*="ftp"*/) : m_bConnected(false) { m_hInternet = InternetOpen(agentName.c_str() , INTERNET_OPEN_TYPE_DIRECT, 0, 0, 0); } ftp::~ftp() { ftp::Disconnect(); InternetCloseHandle(m_hConnection); } bool ftp::Connect(const std::string& host, const std::string& username/*=""*/, const std::string& password/*=""*/, INTERNET_PORT port/*=INTERNET_DEFAULT_FTP_PORT*/, bool passive/*=false*/) { DWORD flag; if(passive) flag = INTERNET_FLAG_PASSIVE; else flag = 0; m_hConnection = InternetConnect(m_hInternet, host.c_str(), port, username.c_str(), password.c_str(), INTERNET_SERVICE_FTP, flag, 0); m_bConnected = (bool)m_hConnection; return m_bConnected; } bool ftp::Disconnect() { BOOL bClose = InternetCloseHandle(m_hConnection); m_bConnected = (bool)!bClose; return bClose; } bool ftp::GetConnectionState() const { return m_bConnected; } bool ftp::List(std::vector<WIN32_FIND_DATA>& vec, const std::string& rootDir/*=""*/) const { if(!m_bConnected) return false; HINTERNET hFind; WIN32_FIND_DATA fileInfo; hFind = FtpFindFirstFile(m_hConnection, rootDir.c_str(), &fileInfo, 0, 0); if(hFind == NULL) return false; vec.push_back(fileInfo); while(InternetFindNextFile(hFind, &fileInfo) == TRUE) { vec.push_back(fileInfo); } InternetCloseHandle(hFind); return true; } bool ftp::DownloadFile(const std::string& remoteFile, const std::string& localFile, bool overwrite/*=false*/) const { return (bool)FtpGetFile(m_hConnection, remoteFile.c_str(), localFile.c_str(), (BOOL)overwrite, FILE_ATTRIBUTE_NORMAL, FTP_TRANSFER_TYPE_UNKNOWN, 0); } bool ftp::UploadFile(const std::string& localFile, const std::string& remoteFile) const { return (bool)FtpPutFile(m_hConnection, localFile.c_str(), remoteFile.c_str(), FTP_TRANSFER_TYPE_UNKNOWN, 0); } DWORD ftp::GetFileSize(const std::string& remoteFile, FTP_SIZE_TYPE type/*=FTP_SIZE_BYTE*/) const { if(!m_bConnected) return 0; HINTERNET hFile; DWORD size; hFile = FtpOpenFile(m_hConnection, remoteFile.c_str(), GENERIC_READ, FTP_TRANSFER_TYPE_UNKNOWN, 0); size = FtpGetFileSize(hFile, 0); InternetCloseHandle(hFile); switch(type) { case FTP_SIZE_KB: return size / 1024; case FTP_SIZE_MB: return size / (1024*1024); case FTP_SIZE_GB: return size / (1024*1024*1024); default: return size; } } bool ftp::CreateDirectory(const std::string& remoteDir) { return (bool)FtpCreateDirectory(m_hConnection, remoteDir.c_str()); } bool ftp::DeleteFile(const std::string& remoteFile) { return (bool)FtpDeleteFile(m_hConnection, remoteFile.c_str()); } bool ftp::DeleteDirectory(const std::string& remoteDir) { return (bool)FtpRemoveDirectory(m_hConnection, remoteDir.c_str()); } bool ftp::RenameFile(const std::string& remoteFile, const std::string& newFile) { return (bool)FtpRenameFile(m_hConnection, remoteFile.c_str(), newFile.c_str()); } #endif // FTP_H The only thing I'm missing is creating a callback function inside the class that will help me update m_bConnected if anything happens to the connection with the server. Any suggestions? Link to comment Share on other sites More sharing options...
Valik Posted June 13, 2011 Share Posted June 13, 2011 C-style casts? Really? Fail. Link to comment Share on other sites More sharing options...
Richard Robertson Posted June 13, 2011 Share Posted June 13, 2011 What's with all the bool casts anyway? Link to comment Share on other sites More sharing options...
Info Posted June 13, 2011 Author Share Posted June 13, 2011 what's wrong with converting BOOL to bool using (bool)? Should I have used static_cast or..? Link to comment Share on other sites More sharing options...
Valik Posted June 13, 2011 Share Posted June 13, 2011 Never use a C style cast in C++ code. Ever. If you can't figure out how to use the correct cast then you need to 1) Rewrite your code; 2) Learn about casting. Link to comment Share on other sites More sharing options...
Administrators Jon Posted June 13, 2011 Administrators Share Posted June 13, 2011 I'm sure Valik wasn't keen on this either: m_bConnected = (bool)m_hConnection Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
Valik Posted June 13, 2011 Share Posted June 13, 2011 I'm sure Valik wasn't keen on this either: m_bConnected = (bool)m_hConnection Didn't see it. Now that I do, yeah, that's just stupid. Then again all the casts are stupid so par for the course I suppose. Makes me glad we don't have people like that working on AutoIt (anymore). Link to comment Share on other sites More sharing options...
Info Posted June 13, 2011 Author Share Posted June 13, 2011 (edited) Could you explain why is that so stupid? Will it be better with static_cast? Also, according to www.codeguru.com/forum/showthread.php?t=312456 (sorry, linking doesn't seem to work), all the C++ type casting operators are for classes, pointers to classes and references to classes. So which way will be better for converting BOOL to bool? Edited June 13, 2011 by Info Link to comment Share on other sites More sharing options...
Valik Posted June 13, 2011 Share Posted June 13, 2011 Could you explain why is that so stupid? Will it be better with static_cast?Also, according to www.codeguru.com/forum/showthread.php?t=312456 (sorry, linking doesn't seem to work), all the C++ type casting operators are for classes, pointers to classes and references to classes.I suggest you read that page closer.So which way will be better for converting BOOL to bool?All of them are better than what you are doing. There are at least 3 ways to write those expressions (2 of which don't involve casts at all). If you can't think of at least one way then you need to stop what you are doing and go back to reading. Link to comment Share on other sites More sharing options...
Info Posted June 13, 2011 Author Share Posted June 13, 2011 ah return (func() == TRUE) I guess Is there any other thing I've done badly? Link to comment Share on other sites More sharing options...
Administrators Jon Posted June 14, 2011 Administrators Share Posted June 14, 2011 I used to use C casts all the time until Valik started being the cast police. We had a pretty hard time converting from x86 to x64 in the AutoIt source code and one of the reasons was casting was hiding some pretty horrific assumptions. There was also no way "search" for C casts as they are just () rather than a keyword, so we couldn't even search the problem areas of code. They also provide a bit of sanity checking where static_cast won't let you do really stupid things where it really doesn't make sense whereas the C style cast doesn't give a **** and will cast anything to anything regardless of if it will break everything. For this m_bConnected = (bool)m_hConnection Traditionally I would have actually done it longhand (I prefer readability over cleverness myself, and clever versions would only likely produce the same assembly as the readable version anyhow) if (m_hConnection) m_bConnected = true; else m_bConnected = false; But Valik got me into these types of statements and I can read them without panicing these days: m_bConnected = m_hConnection ? true : false; I think this would also work, but would be my worst nightmare to read: m_bConnected = !!m_hConnection Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
Info Posted June 14, 2011 Author Share Posted June 14, 2011 I don't get it. Doesn't this if (m_hConnection) m_bConnected = true; else m_bConnected = false; and this m_bConnected = m_hConnection ? true : false; also force a BOOL to bool conversion? And what's so bad about C-style casting? Link to comment Share on other sites More sharing options...
Administrators Jon Posted June 14, 2011 Administrators Share Posted June 14, 2011 Some examples here http://cboard.cprogramming.com/faq-board/86924-faq-difference-between-c-cplusplus-style-casting.html Lots of other pages come up on google. Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
Valik Posted June 14, 2011 Share Posted June 14, 2011 I used to use C casts all the time until Valik started being the cast policeSo fast forward to this morning when I see the COM bugfix commit in my email and there are C-style casts in it. Traditionally I would have actually done it longhand (I prefer readability over cleverness myself, and clever versions would only likely produce the same assembly as the readable version anyhow) if (m_hConnection) m_bConnected = true; else m_bConnected = false; But Valik got me into these types of statements and I can read them without panicing these days: m_bConnected = m_hConnection ? true : false; And by "got me into" he means "Valik wrote a shitload of them in AutoIt and I had to cope". I think this would also work, but would be my worst nightmare to read: m_bConnected = !!m_hConnection Agreed. That just obfuscates what's going on. That being said I've seen that code in the wild. I don't get it. Doesn't this if (m_hConnection) m_bConnected = true; else m_bConnected = false; and this m_bConnected = m_hConnection ? true : false; also force a BOOL to bool conversion? It doesn't force anything, it evaluates an expression and explicitly sets the results. And what's so bad about C-style casting?How wasn't Jon clear? Because you have no clue what the fuck a C style cast is really doing. It might just simply be a (relatively) harmless static cast or it might be a far more dangerous and probably just plain wrong reinterpret cast. A lot of times it's a const cast and const should only be cast away after careful study to make sure it really is safe to pass const data to a non-const function.. Explicit C++ casting forces you to think about and understand the code and how it works. C casts let you be lazy and a bad programmer who doesn't understand parts of their code. Link to comment Share on other sites More sharing options...
Administrators Jon Posted June 14, 2011 Administrators Share Posted June 14, 2011 (edited) So fast forward to this morning when I see the COM bugfix commit in my email and there are C-style casts in it.lol, that would have been trancexx and I must have missed it when I added it Edit: Actually I can't see any new ones (apart from a const_cast I'm not sure about) I think they are leftovers but look like new because the function changed so much. Edited June 14, 2011 by Jon Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
Valik Posted June 14, 2011 Share Posted June 14, 2011 lol, that would have been trancexx and I must have missed it when I added it Edit: Actually I can't see any new ones (apart from a const_cast I'm not sure about) I think they are leftovers but look like new because the function changed so much.Nah, I knew they weren't new. But they still weren't fixed. Link to comment Share on other sites More sharing options...
Administrators Jon Posted June 14, 2011 Administrators Share Posted June 14, 2011 I'm already having nightmares about script_object.cpp as it is - the less time I'm in there the better. Deployment Blog: https://www.autoitconsulting.com/site/blog/ SCCM SDK Programming: https://www.autoitconsulting.com/site/sccm-sdk/ Link to comment Share on other sites More sharing options...
jaberwacky Posted June 15, 2011 Share Posted June 15, 2011 According to this page: http://www.codeguru.com/forum/showthread.php?t=332831, functions that return BOOL can sometimes return a -1 for error, so take that into account too. You can't just check for true or false. Helpful Posts and Websites: AutoIt3 Variables and Function Parameters MHz | AutoIt Wiki | Using the GUIToolTip UDF BrewManNH | Can't find what you're looking for on the Forum? Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now