|
|
1.1 root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.