1 // Scintilla source code edit control
2 /** @file LexAccessor.h
3 ** Interfaces between Scintilla and lexers.
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.
15 enum EncodingType
{ enc8bit
, encUnicode
, encDBCS
};
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];
30 enum EncodingType encodingType
;
32 char styleBuf
[bufferSize
];
34 unsigned int startSeg
;
38 void Fill(int position
) {
39 startPos
= position
- slopSize
;
40 if (startPos
+ bufferSize
> lenDoc
)
41 startPos
= lenDoc
- bufferSize
;
44 endPos
= startPos
+ bufferSize
;
48 pAccess
->GetCharRange(buf
, startPos
, endPos
-startPos
);
49 buf
[endPos
-startPos
] = '\0';
53 explicit LexAccessor(IDocument
*pAccess_
) :
54 pAccess(pAccess_
), startPos(extremePosition
), endPos(0),
55 codePage(pAccess
->CodePage()),
56 encodingType(enc8bit
),
57 lenDoc(pAccess
->Length()),
59 startSeg(0), startPosStyling(0),
60 documentVersion(pAccess
->Version()) {
63 encodingType
= encUnicode
;
70 encodingType
= encDBCS
;
73 char operator[](int position
) {
74 if (position
< startPos
|| position
>= endPos
) {
77 return buf
[position
- startPos
];
79 IDocumentWithLineEnd
*MultiByteAccess() const {
80 if (documentVersion
>= dvLineEnd
) {
81 return static_cast<IDocumentWithLineEnd
*>(pAccess
);
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
) {
89 if (position
< startPos
|| position
>= endPos
) {
90 // Position is outside range of document
94 return buf
[position
- startPos
];
96 bool IsLeadByte(char ch
) const {
97 return pAccess
->IsDBCSLeadByte(ch
);
99 EncodingType
Encoding() const {
102 bool Match(int pos
, const char *s
) {
103 for (int i
=0; *s
; i
++) {
104 if (*s
!= SafeGetCharAt(pos
+i
))
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
);
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;
129 return startNext
- 1;
132 int LevelAt(int line
) const {
133 return pAccess
->GetLevel(line
);
140 pAccess
->SetStyles(validLen
, styleBuf
);
141 startPosStyling
+= validLen
;
145 int GetLineState(int line
) const {
146 return pAccess
->GetLineState(line
);
148 int SetLineState(int line
, int state
) {
149 return pAccess
->SetLineState(line
, state
);
152 void StartAt(unsigned int start
) {
153 pAccess
->StartStyling(start
, '\377');
154 startPosStyling
= start
;
156 unsigned int GetStartSegment() const {
159 void StartSegment(unsigned int 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
) {
170 if (validLen
+ (pos
- startSeg
+ 1) >= bufferSize
)
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
));
176 for (unsigned int i
= startSeg
; i
<= pos
; i
++) {
177 assert((startPosStyling
+ validLen
) < Length());
178 styleBuf
[validLen
++] = static_cast<char>(chAttr
);
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
);