Did you know ... | Search Documentation: |
![]() | Defining a BLOB type |
The type PL_blob_t
represents a structure with the
layout displayed below. The structure contains additional fields at the
... for internal bookkeeping as well as future extensions.
typedef struct PL_blob_t { uintptr_t magic; /* PL_BLOB_MAGIC */ uintptr_t flags; /* Bitwise or of PL_BLOB_* */ const char * name; /* name of the type */ int (*release)(atom_t a); int (*compare)(atom_t a, atom_t b); int (*write)(IOSTREAM *s, atom_t a, int flags); void (*acquire)(atom_t a); int (*save)(atom_t a, IOSTREAM *s); atom_t (*load)(IOSTREAM *s); ... } PL_blob_t;
For each type, exactly one such structure should be allocated. Its
first field must be initialised to PL_BLOB_MAGIC
. The
flags is a bitwise or of the following constants:
PL_BLOB_NOCOPY
is also specified, in which case the
pointers are compared.PL_BLOB_UNIQUE
is also specified, uniqueness is determined by comparing the pointer
rather than the data pointed at. Using
PL_BLOB_UNIQUE|
PL_BLOB_NOCOPY
can
be used to make a blob reference an arbitrary pointer where the pointer
data may be reclaimed in the release() handler.PL_BLOB_TEXT
is also set, then the text is made up of
pl_wchar_t
items and the blob's lenght is the number of
bytes (that is, the number of characters times sizeof(pl_wchar_t)
).
As PL_BLOB_TEXT
, this flag should not be set in
user-defined blobs.
The name field represents the type name as available to
Prolog. See also current_blob/2.
The other fields are function pointers that must be initialised to
proper functions or NULL
to get the default behaviour of
built-in atoms. Below are the defined member functions:
atom_t
handle into the content of the blob. Given a pointer
to the content, we can now use PL_unify_atom()
to bind a Prolog term with a reference to the pointed to object. If the
content of the blob can be modified (PL_BLOB_UNIQUE
is not
present) this is the only way to get access to the atom_t
handle that belongs to this blob. If
PL_BLOB_UNIQUE
is provided and respected, PL_unify_blob()
given the same pointer and length will produce the same atom_t
handle.FALSE
, the atom garbage collector will not reclaim
the atom. The release(f)unction
is called when the atom is reclaimed by the atom garbage collector. For
critical resources such as file handles or significant memory resources
it may be desirable to have an explicit call to dispose (most of) the
resources. For example,
close/1
reclaims the file handle and most of the resources associated with a
stream, leaving only a tiny bit of content to the garbage collector. See
also setup_call_cleanup/3.static int compare_my_blob(atom_t a, atom_t b) { const struct my_blob_data *blob_a = PL_blob_data(a, NULL, NULL); const struct my_blob_data *blob_b = PL_blob_data(b, NULL, NULL); return (blob_a > blob_b) ? 1 : (blob_a < blob_b) ? -1 : 0; }
PL_WRT_*
flags defined
in
SWI-Prolog.h
. This prototype is available if the
SWI-Stream.h
is included before
SWI-Prolog.h
. This function can retrieve the data of the
blob using PL_blob_data().
If this function is not provided, write/1
emits the content of the blob for blobs of type PL_BLOB_TEXT
or a string of the format <#
hex data>
for binary blobs.
If a blob type is registered from a loadable object (shared object or DLL) the blob type must be deregistered before the object may be released.
NULL
), the default implementation saves and
restores the blob as if it is an array of bytes which may contain null (’
0'
) bytes.
SWI-Stream.h
defines a number of PL_qlf_put_*()
functions that write data in a machine-independent form that can be read
by the corresponding PL_qlf_get_*() functions.
If the “save'' function encounters an error, it should call
PL_warning(),
raise an exception (see PL_raise_exception()),
and return FALSE
.221Details
are subject to change. Note that failure to save/restore a
blob makes it impossible to compile a file that contains such a blob
using qcompile/2
as well as creating a
saved state from a program that contains such a blob
impossible. Here, contains means that the blob appears in a
clause or directive.
NULL
, the
default implementation assumes that the blob was written by the default “save''
- that is, as an array of bytes
SWI-Stream.h
defines a number of PL_qlf_get_*()
functions that read data in a machine-independent form, as written by
the by the corresponding PL_qlf_put_*() functions.
The atom that the “load'' function returns can be created using PL_new_blob().
unregistered
, avoiding further
reference to the type structure, functions referred by it, as well as
the data. This function returns TRUE
if no blobs of this
type existed and FALSE
otherwise. PL_unregister_blob_type()
is intended for the uninstall() hook of foreign modules, avoiding
further references to the module.