home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgLangD.iso / C++-7 / DISK3 / MFC / SAMPLES / FILEVIEW / LINEFILE.CP$ / linefile
Encoding:
Text File  |  1992-03-05  |  3.3 KB  |  203 lines

  1. // linefile.cpp : Defines the class behaviors for the line file class.
  2. //
  3. // This is a part of the Microsoft Foundation Classes C++ library.
  4. // Copyright (C) 1992 Microsoft Corporation
  5. // All rights reserved.
  6. //
  7. // This source code is only intended as a supplement to the
  8. // Microsoft Foundation Classes Reference and Microsoft
  9. // QuickHelp documentation provided with the library.
  10. // See these sources for detailed information regarding the
  11. // Microsoft Foundation Classes product.
  12.  
  13. #include "fileview.h"
  14.  
  15. IMPLEMENT_DYNAMIC(CLineFile, CStdioFile)
  16.  
  17. CLineFile::~CLineFile()
  18. {
  19. }
  20.  
  21. CLineFile::CLineFile() : CStdioFile()
  22. {
  23.     m_lBeginLine = 0L;
  24. }
  25.  
  26. CLineFile::CLineFile(const char* pszFileName, UINT nOpenFlags)
  27.         : CStdioFile(pszFileName, nOpenFlags)
  28. {
  29.     m_lBeginLine = 0L;
  30. }
  31.  
  32. //
  33. // assuming the current file offset points to the beginning of a line
  34. // read the next line, return offset of next line
  35. // also expand tabs to spaces
  36. //
  37.  
  38. #define TABNUM 8
  39.  
  40. LONG
  41. CLineFile::NextLine(char FAR* lpszArg, UINT nMax)
  42. {
  43.     register char FAR * lpsz = lpszArg;
  44.     register UINT n;
  45.  
  46.     m_lBeginLine = GetPosition();
  47.  
  48.     for (n=0;;)
  49.     {
  50.         if ( Read( lpsz, 1) != 1 )
  51.         {
  52.             break;
  53.         }
  54.  
  55.         n++;
  56.  
  57.         if ( *lpsz == '\n' )
  58.         {
  59.             break;
  60.         }
  61.  
  62.         if ( *lpsz == '\r' )
  63.         {
  64.             continue;
  65.         }
  66.  
  67.         if ( *lpsz == '\t' )
  68.         {
  69.             for ( *lpsz++ = ' '; n%TABNUM && n < nMax; n++, lpsz++ )
  70.             {
  71.                  *lpsz = ' ';
  72.             }
  73.         }
  74.         else
  75.         {
  76.             lpsz++;
  77.         }
  78.  
  79.         if ( n >= nMax )
  80.         {
  81.             break;
  82.         }
  83.     }
  84.  
  85.     *lpsz = 0;
  86.  
  87.     return GetPosition();
  88. }
  89.  
  90. LONG
  91. CLineFile::SetBegin(LONG newBegin)
  92. {
  93.     LONG save = m_lBeginLine;
  94.  
  95.     m_lBeginLine = newBegin;
  96.  
  97.     return save;
  98. }
  99.  
  100. //
  101. // read backwards a few ( nLines ) lines
  102. //
  103.  
  104. #define GUESS       100L
  105. #define MAXLINES    200
  106.  
  107. LONG
  108. CLineFile::BackLines(char FAR* lpsz, UINT nMax, UINT nLines)
  109. {
  110.  
  111.     LONG    lines[ MAXLINES ];
  112.     LONG    guess;
  113.     register UINT i;
  114.  
  115.     if (m_lBeginLine == 0L)
  116.     {
  117.         Seek(0L, CFile::begin);
  118.         return NextLine(lpsz, nMax);
  119.     }
  120.  
  121.     if (nLines > MAXLINES)
  122.     {
  123.         nLines = MAXLINES;
  124.     }
  125.  
  126.     guess = m_lBeginLine - ( GUESS * nLines );
  127.  
  128.     if (guess < 0L)
  129.     {
  130.         guess = 0L;
  131.     }
  132.  
  133.     TRY
  134.     {
  135.         Seek( guess, CFile::begin);
  136.     }
  137.     CATCH( CFileException, e )
  138.     {
  139.         TRACE( "Bad Seek in BackLines %ld\n", guess );
  140.         return -1;
  141.     }
  142.     END_CATCH
  143.  
  144.     if (guess != 0L)
  145.     {
  146.         ReadString( lpsz, nMax );       // skip forward to a line
  147.     }
  148.  
  149.     for ( i = 0; i < nLines; i++ )
  150.     {
  151.         lines[ i ] = -1L;
  152.     }
  153.  
  154.     for ( ; ; )
  155.     {
  156.         for ( i=MAXLINES-2; i > 0; i-- )
  157.         {
  158.             lines[ i ] = lines[ i - 1 ];
  159.         }
  160.  
  161.         lines[ 0 ] = GetPosition();
  162.  
  163.         if ( lines[0] >= m_lBeginLine )
  164.         {
  165.             break;
  166.         }
  167.  
  168.         ReadString( lpsz, nMax );       // skip forward a line
  169.     }
  170.  
  171.     for ( ; lines[ nLines ] == -1L; nLines-- );
  172.  
  173.     Seek( lines[ nLines ], CFile::begin );
  174.  
  175.     NextLine( lpsz, nMax );
  176.     m_lBeginLine = lines[ nLines ];
  177.  
  178.     return m_lBeginLine;
  179. }
  180.  
  181. //
  182. // read a line near some file offset
  183. //
  184.  
  185. LONG
  186. CLineFile::LineNear(char FAR* lpsz, UINT nMax, LONG  lOffset)
  187. {
  188.     TRY
  189.     {
  190.         Seek(lOffset, CFile::begin);
  191.     }
  192.     CATCH( CFileException, e )
  193.     {
  194.         TRACE("Bad Seek in LineNear %ld\n", lOffset);
  195.         return -1;
  196.     }
  197.     END_CATCH
  198.  
  199.     m_lBeginLine = NextLine(lpsz, nMax);    // find a real line
  200.  
  201.     return BackLines( lpsz, nMax, 1 );      // one just before it
  202. }
  203.