News

Hexlicense 1.0.3 is shipping

Vestfold, Norway 16.03.2017

We are proud to inform you that HexLicense 1.0.3 is now shipping to customers. This is an intermediate update between the current codebase and our Ironwood framework.

Binary hotfix

Compression made easy
HexLicense 1.0.3 is shipping

A minor problem with text overflow could occur in rare circumstances has been fixed. However this breaks binary compatibility with already generated license data.

A secondary loader will be included with Ironwood, which will detect older license data and attempt to correctly consume the information. However we urge our customers to use this version to be absolutely safe.

Low-level data framework

As promised earlier, our low-level buffer framework is now an integral part of the solution. The new classes (FMX.hexbuffers.pas and hexbuffers.pas for VCL) bring a wealth of functionality to a topic that many developers are uncomfortable with.

Things like compression, Encryption, easy access to REST and http services, full storage medium abstraction – these are but some of the benefits buffering brings. And they are all implemented or build on the functionality in this update.

Updated documentation

Documentation is being updated as we type. It should be published by monday 20th. Customers will receive an email notification. As always the documentation is available online as well as through download.

Sincerly

Jon Lennart Aasenden

Time limited offer, a whopping $40 discount!

This offer has expired

For a short time we offer you our FMX, VCL and VJL package with a $40 discount! That is a significant saving for a great product!

By acting now you gain full access to our classical component packages – as well as our next-generation licensing engine and platform:

  • 12 month subscription
    • 4 updates guaranteed
  • Full source code
    • VCL version
    • FMX version
      • Windows
      • OS X
      • iOS
      • Android
    • JVL version (Smart)
      • All mobile platforms
      • HTML5 applications
      • Node.js client and server applications
  • Solid documentation
  • Easy to use and drop into existing projects
  • Ships with examples
  • Support via E-mail

Ironwood

ironwood2The next generation HexLicense formula and license generator is Ironwood. This has been in the making for some time and is through the beta phase. We have used the absolute latest RTL for Smart – which will be in circulation within a few weeks. So you are getting the absolute latest to play with – which is can be used by both visual and node.js projects.

By acting now you not only save money but you also get a great deal on our classical Delphi components. Most importantly however, is that the discount buys you access to our next generation components. The next generation components which will retail at a higher price.

Smart Pascal

With mobile application development taking place more and more through HTML5 and phonegap – not to mention that node.js is quickly becoming a market standard server-side, compilers that targets the JavaScript virtual machine is becoming increasingly important.

Especially for traditional languages like Delphi and C++.

With access to Ironwood for Smart Pascal, your existing VCL and FMX products can continue to function as they do right now – while you move your licensing mechanisms to the cost-effective, scalable and portable node.js cloud servers.

Why pay huge amounts of money to rent a full virtual instance to host a native Delphi service – when you can do the exact same under node.js and Smart for but a fraction of the price? Not to mention the many benefits node brings to the table.

Discount covers all platforms!

discountWith Ironwood for Delphi you have not just one tried and tested license management system at your disposal, but two. You get the classical THexLicense package – now extended with a while set of new and powerful components and classes.

Again, this package will retail at a higher price and forms the basis of our future cloud based licensing services.

By acting now you secure early access!

Note: This is a time limited offer. Only the link above this text is valid for this discount.

Ironwood for Smart Pascal is shipping!

Tønsberg, vestfold, Norway 10.02.2017

Quartex Components are happy to announce that Ironwood for Smart Pascal is now shipping. Existing customers will receive an email notification with the download URL for the code.

The Ironwood units are compatible with both visual mobile application types, visual HTML5 applications and naturally node.js.

About Ironwood

Disk or memory, it matters not

Ironwood represents the next-generation license and serial number engine. It is more secure, faster and yields a larger amount of serial numbers per seed.

As always Hexlicense in all its forms is included for our customers. All customers recieve VCL, Firemonkey and Smart Pascal editions.

Ironwood for Delphi

Now that the Smart edition has been settled and uses the latest RTL (this RTL is due for public consumption within 1-2 weeks), focus is now on the Delphi edition of Ironwood.

Presenting Hexbuffers, a platform independent library for dealing with binary data

Note: HexBuffers is a part of Hexlicense and ships with the product.

In the previous update we shipped an auxiliary unit called FMX.hexbuffers.pas. This was to give our customers early access to some of the features in store for HexLicense. Well, a lot has happened since the last update and we want to give you a quick update on what to expect, and more hands-on information about HexBuffers.

First of all, Ironwood for Smart Pascal is now ready! It will ship with the next update and is free for all existing customers. It allows you to use Smart Mobile Studio to write node.js based servers that delivers licensing solutions for your applications. Node.js gives you plenty of perks out of the box, like being scalable, capable of running cluster mode (where high performance is achieved by dividing the payload between several server instances) and much, much more.

nodejs-2-562x3092x-op
Host your licencing solutions anywhere on any platform with node.js

Node.js is also fairly universal and can be honest on any computer system regardless of operating system. Code is also portable, meaning that unless your code use some very platform specific third-party libraries – you can move your servers and service between Windows, Linux and Unix without any changes needed.

Speed is also phenomenal. We were unable to detect any speed advantages for Delphi when it comes to node.js. In fact, node.js performs better in most cases than multi-threaded Indy based servers. This has to do with the way node.js and JavaScript in general is architected. No other system in the world has seen more development by a diverse range of programmers than the v8 JavaScript virtual machine, and its accompanying webkit HTML5 rendering engine. Both Apple, Google and thousands of freelance developers have contributed. Webkit is the de-facto browser engine for Android, iOS, OS X and the majority of embedded systems out there.

Streams and their shortcomings

processStreams are considered industry standard. Every programming language has them, be it basic dialects, C++ or object pascal. They provide a clear-cut interface for reading, writing and dealing with binary data.

What streams lack however, are operations. The kind of operations you will sooner or later have to deal with when it comes to working with complex binary data.

Take something simple, like an insert() function. This has been lacking in Delphi since the very beginning. When you write data to a stream, it is either appended or overwriting existing content (depending where the position cursor is).

Imagine for instance that you want to insert 1 megabyte of data into a file 6 gigabytes in size. How will you do this? Remember you are inserting into the middle of the file, not appending at the end. And we are not talking about a simple write operation, you are not allowed to overwrite any of the existing data. An insert() operation must inject the data without overwriting or causing damage to a single byte.

Such an operation needs a few steps:

  • Grow the file by 1 megabyte
  • Copy the data below the destination mark forward by 1 megabyte
  • Write the injected data to the destination mark

You may be wondering what type of scenario would demand that you inject a megabyte of data into a huge 6 gigabyte file, but that is beside the point. HexLicense deals with license data, data that must be protected and made hard to obtain or extract. Being capable of hiding license data inside other files should be considered a basic operation.

But inserting is not the only thing lacking from ordinary streams. Delete or some form or remove() operation is equally important. And equally missing. Let’s say you need to delete 1 megabyte from the same file, perhaps it’s a record in your own database system, perhaps its a license that is invalid — there can be 100 reasons to why you need to perform this operation. But Delphi’s TStream class simply have no such complex features.

But it doesn’t stop there. Duplicating data, injecting, copying and pasting, performing live compression, encryption or downloading content directly from the internet. These are all things that can be done, but with a great deal of work – but it’s not a ready to use solution in either Delphi or C++.

THexBuffer

Disk or memory, it matters not
Disk or memory, it matters not

THexBuffer is an abstract class. It implements a range of methods similar to TStream, but it has more features than streams in any language can offer. What is important to underline is that there is no difference between memory based buffers or disk buffers. The classes implement the exact same behavior (just like streams do) regardless of medium. Considering the complex features buffers have to offer, that should make you thrilled.

In short: A buffer represents either a memory allocation or file allocation. It provides the same functionality and abilities to perform advanced and complex file operations on both, regardless of medium. But you are free to implement other mediums as you please.

In fact, you could easily inherit from THexBuffer and have it read and write data to a remote file on a server. If your server expose some basic file IO functions, the buffer methods would not care or notice that the data is actually read from a remote location. They are completely abstracted from the storage medium.

Bridging buffers and standard Delphi IO

Making buffers work seamless side by side with ordinary streams is naturally very important. Otherwise data would have to be copied, rendering all the low-level power of buffers impressive, but worthless in real-life software.

To make sure this is not the case we ship with a class called THexStreamAdapter. This is a virtual stream class (inheriting from TCustomStream) that delegates all stream operations to whatever buffer it is connected to.This is extremely useful when you have performed complex operations using HexBuffers – and now need to interface with Delphi’s standard IO mechanisms (read: classes expecting TStream rather than a buffer).

So you do not lose anything by using buffers, you gain a very rich and highly flexible framework for dealing with binary files and data.

What does a buffer class look like?`

Here is the baseclass (we removed some protected sections to save some space), THexBuffer, that all buffer types inherit from. This should give you some idea of the complexity the unit offers. As of writing, the unit is close to 7000 lines of code, all of it representing the means to work with binary data efficiently and objectively.

THexBuffer = class(TInterfacedPersistent)
Protected
  (*  Extended persistence.
      The function ObjectHasData() is called by the normal VCL
      DefineProperties to determine if there is any data to save.
      The other methods are invoked before and after either loading or
      saving object data.

      NOTE: To extend the functionality of this object please override
      ReadObject() and WriteObject(). The object will take care of
      everything else. *)
  function ObjectHasData: boolean;
  procedure BeforeReadObject;virtual;
  procedure AfterReadObject;virtual;
  procedure BeforeWriteObject;virtual;
  procedure AfterWriteObject;virtual;
  procedure ReadObject(Reader: TReader);virtual;
  procedure WriteObject(Writer: TWriter);virtual;
Protected
  (* Call this to determine if the object is empty (holds no data) *)
  function GetEmpty: boolean;virtual;
Protected
  (* Actual Buffer implementation. Decendants must override and
     implement these methods. It does not matter where or how the
     data is stored - this is up to the implementation. *)
  function DoGetCapabilities: THexBufferCapabilities;virtual;abstract;
  function DoGetDataSize: Int64;virtual;abstract;
  procedure DoReleaseData;virtual;abstract;
  procedure DoGrowDataBy(const Value: integer);virtual;abstract;
  procedure DoShrinkDataBy(const Value: integer);virtual;abstract;
  procedure DoReadData(Start: Int64; var Buffer;
      BufLen: integer);virtual;abstract;
  procedure DoWriteData(Start: int64; const Buffer;
      BufLen: integer);virtual;abstract;
  procedure DoFillData(Start: Int64; FillLength: Int64;
            const Data; DataLen: integer);virtual;
  procedure DoZeroData;virtual;
Public
  property  Empty: boolean read GetEmpty;
  property  Capabilities: THexBufferCapabilities read FCaps;
  property  Size: int64 read DoGetDataSize write SetSize;

 {$IFDEF BR_SUPPORT_ZLIB}
 property   ZLibDeflateEvents: THexDeflateEvents read FZDEvents write FZDEvents;
 property   ZLibInflateEvents: THexInflateEvents read FZIEvents write FZIEvents;
 {$ENDIF}

  procedure Assign(Source: TPersistent);Override;

  (* Read from buffer content to memory *)
  function  Read(const ByteIndex: int64; DataLength: integer; var Data): integer;overload;

  (* Write to buffer content from memory *)
  function  Write(const ByteIndex: int64; DataLength: integer; const Data): integer;overload;

  (* Append data to end-of-buffer from various sources *)
  procedure Append(const Buffer:THexBuffer);overload;
  procedure Append(const Stream:TStream);overload;
  procedure Append(const Data;const DataLength:integer);overload;

  (* Fill the buffer with a repeating pattern of data *)
  function  Fill(const ByteIndex: int64;
            const FillLength: int64;
            const DataSource; const DataSourceLength: integer): int64;

  (* Fill the buffer with the value zero *)
  procedure Zero;

  (*  Insert data into the buffer. Note: This is not a simple "overwrite"
      insertion. It will inject the new data and push whatever data is
      successive to the byteindex forward *)
  procedure Insert(const ByteIndex: int64;const Source; DataLength: integer);overload;
  procedure Insert(ByteIndex: int64; const Source:THexBuffer);overload;

  (* Remove X number of bytes from the buffer at any given position *)
  procedure Remove(const ByteIndex: int64; DataLength: integer);

  (* Simple binary search inside the buffer *)
  function Search(const Data; const DataLength: integer; var FoundbyteIndex: int64): boolean;

  (*  Push data into the buffer from the beginning, which moves the current
      data already present forward *)
  function  Push(const Source; DataLength:integer):integer;

  (* Poll data out of buffer, again starting at the beginning of the buffer.
     The polled data is removed from the buffer *)
  function  Pull(Var Target; DataLength:integer):integer;

  (* Generate a normal DWORD ELF-hashcode from the content *)
  function  HashCode:Longword;virtual;

  (* Standard IO methods. Please note that these are different from those
     used by persistence. These methods does not tag the content but loads
     it directly. The methods used by persistentse will tag the data with
     a length variable *)
  procedure   LoadFromFile(Filename: string);
  procedure   SaveToFile(Filename: string);
  procedure   SaveToStream(Stream: TStream);
  procedure   LoadFromStream(Stream: TStream);

  (* Export data from the buffer into various output targets *)
  function    ExportTo(ByteIndex: Int64; DataLength: integer; const Writer: TWriter):integer;

  (* Import data from various input sources *)
  function    ImportFrom(ByteIndex: Int64; DataLength: integer; const Reader:TReader):integer;

 {$IFDEF BR_SUPPORT_ZLIB}
  procedure   CompressTo(const Target:THexBuffer);overload;
  procedure   DeCompressFrom(const Source:THexBuffer);overload;
  function    CompressTo:THexBuffer;overload;
  function    DecompressTo:THexBuffer;overload;
  procedure   Compress;
  procedure   Decompress;
  {$ENDIF}

  (* release the current content of the buffer *)
  procedure   Release;
  procedure   AfterConstruction;Override;
  procedure   BeforeDestruction;Override;

  (* Generic ELF-HASH methods *)
  class function ElfHash(const Data; DataLength: integer):longword;overload;
  class function ElfHash(const Text: string): longword;overload;

  (* Kernigan and Ritchie Hash ["the C programming language"] *)
  class function KAndRHash(const Data; DataLength: integer): longword;overload;
  class function KAndRHash(const Text: string): longword;overload;

  (* Generic Adler32 hash *)
  class function AdlerHash(const Adler: Cardinal; const Data; DataLength: integer): longword; overload;
  class function AdlerHash(const Data; DataLength: integer): longword;overload;
  class function AdlerHash(const Text: string): longword;overload;

  class function BorlandHash(const Data; DataLength: integer): longword;overload;
  class function BorlandHash(const Text: string): longword;overload;

  class function BobJenkinsHash(const Data; DataLength: integer): longword;overload;
  class function BobJenkinsHash(const Text: string): longword;overload;

  (* Generic memory fill methods *)
  class procedure Fillbyte(Target:Pbyte;
        const FillSize:integer;const Value: byte);

  class procedure FillWord(Target:PWord;
        const FillSize:integer;const Value: Word);

  class procedure FillTriple(dstAddr:PHexTriplebyte;
        const inCount:integer;const Value: THexTriplebyte);

  class procedure FillLong(dstAddr:PLongword;const inCount:integer;
        const Value: Longword);
end;

As you can see THexBuffer offers some very handy functions. It must also be stressed that the entire unit is written from scratch, every method is implemented by us – including the hashing methods (these are also present in Delphi, but not like this).

Performing in place compression

Compression made easy
Compression made easy

Let’s say you have a stream with some data that you want to compress. In Delphi that means creating a target stream for the result, then you must create and use a stream compression instance to glue source and target together, before you perform a copy operation that actually makes use of the compression routine. While this may be well abstracted and future-proof, we fill it’s overkill in the extreme for such a simple thing. The only option in question should really be compression mechanism, but since Delphi only ships with ZLib out of the box – we even refactored that out.

So this is now a one-liner:

FBuffer.Compress();

This naturally has its matching opposite in the UnCompress() method.

You can also compress and emit the data in a different buffer, using the CompressTo() method (and it’s corresponding DecompressTo() method). THexBuffer gives you a lot of input options, be they streams, direct memory access or even TReader. We have tried to make buffers as useful and simple to deploy as possible.

In memory records

The unit ships with a class called THexRecord, a class that has a number of field-classes associated with it. This class essentially represents an in-memory record. But fully object-oriented. So you create a record by adding fields manually, or allowing the object to automatically create them on demand for you. It will check if a field exists by name when you write to it, if it does not – it can create the field for you.

This class and it’s child classes are exceptionally handy when reading with custom file-formats. For example, when you writing a header to your own database file-format. Not to mention working with networking and raw, binary packets. Such code quickly turns into a mess, but with THexRecord you get to approach the task from a purely object-oriented viewpoint.

Write your own database engine

The Hexbuffers unit has actually been used to create a fully operational, 100% Delphi only flat-file database (amongst many other things). There is a class called THexPartsAccess that allows you to access a file as fixed-size pages. Essentially a page represents a chunk or block of binary data. A database record can require several pages to be stored (normally a database page is 1024 or 4096 bytes in size), typically such a page has a “next” field, pointing to the ID number of the next page making up a record.

Roll your own, it's not that hard
Roll your own, it’s not that hard

You typically use a bit-map, a range of bits, each representing a block, to keep track of what blocks are free and what blocks are in use by records. So when you delete a record you don’t have to shrink the file each time (that would be very time-consuming), you simply mark the blocks as un-used so they can be recycled. You then isolate a full cleanup in a procedure like Compact() or similar.

So writing complex software is not hard when you got the right tools. And HexBuffers will give you a lot of interesting new possibilities for working with licensing and where/how you store your license.

It is also a solid foundation to build more and more complex license behavior. It is platform independent, framework independent and will run just as fine on iOS as it will on a Linux server.

 

Ironwood for Smart Pascal now in beta

Tønsberg 27.11.2016

Hexlicense “Ironwood” has finally reached the early stage of beta – which means the Smart Pascal (JavaScript) edition will ship to customers late mid december as planned.

All customers that have bought Hexlicense within the past 12 months will be emailed a download link for the product.

Hexlicense for node.js servers and HTML5 clients
Hexlicense for node.js servers and HTML5 clients

Smart Pascal

16886941Smart Mobile Studio is an object pascal environment that compiles to JavaScript and HTML5 rather than machine code. It can be used to write HTML5 applications, native applications (using Cordova and Adobe build services to convert the JavaScript code into binaries) for almost every platform on the market.

HexLicense cannot be used with the free, stand-alone commandline compiler. It relies on several features of the Smart RTL, which requires a proper Smart Mobile Studio License to deploy.

For more information about Smart Mobile Studio, head over to The Smart Company and check it out.

Hexlicense for FMX is shipping

We are happy to inform you that HexLicense for Firemonkey is finally out of beta and will ship to registered customers tomorrow (13.10.2016).

Hexlicense for Firemonkey is now shipping
Hexlicense for Firemonkey is now shipping

HexLicense has been tested on all major platforms:

  • Microsoft Windows 32 and 64 bit
  • Apple OS X 64 bit
  • Google Android
  • Apple iOS

Consistency between platforms

Hexlicense implements the same visual consistency between platforms. We have also implemented platform specific code to make sure HexTools yields the same information regardless of device.

This is now a “write once, deploy everywhere” solution.

Consistency across platforms
Consistency across platforms

New units

Two new source units has made it into the HexLicense package, namely fmx.hexbuffers and fmx.hex.ios.tools. HexBuffers is a core unit from the upcoming Ironwood milestone. It provides a great deal of functionality and classes for working with memory and files using identical code. It is platform dependent and 100% pure object pascal.

The iOS tools unit contains code used by THexHelper to obtain information on Apple mobile devices.

The documentation for HexLicense will be updated over the next week to reflect these new additions.

Gearing up for Ironwood

ironwood2Not resting on our laurels work on Ironwood begins next week. The Smart Pascal edition is more or less finished, and porting the codebase to Delphi and Lazarus is what’s next on the menu.

Ironwood brings you a substancial amount of new components, most importantly the Ironwood key generator which is more efficient than our traditional HexLicense formula. You also get fine-tune control over the process right down to how numbers are grown and modulated.

You can give Ironwood a test-drive right in your browser, click here to see a demo

Try it in your browser

The upcoming HexLicense “Ironwood” edition is still in the making for Delphi – but the JavaScript version already exist, so why not test drive it in your browser? Just click below and you can generate some license numbers.

Hexlicense running under Javascript
Hexlicense running under Javascript

Limitations for the browser

Ironwood for JavaScript is meant to execute in a webworker (thread) within a node.js server environment. We have basically compiled this code ad-hoc for the browser, which means that should you try to generate to much data – the browser will probably shut down the code (there is a time limit for code running in a browser).

The codebase between Smart Pascal, Delphi VCL and Delphi FMX is more or less identical in Ironwood. You can read more about Ironwood in our roadmap for 2016 and beyond.