Jump to content

Fr0sT.Brutal

Members
  • Content Count

    2268
  • Joined

  • Last visited

  • Days Won

    46

Everything posted by Fr0sT.Brutal

  1. Fr0sT.Brutal

    Workaround for binary data in strings ...

    Hmm, is there well-optimized Pos function that takes TBytes in RTL? Strings were used for byte chunks because of lots of convenient utilities.
  2. Fr0sT.Brutal

    Workaround for binary data in strings ...

    Well, while this example by R.Chen is good finding, it's a bit useless for Delphi. Why reinvent the wheel when Delphi already has codepage-neutral RawByteString that won't do any char conversion at all? AFAIU only "uint8" <=> "uint16" conversion is performed when assigning Rawbytes to unicode and vice versa.
  3. Yeah, I must've expressed my point a bit unclear. I mean, if you have algo like this Recv(MsgSize, SizeOfMsgField); while MsgRecv < MsgSize do recvd := Recv(Buf[MsgRecv], MsgSize - MsgRecvd); and SizeOfMsgField > 1 there's a little probability to not have whole SizeOfMsgField of data in socket. So the reliable workflow is to read everything to buffer until you get the whole header and then start reading message body (considering the chunk you've already got). It's a universal pattern of reading with parsing. If a header is pretty big, reader could start parsing before it gets the whole header (f.ex., HTTP) but it splits data to logical parts anyway (CRLF-delimited lines). Well, I'd say "it is important to read at least some data". As TWSocket implements the read loop already internally, it's not necessary to create another loop in one's code. Sometimes it's more convenient and simple to read just as much as needed (f.ex. when parsing some message, read just one to the end and then exit OnDataAvail)
  4. Fr0sT.Brutal

    Drone control from mobile

    Fix: APPle :D
  5. I have no issues not caring about this. TCustomWSocket.TriggerDataAvailable has the loop already while Receive gets full buffer requested and TCustomWSocket.ASyncReceive loops as well unless the socket has wsoNoReceiveLoop option set. Anyway in my stream-reading classes I especially set wsoNoReceiveLoop, just making sure OnDataAvailable handler calls Receive in any condition (even 0-byte read is fine). With this setup ASyncReceive is called again and again until all data is read. Just foresee that your fixed size could arrive incomplete if it's > 1 byte. I usually read data to buffer to fill header and only then start reading the contents.
  6. Fr0sT.Brutal

    git workflow question

    IDK about SourceTree but it shouldn't. Merge adds single "merge commit" to your master branch but preserves all the history of a branch being merged. For me squashing is good when I have tons of temporary WIP commits in feature branch and don't want to pollute history with them. Then, when a feature is done, I squash these commits into well-commented pretty commits that will go to master's history. Usually I do it with cherry-pick. When a branch is ready, I merge it (sometimes I intentionally force merge even if changes could be fast-forwarded just to designate that a feature has been implemented.
  7. Fr0sT.Brutal

    git workflow question

    Hmm, no, squash is just join all commits into one.
  8. Fr0sT.Brutal

    Is variable value kept after For.. in ... do loop?

    Major rule of optimization says: Benchmark First Before Trying To Optimize 😉 . Syntax sugar is created for code simplicity and shortness and in most cases perf degradation will be insignificant I've really seen perf gain in string processing. With index loop you have ArrPtr + I*SizeOf(Item) each time which could, f.ex., cause cache misses. OTOH, Inc(CurrPtr, SizeOf(Item)) always operates on near memory area. Honestly I'm not a CPU-level expert and array loops could be well optimized already but in my case benches shown that pointer loop is faster.
  9. Fr0sT.Brutal

    Variation of FormatDateTime(

    Side note 1: for my projects I try to not rely on implementation details of data types. That is, assumption that Datetime1 - Datetime2 is "days between" Side note 2: usually it's more wise to store some meaningful value in DB and convert it to readable form on display (probably one day you'll want to calc some stats about durations - so you'll have to write 'ddd:hh:mm:ss' => Number convertor) Btw, here's function I use in my project: const NoneLbl = '(None)'; // Patterns RightNowLbl = 'less than a minute'; MinsPatt = '%d min'; HoursMinsPatt = '%d hr %.2d min'; DaysHoursMinsPatt = '%d d ' + HoursMinsPatt; // Formats number of minutes elapsed from AFrom to ATo. // If AFrom is 0 returns "None" (process wasn't started) function FormatMinutesSince(AFrom, ATo: TDateTime): string; var Mins: Integer; begin if AFrom = 0 then Exit(NoneLbl); Mins := Abs(MinutesSince(AFrom, ATo)); case Mins of 0: Result := RightNowLbl; 1..MinsPerHour-1: Result := Format(MinsPatt, [Mins]); MinsPerHour..MinsPerDay-1: Result := Format(HoursMinsPatt, [Mins div MinsPerHour, Mins mod MinsPerHour]) else Result := Format(DaysHoursMinsPatt, [Mins div MinsPerDay, (Mins mod MinsPerDay) div MinsPerHour, Mins mod MinsPerHour]); end; end;
  10. Fr0sT.Brutal

    Is variable value kept after For.. in ... do loop?

    Almost all syntax sugar is expensive. for-in means creating iterator, calling its methods etc instead of plain index addressing. But in most cases it doesn't matter. Anyway if speed is important, pointer-based iteration probably will be faster
  11. Fr0sT.Brutal

    git - do you 'pull' before/after switching branches?

    All this could be achieved with branches inside single repo. You can develop in 'private' branch then merge with squashing to 'public' one that will be pushed to Github or whatever.
  12. Fr0sT.Brutal

    string helpers question

    Contemporary Chinese, Japanese, Arabs, Thais, Koreans, Indians etc are roflin' with you
  13. Fr0sT.Brutal

    Drone control from mobile

    Offtop: I'm always wondering why people tend to write "APP" (in uppercase) when it's just a short form of "application". Nobody says "I wrote an APPLICATION".
  14. Fr0sT.Brutal

    string helpers question

    In general, AFAIK, comparing lowercased versions <> case-insensitive comparing. It's the case for some languages. Moreover, in theory direct case-insensitive comparation should be faster than creating a new string + comparing because many languages do not have case at all.
  15. Side note: maybe add some friendliness? Clear error message that will explain what's wrong or even default init that will just work without any additional hassle.
  16. Fr0sT.Brutal

    Best Practices for FireDAC FetchMode/RecordCount Settings

    I don't think indexes will help to avoid joins in this situation. They will only speed up counting but not preparing data array to select from. In general, I'd advice to not use total record count at all. Just output count of currently fetched records so user will see that his request is in progress.
  17. Fr0sT.Brutal

    Best way to prevent multiple instances? Mutex not working

    I use Events for this purpose though it doesn't really matter. What really matters is namespace The name can have a "Global\" or "Local\" prefix to explicitly create the object in the global or session name space
  18. Fr0sT.Brutal

    how to Properly check if Twsocket Tcp client is still connected ?

    Usually you won't even need this check. Check if state is closed and connect if yes; then send data in OnConnect, read in OnDataAvail, close if Recv or Send return -1 or OnError occurs.
  19. Fr0sT.Brutal

    GLAD loader for Delphi

    Yeah, I'm +1 with David. With all the respects to all open-source developers, adding elementary line "What is this" helps much, adds friendliness to a project and teaches to structurize descriptions.
  20. Why not ScrollLock that is useless for any other purpose?
  21. Fr0sT.Brutal

    "Self-updating" terminal services DLL

    Mine was just a general idea and yours is more detailed implementation 🙂
  22. Fr0sT.Brutal

    "Self-updating" terminal services DLL

    Depending on lib usage, you can split your lib into agent part that is rarely updated and functional part that could be unloaded and updated by agent part.
  23. Sure. Anything depends on sizes, contents and use cases 🙂
  24. Yes I know that but that's how things are. If someone's going to shoot himself in the leg, even the most safe code couldn't prevent it. I had no intention of creating a fool-proof class without any real necessity. TList<TObject> has all the same weaknesses but I haven't seen anyone complaining about them. As for allocations, they're not so massive and quite acceptable compared to array-of-large-blocks allocations and moves when the list is sorted.
  25. https://sourceforge.net/p/gexperts/feature-requests/72/
×