Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

241 lines
5.1 KiB

  1. // LinkFile.cpp: implementation of the CLinkFile class.
  2. //
  3. //////////////////////////////////////////////////////////////////////
  4. #include "stdafx.h"
  5. #include "NxtLnk.h"
  6. #include "LinkFile.h"
  7. #include "NextLink.h"
  8. extern CMonitor* g_pMonitor;
  9. //--------------------------------------------------------------------
  10. // IsTab
  11. //
  12. // Function object to read a stream until a tab is encounterd
  13. //
  14. //--------------------------------------------------------------------
  15. struct IsTab : public CharCheck
  16. {
  17. virtual bool operator()(_TCHAR);
  18. };
  19. bool
  20. IsTab::operator()(
  21. _TCHAR c )
  22. {
  23. return ( c == _T('\t') );
  24. }
  25. //--------------------------------------------------------------------
  26. // CLinkNotify
  27. //--------------------------------------------------------------------
  28. CLinkNotify::CLinkNotify()
  29. : m_isNotified(0)
  30. {
  31. }
  32. void
  33. CLinkNotify::Notify()
  34. {
  35. ::InterlockedExchange( &m_isNotified, 1 );
  36. }
  37. bool
  38. CLinkNotify::IsNotified()
  39. {
  40. return ( ::InterlockedExchange( &m_isNotified, 0 ) ? true : false );
  41. }
  42. //---------------------------------------------------------------------
  43. // CLinkFile
  44. //---------------------------------------------------------------------
  45. //////////////////////////////////////////////////////////////////////
  46. // Construction/Destruction
  47. //////////////////////////////////////////////////////////////////////
  48. CLinkFile::CLinkFile(
  49. const String& strFile )
  50. : m_bIsOkay( false ),
  51. m_strFile( strFile ),
  52. m_fUTF8(false)
  53. {
  54. m_pNotify = new CLinkNotify;
  55. bool loadStatus = LoadFile ();
  56. if ( loadStatus )
  57. {
  58. g_pMonitor->MonitorFile( m_strFile.c_str(), m_pNotify );
  59. }
  60. }
  61. CLinkFile::~CLinkFile()
  62. {
  63. if ( g_pMonitor )
  64. {
  65. g_pMonitor->StopMonitoringFile( m_strFile.c_str() );
  66. }
  67. }
  68. int
  69. CLinkFile::LinkIndex(
  70. const String& strPage )
  71. {
  72. int rc = 0;
  73. for ( int i = 0; i < m_links.size(); i++ )
  74. {
  75. if ( m_links[i]->IsEqual( strPage ) )
  76. {
  77. rc = i+1;
  78. i = m_links.size();
  79. }
  80. }
  81. return rc;
  82. }
  83. CLinkPtr
  84. CLinkFile::Link(
  85. int nIndex )
  86. {
  87. CLinkPtr pLink = NULL;
  88. if ( m_links.size() > 0 )
  89. {
  90. if ( nIndex > m_links.size() )
  91. {
  92. pLink = m_links.front();
  93. }
  94. else if ( nIndex < 1 )
  95. {
  96. pLink = m_links.back();
  97. }
  98. else
  99. {
  100. pLink = m_links[nIndex-1];
  101. }
  102. }
  103. return pLink;
  104. }
  105. CLinkPtr
  106. CLinkFile::NextLink(
  107. const String& strPage )
  108. {
  109. CLinkPtr pLink;
  110. int nIndex = LinkIndex( strPage );
  111. if ( nIndex > 0 )
  112. {
  113. pLink = Link( nIndex + 1 );
  114. }
  115. else if ( m_links.size() > 0 )
  116. {
  117. pLink = m_links.back();
  118. }
  119. return pLink;
  120. }
  121. CLinkPtr
  122. CLinkFile::PreviousLink(
  123. const String& strPage )
  124. {
  125. CLinkPtr pLink;
  126. int nIndex = LinkIndex( strPage );
  127. if (nIndex > 0)
  128. {
  129. pLink = Link( nIndex - 1 );
  130. }
  131. else if ( m_links.size() > 0 )
  132. {
  133. pLink = m_links.front();
  134. }
  135. return pLink;
  136. }
  137. //---------------------------------------------------------------------------
  138. //
  139. // Refresh will check to see if the cached information is out of date with
  140. // the ini file. If so, the cached will be purged
  141. //
  142. //---------------------------------------------------------------------------
  143. bool
  144. CLinkFile::Refresh()
  145. {
  146. bool rc = false;
  147. if ( m_pNotify->IsNotified() )
  148. {
  149. rc = LoadFile();
  150. }
  151. return rc;
  152. }
  153. bool
  154. ValidateURL(String &url)
  155. {
  156. if (!url.compare(0, 2, "//")
  157. || !url.compare(0, 2, "\\\\")
  158. || !url.compare(0, 5, "http:")
  159. || !url.compare(0, 6, "https:"))
  160. return false;
  161. else
  162. return true;
  163. }
  164. bool
  165. CLinkFile::LoadFile()
  166. {
  167. USES_CONVERSION;
  168. bool rc = false;
  169. CWriter wtr( *this );
  170. m_links.clear();
  171. // parse the file for the links
  172. FileInStream fs;
  173. HRESULT hr = fs.Init ( m_strFile.c_str() );
  174. if ( SUCCEEDED (hr) && fs.is_open())
  175. {
  176. m_fUTF8 = fs.is_UTF8();
  177. while ( !fs.eof() )
  178. {
  179. String strLine;
  180. fs.readLine( strLine );
  181. if ( strLine != _T("") )
  182. {
  183. StringInStream ss( strLine );
  184. String strURL = _T(""), strDesc = _T("");
  185. ss.read( IsTab(), strURL );
  186. ss.read( IsTab(), strDesc );
  187. // anything following description is just a comment which is discarded
  188. if (ValidateURL(strURL)) {
  189. CLinkPtr pLink = new CLink( strURL, strDesc );
  190. m_links.push_back( pLink );
  191. }
  192. }
  193. }
  194. if (m_links.size())
  195. {
  196. rc = true;
  197. }
  198. else
  199. {
  200. rc = false;
  201. CNextLink::RaiseException( IDS_ERROR_INVALID_LINKFILE );
  202. }
  203. }
  204. else
  205. {
  206. CNextLink::RaiseException( IDS_ERROR_CANNOT_OPEN_FILE );
  207. }
  208. m_bIsOkay = rc;
  209. return rc;
  210. }