xref: /MusicPlayer2/scintilla/lexlib/LexAccessor.h (revision 8af74909132ed5e696cb05b6689ae4baf14c1c96)
1*8af74909SZhong Yang // Scintilla source code edit control
2*8af74909SZhong Yang /** @file LexAccessor.h
3*8af74909SZhong Yang  ** Interfaces between Scintilla and lexers.
4*8af74909SZhong Yang  **/
5*8af74909SZhong Yang // Copyright 1998-2010 by Neil Hodgson <[email protected]>
6*8af74909SZhong Yang // The License.txt file describes the conditions under which this software may be distributed.
7*8af74909SZhong Yang 
8*8af74909SZhong Yang #ifndef LEXACCESSOR_H
9*8af74909SZhong Yang #define LEXACCESSOR_H
10*8af74909SZhong Yang 
11*8af74909SZhong Yang namespace Scintilla {
12*8af74909SZhong Yang 
13*8af74909SZhong Yang enum class EncodingType { eightBit, unicode, dbcs };
14*8af74909SZhong Yang 
15*8af74909SZhong Yang class LexAccessor {
16*8af74909SZhong Yang private:
17*8af74909SZhong Yang 	IDocument *pAccess;
18*8af74909SZhong Yang 	enum {extremePosition=0x7FFFFFFF};
19*8af74909SZhong Yang 	/** @a bufferSize is a trade off between time taken to copy the characters
20*8af74909SZhong Yang 	 * and retrieval overhead.
21*8af74909SZhong Yang 	 * @a slopSize positions the buffer before the desired position
22*8af74909SZhong Yang 	 * in case there is some backtracking. */
23*8af74909SZhong Yang 	enum {bufferSize=4000, slopSize=bufferSize/8};
24*8af74909SZhong Yang 	char buf[bufferSize+1];
25*8af74909SZhong Yang 	Sci_Position startPos;
26*8af74909SZhong Yang 	Sci_Position endPos;
27*8af74909SZhong Yang 	int codePage;
28*8af74909SZhong Yang 	enum EncodingType encodingType;
29*8af74909SZhong Yang 	Sci_Position lenDoc;
30*8af74909SZhong Yang 	char styleBuf[bufferSize];
31*8af74909SZhong Yang 	Sci_Position validLen;
32*8af74909SZhong Yang 	Sci_PositionU startSeg;
33*8af74909SZhong Yang 	Sci_Position startPosStyling;
34*8af74909SZhong Yang 	int documentVersion;
35*8af74909SZhong Yang 
Fill(Sci_Position position)36*8af74909SZhong Yang 	void Fill(Sci_Position position) {
37*8af74909SZhong Yang 		startPos = position - slopSize;
38*8af74909SZhong Yang 		if (startPos + bufferSize > lenDoc)
39*8af74909SZhong Yang 			startPos = lenDoc - bufferSize;
40*8af74909SZhong Yang 		if (startPos < 0)
41*8af74909SZhong Yang 			startPos = 0;
42*8af74909SZhong Yang 		endPos = startPos + bufferSize;
43*8af74909SZhong Yang 		if (endPos > lenDoc)
44*8af74909SZhong Yang 			endPos = lenDoc;
45*8af74909SZhong Yang 
46*8af74909SZhong Yang 		pAccess->GetCharRange(buf, startPos, endPos-startPos);
47*8af74909SZhong Yang 		buf[endPos-startPos] = '\0';
48*8af74909SZhong Yang 	}
49*8af74909SZhong Yang 
50*8af74909SZhong Yang public:
LexAccessor(IDocument * pAccess_)51*8af74909SZhong Yang 	explicit LexAccessor(IDocument *pAccess_) :
52*8af74909SZhong Yang 		pAccess(pAccess_), startPos(extremePosition), endPos(0),
53*8af74909SZhong Yang 		codePage(pAccess->CodePage()),
54*8af74909SZhong Yang 		encodingType(EncodingType::eightBit),
55*8af74909SZhong Yang 		lenDoc(pAccess->Length()),
56*8af74909SZhong Yang 		validLen(0),
57*8af74909SZhong Yang 		startSeg(0), startPosStyling(0),
58*8af74909SZhong Yang 		documentVersion(pAccess->Version()) {
59*8af74909SZhong Yang 		// Prevent warnings by static analyzers about uninitialized buf and styleBuf.
60*8af74909SZhong Yang 		buf[0] = 0;
61*8af74909SZhong Yang 		styleBuf[0] = 0;
62*8af74909SZhong Yang 		switch (codePage) {
63*8af74909SZhong Yang 		case 65001:
64*8af74909SZhong Yang 			encodingType = EncodingType::unicode;
65*8af74909SZhong Yang 			break;
66*8af74909SZhong Yang 		case 932:
67*8af74909SZhong Yang 		case 936:
68*8af74909SZhong Yang 		case 949:
69*8af74909SZhong Yang 		case 950:
70*8af74909SZhong Yang 		case 1361:
71*8af74909SZhong Yang 			encodingType = EncodingType::dbcs;
72*8af74909SZhong Yang 		}
73*8af74909SZhong Yang 	}
74*8af74909SZhong Yang 	char operator[](Sci_Position position) {
75*8af74909SZhong Yang 		if (position < startPos || position >= endPos) {
76*8af74909SZhong Yang 			Fill(position);
77*8af74909SZhong Yang 		}
78*8af74909SZhong Yang 		return buf[position - startPos];
79*8af74909SZhong Yang 	}
MultiByteAccess()80*8af74909SZhong Yang 	IDocument *MultiByteAccess() const noexcept {
81*8af74909SZhong Yang 		return pAccess;
82*8af74909SZhong Yang 	}
83*8af74909SZhong Yang 	/** Safe version of operator[], returning a defined value for invalid position. */
84*8af74909SZhong Yang 	char SafeGetCharAt(Sci_Position position, char chDefault=' ') {
85*8af74909SZhong Yang 		if (position < startPos || position >= endPos) {
86*8af74909SZhong Yang 			Fill(position);
87*8af74909SZhong Yang 			if (position < startPos || position >= endPos) {
88*8af74909SZhong Yang 				// Position is outside range of document
89*8af74909SZhong Yang 				return chDefault;
90*8af74909SZhong Yang 			}
91*8af74909SZhong Yang 		}
92*8af74909SZhong Yang 		return buf[position - startPos];
93*8af74909SZhong Yang 	}
IsLeadByte(char ch)94*8af74909SZhong Yang 	bool IsLeadByte(char ch) const {
95*8af74909SZhong Yang 		return pAccess->IsDBCSLeadByte(ch);
96*8af74909SZhong Yang 	}
Encoding()97*8af74909SZhong Yang 	EncodingType Encoding() const noexcept {
98*8af74909SZhong Yang 		return encodingType;
99*8af74909SZhong Yang 	}
Match(Sci_Position pos,const char * s)100*8af74909SZhong Yang 	bool Match(Sci_Position pos, const char *s) {
101*8af74909SZhong Yang 		for (int i=0; *s; i++) {
102*8af74909SZhong Yang 			if (*s != SafeGetCharAt(pos+i))
103*8af74909SZhong Yang 				return false;
104*8af74909SZhong Yang 			s++;
105*8af74909SZhong Yang 		}
106*8af74909SZhong Yang 		return true;
107*8af74909SZhong Yang 	}
StyleAt(Sci_Position position)108*8af74909SZhong Yang 	char StyleAt(Sci_Position position) const {
109*8af74909SZhong Yang 		return pAccess->StyleAt(position);
110*8af74909SZhong Yang 	}
GetLine(Sci_Position position)111*8af74909SZhong Yang 	Sci_Position GetLine(Sci_Position position) const {
112*8af74909SZhong Yang 		return pAccess->LineFromPosition(position);
113*8af74909SZhong Yang 	}
LineStart(Sci_Position line)114*8af74909SZhong Yang 	Sci_Position LineStart(Sci_Position line) const {
115*8af74909SZhong Yang 		return pAccess->LineStart(line);
116*8af74909SZhong Yang 	}
LineEnd(Sci_Position line)117*8af74909SZhong Yang 	Sci_Position LineEnd(Sci_Position line) const {
118*8af74909SZhong Yang 		return pAccess->LineEnd(line);
119*8af74909SZhong Yang 	}
LevelAt(Sci_Position line)120*8af74909SZhong Yang 	int LevelAt(Sci_Position line) const {
121*8af74909SZhong Yang 		return pAccess->GetLevel(line);
122*8af74909SZhong Yang 	}
Length()123*8af74909SZhong Yang 	Sci_Position Length() const {
124*8af74909SZhong Yang 		return lenDoc;
125*8af74909SZhong Yang 	}
Flush()126*8af74909SZhong Yang 	void Flush() {
127*8af74909SZhong Yang 		if (validLen > 0) {
128*8af74909SZhong Yang 			pAccess->SetStyles(validLen, styleBuf);
129*8af74909SZhong Yang 			startPosStyling += validLen;
130*8af74909SZhong Yang 			validLen = 0;
131*8af74909SZhong Yang 		}
132*8af74909SZhong Yang 	}
GetLineState(Sci_Position line)133*8af74909SZhong Yang 	int GetLineState(Sci_Position line) const {
134*8af74909SZhong Yang 		return pAccess->GetLineState(line);
135*8af74909SZhong Yang 	}
SetLineState(Sci_Position line,int state)136*8af74909SZhong Yang 	int SetLineState(Sci_Position line, int state) {
137*8af74909SZhong Yang 		return pAccess->SetLineState(line, state);
138*8af74909SZhong Yang 	}
139*8af74909SZhong Yang 	// Style setting
StartAt(Sci_PositionU start)140*8af74909SZhong Yang 	void StartAt(Sci_PositionU start) {
141*8af74909SZhong Yang 		pAccess->StartStyling(start);
142*8af74909SZhong Yang 		startPosStyling = start;
143*8af74909SZhong Yang 	}
GetStartSegment()144*8af74909SZhong Yang 	Sci_PositionU GetStartSegment() const {
145*8af74909SZhong Yang 		return startSeg;
146*8af74909SZhong Yang 	}
StartSegment(Sci_PositionU pos)147*8af74909SZhong Yang 	void StartSegment(Sci_PositionU pos) {
148*8af74909SZhong Yang 		startSeg = pos;
149*8af74909SZhong Yang 	}
ColourTo(Sci_PositionU pos,int chAttr)150*8af74909SZhong Yang 	void ColourTo(Sci_PositionU pos, int chAttr) {
151*8af74909SZhong Yang 		// Only perform styling if non empty range
152*8af74909SZhong Yang 		if (pos != startSeg - 1) {
153*8af74909SZhong Yang 			assert(pos >= startSeg);
154*8af74909SZhong Yang 			if (pos < startSeg) {
155*8af74909SZhong Yang 				return;
156*8af74909SZhong Yang 			}
157*8af74909SZhong Yang 
158*8af74909SZhong Yang 			if (validLen + (pos - startSeg + 1) >= bufferSize)
159*8af74909SZhong Yang 				Flush();
160*8af74909SZhong Yang 			const char attr = static_cast<char>(chAttr);
161*8af74909SZhong Yang 			if (validLen + (pos - startSeg + 1) >= bufferSize) {
162*8af74909SZhong Yang 				// Too big for buffer so send directly
163*8af74909SZhong Yang 				pAccess->SetStyleFor(pos - startSeg + 1, attr);
164*8af74909SZhong Yang 			} else {
165*8af74909SZhong Yang 				for (Sci_PositionU i = startSeg; i <= pos; i++) {
166*8af74909SZhong Yang 					assert((startPosStyling + validLen) < Length());
167*8af74909SZhong Yang 					styleBuf[validLen++] = attr;
168*8af74909SZhong Yang 				}
169*8af74909SZhong Yang 			}
170*8af74909SZhong Yang 		}
171*8af74909SZhong Yang 		startSeg = pos+1;
172*8af74909SZhong Yang 	}
SetLevel(Sci_Position line,int level)173*8af74909SZhong Yang 	void SetLevel(Sci_Position line, int level) {
174*8af74909SZhong Yang 		pAccess->SetLevel(line, level);
175*8af74909SZhong Yang 	}
IndicatorFill(Sci_Position start,Sci_Position end,int indicator,int value)176*8af74909SZhong Yang 	void IndicatorFill(Sci_Position start, Sci_Position end, int indicator, int value) {
177*8af74909SZhong Yang 		pAccess->DecorationSetCurrentIndicator(indicator);
178*8af74909SZhong Yang 		pAccess->DecorationFillRange(start, value, end - start);
179*8af74909SZhong Yang 	}
180*8af74909SZhong Yang 
ChangeLexerState(Sci_Position start,Sci_Position end)181*8af74909SZhong Yang 	void ChangeLexerState(Sci_Position start, Sci_Position end) {
182*8af74909SZhong Yang 		pAccess->ChangeLexerState(start, end);
183*8af74909SZhong Yang 	}
184*8af74909SZhong Yang };
185*8af74909SZhong Yang 
186*8af74909SZhong Yang struct LexicalClass {
187*8af74909SZhong Yang 	int value;
188*8af74909SZhong Yang 	const char *name;
189*8af74909SZhong Yang 	const char *tags;
190*8af74909SZhong Yang 	const char *description;
191*8af74909SZhong Yang };
192*8af74909SZhong Yang 
193*8af74909SZhong Yang }
194*8af74909SZhong Yang 
195*8af74909SZhong Yang #endif
196