1.x vs 2.x ========== Allocation ---------- Allocation mechanisms has been revised. All objects are still allocated from a private storage (called heap), but now the heap serves properly aligned memory chunks. Implementation of the heap is (hopefully) platform independent, so all ``ARM_COMPLIANT`` checks has been removed. Some details work differently on 32/64-bit machines, this distinction seems inevitable. Allocation related code has been moved to ``util/utilmem*.c`` files. [There are actually 3 different allocators - **heap**, **stock**, and **pool** - each of which has 4 variants for 1, 2, 4 and 8 bytes alignment. So far ``pplib`` uses only the **heap**, but I want to have this part in a single place for a while. More notes about allocators in ``utilmemallc.h``.] ``pplib`` uses two heaps: * bytes heap - providing 2-bytes aligned memory chunks for byte data * structures heap - providing 8-bytes aligned chunks for all structures 2-bytes alignment of byte data is caused by implementation details / limits, ``pplib`` doesn't make a use of it (could be unaligned as well). All the structures are stored in 8-bytes aligned chunks on both 32 and 64-bit machines (in some structures we use ``double`` and ``int64_t``, which generally needs 8-bytes). Strings And Names ----------------- So far, both ``ppname`` and ``ppstring`` were aliases to ``char *`` with an extra structure hidden just below the data address. The idea was to make a string or name usable whenever chars array can, at the cost of some pointers trickery. Both names and strings keep an information about pdf-encoded data, as well as plain bytes data. I implemented this feature once ``pplib 1.0`` was almost done, and to avoid a revolution, I made that with yet another trick. This all was dirty and caused lots of alignment issues. Now ``ppstring`` and ``ppname`` are **structures**, keeping data and size members, pretty much like ``pparray``:: struct ppname { ppbyte *data; size_t size; ppname *alterego; int flags; }; struct ppstring { ppbyte *data; size_t size; ppstring *alterego; int flags; }; Data member is a pointer to (2-bytes aligned) bytes array -- ``ppbyte *``. ``ppbyte`` is an alias to ``char``. ``pplib`` makes no assumptions about ``ppbyte`` signedness. [I'd prefer to have ``uint8_t``, but better keep that in sync with ``ppdict_get_*`` suite, which accepts ``char *``. Using ``"string literals"`` with ``ppdict_get`` function is the most common case, I guess.] ``ppname_size()`` and ``ppstring_size() `` now have trivial ``ppname_data()`` and ``ppstring_data()`` counterparts:: #define ppname_size(name) ((name)->size) #define ppname_data(name) ((name)->data) #define ppstring_size(string) ((string)->size) #define ppstring_data(string) ((string)->data) Switching between encoded / decoded variants is made via explicit ``alterego`` member. If encoded and decoded forms are identical, then ``self->alfterego == self`` (never NULL). Helper functions for that:: PPAPI ppname * ppname_decoded (ppname *name); PPAPI ppname * ppname_encoded (ppname *name); PPAPI ppbyte * ppname_decoded_data (ppname *name); PPAPI ppbyte * ppname_encoded_data (ppname *name); PPAPI ppstring * ppstring_decoded (ppstring *string); PPAPI ppstring * ppstring_encoded (ppstring *string); PPAPI ppbyte * ppstring_decoded_data (ppstring *string); PPAPI ppbyte * ppstring_encoded_data (ppstring *string); Since ``ppname`` and ``ppstring`` are now structures, all API functions returning name/string or taking name/string as an argument, now take **a pointer to name/string**. Watch out for ``ppdict_get_*`` functions suite. They still accept ``const char *`` key as an argument, but ``ppname`` type can no longer be used there:: ppname key; ppdict_get_something(dict, key); // wrong ppdict_get_something(dict, key.data); // ok ppname *pkey; ppdict_get_something(dict, (const char *)pkey); // wrong ppdict_get_something(dict, pkey->data); // ok Consequently, functions / macros that used pointer to ``ppname`` (``ppdict_first()`` / ``ppdict_next()``), now needs ``ppname **pname``. Cleanups -------- Some of unused utils were removed. There is still some code in utils part that is not used by the library, but I need this tollbox in many other places and don't want to maintain two versions. Some unification in integer types; ``size_t`` seems to be the best choice for and integer representing machine word (``unsigned long`` is not long enough on windows), less utils dependencies, less compiler warnings.