Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Fr0sT.Brutal last won the day on January 13

Fr0sT.Brutal had the most liked content!

Community Reputation

321 Excellent

1 Follower

Technical Information

  • Delphi-Version
    Delphi XE2

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I've never seen FileCreate/FileClose inlined; DeleteFile is inlined for Posix and yes, RenameFile is still inlined for all platforms (checking in XE2 and 10.3). Odd decision really. The worse thing with inlines is that they can't use internal constants 😞
  2. Fr0sT.Brutal

    Nneed a mentor

    Well, I suppose if you need both English&coding tutor, you should expect x2 price 😄
  3. Fr0sT.Brutal

    Nneed a mentor

    It's weird to seek for a mentor on international forum with such lang skills. Why don't try at sql.ru?
  4. Fr0sT.Brutal

    Edge Webview update (?)

    *facepalm* Winsock is included into RTL and you can create client-server apps with it. What a stupid policy
  5. Fr0sT.Brutal

    Micro optimization: Split strings

    @Attila Kovacs yep that's why I came up to AllowEmpty option. Nevertheless I agree that behavior should be consistent between implementations in other languages (this issue is long-lasting TODO entry, probably I'll move it somewhat upper)
  6. Fr0sT.Brutal

    Blogged : Advice for Delphi library authors

    Pity. I thought it was intended for such cases
  7. I'm already glad they dropped dependency on that odd Visual J++ 😄
  8. Fr0sT.Brutal

    Micro optimization: Split strings

    Well, I thought hard on this nuance as well. Vote "for" is when string is constructed by dumb but simple loop `s := s + part + sep`, it will contain last sep that actually doesn't designate an element. Vote "against" is logic: if there's a separator - then an element must follow.
  9. Fr0sT.Brutal

    Micro optimization: Split strings

    Yep, here it is (on DUnitX facilities) TStrArray is array<string> and DefListDelim is ';' // Split/Join/GetElement procedure TTest_Utils.TestSplit; var arr: TStrArray; procedure CheckEquals(const CompArr: array of string; const TestDescr: string); var i: Integer; begin Assert.AreEqual(Integer(Length(CompArr)), Integer(Length(arr)), TestDescr + ' check lengths'); for i := 0 to Length(CompArr) - 1 do Assert.AreEqual(CompArr[i], arr[i], TestDescr + ' compare items #'+IntToStr(i)); end; begin arr := Split(''); CheckEquals([], 'Empty'); arr := Split('qq'); CheckEquals(['qq'], 'Single'); arr := Split('qq;ww;ee'); CheckEquals(['qq','ww','ee'], 'Normal'); arr := Split('qq;ww;ee;'); CheckEquals(['qq','ww','ee'], 'Sep on end'); arr := Split('qq;ww;;;ee', DefListDelim, True); CheckEquals(['qq','ww','','','ee'], 'Empty items -- allow'); arr := Split('qq;ww;;;ee', DefListDelim, False); CheckEquals(['qq','ww','ee'], 'Empty items -- deny'); arr := Split('qq==ww==ee=', '=='); CheckEquals(['qq','ww','ee='], 'Multichar sep'); arr := Split('qq;ww;"ee;ll"', ';', True); CheckEquals(['qq','ww','"ee','ll"'], 'LastIdx 1'); arr := Split('qq;ww;"ee;ll"', ';', True, 0); CheckEquals(['qq;ww;"ee;ll"'], 'LastIdx 1'); arr := Split('qq;ww;"ee;ll"', ';', True, 1); CheckEquals(['qq','ww;"ee;ll"'], 'LastIdx 1'); arr := Split('qq;ww;"ee;ll"', ';', True, 2); CheckEquals(['qq','ww','"ee;ll"'], 'LastIdx 2'); end;
  10. Fr0sT.Brutal

    Blogged : Advice for Delphi library authors

    Hmm, wasn't that a mistake in that package? And how did it happen, its dev didn't try to build it? Not exactly what I was talking about. Packages are good, but in many cases personal package project files for every version are excess. Delphi has pretty cool compatibility with older versions so one project file for all XEs should be enough (honestly I just dislike all those huge listings of <name>_D<whatever>.dproj files that are completely identical in fact). IMHO component packages should not bother about installation process at all. Let IDE decide how and where to build them! There are plenty of libs that suggest to install themselves in Program files, or C:\, or %APPDATA%, or %ALLUSERSPROFILE%... sometimes they don't even ask for path and silently install where they decide! My opinion here: custom installers for component libs are evil. Doesn't upgrade from GetIt solve this issue?
  11. Fr0sT.Brutal

    Micro optimization: Split strings

    Well, for values that accept anything >= 0, "-1" is short "default"/"not set" magic constant. It's not intended for use in code anyway because it's declared as default parameter (in decl section that I didn't copy). I guess you're right and MaxInt constant will do better; moreover it will eliminate one condition in code. And it's aligned to parameters of Copy(). Nice note!
  12. Fr0sT.Brutal

    Blogged : Advice for Delphi library authors

    Package Names I guess many projects don't even require personal package files for every Delphi version. Not talking about DPK files which mainly are the same. Use Search Paths for includes Tend to disagree. This makes package files obligatory while otherwise they're optional. Moreover, you won't be able to explore that include file from unit code unless you loaded the package project. What's wrong with relational paths?
  13. Fr0sT.Brutal

    Hiding a public property in a descendant class

    Good though there's still a chance you miss some cases procedure TForm1.EditOnChange(Sender: TObject); begin with TEdit(Sender) do Text := Text + 'lol'; end;
  14. Fr0sT.Brutal

    SQLite, adding a function

    Hmm don't you know that uppercase letters occupy more memory causing overall slowdown?! 😄
  15. Fr0sT.Brutal

    Micro optimization: Split strings

    function Split(const Str: string; const Delim: string; AllowEmpty: Boolean; LastIdx: Integer): TStrArray; var CurrDelim, NextDelim, CurrIdx: Integer; begin if Str = '' then begin SetLength(Result, 0); Exit; end; CurrDelim := 1; CurrIdx := 0; SetLength(Result, 16); repeat if CurrIdx = Length(Result) then SetLength(Result, CurrIdx + 16); // check if array if full and extend if needed if (LastIdx <> -1) and (CurrIdx = LastIdx) then // last index reached - write all up to end begin NextDelim := Length(Str)+1; end else begin NextDelim := Pos(Delim, Str, CurrDelim); // next delim if NextDelim = 0 then // string is finished - write all up to end NextDelim := Length(Str)+1; end; Result[CurrIdx] := Copy(Str, CurrDelim, NextDelim - CurrDelim); CurrDelim := NextDelim + Length(Delim); // if fragment is not empty or empty are OK - inc index if (Result[CurrIdx] <> '') or AllowEmpty then Inc(CurrIdx) else Continue; until CurrDelim > Length(Str); SetLength(Result, CurrIdx); // cut the array down end; - any string as delimiter - customize if empty elements will be extracted ("foo;;;bar" & AllowEmpty=False => ["foo", "bar"]) - optional stop splitting after N elements found (mainly for name-value pairs like "login: user:pass" & LastIdx=1 => ["login", "user:pass"])