How to compare C++ builder/Delphi DFM binary files with Tortoise SVN ?


With antique versions of Delphi or C++ builder (<= 4), the DFM files – which define the structure of the application forms – are stored as binary files.
Binary files are a hassle because they prevent any batch processing, search, etc… But only with version control do they become a real pain in the ass. Versions can’t be compared, which makes conflict solving almost impossible. And conflicts happen often because Delphi and C++ builder modifiy DFM files for any reason (ex : moving a form around).

If you use Tortoise SVN and strugle with DFM conflicts, here is a solution to automate DFM comparison : Continuer la lecture

Why is « boolean val = (0 == 0 ? null : true) » causing a Java NullPointerException ?

This would be a funny interview question : why is the following Java code compiling but throwing a NullPointerException at runtime ?
[code lang=java]
boolean val = (0 == 0 ? null : true);
[/code]

Since boolean is a primitive data type, it can’t be initialized with a null value. As a matter of fact, the compiler rejects the following code :
[code lang=java]boolean val = null;[/code]
So, one would expect the conditional/ternary operator assignement to also fail at compile time, whether because null can’t be assigned to a boolean, or because null and true don’t have the same data type, which is not allowed by the ternary operator.
That’s not the case, compilation runs fine, only at runtime do you get a NullPointerException.
Why ?

I guess this comes from Java autoboxing/autounboxing feature. Since the « then » and « else » parts of the operator must have the same type, Java autoboxes true to Boolean.TRUE, and assumes null is a Boolean. Knowing that Boolean can be autounboxed to boolean, the compiler will accept the statement.

Then, at runtime, null will be autoboxed to boolean, eventually causing the NullPointerException. Et voilà !

C++ builder EAccessViolation when calling Variant.OlePropertySet() for Excel Automation

After migrating an application from C++ Builder 4 to C++builder 6, the excel COM automation started to crash with error EAccessViolation at address 00000800 when calling the Variant.OlePropertySet(), OlePropertyGet() or OleFunction() methods, as in the following code :

[code lang=cpp]
Variant xlApp = Variant::CreateObject(« Excel.Application »);
xlApp.OlePropertySet(« Visible », true); // causes the EAccessViolation
Variant workbooks = xlApp.OlePropertyGet(« Workbooks »);
Variant currentWorkbook ClasseurCourant = workbooks.OleFunction(« Open », L »C:\\MyExcelFile.xls »);
[/code]
Excel-OlePropertySet-EAccessViolation
This code was working fine with Builder 4, it was also working fine when used in a brand new application, but it always crashed in the converted app. Given that many developers reported the same error, with no known fix, and that one couldn’t expect support for a 12 years old IDE, I eventually fixed the issue by bypassing the Borland Wrappers and using directly COM.
Continuer la lecture

Wattpad API requests must contain a valid browser User-Agent header

Recently, I’ve been playing with the Wattpad API. I was interested in collecting stats about the most popular publications.
Wattpad_logo_svg
Even though the API is simple and well documented, all attempts to use it through a python script failed. Requests were rejected with a « 403 Access forbidden » HTTP error. My first intuition was that the basic authentication was incorrectly specified, but despite the API samples, I couldn’t figure out what was wrong with it.

Using WireShark to sniff the API sample requests would have helped solving the issue, but since the API only supports https, sniffing wasn’t an option (I later realized that I could have simply disabled https, just to sniff the request, since I didn’t care about the response).

Eventually, the problem came from the User-Agent header. The python script used a default User-Agent, which was rejected by the Wattpad server. Impersonating a legitimate browser (ex : chrome) solved the issue, requests were immediately accepted.

Below is a Python sample.
Continuer la lecture