-
Content Count
2268 -
Joined
-
Last visited
-
Days Won
46
Everything posted by Fr0sT.Brutal
-
Workaround for binary data in strings ...
Fr0sT.Brutal replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
Hmm, is there well-optimized Pos function that takes TBytes in RTL? Strings were used for byte chunks because of lots of convenient utilities. -
Workaround for binary data in strings ...
Fr0sT.Brutal replied to A.M. Hoornweg's topic in RTL and Delphi Object Pascal
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. -
TWSocketClient.OnDataAvailable not firing off after a day or two
Fr0sT.Brutal replied to aehimself's topic in Network, Cloud and Web
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) -
Fix: APPle :D
-
TWSocketClient.OnDataAvailable not firing off after a day or two
Fr0sT.Brutal replied to aehimself's topic in Network, Cloud and Web
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. -
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.
-
Hmm, no, squash is just join all commits into one.
-
Is variable value kept after For.. in ... do loop?
Fr0sT.Brutal replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
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. -
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;
-
Is variable value kept after For.. in ... do loop?
Fr0sT.Brutal replied to Mike Torrettinni's topic in RTL and Delphi Object Pascal
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 -
git - do you 'pull' before/after switching branches?
Fr0sT.Brutal replied to David Schwartz's topic in General Help
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. -
string helpers question
Fr0sT.Brutal replied to David Schwartz's topic in RTL and Delphi Object Pascal
Contemporary Chinese, Japanese, Arabs, Thais, Koreans, Indians etc are roflin' with you -
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".
-
string helpers question
Fr0sT.Brutal replied to David Schwartz's topic in RTL and Delphi Object Pascal
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. -
tsslhttpcli TSslHttpCli Access violation at address or 404 error
Fr0sT.Brutal replied to Estefanie's topic in ICS - Internet Component Suite
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. -
Best Practices for FireDAC FetchMode/RecordCount Settings
Fr0sT.Brutal replied to Larry Hengen's topic in Databases
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. -
Best way to prevent multiple instances? Mutex not working
Fr0sT.Brutal replied to bilbo221's topic in VCL
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 -
how to Properly check if Twsocket Tcp client is still connected ?
Fr0sT.Brutal replied to Skullcode's topic in VCL
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. -
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.
-
Blocking the Windows Screen Saver in Delphi
Fr0sT.Brutal replied to dummzeuch's topic in Tips / Blogs / Tutorials / Videos
Why not ScrollLock that is useless for any other purpose? -
Mine was just a general idea and yours is more detailed implementation 🙂
-
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.
-
Generics: Classes vs Records - Differences in use
Fr0sT.Brutal replied to Lars Fosdal's topic in Algorithms, Data Structures and Class Design
Sure. Anything depends on sizes, contents and use cases 🙂 -
Generics: Classes vs Records - Differences in use
Fr0sT.Brutal replied to Lars Fosdal's topic in Algorithms, Data Structures and Class Design
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. -
Open File expert and Uses Clause Manager don't understand environment variables
Fr0sT.Brutal replied to merijnb's topic in GExperts
https://sourceforge.net/p/gexperts/feature-requests/72/