#ifndef GapText_First #define GapText_First #ifdef __GNUG__ #pragma interface #endif #include "Text.h" class RegularExp; class GapTextIter; extern const int cShrinkFactor, cMaxOutput; //---- GapText ----------------------------------------------------------------- class GapText: public Text { public: MetaDef(GapText); GapText(int s= cTextInitCap, Font *fd= gSysFont); GapText(const char *buf, int len= -1, Font *fd= gSysFont); GapText(const byte *buf, int len= -1, Font *fd= gSysFont); ~GapText(); void InitNew(); void GapTextInit(const char *buf, int len, Font *fd, int cap); //---- editing void CopyInStr(byte *str, int strsize, int from, int to); void ReplaceRange(int from, int to, Text *tsrc, int sfrom, int sto); //---- accessing const char *AsString(); byte& operator[](int i); int Size(); int Search(RegularExp *rex, int *nMatched, int start= 0, int range= cMaxInt, bool dir= cSearchForward); //---- iterators TextIter *MakeIterator(int from= 0, int to= cMaxInt, void *placement= 0); //---- TextPainter access byte *GetLineAccess(byte **buf, int from, int to); //---- TextReader access void AddChar(int at, byte b); //---- input/output OStream& PrintOn(OStream&); IStream& ReadFrom(IStream&); OStream& PrintOnAsPureText(OStream &s); IStream& ReadFromAsPureText(IStream &s, long sizeHint= -1); protected: byte CharAt(int i); void Terminate(); Text *MakeScratchText(byte *buf, int size); private: friend GapTextIter; int size; // size of allocated memory int length; // length of text int part1len; // length of text before gap int part2len; // redundant (for meta-info) int gaplen; // length of gap byte *body; // access to text before gap byte *part2body; // access to text behind gap byte *body2; // redundant (for meta-info) void Update(int l); void Init(int l, Font *fd); void Expand(int to= 0, int moveto= cMaxInt); void Shrink(int to= 0); void MoveGap(int to); void CopyTo(byte *dst, int from, int to); bool HighWaterMark(int n); bool LowWaterMark(); void CheckPtr(byte *ptr); }; inline bool GapText::HighWaterMark(int n) { return (body == 0) || (gaplen <= n); } inline bool GapText::LowWaterMark() { return (size / 5) > length; } inline byte GapText::CharAt(int i) { return (i < part1len ? body : part2body)[i]; } //---- GapTextIter ------------------------------------------------------------- class GapTextIter: public TextIter { int nextFontChange; byte escape; GapText *st; CharStyle *sp; bool TestFontChange(int at, CharStyle *&sp); int GraphicSize(int at, LineDesc *l); byte CharAt(int i); bool TestFontChange(CharStyle *&sp); bool TestVisualMark(int at, int ch); public: GapTextIter(Text *s, int from= 0, int to= cMaxInt); void Reset(Text *s, int from= 0, int to= cMaxInt); int operator()(int *width= 0, LineDesc *ld= 0); int Token(int *width, LineDesc*); // returns next token with its extent }; inline byte GapTextIter::CharAt(int i) { return st->CharAt(i); } inline bool GapTextIter::TestFontChange(CharStyle *&s) { if (ce == nextFontChange) { nextFontChange= st->GetNextFontChange(ce, s); return TRUE; } else return FALSE; } inline bool GapTextIter::TestVisualMark(int at, int ch) { return (bool) (ch == escape && st->IsVisualMark(at)); } #endif