]> git.saurik.com Git - wxWidgets.git/blob - src/stc/scintilla/lexlib/LexAccessor.h
simplify code so it always returns the same object
[wxWidgets.git] / src / stc / scintilla / lexlib / LexAccessor.h
1 // Scintilla source code edit control
2 /** @file LexAccessor.h
3 ** Interfaces between Scintilla and lexers.
4 **/
5 // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
6 // The License.txt file describes the conditions under which this software may be distributed.
7
8 #ifndef LEXACCESSOR_H
9 #define LEXACCESSOR_H
10
11 #ifdef SCI_NAMESPACE
12 namespace Scintilla {
13 #endif
14
15 class LexAccessor {
16 private:
17 IDocument *pAccess;
18 enum {extremePosition=0x7FFFFFFF};
19 /** @a bufferSize is a trade off between time taken to copy the characters
20 * and retrieval overhead.
21 * @a slopSize positions the buffer before the desired position
22 * in case there is some backtracking. */
23 enum {bufferSize=4000, slopSize=bufferSize/8};
24 char buf[bufferSize+1];
25 int startPos;
26 int endPos;
27 int codePage;
28 int lenDoc;
29 int mask;
30 char styleBuf[bufferSize];
31 int validLen;
32 char chFlags;
33 char chWhile;
34 unsigned int startSeg;
35 int startPosStyling;
36
37 void Fill(int position) {
38 startPos = position - slopSize;
39 if (startPos + bufferSize > lenDoc)
40 startPos = lenDoc - bufferSize;
41 if (startPos < 0)
42 startPos = 0;
43 endPos = startPos + bufferSize;
44 if (endPos > lenDoc)
45 endPos = lenDoc;
46
47 pAccess->GetCharRange(buf, startPos, endPos-startPos);
48 buf[endPos-startPos] = '\0';
49 }
50
51 public:
52 LexAccessor(IDocument *pAccess_) :
53 pAccess(pAccess_), startPos(extremePosition), endPos(0),
54 codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
55 mask(127), validLen(0), chFlags(0), chWhile(0),
56 startSeg(0), startPosStyling(0) {
57 }
58 char operator[](int position) {
59 if (position < startPos || position >= endPos) {
60 Fill(position);
61 }
62 return buf[position - startPos];
63 }
64 /** Safe version of operator[], returning a defined value for invalid position. */
65 char SafeGetCharAt(int position, char chDefault=' ') {
66 if (position < startPos || position >= endPos) {
67 Fill(position);
68 if (position < startPos || position >= endPos) {
69 // Position is outside range of document
70 return chDefault;
71 }
72 }
73 return buf[position - startPos];
74 }
75 bool IsLeadByte(char ch) {
76 return pAccess->IsDBCSLeadByte(ch);
77 }
78
79 bool Match(int pos, const char *s) {
80 for (int i=0; *s; i++) {
81 if (*s != SafeGetCharAt(pos+i))
82 return false;
83 s++;
84 }
85 return true;
86 }
87 char StyleAt(int position) {
88 return static_cast<char>(pAccess->StyleAt(position) & mask);
89 }
90 int GetLine(int position) {
91 return pAccess->LineFromPosition(position);
92 }
93 int LineStart(int line) {
94 return pAccess->LineStart(line);
95 }
96 int LevelAt(int line) {
97 return pAccess->GetLevel(line);
98 }
99 int Length() const {
100 return lenDoc;
101 }
102 void Flush() {
103 startPos = extremePosition;
104 if (validLen > 0) {
105 pAccess->SetStyles(validLen, styleBuf);
106 startPosStyling += validLen;
107 validLen = 0;
108 }
109 }
110 int GetLineState(int line) {
111 return pAccess->GetLineState(line);
112 }
113 int SetLineState(int line, int state) {
114 return pAccess->SetLineState(line, state);
115 }
116 // Style setting
117 void StartAt(unsigned int start, char chMask=31) {
118 // Store the mask specified for use with StyleAt.
119 mask = chMask;
120 pAccess->StartStyling(start, chMask);
121 startPosStyling = start;
122 }
123 void SetFlags(char chFlags_, char chWhile_) {
124 chFlags = chFlags_;
125 chWhile = chWhile_;
126 }
127 unsigned int GetStartSegment() const {
128 return startSeg;
129 }
130 void StartSegment(unsigned int pos) {
131 startSeg = pos;
132 }
133 void ColourTo(unsigned int pos, int chAttr) {
134 // Only perform styling if non empty range
135 if (pos != startSeg - 1) {
136 assert(pos >= startSeg);
137 if (pos < startSeg) {
138 return;
139 }
140
141 if (validLen + (pos - startSeg + 1) >= bufferSize)
142 Flush();
143 if (validLen + (pos - startSeg + 1) >= bufferSize) {
144 // Too big for buffer so send directly
145 pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
146 } else {
147 if (chAttr != chWhile)
148 chFlags = 0;
149 chAttr = static_cast<char>(chAttr | chFlags);
150 for (unsigned int i = startSeg; i <= pos; i++) {
151 assert((startPosStyling + validLen) < Length());
152 styleBuf[validLen++] = static_cast<char>(chAttr);
153 }
154 }
155 }
156 startSeg = pos+1;
157 }
158 void SetLevel(int line, int level) {
159 pAccess->SetLevel(line, level);
160 }
161 void IndicatorFill(int start, int end, int indicator, int value) {
162 pAccess->DecorationSetCurrentIndicator(indicator);
163 pAccess->DecorationFillRange(start, value, end - start);
164 }
165
166 void ChangeLexerState(int start, int end) {
167 pAccess->ChangeLexerState(start, end);
168 }
169 };
170
171 #ifdef SCI_NAMESPACE
172 }
173 #endif
174
175 #endif