Jump to content

Fr0sT.Brutal

Members
  • Content Count

    2268
  • Joined

  • Last visited

  • Days Won

    46

Everything posted by Fr0sT.Brutal

  1. Fr0sT.Brutal

    Determining why Delphi App Hangs

    Isn't it classic block while not DS.Eof do begin ..copy values... FormProgress.PrBar.Stepit; DS.Next; end; ? If so, there's nothing that hangs in your app.
  2. Fr0sT.Brutal

    Determining why Delphi App Hangs

    This is simple and good enough idea for the app described. Side effects are insignificant in single-threaded app (possibility of user input during processing could be easily blocked). Using bg threads for DB actions is getting a little closer to rocket science than App.PrMsg and could seem an overkill for simple app or junior dev.
  3. Fr0sT.Brutal

    Determining why Delphi App Hangs

    Simple way is to call Application.ProcessMessages from time to time
  4. Here are helper methods for quick and easy setting of remote URL (host:port) and proxy URL (proto://[user:password@]host[:port] where "proto" = 'socks5' or 'http') and if port is empty, proto-specific default value is assigned use OverbyteIcsUrl ... const PROXY_PROTO_HTTP = 'http'; PROXY_PROTO_SOCKS5 = 'socks5'; PROXY_PORT_HTTP = '8080'; // HTTP tunnel default port PROXY_PORT_SOCKS5 = '1080'; // Socks5 default port type TfrWSocket = class(TWSocket) public procedure SetURL(const URL: string); procedure SetSocks(const Host: string = ''; const Port: string = PROXY_PORT_SOCKS5; const User: string = ''; const Pass: string = ''); procedure SetHTTPTunnel(const Host: string = ''; const Port: string = PROXY_PORT_HTTP; const User: string = ''; const Pass: string = ''); procedure SetProxyURL(const URL: string); end; // Set combined 'host:port' string. Accepts any URL string but raises exception // if it contains anything more than host and port (other parts are unused at // socket level) procedure TfrWSocket.SetURL(const URL: string); var Proto, User, Pass, Host, Port, Path: String; begin if URL <> '' then ParseURL(URL, Proto, User, Pass, Host, Port, Path); // check that no more than host and port assigned if (Proto <> '') or (User <> '') or (Pass <> '') or (Path <> '') then begin RaiseException('Error with URL "' + URL + ' - it must contain only host and port'); Exit; end; Self.Addr := Host; Self.Port := Port; end; // Set socks requisites by single function. If Host is empty, cleanup everything procedure TfrWSocket.SetSocks(const Host, Port, User, Pass: string); begin // Cleanup everything if Host = '' then begin SocksServer := ''; SocksPort := ''; SocksAuthentication := socksNoAuthentication; SocksUsercode := ''; SocksPassword := ''; Exit; end; SocksServer := Host; SocksPort := Port; if (User = '') then SocksAuthentication := socksNoAuthentication else SocksAuthentication := socksAuthenticateUsercode; SocksUsercode := User; SocksPassword := Pass; end; // Set http proxy requisites by single function. If Host is empty, cleanup everything procedure TfrWSocket.SetHTTPTunnel(const Host, Port, User, Pass: string); begin // Cleanup everything if Host = '' then begin HttpTunnelServer := ''; HttpTunnelPort := ''; HttpTunnelAuthType := htatNone; HttpTunnelUsercode := ''; HttpTunnelPassword := ''; Exit; end; HttpTunnelServer := Host; HttpTunnelPort := Port; if (User = '') then HttpTunnelAuthType := htatNone else HttpTunnelAuthType := htatBasic; HttpTunnelUsercode := User; HttpTunnelPassword := Pass; end; // Set HTTP or Socks proxy URL: 'proto://[user:password@]host[:port]' where "proto" = 'socks5' or 'http' // If port is empty, proto-specific default value is assigned procedure TfrWSocket.SetProxyURL(const URL: string); var Proto, User, Pass, Host, Port, Path: String; begin // Cleanup everything if URL = '' then begin SetSocks(''); SetHTTPTunnel(''); Exit; end; ParseURL(URL, Proto, User, Pass, Host, Port, Path); // check that Proto and Host are assigned if (Proto = '') or (Host = '') then begin RaiseException('Error with proxy URL "' + URL + ' - it must contain proto and host'); Exit; end; // check that Path is not assigned if (Path <> '') then begin RaiseException('Error with proxy URL "' + URL + ' - it must not contain path'); Exit; end; // switch proto if Proto = PROXY_PROTO_HTTP then SetHTTPTunnel(Host, Port, User, Pass) else if Proto = PROXY_PROTO_SOCKS5 then SetSocks(Host, Port, User, Pass) else RaiseException('Error with proxy URL "' + URL + ' - Unknown proxy protocol'); end; They're implemented as descendant's methods but you can turn them into functions. Methods require OverbyteIcsUrl unit so I'm unsure if they could be suggested to merge into upstream
  5. Looks nice, thanks! You mean 3proxy? It could run with the most minimal config in the world 🙂 socks Save it as 3proxy.cfg and just run exe and that's all, socks is available at #1080. I'm not sure what "its limit" do you mean though.
  6. Fr0sT.Brutal

    Min & Max

    Me too! Implemented my own routines for this
  7. Wonderful! 🙂 You can check with powerful opensource 3proxy ( https://github.com/z3APA3A/3proxy ) or SSH tunnel or Tor or any other software you like more. My ICS-powered app is running thru 3proxy very well No problem, it's a convenience method for my own socket class but it surely does too little to be added to upstream.
  8. Probably, but not in so big numbers as it could be if MM wouldn't reserve space at all. In most cases, the more specific an algo is, the more it could be optimied for speed because you can make some assumptions that reduce conditions. F.ex., generic string replace, even pretty optimized on ASM, being used for replacing one char with another would be likely beaten by dumb "for ch:=1 to Length(Src) if Src[ch] = CharFrom then Dst[ch] := CharTo else Dst[ch] := Src[ch]" @Mike Torrettinni if your goal is just to remove HTML entities, better utilize specific routine where you could make these assumptions: - Result will always be shorter than source. So allocate space for result once at the beginning and truncate it to actual length in the end - List of entities is standardized. You can hardcode them for better performance -- Any non-ASCII char after & and before ; should be skipped -- possible set of distances from & to ; is known beforehand -- convert input char (you already ensured it's ASCII alpha) to fixed case with simple bitwise operation to reduce ranges -- Use "case 'a'..'z'" instead of CharInSet -- some more hard optimizations that make code too specific but very fast - Flow prediction could play big role as well. In good HTML there won't happen a & that's not an entity so "if currChar = '&' and IsEntity then ... else Continue" could outperform "if currChar = '&' and (not IsEntity) then Continue" - The more you optimize your code, the less readable/universal/pretty it becomes 😞
  9. Well, SB does allocations by FastMM as well. The only difference is that with FastMM you can't control initially reserved space. Heavily thread programs shouldn't use heap allocations in hot places at all or switch to mem managers that implement thread-local heaps
  10. I like this one. This is the only solid and robut approach to the most generic task - multi-replace. Every solution that modifies a source and then scans the modified value for the next entry has the flaw of processing already replaced fragments: MultipleReplace('I like milk. I'm afraid of bees.', ['milk', 'beer'], ['bee', 'spider']) => 'I like spiderr. I'm afraid of spiders.'
  11. In fact, FastMM already reserves some space for dynarrays and strings making StringBuilder nearly useless. SB would benefit if it cached added strings to some internal array and only flushed them to final buffer when needed but it's not the case currently
  12. The attached patch adds TCustomHttpTunnelWSocket.HttpTunnelState - protected RO property for accessing by descendants (to ensure connection is ready) TCustomHttpTunnelWSocket.HttpTunnelState prop.diff
  13. Nice to know! The lesser personal changes to the main upstream I have to keep, the better 🙂 I was unsure if adding OverbyteIcsUrl to OverbyteIcsWSocket is an option.
  14. Fr0sT.Brutal

    Help debugging code please

    Talking frankly, this code is piece of garbage, the fact it worked before is just a big luck. You address 1-th char of an empty string and expect it to pass.
  15. Fr0sT.Brutal

    Thread Issues: using resume and start

    Btw, thread.Resume is considered bad practice and deprecated since XE
  16. Side note: that's why we need auto-wrapping code blocks
  17. It's vertical selection. I sometimes miss these actions as well after VSCode.
  18. Fr0sT.Brutal

    Waiting for multiple threads

    I meant, multithread apps usually have one. Otherwise they will have big troubles on closing
  19. Fr0sT.Brutal

    How to compare performance between Delphi versions?

    What exactly is unclear? Create set of DLLs with every RAD version you want, export the functions you want to check then use all these DLLs in one bench project. Basic xp should be quite enough for this 🙂 Of course it's just an option. Exe's likely will be fine as well
  20. Fr0sT.Brutal

    How to gracefully get rid of the use of dictionaries?

    TDirections = set of TDirection ? note: I could miss some important detail here as it's monday and even coffee doesn't help much %-)
  21. Fr0sT.Brutal

    How to compare performance between Delphi versions?

    Yes they will but with DLLs you can check perf inside the same process which probably could be more useful & give more precise results
  22. Fr0sT.Brutal

    Developer Express gave up on FMX

    Which is a road to dead end because mobile and desktop UI is completely different anyway unless we're talking about one-button UIs
  23. Fr0sT.Brutal

    How to compare performance between Delphi versions?

    I'd choose multiple VM's for each IDE version. Functions to benchmark could be put into DLL's and tested on a host machine
  24. Fr0sT.Brutal

    Profiler for Delphi

    Classic. The issue Emba couldn't resolve in decades is done in couple of days by a clever enthusiast
×