Jump to content


Popular Content

Showing content with the highest reputation on 01/29/22 in all areas

  1. Sherlock

    did Sherlock left DP?

    I'm OK, guys, thanks for asking. Not Corona, but I've spent some time in the hospital nonetheless.
  2. Well, this is a private research-project about the EU Covid-certificates. I wanted to know how that stuff works and how the pieces are glued together. After a wild mixture of very interesting and also some nasty hours, I got it working. I also learned about new data formats that were previously unknown to me (hello "cbor"). Many different techniques come together here: decoding the data from Base45 (yes, forty-five) decompressing the result using the zlib-classes downloading external supplementary files using the http-components hopping from the formats "COSE" to "CBOR" to "JSON" using OpenSSL to extract and validate the digital signature against the official public keys All of this is now integrated in a small and fluffy Delphi program. This client reads the personal/medical data from the certificate displays the specific information for "vaccinated"-certificates "tested"-certificates "recovered"-certificates reads the digital signature from the certificate verifys that signature using the public keys from the official trust-list to detect fraud is clearly not an official application ready for production use anywhere Important: Some, but not all code ist from me. The unit "cbor.pas" comes from "https://github.com/mikerabat/DelphiCBOR", the interface to openssl comes from "https://github.com/Arvur/OpenSSL-Delphi". Just in case you're interested and want to try it: Download attached zip-archive. It contains the complete Delphi-project as well as the value-sets and trust-list (see #3). You need to get your hands on the openssl-libraries "libeay32.dll" and "ssleay32.dll" (not included in the downloads). These libraries must be located in the same directory as the executable. By default "Win32-Debug" is the output-path for this project. If you decide to switch to 64bit, you should provide the matching libraries. This program reads the trust-list and the so-called value-sets from external json-files. These files can be downloaded using the button "Download supplementary data" (button starts download, gives no feedback, you must restart the program afterwards). The trust-list contains the list of currently valid public-certificates. The value-sets contain the translations from IDs (values) to readable strings. All the json-files must be in the same directory as the executable - and that directory must be writable. The json-files from today are included in the download. You need - of course - an EU Covid-19 health certificate (vaccinated, tested or recovered). Take any barcode-scanner to translate the barcode into textual representation: You should get a string starting with "HC1:". Paste that code into the windows that opened after pressing "Scan certificate". CovDemo_06-Feb-2022.zip
  3. Dalija Prasnikar

    Using uninitialized object works on Win32, throws AV on Win64

    Yes, you were lucky. Uninitialized variable will contain whatever was previously written at that location. If you were lucky enough that value is zero, broken code would work. Yes, there is a compiler difference one is 32bit compiler another is 64bit one. Pointer sizes are different. Memory layout will be different. But, different compiler is besides the point. Working with uninitialized variables is undefined behavior. That means anything can happen even with the same compiler.
  4. Modelmaker CodeExplorer (MMX) offers that, and a lot of similar stuff for quickly adding methods etc. And it's free now. Could not live without it...
  5. David Heffernan

    Using uninitialized object works on Win32, throws AV on Win64

    You weren't lucky. You were unlucky. Lucky would have been if the error had shown itself immediately. No point analysing luck. Fix your code and move on.
  6. Just more of the same debate about how many angels can dance on the head of a pin, and the debate either devolves into what the angels are wearing or how big the head of the pin is. If you don't like using properties, don't use them. It's that simple. If you think having functions called by a property adds more overhead than calling a function yourself (as if that's a big deal) then just put "inline" after the function declaration. If you'd rather have longer, more descriptive names, then just give them longer more descriptive names: property GetThisViaRESTService : integer read gtvrs; I find far more advantage to using properties than not using them. And for every (infrequent) instance where there's a limitation, it's easy to get around it. I only wish it were easier to type in a bunch of property declarations that follow a simple pattern: a popup box that asks for the property name, its type, checkbox for read and write and whether they're a local var or a method. Is there anything that simple that doesn't require me to install a huge amount of other stuff at the same time? The most frequent problem I have is when I try to pass one into a var or out parameter in a method call. Thankfully those are not very common.
  7. I think that if Delphi was created today, the DFM file would be a JSON file. Since you're familiar with JSON, you know that if there's nothing in it, it's very small. The format used by DFM files is like JSON only simpler. DFM files are used to save property values defined in the Object Inspector at design time for a given form or DFM. If there are no components on the form or DM canvas, then the DFM file is basically empty. Also, since it's managed the same way as any other form in Delphi, you have the same degree of control of when they're created. By default, they're created automatically. But you can right-click on your project, select Options... then Forms and move it to the right-hand column which represents all of the forms and DMs that you do NOT want to be created automatically. A simpler way is to just right-click on the project, select View Source, and delete the line where a form or DM is created, then save it. In your code, simply call Create where you want an instance and save the reference in a variable somewhere. You can use the one that's emitted in the file by default (a global var in the unit), or you can use any other variable. You can also call it multiple times to create multiple instances. When you're done, just just Free them. I'm sorry for so many words, but I take a lot of words to explain stuff because it seems a lot of people cannot read between the lines of one-line answers. Since I have taken so many words to explain this, I hope you'll actually try it out and see that what I said earlier is correct.
  8. Different languages have different set of features and also differ in implementations of those features. Properties in general are a tool that provides additional level of abstraction around encapsulation and enables future implementation changes while preserving stable public API. Some of the benefits are more visible in some languages than the others. For instance, if you have public field Name and you want to add some code around retrieving that field is easy to do in Delphi. You can rename field and move it to private section and declare public function Name to retrieve it. I Java, you cannot do such thing because calling method must include brackets. This requires refactoring all code that uses such field. If you want to add setter, you will break the code in any language. This is where using properties helps with encapsulation. They hide unnecessary implementation details and give implementing class to ability to change those without breaking user code. You can start with simple field backed property, which from performance aspect is no different than public field and you can add getters and setters as needed without breaking code. Without properties, you can also maintain stable API, but the cost is having getters and setters for everything and paying the price in performance. No matter how small it is, eventually it can add up. Additionally, code with simple assignment is easier to read than setter method. There are some parts of general properties functionality that Delphi does not implement, like different access levels for reading and writing, or some additional ceremony when declaring properties, especially in interfaces. Some of those could be improved to make properties more flexible, but lacking them is poor argument against using properties. In situations where you really need some functionality properties don't provide, you can use other ways to achieve what you need, but not using properties everywhere else because you cannot do something in rare occasions is also not very convincing argument. Arguments around name refactoring are not very convincing either. They compare name refactoring, where there is a bit more renaming in declaration. Now, compare that single place where you need to make additional rename, to refactoring all code in case where you need to replace public fields with accessor methods. When it comes to extra declaration code needed for properties with accessor methods comparing to only having accessor methods, think how much unnecessary getters and setter methods you need to write in cases where you could use field backed property declaration. Overall using properties results with cleaner code and having more functionality than you can have with simple fields or just accessor methods. The little bit of ceremony around the declaration is price I am more than willing to pay, to get all other benefits.
  9. I use datamodules alot - I remove them from the autocreate list and then manually create and delete them in code (initialising with a nullptr for the owner (I'm a C++ gent)). I find this very convenient. Using pooled connections I find this works well.