Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation since 01/26/21 in all areas

  1. For all who want to try to get the DDevExtensions Delphi IDE plugin to work with Delphi 10.4 can now clone the DDevExtensions git repository. It contains the project files for Delphi 10.2 and 10.3. I'm not able to help with any Delphi 10.4 issues, so you are on your own. GitHub repository: https://github.com/ahausladen/DDevExtensions
  2. Alexander Sviridenkov

    UI created with HTML Library

    Video made for Delphi Showcase. Both, desktop application and server software (for cloud access) are made in Delphi, nothing external except OCR dll. Windows, Mac and Linux versions. All UI is created in HtPanels (HTML Library), document conversion is performed by Office library. Support for custom fonts and letter spacing was added to FMX canvas (currently only for windows), without this PDF documents cannot be rendered properly. https://www.youtube.com/watch?v=PdudQwjhCJg
  3. Carlo Barazzetta

    Native Svg parsing and painting in Windows

    A new brick added to this story: https://github.com/EtheaDev/SVGShellExtensions A short video/demonstration:
  4. Hi All I have been steadily working away on my package manager project - the latest update includes compile on install support. https://github.com/DelphiPackageManager/DPM When a package is first installed, it is automatically compiled (if the package spec has that support enabled) and then the project references the compiled version of the package. This speeds up builds on your own projects, since you are not compiling the dpm package sources each time. As an extreme example of this, the DPM build process (building for 12 versions of delphi!) previously took 13 minutes on my build server, after installing the latest dpm and running 2 builds (the first one compiled the packages), the build time is down to 2 minutes! Much of that speed up comes from the fact that older versions of delphi are quite slow at building Spring4D. I encourage everyone to check it out and provide feedback where possible. To get started using DPM, download the latest release from here : You will need to configure a package feed (folder) and download some packages - see the Getting started page Most of my open source projects have package files available under the releases tab on github - https://github.com/vsoftTechnologies/ I have also added a mirror project for Spring4D on github so that I could publish packages (bitbucket doesn't support that) - https://github.com/VSoftTechnologies/Spring4DMirror Same for JsonDataObjects - Andreas ignored my pull request for over a year so I closed it and just forked the project - https://github.com/VSoftTechnologies/JsonDataObjects I'm still working on getting design time packages loaded.. need to get proper project group support going first. Previous updates here :
  5. We have open sourced our Deployment Manager to simplify deployment of a large number of files or folders to iOS or Android. https://blog.grijjy.com/2021/02/07/deployman/
  6. Dalija Prasnikar

    Interface as Const parameter

    I wouldn't use any of those solutions. Because that is not golden rule. On the contrary, for reference counted types you would almost always use const to avoid unnecessary reference counting overheard. Problem is not in the method that has const, problem happens at call site. As such it should be handled at call site. First, handling it at call site allows you to trigger reference counting only for references that really need it, next, you will avoid situation where performance will become an issue and someone will go and change method signature according to common practice - using const and will inadvertently break code. Far better solutions than 1. or 2. are using additional variable instead of constructing instance during method call, This is also easy rule to remember - don't create anything inplace. Next solution would be explicitly typecasting TFoo.Create as IFoo And the last one, I like the most because it prevents you to make reference counting mistakes in other code, too, is to have class function that will create instance and return it as interface reference. As for finding all places where you can create possible problem and you need to fix it, simple search and replace can go a long way. For instance - if you have class function New, you can just replace TFoo.Create with TFoo.New and if have same parameter list, you are good.
  7. TurboMagic

    DEC 6.1 released

    Hello, there is a new release 6.1 of DEC available . It is located here: https://github.com/MHumm/DelphiEncryptionCompendium/releases/tag/V6.1 WHat's new since V6.0? * x64 compilation works out of the box now, some unit had not been properly listed for x64 * fixed the following cipher algorithms which were broken on x64: Blowfish, RC6 and Q128 * the Sapphire cipher did work with the unit test vectors but failed for some others * added SHA2-224 hash algorithm * added HMAC and pbkdf2 algorithms * somebody provided a build batch file * there is a command line application included now for setting the IDE's library path * progress even got changed and a VCL demo for that one was added * version history is a separate document in docs folder now Cheers TurboMagic
  8. Two blog posts to share: https://blog.synopse.info/?post/2021/02/13/Fastest-AES-PRNG%2C-AES-CTR-and-AES-GCM-Delphi-implementation https://blog.synopse.info/?post/2021/02/12/New-AesNiHash-for-mORMot-2 TL&DR: new AES assembly code burst AES-CTR AES-GCM AES-PRNG and AES-HASH implementation, especially on x86_64, for mORMot 2. It outperforms OpenSSL for AES-CTR and AES-PRNG, and is magnitude times faster than every other Delphi library I know about.
  9. @David Heffernan I admire your patience.
  10. {$APPTYPE CONSOLE} uses System.SysUtils, System.Diagnostics, System.StrUtils; function MyStartsWith(const SearchText, Text: string): Boolean; var Index, SearchTextLen: Integer; begin SearchTextLen := Length(SearchText); if SearchTextLen>Length(Text) then begin Result := False; Exit; end; for Index := 1 to SearchTextLen do if Text[Index]<>SearchText[Index] then begin Result := False; Exit; end; Result := True; end; const cMaxLoop = 10000000; cText = 'Error: Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'; cTextNoHits = 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.'; cStartsWithShort = 'E'; cStartsWithLong = 'Error:'; var vSW: TStopWatch; i, vLen: integer; hitCount: Integer; vResult: boolean; begin Writeln('Substring exists at the start:'); // Short string Writeln('Short string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cText, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cText, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cText.StartsWith(cStartsWithShort) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithShort, cText) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithShort, cText) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); // Long string Writeln('Long string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cText, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cText, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cText.StartsWith(cStartsWithLong) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithLong, cText) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithLong, cText) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); Writeln; // Text DEOS NOT start with selected string Writeln('Substring NOT exists at the start:'); // Short string Writeln('Short string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cTextNoHits, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cTextNoHits, 1, Length(cStartsWithShort)) = cStartsWithShort then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cTextNoHits.StartsWith(cStartsWithShort) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithShort, cTextNoHits) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithShort, cTextNoHits) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); // Long string Writeln('Long string:'); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if Copy(cTextNoHits, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' Copy: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MidStr(cTextNoHits, 1, Length(cStartsWithLong)) = cStartsWithLong then Inc(hitCount); Writeln(' MidStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if cTextNoHits.StartsWith(cStartsWithLong) then Inc(hitCount); Writeln(' StartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if StartsStr(cStartsWithLong, cTextNoHits) then Inc(hitCount); Writeln(' StartsStr: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); hitCount := 0; vSW := TStopWatch.StartNew; for i := 1 to cMaxLoop do if MyStartsWith(cStartsWithLong, cTextNoHits) then Inc(hitCount); Writeln(' MyStartsWith: ' + vSW.ElapsedMilliseconds.ToString, ' ', hitCount); readln; end. Copy is clearly a shocker of an idea for this use. heap allocation!! Really?!!! And the other functions seem really slow. A simple for loop is around 10 times faster. I didn't capture any timings, but it's easy to do it on your machine. I also addressed a couple of issues with your benchmark code. I don't believe this is a bottleneck in your program, but you love premature optimisation with a rarely seen passion.
  11. Leaving aside the issues that are commented on by other, instead of if Supports(fBaseFrameClass, ISupportTask) then (fBaseFrame as ISupportTask).CheckTask; surely you need var Task: ISupportTask; ... if Supports(fBaseFrame, ISupportTask, Task) then Task.CheckTask; Two changes: Ask the implementing object rather than the class whether or not the interface is supported. Use the three argument overload of Supports so that you can get the interface while you are querying for it.
  12. Dalija Prasnikar

    Interface as Const parameter

    Yes. Since such coding pattern is not too common in Delphi because of its manual memory management. So you either cannot use it at all, or you are creating objects and passing ownership which is not the most common scenario, or you are creating reference counted instance where inplace creating creates problems. There is no performance penalty here. You need to trigger reference counting when creating new instance. That is the original issue you are solving. All you can do to prevent accidental misues is great, but sometimes people just need to use their brains and think what they are doing.
  13. Long awaited release of powerful open-source documentation generator for Pascal code is out. Get it New website, using Jekyll, generated from our wiki, see https://github.com/pasdoc/pasdoc.github.io (Michalis) Moved everything to GitHub Ancestors list is now affected by external class hierarchy (Michalis) Markdown support (Fr0sT-Brutal) Supporting bold, italic, inline code, multi-line code, URLs, lists. @note and @warning tags (Bi0T1N) @url tag (Bi0T1N) Allow to lowercase output of @nil, @false, @true by --lowercase-keywords (Bi0T1N) Automatically detect flag like [xxx] at @param description. See here for example. (PifPof) Scan implementation section of a unit in addition to the interface section (Fr0sT-Brutal) Parser improvements to correctly handle some special cases: reading chars > $FF, "*.inc" includes, files with Mac-style line endings (Fr0sT-Brutal) Mem leaks fixed (Fr0sT-Brutal) Tag parameters now could be multiline without enclosing parens by means of "line feed" character "" (Fr0sT-Brutal) Read additional command-line options from file (Fr0sT-Brutal) --auto-back-comments command-line option (Fr0sT-Brutal) pasdoc_gui opens a file given at command-line, opening WWW browser is optional (Fr0sT-Brutal) @longcode without markers fixed (Michalis) Support for namespaces in units in @links (Fr0sT-Brutal) --ignore-marker option (Fr0sT-Brutal) Test suite fixes and better documentation, in particular for Windows users Catalan translation updated (Xavier Martínez) Delphi Tokyo files, to compile all projects and packages (Carlos Feitoza Filho) Brazilian Portuguese translation updated (Carlos Feitoza Filho) Parse identifiers declared as &xxx, where "xxx" may be a reserved word. Possibility to specify additional files using -A or --additional (just like introduction or conclusion, but you can provide any number of items) (Alex Merkel) Added de.utf8 (German with UTF-8 encoding) Automatically remove %region and %endregion from comments Show visibility (public, protected, private...) inside records too (it is meanigful for advanced records) Implement in pasdoc_gui options to (Michalis) customize HTML head and body set external descriptions file configure identifiers excluded from auto-linking Rename "internal" to "nested" to describe this language feature. Because that is how it's called in official docs ( http://docwiki.embarcadero.com/RADStudio/Tokyo/en/Nested_Type_Declarations, https://www.freepascal.org/docs-html/ref/refse41.html ) and the "internal" word has traditionally different meaning ("something not supposed to be visible/used from the outside"). (Michalis) The automatic tests are now easier to run and check (see tests/README.md) (Michalis) @raises and @param is now supported at properties as well as methods. Actually, it's supported everywhere now, but it makes sense only at properties and methods now. (Michalis) Tipue (client-side search) improvements: we have upgraded to use Tipue 6.1, which highlights the found terms we strip HTML from Tipue index, which makes the "search results" page correct Fix handling SVN fixed-length $Date:: Parsing of $if and $elseif expressions, like defined(MSWINDOWS) or defined(UNIX) (Michalis)
  14. @Marco Cantu I wish I as a subscriber could download it without having to reenter information already in your systems.
  15. There is a page in the Delphi wiki on creating packages. https://delphi.fandom.com/wiki/Creating_Packages Edit: I had totally forgotten that I wrote that page myself (many years ago). After reading through it, I must say I still like it. There isn't much I'd change today.
  16. https://github.com/DelphiPraxis/DDevExtensions/releases/tag/v2.87 compiled pre-release, not fully tested yet
  17. RAD Studio is made up of Delphi and C++Builder. On the Delphi side the Object Pascal compiler is a single pass compiler and the compiler itself is not a parallel compiler but when compiling multiple projects in parallel it was able to compile 1 billion lines of Object Pascal code in 5 minutes on the AMD Ryzen 9 5950x 16 core machine. I wanted to see if something similar was possible with C++. This post is part of our modern hardware series where we explore the massive productivity gains that can be achieved on some of the fastest CPUs available at the time of this writing in early 2021. Just how much is 1 billion lines of code? Take a look. https://blogs.embarcadero.com/threadripper-3990x-the-quest-to-compile-1-billion-lines-of-c-on-64-cores/
  18. Anders Melander

    Hashing Street Addresses ?

    I solve most of my problems in the shower. Eureka!
  19. aehimself

    Zeos 7.3 entered the beta phase.

    @Dany Marmur as far as I can see @EgonHugeist already started the development of the Zeos-based memory table. The latest snapshot already has the TZMemTable component - now it's time to start to play with it! Edit: Seems to be working as it should: procedure TForm1.FormCreate(Sender: TObject); begin ZMemTable1.FieldDefs.Add('MyField', ftWideString); ZMemTable1.Open; Try ShowMessage(ZMemTable1.RecordCount.ToString); ZMemTable1.Append; ZMemTable1.FieldByName('MyField').AsString := 'Hello world!'; ZMemTable1.Post; ShowMessage(ZMemTable1.RecordCount.ToString + sLineBreak + ZMemTable1.FieldByName('MyField').AsString); Finally ZMemTable1.Close; End; end; At the moment it throws a nullpointer AV if it's destroyed while it's open but I'll send a pull request with a fix in a minute.
  20. Really? Ouch 😨 It used to be much simpler: function TStringHelper.StartsWith(const Value: string): Boolean; begin Result := StartsWith(Value, False); end; function TStringHelper.StartsWith(const Value: string; IgnoreCase: Boolean): Boolean; begin if not IgnoreCase then Result := System.SysUtils.StrLComp(PChar(Self), PChar(Value), Value.Length) = 0 else Result := System.SysUtils.StrLIComp(PChar(Self), PChar(Value), Value.Length) = 0; end; function StrLComp(const Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; var I: Cardinal; P1, P2: PWideChar; begin P1 := Str1; P2 := Str2; I := 0; while I < MaxLen do begin if (P1^ <> P2^) or (P1^ = #0) then Exit(Ord(P1^) - Ord(P2^)); Inc(P1); Inc(P2); Inc(I); end; Result := 0; end; function StrLIComp(const Str1, Str2: PWideChar; MaxLen: Cardinal): Integer; var P1, P2: PWideChar; I: Cardinal; C1, C2: WideChar; begin P1 := Str1; P2 := Str2; I := 0; while I < MaxLen do begin if P1^ in ['a'..'z'] then C1 := WideChar(Word(P1^) xor $20) else C1 := P1^; if P2^ in ['a'..'z'] then C2 := WideChar(Word(P2^) xor $20) else C2 := P2^; if (C1 <> C2) or (C1 = #0) then Exit(Ord(C1) - Ord(C2)); Inc(P1); Inc(P2); Inc(I); end; Result := 0; end; Compared to StartsStr(), which (eventually) calls CompareString(): function StartsStr(const ASubText, AText: string): Boolean; begin Result := AnsiStartsStr(ASubText, AText); end; function AnsiStartsStr(const ASubText, AText: string): Boolean; begin Result := AnsiSameStr(ASubText, Copy(AText, 1, Length(ASubText))); // WHY Copy()? AnsiStrLComp() could have been used instead! end; function AnsiSameStr(const S1, S2: string): Boolean; begin Result := AnsiCompareStr(S1, S2) = 0; end; function AnsiCompareStr(const S1, S2: string): Integer; {$IFDEF MSWINDOWS} begin Result := CompareString(LOCALE_USER_DEFAULT, 0, PChar(S1), Length(S1), PChar(S2), Length(S2)) - CSTR_EQUAL; end; {$ENDIF MSWINDOWS} {$IFDEF POSIX} begin Result := UCS4CompareStr(UnicodeStringToUCS4String(S1), UnicodeStringToUCS4String(S2)); end; {$ENDIF POSIX} I don't have RTL/VCL source code past XE3, but I keep seeing people mention how bad it's getting in recent years. This is not good.
  21. FPiette

    Delphi book

    There is a new Delphi book in FRENCH. It will be useful to all people wanting to learn object oriented programming using Delphi. The books is based on Delphi 10.3 Community Edition but of course is also very good for all other editions and recent versions. To be noted: the author make use of UML schemas to illustrate OOP. The book is mostly oriented to Windows with VCL but also includes two chapters introducing FMX. https://www.editions-eni.fr/livre/delphi-10-3-programmation-orientee-objet-en-environnement-windows-9782409024665
  22. Sorting a reversed array is 100% from the real world. In a UI where you sort by a column ascending, and then sort by the same column descending.
  23. Nothing needs to be fixed. StringReplace is giving correct output, isn't it? You absolutely don't want to be calling Pos inside an efficient implementation of StringReplace. All that you are learning is that StringReplace is not efficiently written. The correct way to deal with that is to find/write and use a more efficient function to replace text. That is of course if this is a bottleneck in your code. Have you checked? BTW, do you really have calls to Pos littered through your code whenever you call StringReplace?
  24. david_navigator

    Hashing Street Addresses ?

    Thanks for all the replies and suggestions. Just went for a walk with the dog and realised that I don't need the address info at all, I can index the other data fields (5 x integers) to find the record I need 🙂 Amazing how doing something different often brings alternative solutions to the forefront.
  25. Mateus Vicente

    RAD 10.4 Android KeyboardType NumbersAndPunctuation not working

    @John van de Waeter the solution for your problem is add unit FMX.VirtualKeyboard.iOS.pas to the project and comment out two lines near the bottom of the file, on "function TCocoaVirtualKeyboardService.HideVirtualKeyboard: Boolean;": //if FTransient then // <- comment out this // Exit(False); // <- and this More info here: https://quality.embarcadero.com/browse/RSP-30045
×