- regionSwab() calling dataLength() on headerImport() is one of the
busiest paths in rpm, and dataLength() on string types is a very
expensive call as it has to walk through the string looking for \0's.
The data size is actually available most of the time by just looking
at offsets (idea lifted from rpm5.org), which is an order of magnitude
faster than crawling string data. The downside (there always is one)
is that with offsets, string data is not validated to contain
sufficient number of \0's, which means malformed headers could cause
us to crash, burn and overflow when accessing the string data.
- The new "fast" mode enables offset-based calculation at callers
discretion, ie if the caller can reasonably assume the header is
sane (known to be previously validated etc), using the fast-flag
will make header loading/importing considerably faster.
For now, only headerImport() will use the fast mode but it might
make sense to remember the setting in the header and use for other
operations as well.
- Most callers need the size of the blob as well, which the unloader
internals know perfectly well but the interface doesn't support
passing it. So callers were forced to make a second call to
headerSizeof() to recalculate the size. Duh.
- Rename and export doHeaderUnload() as headerExport(), update internal
callers to use the new name. headerExport() is hopefully a bit
more obvious as a name than headerUnload() which doesn't actually
undo the effect of headerLoad() for that header, but merely exports
the data by serializing into on-disk format.
- Header size is not size_t really, its capped to fixed much lower
size. Use unsigned int to better match reality.
- Unlike headerLoad(), headerImport() takes a blob size argument
to allow sanity checking the size calculated from the blob itself
against the "physical" passed-in blob size so its a bit safer.
Note that header size is capped by various things - its not size_t.
- headerImport() also takes a flags argument to allow controlling
various aspects of importing.
- Implement "take copy of blob" as a flag to headerImport(), push
the copying into headerCreate() where we already know the blob
size, avoiding the need to do double-calculations on headerCopyLoad()..
- headerLoad() and headerCopyLoad() are now just compat wrappers
around the new interface.
- The header getters are used for both signature header and the "normal"
header, and even beyond that there's no requirement for a tag in
the header to be part of rpmTag enum. The headerPutFoo() variants
technically do require the tag to be found in the tag table (ie be
an rpmTag) but they still operate on the integer value, they dont
require it to be a "true" enum.
- Inside tagexts.c there are a few "true" enum uses in the
internal helper functions, leave them be.
- While this technically changes some the most commonly used API's,
this wont affect callers really: if the callers were using an enum
before, enum can always be cast naturally to an integer. The other
way around was the problematic part (ie the braindamage we're fixing
here now...)
- Enums are fine for defining the bitfield flags, but the bitfield
itself is not an enumeration. Add a separate typedef on "rpmFlags"
type (presenting a bitfield of flags) for all of these. Compilers
hardly care, but the typedefs give a nice visual clue for
us humans using these flags far away from ho^H^H definitions.
- These are internal helpers only, all refcount users need to use
fooFree() or similar for correct operation. Add fwd declarations
where necessary to avoid moving code around unnecessarily.
- We could add these back later as aliases to fooFree() but for now,
just get them out of the way.
- we dont always want the actual contents of the tag to be copied
on iteration, so add an interface that returns the next tag in the
header
- this lets callers to decide what to do with the tag and how to
retrieve it
- easy to do and some places would like the data this way so why not...
- also add corresponding rpmtd flag so caller can verify he got what
was requested
- set "instance" number on retrieval from rpmdb
- add public headerGetInstance() function for retrieving the value
- ported from rpm5.org, useful for number of things
- get them out of sight from main header.h
- turn headerSprintf() into macro around headerFormat(), that way
rpmTagTable and rpmHeaderFormats lossage can be hidden away as far
as headerSprintf() use is concerned
- requiring all access through rpmtdFromFoo() just adds unnecessary
indirection and pain for little gain, the header is fairly intelligent
when it comes to inserting data
- this gives us various benefits over the old headerAddEntry() interface too:
+ basic type checking done by compiler
+ extra sanity checking (ie you can't add string data to integer tags,
don't permit adding more than one entry to non-array data etc)
+ "do the right thing" approach - add / append as needed and supported
by various types
+ headerPutString() can now be used on both single strings and string
arrays making the interface much nicer for the rather common case of
appending strings one by one to string array tags
- no differences here except headerDel is a nice short name (lifted from
rpm5.org) to go with the new headerGet() etc family
- deprecate headerRemoveEntry()
- earlier there was no way for caller to know if returned data or parts
of it pointed to header memory (other than "know" how rpm behaves on
given types), this allows consistent behavior for callers (ie you
always "own" the returned data, not depending on header) when needed
- if HEADERGET_ALLOC flag is set, all returned data is malloced, instead
of possibly pointing to header memory depending on type
- HEADERGET_ALLOC overrides HEADERGET_MINMEM if both specified
- adjust various header internal callers to accept flags instead of just
minmem argument
- TODO: make sure tag extensions honor this too (all but fsnamesTag
currently allocate anyway)
- everything is now accessible through other methods, no need to expose
our internals
- tagtbl.c is now included from tagname.c instead and not separately built
- bit of a kludgery until fooTag() formatters have been converted
to take rpmtd struct as argument
- idea lifted from rpm5.org, implemented independently (and probably quite
differently)
- add rpmTag_e enumerations for all extension tags
- add extension field to headerTagTableEntry_s for things that are "pure"
extensions (instead of just extension overrides) so we have a chance to
catch out anybody trying to insert such tags to headers
- tag container isn't that big a win on add/append operations as it is on
retrieval, just use the existing headerAddEntry() family to do the
actual work
- headerPut() is a nice and short name, lifted from rpm5.org, API might
differ
- flags to control operation, just whether append is permitted or not for now
- new public API function headerGet() that returns data in rpmtd, with
flags to control operation (just minmem or no for now)
- headerGet() is nice and short name, lifted from rpm5.org but our API
differs as this takes a separate arg for the tag to get instead of
(ab)using the container to pass data back and forth
- internal compatibility wrapper to keep headerGetEntry() and -MinMem
version working