Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 08/07/23 in all areas

  1. It has always irked me that in C you can write: while (0<(BytesRead=Read(...))) { // .. } But in Delphi you have to use the much less readable BytesRead := Stream.Read(Buffer, BufSize); while BytesRead > 0 do begin // .. BytesRead := Stream.Read(Buffer, BufSize); end; Today I had enough and wrote these simple helper functions: function TStream_TryRead(_st: TStream; var _Buffer: TBytes; _Count: Int32; out _BytesRead: Int32): Boolean; overload; inline; begin _BytesRead := _st.Read(_Buffer, _Count); Result := (_BytesRead > 0); end; function TStream_TryRead(_st: TStream; var _Buffer; _Count: Int32; out _BytesRead: Int32): Boolean; overload; inline; begin _BytesRead := _st.Read(_Buffer, _Count); Result := (_BytesRead > 0); end; function TStream_TryRead(_st: TStream; _Buffer: TBytes; _Offset, _Count: Int32; out _BytesRead: Int32): Boolean; overload; inline; begin _BytesRead := _st.Read(_Buffer, _Offset, _Count); Result := (_BytesRead > 0); end; function TStream_TryRead(_st: TStream; _Buffer: TBytes; _Offset, _Count: Int64; out _BytesRead: Int64): Boolean; overload; inline; begin _BytesRead := _st.Read64(_Buffer, _Offset, _Count); Result := (_BytesRead > 0); end; With these you can write: while TStream_TryRead(Buffer, BufSize, BytesRead) do begin // .. end; Yes, that's far from being rocket science. It's probably possible to convert these into a class helper, but I can't be bothered. (Original Blog post.)
  2. Remy Lebeau

    while TStream_TryRead() do

    Sadly, not only is -1 not documented, but it's also not always implemented. For example, THandleStream.Read() returns 0 on failure and end-of-file. Which makes error handling practically impossible for some stream types. That is what the ReadXXX() methods are meant for. Read() is the lower level method that they all use internally.
  3. Fr0sT.Brutal

    while TStream_TryRead() do

    This design was made to handle streaming sources (socket, pipe, file being written, etc). At the moment of call there could be no data but next time it could arrive (I'm sure you know it anyway). But it really could puzzle those who are not aware of this behavior and are sure that Read() really waits until it reads requested amount of data.
  4. David Heffernan

    while TStream_TryRead() do

    Weird repeat loop. I'd do: repeat BytesRead := Stream.Read(Buffer, BufSize); until BytesRead < BufSize;
  5. mvanrijnen

    Project Options -> Version Info aka. dproj madness

    yes, we are working on that also.
  6. Ali Dehban

    EasyDBMigrator

    What? EasyDbMigrator is a database migration library designed for Delphi. It simplifies database evolution and is available in both 32-Bit and 64-Bit versions. Why and how to use it? Please have a look at ReadMe on GitHub(https://github.com/AliDehbansiahkarbon/EasyDBMigrator). Or watch the Introduction Video:
  7. aehimself

    Simple ORM

    Instead of “SELECT * FROM MyTable WHERE ID = 99” use “SELECT * FROM MyTable WHERE ID = :pID”, then assign the value 99 for the parameter named pID.
  8. uligerhardt

    while TStream_TryRead() do

    Wouldn't a repeat-until loop do the trick?
  9. Both of which are done by the new ICS component TIcsNeighbDevices which gives a similar display to the two Nirsoft scanner tools. Angus
  10. dummzeuch

    Project Options -> Version Info aka. dproj madness

    https://blog.dummzeuch.de/2015/09/26/using-my-buildtools/ Actually, it's even older: http://www.dummzeuch.de/delphi/dzprepbuild/englisch.html
  11. dummzeuch

    Project Options -> Version Info aka. dproj madness

    Since the version info stuff never really worked very well since at least Delphi 2005, I don't use the IDE to manage the version info but create a version info resource externally and link it to the executable. As as side effect, I have no more annoying changes in the dproj file that show up in SCM with every build.
  12. Remy Lebeau

    .exe File not outputting

    To elaborate, only the Unicode version of CreateProcess() requires the 2nd parameter to point at writable memory, as it may have to internally normalize/alter the Unicode string. This is documented behavior. In this example, sCommand is pointing at a string literal (ie, its RefCnt is -1), so the compiler won't allocate a block of writable memory for sCommand unless it is modified (ie, copy-on-write semantics), which this code doesn't do. So the UniqueString() is used to ensure that sCommand is pointing at a unique and writable string in memory (ie, its RefCnt is 1). If you use string variables to build up sCommand, then the UniqueString() won't be needed since the resulting string will be unique and writable, eg: var sProgram, sFilename, sCommand: string; sProgram := 'C:\PDF\pdftotext.exe'; sFilename := 'C:\PDF\ABC.PDF'; sCommand := '"' + sProgram + '" "' + sFilename + '"'; // or: sCommand := Format('"%s" "%s"', [sProgram, sFilename]); // etc...
×