XTPSyntaxEditTextIterator.cpp
上传用户:szled88
上传日期:2015-04-09
资源大小:43957k
文件大小:13k
源码类别:

对话框与窗口

开发平台:

Visual C++

  1. // XTPSyntaxEditTextIterator.cpp : implementation file
  2. //
  3. // This file is a part of the XTREME TOOLKIT PRO MFC class library.
  4. // (c)1998-2008 Codejock Software, All Rights Reserved.
  5. //
  6. // THIS SOURCE FILE IS THE PROPERTY OF CODEJOCK SOFTWARE AND IS NOT TO BE
  7. // RE-DISTRIBUTED BY ANY MEANS WHATSOEVER WITHOUT THE EXPRESSED WRITTEN
  8. // CONSENT OF CODEJOCK SOFTWARE.
  9. //
  10. // THIS SOURCE CODE CAN ONLY BE USED UNDER THE TERMS AND CONDITIONS OUTLINED
  11. // IN THE XTREME SYNTAX EDIT LICENSE AGREEMENT. CODEJOCK SOFTWARE GRANTS TO
  12. // YOU (ONE SOFTWARE DEVELOPER) THE LIMITED RIGHT TO USE THIS SOFTWARE ON A
  13. // SINGLE COMPUTER.
  14. //
  15. // CONTACT INFORMATION:
  16. // support@codejock.com
  17. // http://www.codejock.com
  18. //
  19. //
  20. //////////////////////////////////////////////////////////////////////
  21. #include "stdafx.h"
  22. // common includes
  23. #include "Common/XTPNotifyConnection.h"
  24. #include "Common/XTPSmartPtrInternalT.h"
  25. #include "Common/XTPVC80Helpers.h"
  26. // syntax editor includes
  27. #include "XTPSyntaxEditDefines.h"
  28. #include "XTPSyntaxEditStruct.h"
  29. #include "XTPSyntaxEditLexPtrs.h"
  30. #include "XTPSyntaxEditLexClassSubObjT.h"
  31. #include "XTPSyntaxEditTextIterator.h"
  32. #include "XTPSyntaxEditSectionManager.h"
  33. #include "XTPSyntaxEditLexCfgFileReader.h"
  34. #include "XTPSyntaxEditLexClassSubObjDef.h"
  35. #include "XTPSyntaxEditLexClass.h"
  36. #include "XTPSyntaxEditLexParser.h"
  37. #include "XTPSyntaxEditBufferManager.h"
  38. #include "XTPSyntaxEditTextIterator.h"
  39. #define XTP_EDIT_LEX_TEXT_BUF_SIZE 512
  40. #define XTP_EDIT_LEX_TEXT_BUF_START_GAP 10
  41. #ifdef _UNICODE
  42. #define CHAR_W 1
  43. #else
  44. #define CHAR_W 2
  45. #endif
  46. //---------------------------------------------------------------------------
  47. #define CHR_TO_B(nChr) ( (int)((nChr)*sizeof(TCHAR)) )
  48. ////////////////////////////////////////////////////////////////////////////
  49. AFX_INLINE int xtpEdit_StrLenInBytes(LPCTSTR pcszStr, int nChars)
  50. {
  51. #ifdef _UNICODE
  52. return (int)_tcsnbcnt(pcszStr, nChars) * sizeof(TCHAR);
  53. #else
  54. return (int)_tcsnbcnt(pcszStr, nChars);
  55. #endif
  56. }
  57. AFX_INLINE int xtpEdit_StrCharsToBytes(LPCTSTR pcszStr, int nChars)
  58. {
  59. #ifdef _UNICODE
  60. UNREFERENCED_PARAMETER(pcszStr);
  61. return nChars * sizeof(TCHAR);
  62. #else
  63. LPCTSTR p2;
  64. if (nChars == 1)
  65. {
  66. p2 = _tcsinc(pcszStr);
  67. }
  68. else
  69. {
  70. p2 = _tcsninc(pcszStr, nChars);
  71. }
  72. int nB = int(p2 - pcszStr);
  73. return nB;
  74. //return _tcsnbcnt(pcszStr, nChars);
  75. #endif
  76. }
  77. ////////////////////////////////////////////////////////////////////////////
  78. static const TCHAR szEOL[] = _T("x0Dx0A");
  79. ////////////////////////////////////////////////////////////////////////////
  80. //class CXTPSyntaxEditTextIterator
  81. namespace XTPSyntaxEditLexAnalyser
  82. {
  83. BOOL IsEventSet(HANDLE hEvent);
  84. }
  85. CXTPSyntaxEditTextIterator::CXTPSyntaxEditTextIterator(CXTPSyntaxEditBufferManager* pData)
  86. {
  87. m_pData = pData;
  88. if (!m_pData)
  89. return;
  90. m_pData->InternalAddRef();
  91. int nMaxBackOffset_sch = (int)m_pData->GetLexParser()->GetSchemaOptions(
  92. m_pData->GetFileExt())->m_dwMaxBackParseOffset;
  93. // WARNING! - value should be in reasonable range
  94. ASSERT(nMaxBackOffset_sch >= 10 && nMaxBackOffset_sch <= 10*1000);
  95. m_nBufOffsetB_normal = max(nMaxBackOffset_sch, 20);
  96. m_nBufOffsetB_max = XTP_EDIT_LEX_TEXT_BUF_SIZE;
  97. m_nBufOffsetB = 0;
  98. SeekBegin();
  99. }
  100. CXTPSyntaxEditTextIterator::~CXTPSyntaxEditTextIterator()
  101. {
  102. if (m_pData)
  103. {
  104. m_pData->InternalRelease();
  105. }
  106. }
  107. CString CXTPSyntaxEditTextIterator::GetEOL() // "rn", "nr", "r"
  108. {
  109. if (!m_pData)
  110. {
  111. ASSERT(FALSE);
  112. return szEOL;
  113. }
  114. CString strEOL = m_pData->GetCurCRLF();
  115. return strEOL;
  116. }
  117. void CXTPSyntaxEditTextIterator::SeekBegin()
  118. {
  119. m_LCpos.nLine = 1;
  120. m_LCpos.nCol = 0;
  121. m_mapLine2Len.RemoveAll();
  122. int nEndRow = m_pData->GetRowCount();
  123. int nHSize = max(nEndRow/10, 500);
  124. m_mapLine2Len.InitHashTable(nHSize, FALSE);
  125. m_nNextLine = 1;
  126. m_nBufSizeB = 0;
  127. m_nTmpOffsetC = 0;
  128. m_nTmpOffsetB = 0;
  129. m_nBufOffsetB = XTP_EDIT_LEX_TEXT_BUF_START_GAP;
  130. if (m_arBuffer.GetSize() < max(m_nBufOffsetB_normal, 500))
  131. {
  132. m_arBuffer.SetSize(max(m_nBufOffsetB_normal, 500));
  133. }
  134. memset(m_arBuffer.GetData(), 0, m_arBuffer.GetSize());
  135. TCHAR* pData = GetBuffer(m_nBufOffsetB);
  136. STRCPY_S(pData, _tcslen(szEOL) + 1, szEOL);
  137. m_nBufOffsetB += CHR_TO_B(2);
  138. //---
  139. int nLen = GetLineLen(m_nNextLine, TRUE);
  140. m_bEOF = nLen == 0;
  141. }
  142. BOOL CXTPSyntaxEditTextIterator::SeekPos(const XTP_EDIT_LINECOL& posLC, HANDLE hBreakEvent)
  143. {
  144. SeekBegin();
  145. if (m_bEOF)
  146. {
  147. return FALSE;
  148. }
  149. int nSumLenB = 0;
  150. int nLnStart = posLC.nLine;
  151. while (nSumLenB < m_nBufOffsetB_normal && nLnStart > 1)
  152. {
  153. nSumLenB += GetLineLenBytes(nLnStart, TRUE);
  154. nLnStart--;
  155. if (hBreakEvent && XTPSyntaxEditLexAnalyser::IsEventSet(hBreakEvent))
  156. {
  157. return FALSE;
  158. }
  159. }
  160. m_nNextLine = nLnStart;
  161. GetText();
  162. m_LCpos.nLine = nLnStart;
  163. m_LCpos.nCol = 0;
  164. while (m_LCpos < posLC && !m_bEOF)
  165. {
  166. int nSeek = 1;
  167. if (m_LCpos.nLine < posLC.nLine)
  168. {
  169. nSeek = 0;
  170. if (!m_mapLine2Len.Lookup(m_LCpos.nLine, nSeek) || !nSeek)
  171. {
  172. ASSERT(nSeek || !nSeek && m_LCpos.nLine >= m_pData->GetRowCount());
  173. nSeek = 1;
  174. }
  175. }
  176. else
  177. {
  178. ASSERT(m_LCpos.nLine == posLC.nLine);
  179. nSeek = posLC.nCol - m_LCpos.nCol;
  180. ASSERT(nSeek >=0);
  181. }
  182. if (nSeek <= 0)
  183. {
  184. ASSERT(FALSE);
  185. break;
  186. }
  187. SeekNext(nSeek);
  188. if (hBreakEvent && XTPSyntaxEditLexAnalyser::IsEventSet(hBreakEvent))
  189. {
  190. return FALSE;
  191. }
  192. }
  193. BOOL bRes = (m_LCpos == posLC);
  194. return bRes;
  195. }
  196. LPCTSTR CXTPSyntaxEditTextIterator::GetText(int nCharsBuf)  // don't remove line end chars
  197. {
  198. if (!m_pData)
  199. {
  200. ASSERT(FALSE);
  201. return NULL;
  202. }
  203. int nSizeB = (int)m_arBuffer.GetSize();
  204. const int cnReservB = (XTP_EDIT_LEX_TEXT_BUF_SIZE+100)*2;
  205. if (!m_nBufSizeB || (m_nBufSizeB < CHR_TO_B(nCharsBuf)) )
  206. {
  207. int nEndRow = m_pData->GetRowCount();
  208. while (m_nNextLine <= nEndRow && m_nBufSizeB < CHR_TO_B(nCharsBuf) )
  209. {
  210. CString strBuf;
  211. m_pData->GetLineText(m_nNextLine, strBuf, TRUE);
  212. int nLenC = (int)_tcsclen(strBuf);
  213. int nLenB = xtpEdit_StrLenInBytes(strBuf, nLenC);
  214. //---------------------------------------------------------------------------
  215. int nNeedSizeB = m_nBufOffsetB + m_nBufSizeB + nLenB +
  216.  max(256, nCharsBuf*2);
  217. if (nNeedSizeB > nSizeB)
  218. {
  219. m_arBuffer.SetSize(nNeedSizeB + cnReservB);
  220. nSizeB = (int)m_arBuffer.GetSize();
  221. }
  222. //---------------------------------------------------------------------------
  223. TCHAR* pBuf = GetBuffer(m_nBufOffsetB + m_nBufSizeB);
  224. ASSERT(*(pBuf-1) != _T(''));
  225. ASSERT(*pBuf == _T(''));
  226. *pBuf = _T('');
  227. STRCPY_S(pBuf, strBuf.GetLength() + 1, strBuf);
  228. ASSERT(nSizeB-m_nBufOffsetB-m_nBufSizeB > nLenB);
  229. m_nBufSizeB += nLenB;
  230. ASSERT(m_nBufSizeB < nSizeB);
  231. m_mapLine2Len[m_nNextLine] = nLenC;
  232. //TRACE(_T("TEXT-ITERATOR: line(%d) len = %d n"),m_nNextLine, nLenC);
  233. //--------------------------------
  234. if (m_nNextLine == nEndRow)
  235. {
  236. TCHAR* pBufEnd = GetBuffer(m_nBufOffsetB + m_nBufSizeB);
  237. STRCPY_S(pBufEnd, _tcslen(szEOL) + 1, szEOL);
  238. int nLenB2 = xtpEdit_StrLenInBytes(szEOL, 2);
  239. m_nBufSizeB += nLenB2;
  240. ASSERT(m_nBufSizeB < nSizeB);
  241. }
  242. m_nNextLine++;
  243. }
  244. }
  245. ASSERT(m_nBufSizeB < nSizeB);
  246. TCHAR* pText = GetBuffer(m_nBufOffsetB + m_nTmpOffsetB);
  247. return pText;
  248. }
  249. // Move cur pos and return pointer to the text begin;
  250. LPCTSTR CXTPSyntaxEditTextIterator::SeekNext(DWORD dwChars, int nCharsBuf)
  251. {
  252. int nBSize = (int)m_arBuffer.GetSize();
  253. ASSERT(m_nBufSizeB <= nBSize);
  254. if (m_nBufSizeB < CHR_TO_B(nCharsBuf + dwChars))
  255. {
  256. GetText(nCharsBuf + dwChars);
  257. }
  258. if (m_nBufSizeB < CHR_TO_B(dwChars) )
  259. {
  260. dwChars = m_nBufSizeB/sizeof(TCHAR);
  261. }
  262. if (m_nBufSizeB >= CHR_TO_B(dwChars) && m_nBufSizeB)
  263. {
  264. nBSize = (int)m_arBuffer.GetSize();
  265. ASSERT(nBSize > CHR_TO_B(dwChars) );
  266. TCHAR* pText = GetBuffer(m_nBufOffsetB);
  267. //int nStepB = xtpEdit_StrLenInBytes(pText, dwChars);
  268. int nStepB = xtpEdit_StrCharsToBytes(pText, dwChars);
  269. ASSERT(nStepB > 0);
  270. if (m_nBufOffsetB > m_nBufOffsetB_max)
  271. {
  272. int nStepRem = m_nBufOffsetB - m_nBufOffsetB_normal;
  273. ASSERT(nStepRem > 0);
  274. m_arBuffer.RemoveAt(0, nStepRem);
  275. m_nBufOffsetB -= nStepRem;
  276. }
  277. m_nBufOffsetB += nStepB;
  278. m_nBufSizeB -= nStepB;
  279. TCHAR* pBuf = GetBuffer(m_nBufOffsetB + m_nBufSizeB);
  280. ASSERT(*(pBuf-1) != _T(''));
  281. ASSERT(*pBuf == _T(''));
  282. m_bEOF = m_nBufSizeB <= 0;
  283. if (dwChars && !m_bEOF)
  284. {
  285. LCPosAdd(m_LCpos, dwChars);
  286. }
  287. SetTxtOffset(m_nTmpOffsetC);
  288. pText = GetBuffer(m_nBufOffsetB + m_nTmpOffsetB);
  289. return pText;
  290. }
  291. return NULL;
  292. }
  293. LPCTSTR CXTPSyntaxEditTextIterator::SeekPrev()
  294. {
  295. int nBSize = (int)m_arBuffer.GetSize();
  296. ASSERT(m_nBufSizeB <= nBSize);
  297. if (m_nBufOffsetB <= XTP_EDIT_LEX_TEXT_BUF_START_GAP)
  298. {
  299. XTP_EDIT_LINECOL lcPos = m_LCpos;
  300. //LCPosDec(lcPos);
  301. if (!SeekPos(lcPos))
  302. return NULL;
  303. }
  304. if (m_nBufOffsetB > 0 && m_nBufSizeB > 0 && m_LCpos > XTP_EDIT_LINECOL::Pos1)
  305. {
  306. TCHAR* pText0 = GetBuffer(0);
  307. TCHAR* pText1 = GetBuffer(m_nBufOffsetB);
  308. TCHAR* pText = pText1;
  309. pText = _tcsdec(pText0, pText);
  310. if (!pText)
  311. {
  312. m_nBufOffsetB = 0;
  313. m_bEOF = TRUE;
  314. return NULL;
  315. }
  316. int nStepB = int(pText1 - pText) * sizeof(TCHAR);
  317. m_nBufOffsetB -= nStepB;
  318. m_nBufSizeB += nStepB;
  319. LCPosDec(m_LCpos);
  320. //SetTxtOffset(m_nTmpOffsetC);
  321. //pText = GetBuffer(m_nBufOffsetB + m_nTmpOffsetB);
  322. return pText;
  323. }
  324. return NULL;
  325. }
  326. void CXTPSyntaxEditTextIterator::SetTxtOffset(int nOffsetChars)
  327. {
  328. m_nTmpOffsetC = nOffsetChars;
  329. m_nTmpOffsetB = 0;
  330. if (m_nTmpOffsetC)
  331. {
  332. TCHAR* pText = GetBuffer(m_nBufOffsetB);
  333. if (m_nTmpOffsetC < 0)
  334. {
  335. TCHAR* pText_min = GetBuffer(0);
  336. TCHAR* pText0 = pText;
  337. for (int i = 0; i < labs(nOffsetChars); i++)
  338. {
  339. if (pText0 <= pText_min)
  340. {
  341. break;
  342. }
  343. pText0 = _tcsdec(pText_min, pText0);
  344. }
  345. m_nTmpOffsetB = -1 * int( ((byte*)pText) - ((byte*)pText0) );
  346. }
  347. else
  348. {
  349. m_nTmpOffsetB = xtpEdit_StrLenInBytes(pText, m_nTmpOffsetC);
  350. }
  351. }
  352. }
  353. BOOL CXTPSyntaxEditTextIterator::IsEOF()
  354. {
  355. return m_bEOF;
  356. }
  357. XTP_EDIT_LINECOL CXTPSyntaxEditTextIterator::GetPosLC()
  358. {
  359. return m_LCpos;
  360. }
  361. XTP_EDIT_LINECOL CXTPSyntaxEditTextIterator::GetPosLC_last(BOOL bWithEOL)
  362. {
  363. int nEndRow = m_pData->GetRowCount();
  364. return XTP_EDIT_LINECOL::MakeLineCol(nEndRow, GetLineLen(nEndRow, bWithEOL));
  365. }
  366. void CXTPSyntaxEditTextIterator::LCPosAdd(XTP_EDIT_LINECOL& rLC, int nCharsAdd)
  367. {
  368. int nLineLen = 0;
  369. int nRestChars = nCharsAdd;
  370. while (nRestChars)
  371. {
  372. if (m_mapLine2Len.Lookup(rLC.nLine, nLineLen))
  373. {
  374. if (nLineLen == 0)
  375. {
  376. break;   // last empty line
  377. }
  378. ASSERT(nLineLen > 0);
  379. int nDiff = nLineLen - rLC.nCol;
  380. ASSERT(nDiff >= 0);
  381. if (nDiff <= nRestChars)
  382. {
  383. rLC.nLine++;
  384. rLC.nCol = 0;
  385. nRestChars -= nDiff;
  386. }
  387. else
  388. {
  389. rLC.nCol += nRestChars;
  390. nRestChars = 0;
  391. break;
  392. }
  393. }
  394. else
  395. {
  396. break; // no more lines
  397. }
  398. }
  399. }
  400. void CXTPSyntaxEditTextIterator::LCPosDec(XTP_EDIT_LINECOL& rLC)
  401. {
  402. rLC.nCol--;
  403. if (rLC.nCol < 0)
  404. {
  405. if (rLC.nLine <= 1)
  406. {
  407. ASSERT(FALSE);
  408. rLC.nCol = 0;
  409. }
  410. else
  411. {
  412. rLC.nLine--;
  413. int nLineLen = 0;
  414. if (m_mapLine2Len.Lookup(rLC.nLine, nLineLen))
  415. {
  416. ASSERT(nLineLen || rLC.nLine == m_pData->GetRowCount());
  417. nLineLen = max(1, nLineLen);
  418. rLC.nCol = nLineLen-1;
  419. }
  420. else
  421. {
  422. if (rLC.nLine >= 1)
  423. {
  424. nLineLen = m_pData->GetLineTextLengthC(rLC.nLine, TRUE);
  425. ASSERT(nLineLen || rLC.nLine == m_pData->GetRowCount());
  426. nLineLen = max(1, nLineLen);
  427. rLC.nCol = nLineLen-1;
  428. }
  429. else
  430. {
  431. ASSERT(FALSE);
  432. rLC.nLine++;
  433. rLC.nCol++;
  434. }
  435. }
  436. }
  437. }
  438. }
  439. int CXTPSyntaxEditTextIterator::GetLineLen(int nLine, BOOL bWithEOL)
  440. {
  441. if (!m_pData)
  442. {
  443. ASSERT(FALSE);
  444. return 0;
  445. }
  446. int nEndRow = m_pData->GetRowCount();
  447. if (nLine > 0 && nLine <= nEndRow)
  448. {
  449. CString strBuf;
  450. m_pData->GetLineText(nLine, strBuf, bWithEOL);
  451. int nLen = (int)_tcsclen(strBuf);
  452. return nLen;
  453. }
  454. return 0;
  455. }
  456. int CXTPSyntaxEditTextIterator::GetLineLenBytes(int nLine, BOOL bWithEOL)
  457. {
  458. if (!m_pData)
  459. {
  460. ASSERT(FALSE);
  461. return 0;
  462. }
  463. int nEndRow = m_pData->GetRowCount();
  464. if (nLine > 0 && nLine <= nEndRow)
  465. {
  466. CString strBuf;
  467. m_pData->GetLineText(nLine, strBuf, bWithEOL);
  468. int nLenB = xtpEdit_StrLenInBytes(strBuf, strBuf.GetLength());
  469. return nLenB;
  470. }
  471. return 0;
  472. }
  473. CString CXTPSyntaxEditTextIterator::GetFileExt()
  474. {
  475. if (!m_pData)
  476. {
  477. ASSERT(FALSE);
  478. return _T("");
  479. }
  480. CString strFN = m_pData->GetFileExt();
  481. return strFN;
  482. }