BCatalogMirror Class Reference
[Data Model]

#include <support/CatalogMirror.h>

Inheritance diagram for BCatalogMirror:

BnCatalogPermissions BnCatalog BnNode BnIterable BObserver BBinder BBinder IIterable BBinder INode BBinder ICatalog BBinder ICatalogPermissions List of all members.

Detailed Description

CatalogMirror is an ICatalogPermissions + ICatalog.

A CatalogMirror is a combination of ICatalogPermissions and ICatalog. When placed in the namespace, clients can access the mirror as if they are accessing the catalog itself. Except that the mirror can have restrictions, and items hidden or overlayed.

When you create an CatalogMirror, you must give it the ICatalog to mirror. Do that with either @{catalog -> icatalog_binder} or @{catalog_path -> /catalog_path}.

virtual status_t AddEntry (const SString &name, const SValue &entry)
 Add or modify an entry in the catalog.
virtual sptr< INodeAttributes () const
 Retrieve the meta-data catalog associated with this node, or NULL if it doesn't exist.
 BCatalogMirror (const SContext &context, const SValue &args)
 BCatalogMirror constructor - takes "catalog" or "catalog_path".
virtual sptr< IDatumCreateDatum (SString *name, uint32_t flags, status_t *err)
 Create a new IDatum object inside of this catalog.
virtual sptr< INodeCreateNode (SString *name, status_t *err)
 Create a new INode in this catalog.
virtual nsecs_t CreationDate () const
 Retrieve the "creationDate" meta-data entry, or 0 of it doesn't exist.
virtual status_t HideEntry (const SString &name)
 Hide an entry from the original catalog.
virtual SValue Inspect (const sptr< IBinder > &caller, const SValue &which, uint32_t flags)
 Probe binder for interface information.
virtual status_t Link (const sptr< IBinder > &target, const SValue &bindings, uint32_t flags)
 Link registers the IBinder "target" for notification of events.
virtual status_t Merge (const sptr< ICatalog > &catalog)
virtual SString MimeType () const
 Retrieve the "mimeType" meta-data entry, or "" if it doesn't exist.
virtual nsecs_t ModifiedDate () const
 Retrieve the "modifiedDate" meta-data entry, or 0 of it doesn't exist.
virtual sptr< IIteratorNewIterator (const SValue &args, status_t *error=NULL)
 Walk through the namespace based on the given path.
virtual void Observed (const SValue &key, const SValue &value)
 Override this to receive observed events.
virtual status_t OverlayEntry (const SString &location, const SValue &item)
 Overlay an entry in the original catalog.
virtual status_t RemoveEntry (const SString &name)
 Remove an existing entry from the catalog.
virtual status_t RenameEntry (const SString &entry, const SString &name)
 Change the name of an entry in the catalog.
virtual status_t RestoreEntry (const SString &location)
 Restore an entry that was previously replaced.
virtual void SetCreationDate (nsecs_t value)
 Retrieve the "creationDate" meta-data entry, or 0 of it doesn't exist.
virtual void SetMimeType (const SString &value)
 Retrieve the "mimeType" meta-data entry, or "" if it doesn't exist.
virtual void SetModifiedDate (nsecs_t value)
 Retrieve the "modifiedDate" meta-data entry, or 0 of it doesn't exist.
virtual void SetWritable (bool value)
virtual status_t ShowEntry (const SString &name)
 Show an entry that was previously hidden.
virtual status_t Unlink (const wptr< IBinder > &target, const SValue &bindings, uint32_t flags)
 Remove a mapping previously added by Link().
virtual status_t Walk (SString *path, uint32_t flags, SValue *node)
 Walk through the namespace based on the given path.
virtual bool Writable () const
virtual ~BCatalogMirror ()

Friends

class IteratorWrapper


Constructor & Destructor Documentation

BCatalogMirror const SContext context,
const SValue args
 

BCatalogMirror constructor - takes "catalog" or "catalog_path".

BCatalogMirror can be given: catalog->ICatalog} catalog_path->SString} The ICatalog is the catalogectory that we will be mirroring

~BCatalogMirror  )  [protected, virtual]
 


Member Function Documentation

status_t AddEntry const SString name,
const SValue entry
[virtual]
 

Add or modify an entry in the catalog.

Parameters:
[in] name Desired name of the entry.
[in] entry Data or object for the entry.
Returns:
B_OK on success, else an error code.
AddEntry() is a general way to place new entries into a catalog. There are two main ways it can be useful. The first is as an equivalent to the INode::REQUEST_DATA hint for reading entries - if you supply an SValue of data to ddEntry(), it can create a new entry with that data, without requiring an intermediate operation through an IDatum object.

The second reason for using this API is to add new types of objects to the catalog if the SValue contains an IBinder object, the given object will be directly added as the new entry. This latter approach allows you to create places where the namespace crosses processes, mount new types of directories in the namespace, etc. Note, however, that many catalogs (such as one representing a filesystem) will not be able to host references to external objects.

Contrast this with CreateNode() and CreateDatum(), which creates new entry objects that are owned and managed by the catalog.

Todo:
This API should not allow both creation of new entries and modification of existing entries.
Todo:
This API should work more like CreateDatum(), where the name is an in/out parameter, and it should be able to return the created object as an optional output. Perhaps this functionality should be moved to CreateNode() and CreateDatum(), and this method changed to ReplaceEntry() to only modify an existing entry.

Implements ICatalog.

sptr< INode > Attributes  )  const [virtual]
 

Retrieve the meta-data catalog associated with this node, or NULL if it doesn't exist.

The INode interface also supplies access to meta-data associated with the object. The "attributes" read-only property provides direct access to the meta-data node, which is a pointer to another separate INode holding the meta-data. A node may not support meta-data, in which case the attributes property will return NULL.

You will not usually use this property directly, instead using the mimeType, creationDate, and modifiedDate properties to read/write the standard attributes. Also see Walk() for how you can retrieve these and other attributes through the normal path traversal mechanism.

Implements INode.

sptr< IDatum > CreateDatum SString name,
uint32_t  flags,
status_t err
[virtual]
 

Create a new IDatum object inside of this catalog.

Parameters:
[in,out] name Incoming, the desired name for the new entry. Outgoing, the actual name that was used. Some catalogs may completely ignore your desired name and use their own. Alternatively, a catalog may use your name as-is, and return an error if an entry with that name already exists.
[in] flags Additional options. Always set to 0.
[out] err B_OK on success, else an error code.
Returns:
The newly created IDatum, or NULL on failure.
This is like CreateNode() (see that API for further details), but creates an object implementing the IDatum interface and thus allowing you to place actual data under this entry.

Note that the returned object may very well support other interfaces (including INode), however its main purpose is to hold data for you.

Implements ICatalog.

sptr< INode > CreateNode SString name,
status_t err
[virtual]
 

Create a new INode in this catalog.

Parameters:
[in,out] name Incoming, the desired name for the new entry. Outgoing, the actual name that was used. Some catalogs may completely ignore your desired name and use their own. Alternatively, a catalog may use your name as-is, and return an error if an entry with that name already exists.
[out] err B_OK on success, else an error code.
Returns:
The newly created INode, or NULL on failure.
Use this API to create a new subdirectory kind of object inside of this catalog. The returned object will be at least an INode that can itself contain one or more child entries. However, the details of how the node INode works are entirely dependent on this containing catalog: it could start out empty and have its own ICatalog interface through which you can add any arbitrary entries, start out with a fixed set of entries that can not be changed, etc.

This, along with CreateDatum(), is the mechanism you should normally use when entries in a particular catalog, because they allow the catalog to ensure that objects with the correct implementation are created. For example, if the catalog is on a filesystem, it will need to modify the filesystem data to hold the new structure and create and return a proxy object for the new entry it just created.

Even in a generic catalog the use of this function is important, since it ensures objects are created in the same process as the parent directory. Consider, for example, an application that wishes to create a node with some data that will stay around after the application itself exits.

Contrast this with AddEntry(), which if called with an IBinder object will place a reference to that object in the catalog.

Implements ICatalog.

nsecs_t CreationDate  )  const [virtual]
 

Retrieve the "creationDate" meta-data entry, or 0 of it doesn't exist.

Implements INode.

status_t HideEntry const SString name  )  [virtual]
 

Hide an entry from the original catalog.

Implements ICatalogPermissions.

SValue Inspect const sptr< IBinder > &  caller,
const SValue which,
uint32_t  flags
[virtual]
 

Probe binder for interface information.

Return interfaces implemented by this binder object that are requested by which. This is a composition of all interfaces, expressed as { descriptor -> binder } mappings, which are selected through which.

Much more information on Inspect() can be found at Binder Inspect() Details.

Reimplemented from BnCatalog.

status_t Link const sptr< IBinder > &  target,
const SValue bindings,
uint32_t  flags
[virtual]
 

Link registers the IBinder "target" for notification of events.

The bindings is a mapping of keys that will get pushed on this IBinder, to keys that will get pushed on the "target" IBinder. e.g.

  • If you call link thus: binder1->Link(binder2, SValue("A", "B"));
  • When "A" is pushed on binder1: binder1->Push(SValue("A", "C"));
  • The following will get called on binder2: binder2->Effect(SValue("B", "C"), SValue::wild, SValue::undefined, NULL);

Reimplemented from BBinder.

status_t Merge const sptr< ICatalog > &  catalog  )  [virtual]
 

Implements ICatalogPermissions.

SString MimeType  )  const [virtual]
 

Retrieve the "mimeType" meta-data entry, or "" if it doesn't exist.

Implements INode.

nsecs_t ModifiedDate  )  const [virtual]
 

Retrieve the "modifiedDate" meta-data entry, or 0 of it doesn't exist.

Implements INode.

sptr< IIterator > NewIterator const SValue args,
status_t error = NULL
[virtual]
 

Walk through the namespace based on the given path.

Parameters:
[in] args Iterator options as described below.
[out] error Status code from the call, B_OK if all is well else an error code.
Returns:
The new IIterator object on success, else NULL.
The returned iterator has its own state, so you do not have to worry about other threads that may call Iterate() (they will get their own iterator). Most implementations will return a full IRandomIterator; use interface_cast<T> to retrieve that interface.

Clients should usually use SIterator instead of calling NewIterator() directly.

The options parameter is used to control what data is returned by the iterator. The available options are fairly implementation-dependent, but some common ones are described here. Because you can not know what any given IIterable object will be able to do, the IIterator interface you get back has a read-only options property with which you can find out how it is configured. Any of the options supplied to IIterate() that it understands will be propagated to the options property in the form it understood them.

  • "select" (a.k.a. BV_ITERABLE_SELECT) specifies a SQL projection, describing the columns to be included in the iterator results. It is a set of column names to include.
  • "filter" (a.k.a. BV_ITERABLE_FILTER) specifies an abstract filter (as a string) to be applied to the results, interpret in whatever way the IIterable thinks makes the most sense.
  • "where" (a.k.a. BV_ITERABLE_WHERE) specifies a direct SQL WHERE clause, allowing you to filter the results contained in the iterator. This can be used with "filter" at the same time, in which case the result set will be the rows matching both of them.
  • "order_by" (a.k.a. BV_ITERABLE_ORDER_BY) specifies how to order entries returned by the iterator.

See Binder Data Model for more detail on these options.

Implementation Details
Note that semantically each iterator you generate is passive for the set of entries, but the data inside each of those entries may change. That is, if the contents of the container changes, this will not impact the number of entries in any current active iterators. However, if the data inside one of those entries changes, then the next time any iterator requests the data for that entry it will get back the new data. If an entry is removed from the iterable, again the number of items in currently active iterators does not change; however, if that item is requested, both the key and value are returned with B_NULL_VALUE.
This requirement in place so that an iterator's results can be reasonably thread-safe. For example, if a list view gets an IRandomIterator to display an IIterable's contents, it can rely on the indices of that iterator being consistently mapped to the same entry in the iterable.

Implements IIterable.

void Observed const SValue key,
const SValue value
[virtual]
 

Override this to receive observed events.

Implements BObserver.

status_t OverlayEntry const SString location,
const SValue item
[virtual]
 

Overlay an entry in the original catalog.

Overlay an entry in the original catalog with the replacement.

Implements ICatalogPermissions.

status_t RemoveEntry const SString name  )  [virtual]
 

Remove an existing entry from the catalog.

Parameters:
[in] name Name of the entry to be removed.
Returns:
B_OK if the entry was removed, some other error code on error. In particular, B_ENTRY_NOT_FOUND if there is not an entry with the given name.

Implements ICatalog.

status_t RenameEntry const SString entry,
const SString name
[virtual]
 

Change the name of an entry in the catalog.

Parameters:
[in] entry Name of the entry to be renamed.
[in] name New name for the entry.
Returns:
B_OK if the entry was removed, some other error code on error. Most common errors are B_ENTRY_NOT_FOUND (entry does not exist), B_ENTRY_EXISTS (there is already an existing entry named name), B_UNSUPPORTED (this catalog does not support renaming).

Implements ICatalog.

status_t RestoreEntry const SString location  )  [virtual]
 

Restore an entry that was previously replaced.

Implements ICatalogPermissions.

void SetCreationDate nsecs_t  value  )  [virtual]
 

Retrieve the "creationDate" meta-data entry, or 0 of it doesn't exist.

Implements INode.

void SetMimeType const SString value  )  [virtual]
 

Retrieve the "mimeType" meta-data entry, or "" if it doesn't exist.

Implements INode.

void SetModifiedDate nsecs_t  value  )  [virtual]
 

Retrieve the "modifiedDate" meta-data entry, or 0 of it doesn't exist.

Implements INode.

void SetWritable bool  value  )  [virtual]
 

Implements ICatalogPermissions.

status_t ShowEntry const SString name  )  [virtual]
 

Show an entry that was previously hidden.

Implements ICatalogPermissions.

status_t Unlink const wptr< IBinder > &  target,
const SValue bindings,
uint32_t  flags
[virtual]
 

Remove a mapping previously added by Link().

Reimplemented from BBinder.

status_t Walk SString path,
uint32_t  flags,
SValue node
[virtual]
 

Walk through the namespace based on the given path.

Parameters:
[in,out] path Incoming, the '/'-separated path to traverse. Outgoing, if result is B_OK then this is either the remaining path to be walked or "" if the full path has been processed. Otherwise, the output value is not defined.
[in] flags Options controlling the traversal: REQUEST_DATA, COLLAPSE_NODE, CREATE_DATUM, CREATE_NODE.
[out] node The entry found at the given path. If REQUEST_DATA and COLLAPSE_NODE are not provides, this is always an IBinder object; otherwise, it may be some SValue data structure as described below.
Returns:
B_OK if the Walk() was successful (the node contains the result); else an error code on failure. A common error is B_ENTRY_NOT_FOUND if the path could not be resolved.
The Walk() method is used to find an object below the node, by traversing the given path through the namespace. You use separators ('/' -- forward slash) to separate components of the path. If your path contains no separators, you are requesting an object directly under the node.

If the node supports attributes then the Walk() method will allow you to traverse directly to them. This is accomplished by reserving path names whose first character is ":" to indicate that the name is part of the attribute namespace. Thus a Walk() of just the path ":" will return the attributes catalog (and continue walking into it if needed); for a name with ':' as a prefix and additional text the node strips off the ':' and then calls Walk() on the attributes catalog with the remaining text.

Clients will generally not call Walk() directly, instead relying on SNode::Walk(). The latter hides a lot of the complexity of INode::Walk() that we will discuss later.

The flags parameter allows you to control how the namespace walks your supplied path. These allow you to request optimizations to how INode returns its result (REQUEST_DATA, COLLAPSE_NODE), and what it should do if segments of the path don't exist (CREATE_DATUM, CREATE_NODE).

The REQUEST_DATA and COLLAPSE_NODE flags are optimization hints that allow you to bypass the "everything is an object" property of the namespace in certain situations. An INode is not required to honor these requests (and indeed may be entirely unable to do so), so when using them it is the client's responsibility to deal with such a failure.

  • REQUEST_DATA asks, if the final node in the path is an IDatum, for it to return the actual data under its entry (as an SValue) instead of the IDatum object holding that data. For simple read access of small pieces of data, this allows you to bypass the intermediate object. The node is free to ignore this request and return the IDatum anyway.

  • COLLAPSE_NODE asks, if the final node in the path is an INode, for it to return the name/value mappings it contains, as an SValue mapping, instead of the object itself. Again the node is free to ignore this request and return the object anyway.

You can combine REQUEST_DATA and COLLAPSE_NODE to ask for the final node to return an SValue mapping, where each value is actually data. If you use COLLAPSE_NODE without REQUEST_DATA, you will receive SValue mappings where the values are IDatum objects.

  • CREATE_CATALOG flag asks for the nodes parsing your path to automatically create intermediate objects if the requested entries along the path don't exist.

  • CREATE_DATUM flags asks that the final node in the path create a datum for you if one doesn't already exist.

Note:
Never implement Walk() directly yourself. Instead, derive from BGenericNode which will take care of most of the following details for you.
Implementation Details
All implementations of INode must correctly handle paths in their Walk() implementation by finding the first path separator, looking up the node for the entry named by the text before the separator, and recursing into that node with the remaining path string. They must also correctly parse attribute names as described below.
This API is slightly complicated because a Walk() operation does not have to be completed in a single call. The path parameter is also an output parameter, so the node hierarchy can evaluate only a portion of the path, and return the node and remaining path up to that point. Thus clients must repeatedly call Walk() until the path is fully resolved or an error occurs. For example, the node structure will normally return early from Walk() when it hits a point that hops across processes.
Making the path an in/out parameter also has a nice performance benefit: when a node is modifying the path to resolve it for the current level, this can be done in-place directly in the string argument, instead of having to construct a new string to hold the sub-path.
If an object is both an INode and an IDatum and REQUEST_DATA is used, the object should be treated as a datum (as its primary identity), and the REQUEST_DATA flag honored if possible.
Why is Walk() defined this way, instead of simply returning the final leaf? The primary reason is to give the node hierarchy the ability to control how much recursion happens. If it couldn't break the walk up into separate steps, then you may be required to recurse (potentially across many processes) extremely deep in order to perform the walk. In addition, performance should be better by splitting up the walk at each process boundary (though it is completely up to the implementation of a particular INode to decide whether or not to return early from walk).
Todo:
COLLAPSE_NODE should probably be removed.

Implements INode.

bool Writable  )  const [virtual]
 

Implements ICatalogPermissions.


Friends And Related Function Documentation

friend class IteratorWrapper [friend]
 


The documentation for this class was generated from the following files: