stdafx.h 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526
  1. //---------------------------------------------------------------------------
  2. #ifndef StdAfxH
  3. #define StdAfxH
  4. //---------------------------------------------------------------------------
  5. #define _int64 __int64
  6. //---------------------------------------------------------------------------
  7. #define MPEXT_NO_ZLIB
  8. #define MPEXT_NO_GSS
  9. #define _AFX_ENABLE_INLINES
  10. #define _AFX_NOFORCE_LIBS
  11. //---------------------------------------------------------------------------
  12. #define LENOF(x) ( (sizeof((x))) / (sizeof(*(x))))
  13. //---------------------------------------------------------------------------
  14. #include <afx.h>
  15. #include "wtypes.h"
  16. // STL includes
  17. #include <list>
  18. #include <map>
  19. #include <vector>
  20. #include <deque>
  21. #include <set>
  22. #include <algorithm>
  23. //---------------------------------------------------------------------------
  24. class CFileFix;
  25. #define CFile CFileFix
  26. //---------------------------------------------------------------------------
  27. #pragma hdrstop
  28. //---------------------------------------------------------------------------
  29. #include <Global.h>
  30. // these create conflict with afxwin.h
  31. #undef BEGIN_MESSAGE_MAP
  32. #undef END_MESSAGE_MAP
  33. //---------------------------------------------------------------------------
  34. #include "MFC64bitFix.h"
  35. #include <ApiLog.h>
  36. #include <TextsFileZilla.h>
  37. //---------------------------------------------------------------------------
  38. #include <oleauto.h>
  39. #include <afxconv.h>
  40. //---------------------------------------------------------------------------
  41. #define _strlwr strlwr
  42. //---------------------------------------------------------------------------
  43. const int FILEEXISTS_OVERWRITE = 0;
  44. const int FILEEXISTS_RESUME = 1;
  45. const int FILEEXISTS_RENAME = 2;
  46. const int FILEEXISTS_SKIP = 3;
  47. const int FILEEXISTS_COMPLETE = 4;
  48. //---------------------------------------------------------------------------
  49. class t_ffam_statusmessage
  50. {
  51. public:
  52. CString status;
  53. int type;
  54. BOOL post;
  55. };
  56. //---------------------------------------------------------------------------
  57. typedef struct
  58. {
  59. __int64 bytes;
  60. __int64 transfersize;
  61. BOOL bFileTransfer;
  62. } t_ffam_transferstatus;
  63. //---------------------------------------------------------------------------
  64. #undef CFile
  65. //---------------------------------------------------------------------------
  66. class CFileFix : public CFile
  67. {
  68. public:
  69. // MFC CFile::Read does not include file name into error message
  70. UINT Read(void * lpBuf, UINT nCount)
  71. {
  72. ASSERT_VALID(this);
  73. DebugAssert(m_hFile != (UINT)hFileNull);
  74. if (nCount == 0)
  75. {
  76. return 0; // avoid Win32 "null-read"
  77. }
  78. DebugAssert(lpBuf != NULL);
  79. DebugAssert(AfxIsValidAddress(lpBuf, nCount));
  80. DWORD dwRead;
  81. if (!::ReadFile((HANDLE)m_hFile, lpBuf, nCount, &dwRead, NULL))
  82. {
  83. // The only change from MFC CFile::Read is m_strFileName
  84. CFileException::ThrowOsError((LONG)::GetLastError(), m_strFileName);
  85. }
  86. return (UINT)dwRead;
  87. }
  88. // MFC allocates CObject (ancestor of CFile) with new, but deallocates with free,
  89. // what codeguard dislikes, this is fix, not sure if it is necessary for
  90. // release version, but probably causes no harm
  91. void PASCAL operator delete(void * p)
  92. {
  93. delete p;
  94. }
  95. };
  96. //---------------------------------------------------------------------------
  97. #define CFile CFileFix
  98. //---------------------------------------------------------------------------
  99. struct CStringDataA
  100. {
  101. long nRefs; // reference count
  102. int nDataLength; // length of data (including terminator)
  103. int nAllocLength; // length of allocation
  104. // char data[nAllocLength];
  105. CHAR * data() // CHAR* to managed data
  106. {
  107. return (CHAR *)(this+1);
  108. }
  109. };
  110. //---------------------------------------------------------------------------
  111. extern LPCSTR _afxPchNilA;
  112. extern CStringDataA* _afxDataNilA;
  113. #define afxEmptyStringA ((CStringA&)*(CStringA*)&_afxPchNilA)
  114. //---------------------------------------------------------------------------
  115. class CStringA
  116. {
  117. public:
  118. CStringA()
  119. {
  120. m_pchData = afxEmptyStringA.m_pchData;
  121. }
  122. CStringA(const CStringA& stringSrc)
  123. {
  124. DebugAssert(stringSrc.GetData()->nRefs != 0);
  125. if (stringSrc.GetData()->nRefs >= 0)
  126. {
  127. DebugAssert(stringSrc.GetData() != _afxDataNilA);
  128. m_pchData = stringSrc.m_pchData;
  129. InterlockedIncrement(&GetData()->nRefs);
  130. }
  131. else
  132. {
  133. Init();
  134. *this = stringSrc.m_pchData;
  135. }
  136. }
  137. CStringA(LPCSTR lpsz)
  138. {
  139. Init();
  140. if (lpsz != NULL && HIWORD(lpsz) == NULL)
  141. {
  142. DebugFail();
  143. }
  144. else
  145. {
  146. int nLen = SafeStrlen(lpsz);
  147. if (nLen != 0)
  148. {
  149. AllocBuffer(nLen);
  150. memcpy(m_pchData, lpsz, nLen*sizeof(char));
  151. }
  152. }
  153. }
  154. ~CStringA()
  155. {
  156. if (GetData() != _afxDataNilA)
  157. {
  158. if (InterlockedDecrement(&GetData()->nRefs) <= 0)
  159. {
  160. FreeData(GetData());
  161. }
  162. }
  163. }
  164. int GetLength() const
  165. {
  166. return GetData()->nDataLength;
  167. }
  168. char operator[](int nIndex) const
  169. {
  170. // same as GetAt
  171. DebugAssert(nIndex >= 0);
  172. DebugAssert(nIndex < GetData()->nDataLength);
  173. return m_pchData[nIndex];
  174. }
  175. // ref-counted copy from another CString
  176. CStringA& operator=(const CStringA& stringSrc)
  177. {
  178. if (m_pchData != stringSrc.m_pchData)
  179. {
  180. if ((GetData()->nRefs < 0 && GetData() != _afxDataNilA) ||
  181. stringSrc.GetData()->nRefs < 0)
  182. {
  183. // actual copy necessary since one of the strings is locked
  184. AssignCopy(stringSrc.GetData()->nDataLength, stringSrc.m_pchData);
  185. }
  186. else
  187. {
  188. // can just copy references around
  189. Release();
  190. DebugAssert(stringSrc.GetData() != _afxDataNilA);
  191. m_pchData = stringSrc.m_pchData;
  192. InterlockedIncrement(&GetData()->nRefs);
  193. }
  194. }
  195. return *this;
  196. }
  197. const CStringA & operator=(LPCSTR lpsz)
  198. {
  199. DebugAssert(lpsz == NULL || AfxIsValidString(lpsz));
  200. AssignCopy(SafeStrlen(lpsz), lpsz);
  201. return *this;
  202. }
  203. const CStringA & operator+=(char ch)
  204. {
  205. ConcatInPlace(1, &ch);
  206. return *this;
  207. }
  208. friend CStringA AFXAPI operator+(const CStringA & string, char ch);
  209. operator LPCSTR() const
  210. {
  211. return m_pchData;
  212. }
  213. int Compare(LPCSTR lpsz) const
  214. {
  215. DebugAssert(AfxIsValidString(lpsz));
  216. return strcmp(m_pchData, lpsz);
  217. }
  218. CStringA Mid(int nFirst, int nCount) const
  219. {
  220. // out-of-bounds requests return sensible things
  221. if (nFirst < 0)
  222. {
  223. nFirst = 0;
  224. }
  225. if (nCount < 0)
  226. {
  227. nCount = 0;
  228. }
  229. if (nFirst + nCount > GetData()->nDataLength)
  230. {
  231. nCount = GetData()->nDataLength - nFirst;
  232. }
  233. if (nFirst > GetData()->nDataLength)
  234. {
  235. nCount = 0;
  236. }
  237. DebugAssert(nFirst >= 0);
  238. DebugAssert(nFirst + nCount <= GetData()->nDataLength);
  239. // optimize case of returning entire string
  240. if (nFirst == 0 && nFirst + nCount == GetData()->nDataLength)
  241. {
  242. return *this;
  243. }
  244. CStringA dest;
  245. AllocCopy(dest, nCount, nFirst, 0);
  246. return dest;
  247. }
  248. CStringA Left(int nCount) const
  249. {
  250. if (nCount < 0)
  251. {
  252. nCount = 0;
  253. }
  254. if (nCount >= GetData()->nDataLength)
  255. {
  256. return *this;
  257. }
  258. CStringA dest;
  259. AllocCopy(dest, nCount, 0, 0);
  260. return dest;
  261. }
  262. int Find(char ch) const
  263. {
  264. return Find(ch, 0);
  265. }
  266. int Find(char ch, int nStart) const
  267. {
  268. int nLength = GetData()->nDataLength;
  269. if (nStart >= nLength)
  270. {
  271. return -1;
  272. }
  273. // find first single character
  274. LPSTR lpsz = strchr(m_pchData + nStart, (unsigned char)ch);
  275. // return -1 if not found and index otherwise
  276. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  277. }
  278. // find a sub-string (like strstr)
  279. int Find(LPCSTR lpszSub) const
  280. {
  281. return Find(lpszSub, 0);
  282. }
  283. int Find(LPCSTR lpszSub, int nStart) const
  284. {
  285. DebugAssert(AfxIsValidString(lpszSub));
  286. int nLength = GetData()->nDataLength;
  287. if (nStart > nLength)
  288. {
  289. return -1;
  290. }
  291. // find first matching substring
  292. LPSTR lpsz = strstr(m_pchData + nStart, lpszSub);
  293. // return -1 for not found, distance from beginning otherwise
  294. return (lpsz == NULL) ? -1 : (int)(lpsz - m_pchData);
  295. }
  296. void MakeUpper()
  297. {
  298. CopyBeforeWrite();
  299. strupr(m_pchData);
  300. }
  301. protected:
  302. LPSTR m_pchData; // pointer to ref counted string data
  303. CStringDataA * GetData() const
  304. {
  305. DebugAssert(m_pchData != NULL); return ((CStringDataA*)m_pchData)-1;
  306. }
  307. void Init()
  308. {
  309. m_pchData = afxEmptyStringA.m_pchData;
  310. }
  311. void AllocCopy(CStringA & dest, int nCopyLen, int nCopyIndex, int nExtraLen) const
  312. {
  313. // will clone the data attached to this string
  314. // allocating 'nExtraLen' characters
  315. // Places results in uninitialized string 'dest'
  316. // Will copy the part or all of original data to start of new string
  317. int nNewLen = nCopyLen + nExtraLen;
  318. if (nNewLen == 0)
  319. {
  320. dest.Init();
  321. }
  322. else
  323. {
  324. dest.AllocBuffer(nNewLen);
  325. memcpy(dest.m_pchData, m_pchData+nCopyIndex, nCopyLen*sizeof(char));
  326. }
  327. }
  328. void AllocBuffer(int nLen)
  329. // always allocate one extra character for '\0' termination
  330. // assumes [optimistically] that data length will equal allocation length
  331. {
  332. DebugAssert(nLen >= 0);
  333. DebugAssert(nLen <= INT_MAX-1); // max size (enough room for 1 extra)
  334. if (nLen == 0)
  335. {
  336. Init();
  337. }
  338. else
  339. {
  340. CStringDataA* pData;
  341. {
  342. pData = (CStringDataA*)
  343. new BYTE[sizeof(CStringDataA) + (nLen+1)*sizeof(char)];
  344. pData->nAllocLength = nLen;
  345. }
  346. pData->nRefs = 1;
  347. pData->data()[nLen] = '\0';
  348. pData->nDataLength = nLen;
  349. m_pchData = pData->data();
  350. }
  351. }
  352. void AssignCopy(int nSrcLen, LPCSTR lpszSrcData)
  353. {
  354. AllocBeforeWrite(nSrcLen);
  355. memcpy(m_pchData, lpszSrcData, nSrcLen*sizeof(char));
  356. GetData()->nDataLength = nSrcLen;
  357. m_pchData[nSrcLen] = '\0';
  358. }
  359. void FASTCALL FreeData(CStringDataA * pData)
  360. {
  361. delete[] (BYTE*)pData;
  362. }
  363. void PASCAL Release(CStringDataA * pData)
  364. {
  365. if (pData != _afxDataNilA)
  366. {
  367. DebugAssert(pData->nRefs != 0);
  368. if (InterlockedDecrement(&pData->nRefs) <= 0)
  369. {
  370. FreeData(pData);
  371. }
  372. }
  373. }
  374. void Release()
  375. {
  376. if (GetData() != _afxDataNilA)
  377. {
  378. DebugAssert(GetData()->nRefs != 0);
  379. if (InterlockedDecrement(&GetData()->nRefs) <= 0)
  380. {
  381. FreeData(GetData());
  382. }
  383. Init();
  384. }
  385. }
  386. void ConcatCopy(int nSrc1Len, LPCSTR lpszSrc1Data, int nSrc2Len, LPCSTR lpszSrc2Data)
  387. {
  388. // -- master concatenation routine
  389. // Concatenate two sources
  390. // -- assume that 'this' is a new CString object
  391. int nNewLen = nSrc1Len + nSrc2Len;
  392. if (nNewLen != 0)
  393. {
  394. AllocBuffer(nNewLen);
  395. memcpy(m_pchData, lpszSrc1Data, nSrc1Len*sizeof(char));
  396. memcpy(m_pchData+nSrc1Len, lpszSrc2Data, nSrc2Len*sizeof(char));
  397. }
  398. }
  399. void ConcatInPlace(int nSrcLen, LPCSTR lpszSrcData)
  400. {
  401. // -- the main routine for += operators
  402. // concatenating an empty string is a no-op!
  403. if (nSrcLen == 0)
  404. {
  405. return;
  406. }
  407. // if the buffer is too small, or we have a width mis-match, just
  408. // allocate a new buffer (slow but sure)
  409. if (GetData()->nRefs > 1 || GetData()->nDataLength + nSrcLen > GetData()->nAllocLength)
  410. {
  411. // we have to grow the buffer, use the ConcatCopy routine
  412. CStringDataA* pOldData = GetData();
  413. ConcatCopy(GetData()->nDataLength, m_pchData, nSrcLen, lpszSrcData);
  414. DebugAssert(pOldData != NULL);
  415. CStringA::Release(pOldData);
  416. }
  417. else
  418. {
  419. // fast concatenation when buffer big enough
  420. memcpy(m_pchData+GetData()->nDataLength, lpszSrcData, nSrcLen*sizeof(char));
  421. GetData()->nDataLength += nSrcLen;
  422. DebugAssert(GetData()->nDataLength <= GetData()->nAllocLength);
  423. m_pchData[GetData()->nDataLength] = '\0';
  424. }
  425. }
  426. void CopyBeforeWrite()
  427. {
  428. if (GetData()->nRefs > 1)
  429. {
  430. CStringDataA* pData = GetData();
  431. Release();
  432. AllocBuffer(pData->nDataLength);
  433. memcpy(m_pchData, pData->data(), (pData->nDataLength+1)*sizeof(char));
  434. }
  435. DebugAssert(GetData()->nRefs <= 1);
  436. }
  437. void AllocBeforeWrite(int nLen)
  438. {
  439. if (GetData()->nRefs > 1 || nLen > GetData()->nAllocLength)
  440. {
  441. Release();
  442. AllocBuffer(nLen);
  443. }
  444. DebugAssert(GetData()->nRefs <= 1);
  445. }
  446. static int PASCAL SafeStrlen(LPCSTR lpsz)
  447. {
  448. return (lpsz == NULL) ? 0 : strlen(lpsz);
  449. }
  450. };
  451. //---------------------------------------------------------------------------
  452. inline bool AFXAPI operator==(const CStringA & s1, LPCSTR s2)
  453. {
  454. return s1.Compare(s2) == 0;
  455. }
  456. //---------------------------------------------------------------------------
  457. inline bool AFXAPI operator!=(const CStringA & s1, LPCSTR s2)
  458. {
  459. return s1.Compare(s2) != 0;
  460. }
  461. //---------------------------------------------------------------------------
  462. inline CStringA AFXAPI operator+(const CStringA & string1, char ch)
  463. {
  464. CStringA s;
  465. s.ConcatCopy(string1.GetData()->nDataLength, string1.m_pchData, 1, &ch);
  466. return s;
  467. }
  468. //---------------------------------------------------------------------------
  469. #include <FileZillaApi.h>
  470. #include <FileZillaOpt.h>
  471. //---------------------------------------------------------------------------
  472. #endif