diff --git a/autotest/itos/itos.cpp b/autotest/itos/itos.cpp index 75a40df06..60328c850 100644 --- a/autotest/itos/itos.cpp +++ b/autotest/itos/itos.cpp @@ -47,8 +47,8 @@ CONSOLE_APP_MAIN } } for(int i = 0; i < 1000000; i++) - Test(Random64()); - + Test(Random()); + Test((int)Null); Test((int64)Null); diff --git a/uppsrc/Core/Convert.hpp b/uppsrc/Core/Convert.hpp index 1327d1492..ba294a72e 100644 --- a/uppsrc/Core/Convert.hpp +++ b/uppsrc/Core/Convert.hpp @@ -124,13 +124,13 @@ const CHAR *ScanInt(INT& result, const CHAR *s) inline String FormatUnsigned(dword w) { - return String::MakeSmall([&](char *s) { return utoa32(w, s); }); + return String::Make(12, [&](char *s) { return utoa32(w, s); }); } inline String FormatInt(int i) { - return String::MakeSmall([&](char *s) { + return String::Make(12, [&](char *s) { if(IsNull(i)) return 0; if(i < 0) { diff --git a/uppsrc/Core/Format.cpp b/uppsrc/Core/Format.cpp index cafdd9068..6b8fd6f08 100644 --- a/uppsrc/Core/Format.cpp +++ b/uppsrc/Core/Format.cpp @@ -145,9 +145,9 @@ int utoa64(uint64 value, char *buffer) String FormatUInt64(uint64 w) { if(w < 100000000000000) - return String::MakeSmall([&](char *s) { return utoa64(w, s); }); - char h[32]; - return String(h, utoa64(w, h)); + return String::Make(14, [&](char *s) { return utoa64(w, s); }); + else + return String::Make(20, [&](char *s) { return utoa64(w, s); }); } String FormatInt64(int64 i) @@ -156,21 +156,20 @@ String FormatInt64(int64 i) return String(); if(i < 0) { i = -i; - if(i < 10000000000000) { - return String::MakeSmall([&](char *s) { + if(i < 10000000000000) + return String::Make(14, [&](char *s) { *s++ = '-'; return utoa64(i, s) + 1; }); - } - char h[32]; - *h = '-'; - return String(h, utoa64(i, h + 1) + 1); - } - if(i < 100000000000000) { - return String::MakeSmall([&](char *s) { return utoa64(i, s); }); + return String::Make(20, [&](char *s) { + *s++ = '-'; + return utoa64(i, s) + 1; + }); } + if(i < 100000000000000) + return String::Make(14, [&](char *s) { return utoa64(i, s); }); char h[32]; - return String(h, utoa64(i, h)); + return String::Make(20, [&](char *s) { return utoa64(i, s); }); } String FormatIntBase(int i, int base, int width, char lpad, int sign, bool upper) diff --git a/uppsrc/Core/String.h b/uppsrc/Core/String.h index acd36ee4d..dc8d6af8e 100644 --- a/uppsrc/Core/String.h +++ b/uppsrc/Core/String.h @@ -402,9 +402,6 @@ public: String(const std::string& s) { String0::Set0(s.c_str(), (int)s.length()); } std::string ToStd() const { return std::string(Begin(), End()); } - template - static String MakeSmall(Maker m) { String s; int n = m(s.chr); ASSERT(n <= 14); s.SLen() = n; s.Dsyn(); return s; } - template static String Make(int alloc, Maker m); }; diff --git a/uppsrc/Core/src.tpp/String_en-us.tpp b/uppsrc/Core/src.tpp/String_en-us.tpp index 4a5266f62..27d18d1bf 100644 --- a/uppsrc/Core/src.tpp/String_en-us.tpp +++ b/uppsrc/Core/src.tpp/String_en-us.tpp @@ -251,7 +251,7 @@ gets reallocated to the exact size of source).&] [s5;:String`:`:ToStd`(`)const:%- [_^http`:`/`/en`.cppreference`.com`/w`/cpp`/string`/basic`_string^ s td`::string]_[* ToStd]()_[@(0.0.255) const]&] [s2; Converts String to std`::string.&] -[s3;%- &] +[s3; &] [s4;%- &] [s5;:String0`:`:operator const char`*`(`)const:%- [@(0.0.255) operator]_[@(0.0.255) const ]_[@(0.0.255) char]_`*()_[@(0.0.255) const]&] @@ -264,8 +264,18 @@ td`::string]_[* ToStd]()_[@(0.0.255) const]&] nt]_[*@3 i])_[@(0.0.255) const]&] [s2;%- [%% Returns the character at position ][*@3 i.]&] [s3;%- &] +[s4;%- &] +[s5;:Upp`:`:String`:`:Make`(int`,Maker`):%- [@(0.0.255) template]_<[@(0.0.255) class]_[*@4 M +aker]>_[@(0.0.255) static]_[_^Upp`:`:String^ String]_[* Make]([@(0.0.255) int]_[*@3 alloc], + [*@4 Maker]_[*@3 m])&] +[s2; Optimized static method for creating Strings. This method creates +internal buffer of at least [%-*@3 alloc] and then invokes lambda +[%-*@3 m] passing the char `* pointer to the internal buffer as +lambda parameter. Lambda is then supposed to fill the characters +to this buffer and return the length of string (which must be +<`= [%-*@3 alloc]). For the best performance, [%-*@3 alloc] should +be constant.&] [s0;%- &] -[s0;@(0.0.255) &] [s0;%- &] [ {{10000@(113.42.0) [s0; [*@7;4 WString]]}}&] [s3; &] diff --git a/uppsrc/CtrlLib/Text.cpp b/uppsrc/CtrlLib/Text.cpp index 2fab1e211..d77517b7e 100644 --- a/uppsrc/CtrlLib/Text.cpp +++ b/uppsrc/CtrlLib/Text.cpp @@ -178,17 +178,24 @@ int TextCtrl::Load0(Stream& in, byte charset_, bool view) { return m; } -int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte charset, int max_line_len, int max_total, bool& truncated) const +int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte charset, + int max_line_len, int max_total, bool& truncated, + int *view_line_count) const { StringBuffer ln; bool cr = false; byte b8 = 0; + auto line_count = [&] { return view_line_count ? *view_line_count : ls.GetCount(); }; if(charset == CHARSET_UTF16_LE || charset == CHARSET_UTF16_BE) { WStringBuffer wln; auto put_wln = [&]() { - Ln& ln = ls.Add(); - ln.len = wln.GetCount(); - ln.text = ToUtf8(~wln, ln.len); + if(view_line_count) + (*view_line_count)++; + else { + Ln& ln = ls.Add(); + ln.len = wln.GetCount(); + ln.text = ToUtf8(~wln, ln.len); + } }; for(;;) { int c = charset == CHARSET_UTF16_LE ? in.Get16le() : in.Get16be(); @@ -204,7 +211,7 @@ int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte ch truncate_line: total += wln.GetCount() + 1; put_wln(); - if(ls.GetCount() >= n) + if(line_count() >= n) goto finish; wln.Clear(); } @@ -248,21 +255,28 @@ int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte ch ln.Cat((const char *)b, (const char *)s); } auto put_ln = [&]() -> bool { - Ln& l = ls.Add(); - if(charset == CHARSET_UTF8) { - l.len = CHARSET_UTF8 && (b8 & 0x80) ? utf8len(~ln, ln.GetCount()) : ln.GetCount(); - l.text = ln; + if(view_line_count) { + (*view_line_count)++; + total += charset == CHARSET_UTF8 && (b8 & 0x80) ? utf8len(~ln, ln.GetCount()) + : ln.GetCount(); } else { - l.len = ln.GetCount(); - l.text = ToCharset(CHARSET_UTF8, ln, charset); + Ln& l = ls.Add(); + if(charset == CHARSET_UTF8) { + l.len = (b8 & 0x80) ? utf8len(~ln, ln.GetCount()) : ln.GetCount(); + l.text = ln; + } + else { + l.len = ln.GetCount(); + l.text = ToCharset(CHARSET_UTF8, ln, charset); + } + if(total + l.len + 1 > max_total) { + ls.Drop(); + truncated = true; + return false; + } + total += l.len + 1; } - if(total + l.len + 1 > max_total) { - ls.Drop(); - truncated = true; - return false; - } - total += l.len + 1; return true; }; while(ln.GetCount() >= max_line_len) { @@ -275,7 +289,7 @@ int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte ch truncated = true; if(!put_ln()) goto out_of_limit; - if(ls.GetCount() >= n) { + if(line_count() >= n) { in.Seek(s - posptr + pos); goto finish; } @@ -289,7 +303,7 @@ int TextCtrl::LoadLines(Vector& ls, int n, int64& total, Stream& in, byte ch if(!put_ln()) goto out_of_limit; s++; - if(ls.GetCount() >= n) { + if(line_count() >= n) { in.Seek(s - posptr + pos); goto finish; } @@ -304,10 +318,16 @@ out_of_limit: { WString w = ToUnicode(~ln, ln.GetCount(), charset); if(total + w.GetLength() <= max_total) { - Ln& ln = ls.Add(); - ln.len = w.GetCount(); - ln.text = ToUtf8(~w, ln.len); - total += ln.len; + if(view_line_count) { + (*view_line_count)++; + total += w.GetCount(); + } + else { + Ln& ln = ls.Add(); + ln.len = w.GetCount(); + ln.text = ToUtf8(~w, ln.len); + total += ln.len; + } } } finish: @@ -328,8 +348,9 @@ void TextCtrl::ViewLoading() bool b; int64 t = 0; - LoadLines(l, 256, t, *view, charset, 10000, INT_MAX, b); - viewlines += l.GetCount(); + int line_count = 0; + LoadLines(l, 256, t, *view, charset, 10000, INT_MAX, b, &line_count); + viewlines += line_count; total += t; total256.Add((int)t); diff --git a/uppsrc/CtrlLib/TextEdit.h b/uppsrc/CtrlLib/TextEdit.h index 1f1a4999d..81065aa56 100644 --- a/uppsrc/CtrlLib/TextEdit.h +++ b/uppsrc/CtrlLib/TextEdit.h @@ -132,7 +132,8 @@ protected: int Load0(Stream& in, byte charset, bool view); int LoadLines(Vector& ls, int n, int64& total, Stream& in, byte charset, - int max_line_len, int max_total, bool& truncated) const; + int max_line_len, int max_total, bool& truncated, + int *view_line_count = NULL) const; void ViewLoading(); void SetLine(int i, const String& txt, int len) { lin[i].text = txt; lin[i].len = len; } diff --git a/uppsrc/ide/idefile.cpp b/uppsrc/ide/idefile.cpp index 8b3a3dff1..f207c4c68 100644 --- a/uppsrc/ide/idefile.cpp +++ b/uppsrc/ide/idefile.cpp @@ -7,6 +7,7 @@ String ViewCache() String ViewFileHash(const String& path) { + RTIMING("ViewFileHash"); Sha1Stream s; FindFile ff(path); if(ff) { @@ -413,7 +414,7 @@ void Ide::FlushFile() { RefreshBrowser(); } else - if(!editfile.IsEmpty()) { + if(!editfile.IsEmpty() && !editor.IsView()) { FileData& fd = Filedata(editfile); fd.undodata = editor.PickUndoData(); fd.filehash = EditorHash();