From 209a6979cefb8a2f401a26407d5c2280f20eaabe Mon Sep 17 00:00:00 2001 From: cxl Date: Fri, 20 Mar 2015 08:25:46 +0000 Subject: [PATCH] CtrlLib: TextCtrl::MaxLength handling improved git-svn-id: svn://ultimatepp.org/upp/trunk@8285 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlLib/Text.cpp | 17 +++++++++++++---- uppsrc/CtrlLib/TextEdit.h | 2 ++ uppsrc/CtrlLib/src.tpp/TextCtrl$en-us.tpp | 12 ++++++++++-- uppsrc/ide/idefile.cpp | 2 +- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/uppsrc/CtrlLib/Text.cpp b/uppsrc/CtrlLib/Text.cpp index c2ed471f2..a98c81c91 100644 --- a/uppsrc/CtrlLib/Text.cpp +++ b/uppsrc/CtrlLib/Text.cpp @@ -25,6 +25,7 @@ TextCtrl::TextCtrl() nobg = false; rectsel = false; max_total = 400 * 1024 * 1024; + truncated = false; } TextCtrl::~TextCtrl() {} @@ -53,6 +54,7 @@ void TextCtrl::Clear() { cline = cpos = 0; total = 0; + truncated = false; line.Clear(); line.Shrink(); ClearLines(); @@ -120,6 +122,7 @@ int TextCtrl::Load(Stream& in, byte charset) { } bool cr = false; byte b8 = 0; + truncated = true; if(charset == CHARSET_UTF8) for(;;) { byte h[200]; @@ -157,7 +160,7 @@ int TextCtrl::Load(Stream& in, byte charset) { LTIMING("ADD"); int len = (b8 & 0x80) ? utf8len(~ln, ln.GetCount()) : ln.GetCount(); if(total + len + 1 > max_total) - break; + goto out_of_limit; total += len + 1; Ln& l = line.Add(); l.len = len; @@ -197,7 +200,7 @@ int TextCtrl::Load(Stream& in, byte charset) { if(b < s) { LTIMING("ln.Cat"); if(b - s + ln.GetCount() > max_total) - break; + goto out_of_limit; ln.Cat((const char *)b, (const char *)s); } if(s < e) { @@ -208,14 +211,14 @@ int TextCtrl::Load(Stream& in, byte charset) { LTIMING("ToUnicode"); WString w = ToUnicode(~ln, ln.GetCount(), charset); if(total + w.GetLength() + 1 > max_total) - break; + goto out_of_limit; line.Add(w); total += w.GetLength() + 1; } else { LTIMING("ADD"); if(total + ln.GetCount() + 1 > max_total) - break; + goto out_of_limit; total += ln.GetCount() + 1; Ln& l = line.Add(); l.len = ln.GetCount(); @@ -230,6 +233,8 @@ int TextCtrl::Load(Stream& in, byte charset) { } } + truncated = false; +out_of_limit: WString w = ToUnicode(~ln, ln.GetCount(), charset); if(total + w.GetLength() <= max_total) { line.Add(w); @@ -239,10 +244,14 @@ int TextCtrl::Load(Stream& in, byte charset) { Update(); SetSb(); PlaceCaret(0); + if(truncated) + SetReadOnly(); return line.GetCount() > 1 ? cr ? LE_CRLF : LE_LF : LE_DEFAULT; } void TextCtrl::Save(Stream& s, byte charset, int line_endings) const { + if(truncated) + return; if(charset == CHARSET_UTF8_BOM) { static byte bom[] = { 0xEF, 0xBB, 0xBF }; s.Put(bom, 3); diff --git a/uppsrc/CtrlLib/TextEdit.h b/uppsrc/CtrlLib/TextEdit.h index 7a15ca650..e17374ba5 100644 --- a/uppsrc/CtrlLib/TextEdit.h +++ b/uppsrc/CtrlLib/TextEdit.h @@ -75,6 +75,7 @@ protected: int dirty; int undo_op; byte charset; + bool truncated; bool selclick; Point dropcaret; @@ -112,6 +113,7 @@ public: enum { LE_DEFAULT, LE_CRLF, LE_LF }; int Load(Stream& s, byte charset = CHARSET_DEFAULT); + bool IsTruncated() const { return false; } void Save(Stream& s, byte charset = CHARSET_DEFAULT, int line_endings = LE_DEFAULT) const; int GetInvalidCharPos(byte charset = CHARSET_DEFAULT) const; diff --git a/uppsrc/CtrlLib/src.tpp/TextCtrl$en-us.tpp b/uppsrc/CtrlLib/src.tpp/TextCtrl$en-us.tpp index afd03372b..cff66b90b 100644 --- a/uppsrc/CtrlLib/src.tpp/TextCtrl$en-us.tpp +++ b/uppsrc/CtrlLib/src.tpp/TextCtrl$en-us.tpp @@ -124,9 +124,17 @@ Unlikely to be used in the client code.&] ]_[*@3 s], [_^byte^ byte]_[*@3 charset]_`=_CHARSET`_DEFAULT)&] [s2;%% Loads the text from the stream with defined [%-*@3 charset]. Function returns the detected line endings mode `- LE`_CRLF, -LE`_LF or LE`_DEFAULT if there were no line endings in the file.&] +LE`_LF or LE`_DEFAULT if there were no line endings in the file. +If file is bigger then the limit set by MaxLength, editor is +put into `'truncated`' and read`-only mode.&] [s3;%% &] [s4; &] +[s5;:TextCtrl`:`:IsTruncated`(`)const: [@(0.0.255) bool]_[* IsTruncated]()_[@(0.0.255) cons +t]&] +[s2;%% Indicates that last Load had to truncate the size because +of MaxLength limit.&] +[s3; &] +[s4; &] [s5;:TextCtrl`:`:Save`(Stream`&`,byte`,int`)const: [@(0.0.255) void]_[* Save]([_^Stream^ St ream][@(0.0.255) `&]_[*@3 s], [_^byte^ byte]_[*@3 charset]_`=_CHARSET`_DEFAULT, [@(0.0.255) int]_[*@3 line`_endings]_`=_LE`_DEFAULT)_[@(0.0.255) const]&] @@ -135,7 +143,7 @@ that cannot be represented in suggested [%-*@3 charset] are saved as `'?`'. [%-*@3 line`_endings] parameter sets the line ending mode. LE`_DEFAULT uses platform specific line endings (CRLF in Windows, LF in POSIX), LE`_CRLF sets CRLF line endings, LE`_LF -sets LF line endings).&] +sets LF line endings). If IsTruncated is true, Save is blocked.&] [s3;%% &] [s4; &] [s5;:TextCtrl`:`:GetInvalidCharPos`(byte`)const: [@(0.0.255) int]_[* GetInvalidCharPos]([_^byte^ b diff --git a/uppsrc/ide/idefile.cpp b/uppsrc/ide/idefile.cpp index 2d27e03fd..318127920 100644 --- a/uppsrc/ide/idefile.cpp +++ b/uppsrc/ide/idefile.cpp @@ -531,7 +531,7 @@ void Ide::EditFile0(const String& path, byte charset, bool astext, const String& editor.SetPickUndoData(pick(fd.undodata)); editor.SetLineInfo(fd.lineinfo); editor.SetLineInfoRem(pick(fd.lineinforem)); - if(ff.IsReadOnly() || IsNestReadOnly(editfile)) { + if(ff.IsReadOnly() || IsNestReadOnly(editfile) || editor.IsTruncated()) { editor.SetReadOnly(); editor.NoShowReadOnly(); }