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()) {
61 // Prevent warnings by static analyzers about uninitialized buf and styleBuf.
66 encodingType
= encUnicode
;
73 encodingType
= encDBCS
;
76 char operator[](int position
) {
77 if (position
< startPos
|| position
>= endPos
) {
80 return buf
[position
- startPos
];
82 IDocumentWithLineEnd
*MultiByteAccess() const {
83 if (documentVersion
>= dvLineEnd
) {
84 return static_cast<IDocumentWithLineEnd
*>(pAccess
);
88 /** Safe version of operator[], returning a defined value for invalid position. */
89 char SafeGetCharAt(int position
, char chDefault
=' ') {
90 if (position
< startPos
|| position
>= endPos
) {
92 if (position
< startPos
|| position
>= endPos
) {
93 // Position is outside range of document
97 return buf
[position
- startPos
];
99 bool IsLeadByte(char ch
) const {
100 return pAccess
->IsDBCSLeadByte(ch
);
102 EncodingType
Encoding() const {
105 bool Match(int pos
, const char *s
) {
106 for (int i
=0; *s
; i
++) {
107 if (*s
!= SafeGetCharAt(pos
+i
))
113 char StyleAt(int position
) const {
114 return static_cast<char>(pAccess
->StyleAt(position
));
116 int GetLine(int position
) const {
117 return pAccess
->LineFromPosition(position
);
119 int LineStart(int line
) const {
120 return pAccess
->LineStart(line
);
122 int LineEnd(int line
) {
123 if (documentVersion
>= dvLineEnd
) {
124 return (static_cast<IDocumentWithLineEnd
*>(pAccess
))->LineEnd(line
);
126 // Old interface means only '\r', '\n' and '\r\n' line ends.
127 int startNext
= pAccess
->LineStart(line
+1);
128 char chLineEnd
= SafeGetCharAt(startNext
-1);
129 if (chLineEnd
== '\n' && (SafeGetCharAt(startNext
-2) == '\r'))
130 return startNext
- 2;
132 return startNext
- 1;
135 int LevelAt(int line
) const {
136 return pAccess
->GetLevel(line
);
143 pAccess
->SetStyles(validLen
, styleBuf
);
144 startPosStyling
+= validLen
;
148 int GetLineState(int line
) const {
149 return pAccess
->GetLineState(line
);
151 int SetLineState(int line
, int state
) {
152 return pAccess
->SetLineState(line
, state
);
155 void StartAt(unsigned int start
) {
156 pAccess
->StartStyling(start
, '\377');
157 startPosStyling
= start
;
159 unsigned int GetStartSegment() const {
162 void StartSegment(unsigned int pos
) {
165 void ColourTo(unsigned int pos
, int chAttr
) {
166 // Only perform styling if non empty range
167 if (pos
!= startSeg
- 1) {
168 assert(pos
>= startSeg
);
169 if (pos
< startSeg
) {
173 if (validLen
+ (pos
- startSeg
+ 1) >= bufferSize
)
175 if (validLen
+ (pos
- startSeg
+ 1) >= bufferSize
) {
176 // Too big for buffer so send directly
177 pAccess
->SetStyleFor(pos
- startSeg
+ 1, static_cast<char>(chAttr
));
179 for (unsigned int i
= startSeg
; i
<= pos
; i
++) {
180 assert((startPosStyling
+ validLen
) < Length());
181 styleBuf
[validLen
++] = static_cast<char>(chAttr
);
187 void SetLevel(int line
, int level
) {
188 pAccess
->SetLevel(line
, level
);
190 void IndicatorFill(int start
, int end
, int indicator
, int value
) {
191 pAccess
->DecorationSetCurrentIndicator(indicator
);
192 pAccess
->DecorationFillRange(start
, value
, end
- start
);
195 void ChangeLexerState(int start
, int end
) {
196 pAccess
->ChangeLexerState(start
, end
);