123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205 |
- // Scintilla source code edit control
- /** @file LexAccessor.h
- ** Interfaces between Scintilla and lexers.
- **/
- // Copyright 1998-2010 by Neil Hodgson <neilh@scintilla.org>
- // The License.txt file describes the conditions under which this software may be distributed.
- #ifndef LEXACCESSOR_H
- #define LEXACCESSOR_H
- #ifdef SCI_NAMESPACE
- namespace Scintilla {
- #endif
- enum EncodingType { enc8bit, encUnicode, encDBCS };
- class LexAccessor {
- private:
- IDocument *pAccess;
- enum {extremePosition=0x7FFFFFFF};
- /** @a bufferSize is a trade off between time taken to copy the characters
- * and retrieval overhead.
- * @a slopSize positions the buffer before the desired position
- * in case there is some backtracking. */
- enum {bufferSize=4000, slopSize=bufferSize/8};
- char buf[bufferSize+1];
- Sci_Position startPos;
- Sci_Position endPos;
- int codePage;
- enum EncodingType encodingType;
- Sci_Position lenDoc;
- char styleBuf[bufferSize];
- Sci_Position validLen;
- Sci_PositionU startSeg;
- Sci_Position startPosStyling;
- int documentVersion;
- void Fill(Sci_Position position) {
- startPos = position - slopSize;
- if (startPos + bufferSize > lenDoc)
- startPos = lenDoc - bufferSize;
- if (startPos < 0)
- startPos = 0;
- endPos = startPos + bufferSize;
- if (endPos > lenDoc)
- endPos = lenDoc;
- pAccess->GetCharRange(buf, startPos, endPos-startPos);
- buf[endPos-startPos] = '\0';
- }
- public:
- explicit LexAccessor(IDocument *pAccess_) :
- pAccess(pAccess_), startPos(extremePosition), endPos(0),
- codePage(pAccess->CodePage()),
- encodingType(enc8bit),
- lenDoc(pAccess->Length()),
- validLen(0),
- startSeg(0), startPosStyling(0),
- documentVersion(pAccess->Version()) {
- // Prevent warnings by static analyzers about uninitialized buf and styleBuf.
- buf[0] = 0;
- styleBuf[0] = 0;
- switch (codePage) {
- case 65001:
- encodingType = encUnicode;
- break;
- case 932:
- case 936:
- case 949:
- case 950:
- case 1361:
- encodingType = encDBCS;
- }
- }
- char operator[](Sci_Position position) {
- if (position < startPos || position >= endPos) {
- Fill(position);
- }
- return buf[position - startPos];
- }
- IDocumentWithLineEnd *MultiByteAccess() const {
- if (documentVersion >= dvLineEnd) {
- return static_cast<IDocumentWithLineEnd *>(pAccess);
- }
- return 0;
- }
- /** Safe version of operator[], returning a defined value for invalid position. */
- char SafeGetCharAt(Sci_Position position, char chDefault=' ') {
- if (position < startPos || position >= endPos) {
- Fill(position);
- if (position < startPos || position >= endPos) {
- // Position is outside range of document
- return chDefault;
- }
- }
- return buf[position - startPos];
- }
- bool IsLeadByte(char ch) const {
- return pAccess->IsDBCSLeadByte(ch);
- }
- EncodingType Encoding() const {
- return encodingType;
- }
- bool Match(Sci_Position pos, const char *s) {
- for (int i=0; *s; i++) {
- if (*s != SafeGetCharAt(pos+i))
- return false;
- s++;
- }
- return true;
- }
- char StyleAt(Sci_Position position) const {
- return static_cast<char>(pAccess->StyleAt(position));
- }
- Sci_Position GetLine(Sci_Position position) const {
- return pAccess->LineFromPosition(position);
- }
- Sci_Position LineStart(Sci_Position line) const {
- return pAccess->LineStart(line);
- }
- Sci_Position LineEnd(Sci_Position line) {
- if (documentVersion >= dvLineEnd) {
- return (static_cast<IDocumentWithLineEnd *>(pAccess))->LineEnd(line);
- } else {
- // Old interface means only '\r', '\n' and '\r\n' line ends.
- Sci_Position startNext = pAccess->LineStart(line+1);
- char chLineEnd = SafeGetCharAt(startNext-1);
- if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r'))
- return startNext - 2;
- else
- return startNext - 1;
- }
- }
- int LevelAt(Sci_Position line) const {
- return pAccess->GetLevel(line);
- }
- Sci_Position Length() const {
- return lenDoc;
- }
- void Flush() {
- if (validLen > 0) {
- pAccess->SetStyles(validLen, styleBuf);
- startPosStyling += validLen;
- validLen = 0;
- }
- }
- int GetLineState(Sci_Position line) const {
- return pAccess->GetLineState(line);
- }
- int SetLineState(Sci_Position line, int state) {
- return pAccess->SetLineState(line, state);
- }
- // Style setting
- void StartAt(Sci_PositionU start) {
- pAccess->StartStyling(start, '\377');
- startPosStyling = start;
- }
- Sci_PositionU GetStartSegment() const {
- return startSeg;
- }
- void StartSegment(Sci_PositionU pos) {
- startSeg = pos;
- }
- void ColourTo(Sci_PositionU pos, int chAttr) {
- // Only perform styling if non empty range
- if (pos != startSeg - 1) {
- assert(pos >= startSeg);
- if (pos < startSeg) {
- return;
- }
- if (validLen + (pos - startSeg + 1) >= bufferSize)
- Flush();
- if (validLen + (pos - startSeg + 1) >= bufferSize) {
- // Too big for buffer so send directly
- pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
- } else {
- for (Sci_PositionU i = startSeg; i <= pos; i++) {
- assert((startPosStyling + validLen) < Length());
- styleBuf[validLen++] = static_cast<char>(chAttr);
- }
- }
- }
- startSeg = pos+1;
- }
- void SetLevel(Sci_Position line, int level) {
- pAccess->SetLevel(line, level);
- }
- void IndicatorFill(Sci_Position start, Sci_Position end, int indicator, int value) {
- pAccess->DecorationSetCurrentIndicator(indicator);
- pAccess->DecorationFillRange(start, value, end - start);
- }
- void ChangeLexerState(Sci_Position start, Sci_Position end) {
- pAccess->ChangeLexerState(start, end);
- }
- };
- #ifdef SCI_NAMESPACE
- }
- #endif
- #endif
|