Update Scintilla to version 3.4.4
[TortoiseGit.git] / ext / scintilla / lexlib / LexAccessor.h
blob248f1c54bb0571eca6c9181bac5b48ba2f437d7b
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.
8 #ifndef LEXACCESSOR_H
9 #define LEXACCESSOR_H
11 #ifdef SCI_NAMESPACE
12 namespace Scintilla {
13 #endif
15 enum EncodingType { enc8bit, encUnicode, encDBCS };
17 class LexAccessor {
18 private:
19 IDocument *pAccess;
20 enum {extremePosition=0x7FFFFFFF};
21 /** @a bufferSize is a trade off between time taken to copy the characters
22 * and retrieval overhead.
23 * @a slopSize positions the buffer before the desired position
24 * in case there is some backtracking. */
25 enum {bufferSize=4000, slopSize=bufferSize/8};
26 char buf[bufferSize+1];
27 int startPos;
28 int endPos;
29 int codePage;
30 enum EncodingType encodingType;
31 int lenDoc;
32 char styleBuf[bufferSize];
33 int validLen;
34 unsigned int startSeg;
35 int startPosStyling;
36 int documentVersion;
38 void Fill(int position) {
39 startPos = position - slopSize;
40 if (startPos + bufferSize > lenDoc)
41 startPos = lenDoc - bufferSize;
42 if (startPos < 0)
43 startPos = 0;
44 endPos = startPos + bufferSize;
45 if (endPos > lenDoc)
46 endPos = lenDoc;
48 pAccess->GetCharRange(buf, startPos, endPos-startPos);
49 buf[endPos-startPos] = '\0';
52 public:
53 explicit LexAccessor(IDocument *pAccess_) :
54 pAccess(pAccess_), startPos(extremePosition), endPos(0),
55 codePage(pAccess->CodePage()),
56 encodingType(enc8bit),
57 lenDoc(pAccess->Length()),
58 validLen(0),
59 startSeg(0), startPosStyling(0),
60 documentVersion(pAccess->Version()) {
61 switch (codePage) {
62 case 65001:
63 encodingType = encUnicode;
64 break;
65 case 932:
66 case 936:
67 case 949:
68 case 950:
69 case 1361:
70 encodingType = encDBCS;
73 char operator[](int position) {
74 if (position < startPos || position >= endPos) {
75 Fill(position);
77 return buf[position - startPos];
79 IDocumentWithLineEnd *MultiByteAccess() const {
80 if (documentVersion >= dvLineEnd) {
81 return static_cast<IDocumentWithLineEnd *>(pAccess);
83 return 0;
85 /** Safe version of operator[], returning a defined value for invalid position. */
86 char SafeGetCharAt(int position, char chDefault=' ') {
87 if (position < startPos || position >= endPos) {
88 Fill(position);
89 if (position < startPos || position >= endPos) {
90 // Position is outside range of document
91 return chDefault;
94 return buf[position - startPos];
96 bool IsLeadByte(char ch) const {
97 return pAccess->IsDBCSLeadByte(ch);
99 EncodingType Encoding() const {
100 return encodingType;
102 bool Match(int pos, const char *s) {
103 for (int i=0; *s; i++) {
104 if (*s != SafeGetCharAt(pos+i))
105 return false;
106 s++;
108 return true;
110 char StyleAt(int position) const {
111 return static_cast<char>(pAccess->StyleAt(position));
113 int GetLine(int position) const {
114 return pAccess->LineFromPosition(position);
116 int LineStart(int line) const {
117 return pAccess->LineStart(line);
119 int LineEnd(int line) {
120 if (documentVersion >= dvLineEnd) {
121 return (static_cast<IDocumentWithLineEnd *>(pAccess))->LineEnd(line);
122 } else {
123 // Old interface means only '\r', '\n' and '\r\n' line ends.
124 int startNext = pAccess->LineStart(line+1);
125 char chLineEnd = SafeGetCharAt(startNext-1);
126 if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r'))
127 return startNext - 2;
128 else
129 return startNext - 1;
132 int LevelAt(int line) const {
133 return pAccess->GetLevel(line);
135 int Length() const {
136 return lenDoc;
138 void Flush() {
139 if (validLen > 0) {
140 pAccess->SetStyles(validLen, styleBuf);
141 startPosStyling += validLen;
142 validLen = 0;
145 int GetLineState(int line) const {
146 return pAccess->GetLineState(line);
148 int SetLineState(int line, int state) {
149 return pAccess->SetLineState(line, state);
151 // Style setting
152 void StartAt(unsigned int start) {
153 pAccess->StartStyling(start, '\377');
154 startPosStyling = start;
156 unsigned int GetStartSegment() const {
157 return startSeg;
159 void StartSegment(unsigned int pos) {
160 startSeg = pos;
162 void ColourTo(unsigned int pos, int chAttr) {
163 // Only perform styling if non empty range
164 if (pos != startSeg - 1) {
165 assert(pos >= startSeg);
166 if (pos < startSeg) {
167 return;
170 if (validLen + (pos - startSeg + 1) >= bufferSize)
171 Flush();
172 if (validLen + (pos - startSeg + 1) >= bufferSize) {
173 // Too big for buffer so send directly
174 pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
175 } else {
176 for (unsigned int i = startSeg; i <= pos; i++) {
177 assert((startPosStyling + validLen) < Length());
178 styleBuf[validLen++] = static_cast<char>(chAttr);
182 startSeg = pos+1;
184 void SetLevel(int line, int level) {
185 pAccess->SetLevel(line, level);
187 void IndicatorFill(int start, int end, int indicator, int value) {
188 pAccess->DecorationSetCurrentIndicator(indicator);
189 pAccess->DecorationFillRange(start, value, end - start);
192 void ChangeLexerState(int start, int end) {
193 pAccess->ChangeLexerState(start, end);
197 #ifdef SCI_NAMESPACE
199 #endif
201 #endif