docs/develop: Mass directory restructure.

Now vaguely follows the tree structure of "src", with the exception of
directories that described subsystems spanning more than one "kit" or
"server" (e.g. "media", "midi", "bluetooth") -- these have been left as their
own top-level directory within docs/develop.
This commit is contained in:
Augustin Cavalier
2018-01-10 16:12:14 -05:00
parent cdf0ad6a80
commit e81a954787
60 changed files with 0 additions and 0 deletions
@@ -0,0 +1,154 @@
<HTML>
<HEAD>
<TITLE>BClipboard Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BClipboard Use Cases and Implementation Details:</H1>
<P>This document describes the BClipboard interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BClipboard Interface</A></LI>
<LI><A HREF="#usecases">BClipboard Use Cases</A></LI>
<LI><A HREF="#implement">BClipboard Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BClipboard Interface:</H2>
<P>The BClipboard class provides an interface to a named, system-wide, temporary storage resource.
Access to the system clipboard is provided by the be_clipboard variable provided by a BApplication object (or by constructing a clipboard with the name "system").
The best source of information for the BClipboard interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/Clipboard.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BClipboard Use Cases:</H2>
<P>The following use cases cover the BClipboard functionality:</P>
<OL>
<LI><P><B>Construction:</B> A BClipboard will accept one or two arguments to construction.
A name is required for identifying the clipboard. The discard argument indicates whether the
clipboard data should be discarded between boots. Te discard argument defaults to false, however
this is meaningless since functionality has not been implemented to maintain clipboard data
between boots.
After construction, the queue is empty.</P></LI>
<LI><P><B>Destruction:</B> The destructor destroys the BClipboard object, however the system-wide clipboard itself is unaffected.</P></LI>
<LI><P><B>Writing to clipboard 1:</B>
The normal procedure for writing data consists of the following: locking the clipboard via Lock(), clearing the
data via Clear(), adding data to the clipboard message, committing the data via Commit(), and unlocking the
clipboard via Unlock().
</P></LI>
<LI><P><B>Writing to clipboard 2:</B>
The data which is to be written is not added directly to the BClipboard object, but is added to the data
message for the BClipboard. The message is obtained by calling BClipboard::Data(). Data is added in fields
of type B_MIME_TYPE. The name of the field corresponds to the MIME type of the data. If multiple fields are
added, they should contain the same data, but formatted for different MIME types.
</P></LI>
<LI><P><B>Writing to clipboard 3:</B>
In the event that one wishes to back out of writing process before calling Commit(), Revert() must be called.
Otherwise, the changes to the clipboard remain in the BClipboard object.
</P></LI>
<LI><P><B>Reading from clipboard 1:</B>
The normal procedure for reading data consists of the following: locking the clipboard via Lock(), obtaining
the data from the clipboards data message, and unlocking the clipboard via Unlock().
</P></LI>
<LI><P><B>Reading from clipboard 2:</B>
The data message is obtained from a call to BClipboard::Data(). Data is obtained from the message by using
BMessage::FindData for a specified MIME type.
</P></LI>
<LI><P><B>Reading from clipboard 3:</B>
The data is uploaded from the system when Lock() is called, therefore any data which is written to the clipboard
between the calls to Lock() and Data() will not be included in the data message.
</P></LI>
<LI><P><B>Reading from clipboard 4:</B>
It is permissible to Unlock() the clipboard before calling FindData on the data message.
</P></LI>
<LI><P><B>Clearing:</B>
The Clear() function is used to remove all data from the clipboard and is used before adding new data which is
to be written to the clipboard. Clear() returns B_ERROR if the BClipboard is not locked, and returns B_OK if
it is locked.
</P></LI>
<LI><P><B>Committing:</B>
The Commit() function is used to upload data from the BClipboard to the system. The data is immediately
available to other applications once Commit() has been called. Commit() returns B_ERROR if the BClipboard
is not locked, and returns B_OK if it is locked.
</P></LI>
<LI><P><B>Revert:</B>
The Revert() function is used to synchronize the data in the BClipboard to the system. This is only needed in
case one begins to modify the data message and wishes to back out of the changes. Revert() returns B_ERROR if
the BClipboard is not locked, and returns B_OK if it is locked.
</P></LI>
<LI><P><B>Accessing data:</B>
Data() is used to obtain a pointer to the BClipboard's data message. One is expected to read and write data
directly to the message, but the message must not be freed or dispatched. Data() returns NULL if the
BClipboard is not locked.
</P></LI>
<LI><P><B>Accessing a data source:</B>
DataSource() is used to obtain a BMessenger pointed at the BApplication which last committed data to the
clipboard. There is no requirement for the the BClipboard to be locked when calling DataSource().
</P></LI>
<LI><P><B>Obtaining a count:</B>
The count refers to the number of times that data has been uploaded to the clipboard.
There are two count functions. SystemCount() returns an up to date count which is obtained from the system.
Count() returns a cached count. The cached count is set to zero upon creation
of the BClipboard, and is updated when Lock() or Commit() is called.
</P></LI>
<LI><P><B>Locking:</B>
Lock() is used to upload data from the system into the BClipboard object and prevent other threads in the
application from using it. It must be called before reading or writing data to the BClipboard. It blocks
if the BClipboard is already locked. The return value is true if the BClipboard is successfully locked, or
false if the BClipboard was deleted while Lock() was blocked.
</P></LI>
<LI><P><B>Unlocking:</B>
Unlock() is used to unlock the BClipboard and allow other threads in the application to use it.
</P></LI>
<LI><P><B>Checking lock status:</B>
IsLocked() returns true if the BClipboard is locked by the current thread, and false if it is not lockedi or is locked by another thread.
</P></LI>
<LI><P><B>Checking clipboard name:</B>
Name() returns a string containing the name of the clipboard. It is not necessary for the BClipboard to be
locked when calling Name().
</P></LI>
<LI><P><B>Watching a clipboard:</B>
StartWatching and StopWatching are used to enable and disable watching of a clipboard. When the clipboard is
changed, a B_CLIPBOARD_CHANGED message is sent to the target specified in the call to StartWatching.
</P></LI>
</OL>
<A NAME="implement"></A><H2>BClipboard Implementation:</H2>
<P>
The BClipboard class is implemented via a message passing system between the BClipboard, the Registrar, and
the Clipboard Handler associated with the Registrar. Details of the message passing protocol are listed in the
Registrar documentation.
</P>
</BODY>
</HTML>
@@ -0,0 +1,50 @@
<HTML>
<HEAD>
<TITLE>BCursor Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BCursor Use Cases and Implementation Details:</H1>
<P>This document describes the BCursor interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BCursor Interface</A></LI>
<LI><A HREF="#usecases">BCursor Use Cases</A></LI>
<LI><A HREF="#implement">BCursor Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BCursor Interface:</H2>
<P>The BCursor class is a simple class used to represent a mouse cursor as an object instead of an array of pixel data. The best source of information for the BCursor interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/Cursor.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BCursor Use Cases:</H2>
<P>The following use cases cover the BCursor functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> The first BCursor constructor requires a pointer to the pixel data. The format for the pixel data is described
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/Cursor.html#Cursor_Data_Format">here in the Be Book</A>.
This pixel data is used to initialize the BCursor, but BCursor does not take ownership of the data, therefore you are responsible for freeing the memory after construction.</P></LI>
<LI><P><B>Construction 2:</B> The second BCursor constructor requires a BMessage as an archive, however BCursor does not currently support archiving. Do not use this constructor.</P></LI>
<LI><P><B>Destruction:</B> This releases all resources used by the BCursor.</P></LI>
<LI><P><B>Instantiate:</B> This always returns NULL since it relies on the second constructor (which is not currently supported). If it were implemented, this would return a new BArchivable consisting of a BCursor created from the archive passed in as an argument. </P></LI>
</OL>
<A NAME="implement"></A><H2>BCursor Implementation:</H2>
<P>All meaningful work of the BCursor is implemented in the first constructor. The constructor establishes a link with the app_server and sends it the pixel data. The app_server provides the BCursor with a token which identifies the pixel data. When BApplication::SetCursor(BCursor) is called, it must get the needed cursor data by obtaining the BCursor's token (BApplication is a friend of BCursor) and using the token to request the data from the app_server. Note that BCursor does not internally store the pixel data.</P>
</BODY>
</HTML>
@@ -0,0 +1,123 @@
<HTML>
<!-- $Id: BMessageFilterUseCases.html 449 2002-07-26 03:06:04Z jrand $ -->
<HEAD>
<TITLE>BMessageFilter Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BMessageFilter Use Cases and Implementation Details:</H1>
<P>This document describes the BMessageFilter interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BMessageFilter Interface</A></LI>
<LI><A HREF="#usecases">BMessageFilter Use Cases</A></LI>
<LI><A HREF="#implement">BMessageFilter Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BMessageFilter Interface:</H2>
<P>The BMessageFilter class is a simple class for processing incoming BMessage's before
they are dispatched to a BLooper. The best source of information for the BMessageFilter interface
can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/MessageFilter.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BMessageFilter Use Cases:</H2>
<P>The following use cases cover the BMessageFilter functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BMessageFilter can be created by specifying a message_delivery
option, a message_source option, a command code and an optional filter function. These
options are used to determine the messages on which the filter will act and the filter itself
(see the "Filter" use cases).</P></LI>
<LI><P><B>Construction 2:</B> A BMessageFilter can be created by specifying a message_delivery
option, a message_source option and an optional filter function. These options are used to
determine the messages on which the filter will act and the filter itself (see the "Filter" use
cases).</P></LI>
<LI><P><B>Construction 3:</B> A BMessageFilter can be created by specifying a command code
and an optional filter function. These options are used to determine the messages on which the
filter will act and the filter itself (see the "Filter" use cases).</P></LI>
<LI><P><B>Construction 4:</B> A BMessageFilter can be constructed by use of a copy constructor
which can take a reference to or a pointer to another BMessageFilter. The new BMessageFilter
will have all the options of the source BMessageFilter when that source filter was constructed.
Any other state of the source BMessageFilter that it has accumulated after construction is not
copied to the new filter.</P></LI>
<LI><P><B>Assignment:</B> A BMessageFilter can be assigned the attributes of a source
BMessageFilter by the use of the assignment operator. The target BMessageFilter will have all
the options of the source BMessageFilter when that source filter was constructed. Any other
state of the source BMessageFilter that it has accumulated after construction is not copied
to the new filter.</P></LI>
<LI><P><B>Destruction:</B> When a BMessageFilter is deconstructed, the BMessageFilter releases
any shared resources it may have allocated.</P></LI>
<LI><P><B>Command:</B> When Command() is used on a BMessageFilter, the command code specified
at construction time for this filter is returned. If a BMessageFilter was not constructed
with a specific command code, this member function does not return a valid result.</P></LI>
<LI><P><B>FiltersAnyCommand:</B> When FiltersAnyCommand() is called on a BMessageFilter, it
returns true if a command code was not specified at construction time for this filter. It
returns false if a command code was specified at construction time. The Command() member
function (see above use case) is only valid when FiltersAnyCommand() returns false.</P></LI>
<LI><P><B>Looper:</B> The Looper() member function returns a pointer to the BLooper (or BHandler)
to which this filter has been added. If the filter has not been added to a BLooper, NULL is
returned. The member functions BLooper::AddCommonFilter() or BHandler::AddFilter() can be
used to add the filter to a looper (see use cases for BLooper and BHandler for details about
adding a filter).</P></LI>
<LI><P><B>MessageDelivery:</B> The MessageDelivery() member function returns the message delivery
value that was specified at construction time for this filter. The possible values are
B_DROPPED_DELIVERY, B_PROGRAMMED_DELIVERY and B_ANY_DELIVERY. If no message delivery value
was specified at construction time, B_ANY_DELIVERY is returned.</P></LI>
<LI><P><B>MessageSource:</B> The MessageSource() member function returns the message source
value that was specified at construction time for this filter. The possible values are
B_LOCAL_SOURCE, B_REMOTE_SOURCE and B_ANY_SOURCE. If no message source value
was specified at construction time, B_ANY_SOURCE is returned.</P></LI>
<LI><P><B>Filter 1:</B> The filter can be applied for a message by passing the message and the
target BHandler which has received that message to the Filter() member function. This member
function returns B_DISPATCH_MESSAGE or B_SKIP_MESSAGE to the caller. The actual impact
of these filter results is dependent on the BLooper and BHandler behaviour (see the use cases for
these classes for more details).</P></LI>
<LI><P><B>Filter 2:</B> If a filter function was not supplied on construction of the
BMessageFilter, then the Filter() member function determines the result of the filter. If the
Filter() member has been overridden in a derived class, the result depends on the behaviour of
this derived class. If the class has not been overridden and no filter function was provided
on construction, the B_DISPATCH_MESSAGE is returned. If a filter function was provided on
construction, then the filter function will be called and the Filter() member will return what
this filter function returns.</P></LI>
</OL>
<A NAME="implement"></A><H2>BMessageFilter Implementation:</H2>
<P>The implementation of the BMessageFilter is pretty simple. It is mainly a container for
properties of the filter itself and a few simple methods for getting and setting these
properties.</P>
<P>The actual act of dispatching or skipping the message as dictated by the filter is implemented
in BLooper or BHandler. The BMessageFilter just provides a mechanism for these classes to
determine which to do. Also the BLooper or BHandler decide whether to pass the message through
the filter on their own. The filter does not look at every message to see whether the source
and delivery of this message is such that it should pass through the filter. Instead, BLooper or
BHandler look at the filter, check the source and delivery options of the filter against the
message itself and call the filter if appropriate. So, the filter is really just a container for
these options and doesn't take action based on them.</P>
</BODY>
</HTML>
@@ -0,0 +1,147 @@
<HTML>
<!-- $Id: BMessageQueueUseCases.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
<HEAD>
<TITLE>BMessageQueue Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BMessageQueue Use Cases and Implementation Details:</H1>
<P>This document describes the BMessageQueue interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BMessageQueue Interface</A></LI>
<LI><A HREF="#usecases">BMessageQueue Use Cases</A></LI>
<LI><A HREF="#implement">BMessageQueue Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BMessageQueue Interface:</H2>
<P>The BMessageQueue class is a simple class for managing a queue of BMessages. The best
source of information for the BMessageQueue interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/MessageQueue.html">here in the Be Book</A>.
</P>
<A NAME="usecases"></A><H2>BMessageQueue Use Cases:</H2>
<P>The following use cases cover the BMessageQueue functionality:</P>
<OL>
<LI><P><B>Construction:</B> A BMessageQueue does not take any arguments when it is constructed.
After construction, the queue is empty.</P></LI>
<LI><P><B>Destruction:</B> When a BMessageQueue is deconstructed, all BMessages on the queue are
deleted. This implies that all BMessages added to a BMessageQueue must be allocated on the heap
with the new operation. The BMessageQueue is locked before performing the delete to ensure
that the queue doesn't change while it is being deleted. The lock is never released from the
destructor to ensure that any AddMessage() or other members blocking for the lock never
succeed in getting the lock. They will fail once the BMessageQueue is completely deleted.</P></LI>
<LI><P><B>Add Message 1:</B> When AddMessage() is used to put a BMessage on the queue, the
BMessageQueue takes ownership of the BMessage. The BMessage should be created on the heap but
there is no checking to ensure that has happened. The BMessageQueue records the order in
which the BMessages are added to the queue.</P></LI>
<LI><P><B>Add Message 2:</B> No check is performed to see if the BMessage is already part of that
BMessageQueue or any other when AddMessage() is used to put a BMessage on a queue. An attempt to
add a BMessage to a BMessageQueue which already has that same BMessage in it (where equality is
based on the address of the BMessage) will corrupt the queue. An attempt to add a BMessage to a
BMessageQueue when that BMessage is already in another BMessageQueue will corrupt the original
BMessageQueue. It is up to the caller of AddMessage() to use RemoveMessage() to prevent
queue corruption.</P></LI>
<LI><P><B>Add Message 3:</B> BMessage's can be added using AddMessage() from multiple threads
at the same time with no risk of queue corruption. Similarly, RemoveMessage() or NextMessage()
can be executing from another thread while an AddMessage() is started without corrupting the queue.
An AddMessage() attempt will block if another thread has used the Lock() member to lock the
BMessageQueue.</P></LI>
<LI><P><B>Remove Message 1:</B> The RemoveMessage() member takes a BMessage pointer. The
BMessageQueue is searched for this BMessage pointer. If that pointer is in the queue, then it
is removed from the queue. The BMessage is not deleted (note the BeBook implies it is but in
fact it is not). If the BMessage pointer is not on this BMessageQueue, this call has no affect.
After this call completes successfully, it is as though AddMessage() was never called for
this BMessage pointer.</P></LI>
<LI><P><B>Remove Message 2:</B> BMessage's can be removed using RemoveMessage() from multiple
threads at the same time with no risk of queue corruption. Similarly, AddMessage() or
NextMessage() can be executing from another thread while a RemoveMessage() is started without
corrupting the queue. A RemoveMessage() attempt will block if another thread has used the Lock()
member to lock the BMessageQueue.</P></LI>
<LI><P><B>Count Messages:</B> The CountMessages() member function returns the number of BMessage's
in the BMessageQueue. If there are no messages on the queue (an example of this situation is just
after construction), the member returns 0. Note, it is possible for the count to become corrupted
if the situation in Add Message 2 occurs.</P></LI>
<LI><P><B>Is Empty:</B> The IsEmpty() member function returns true if there are no BMessages on the
BMessageQueue. If there are one or more BMessages on the BMessageQueue, it returns false.</P></LI>
<LI><P><B>Find Message 1:</B> The FindMessage() member function is overloaded. If the member
function takes a single int32 argument, it is used to return the BMessage on the queue at a
particular index as indicated by the argument. The first message is at index 0, the second
at index 1 etc. If no message is at that index, NULL is returned.</P></LI>
<LI><P><B>Find Message 2:</B> The other FindMessage() member function takes a single uint32
argument and an optional int32 argument. The first mandatory argument specifies the "what" code
for the BMessage being searched for. The second optional argument specifies what occurance of
that "what" code in a BMessage on the queue should be returned. If the second argument is not
provided, it is assumed to be 0. If the second argument is 0, the first BMessage that has the
what code provided is returned. If the second argument is 1, the second BMessage that has the
what code provided is returned, etc. If no match is found, NULL is returned.</P></LI>
<LI><P><B>Lock 1:</B> The Lock() member function blocks until this thread can acquire exclusive
access to the BMessageQueue. Only one thread can hold the lock at any one time. A thread can
acquire the Lock() multiple times but release it the same number of times. While a thread holds
the lock, other threads will not be able to perform AddMessage(), RemoveMessage() or NextMessage().
Any threads attempting to do so will block until the BMessageQueue is unlocked.</P></LI>
<LI><P><B>Lock 2:</B> The Lock() member function returns true if the lock has successfully been
acquired. It will return false if an unrecoverable error has occurred. An example of such an
error would be deleting the BMessageQueue.</P></LI>
<LI><P><B>Unlock:</B> The Unlock() member function releases a lock on the BMessageQueue. If the
thread no longer holds any locks on the BMessageQueue, other threads are free to acquire the
BMessageQueue lock or call member functions like AddMessage(), RemoveMessage(), NextMessage() or
delete the BMessageQueue.</P></LI>
<LI><P><B>Next Message 1:</B> The NextMessage() member function removes the BMessage which is the
oldest on the queue. It returns that BMessage to the caller. After the call completes, the
BMessage is no longer on the queue and the next oldest BMessage is at the front of the queue
(ie next to be returned by NextMessage()).</P></LI>
<LI><P><B>Next Message 2:</B> BMessage's can be removed using NextMessage() from multiple
threads at the same time with no risk of queue corruption. Similarly, AddMessage() or
RemoveMessage() can be executing from another thread while a NextMessage() is started without
corrupting the queue. A NextMessage() attempt will block if another thread has used the Lock()
member to lock the BMessageQueue.</P></LI>
</OL>
<A NAME="implement"></A><H2>BMessageQueue Implementation:</H2>
<P>Internally, the BMessageQueue uses a BLocker to ensure that member functions like AddMessage(),
RemoveMessage() and NextMessage() do not corrupt the queue when used from multiple threads. The
same BLocker is used to implemented the Lock() and Unlock() members.</P>
<P>Testing with a debugger shows that the queue is implemented using a "link" pointer in the
BMessage class itself. Each BMessage is also a singly linked list which represents the queue.
All the BMessageQueue needs is a pointer to the BMessage which starts the list. For performance
reasons, it is worth maintaining a pointer to the BMessage at the end of the list and the count
of the number of elements in the list. If these are not maintained, adding an element to the
list will get slower as the number of elements grows and the cost to determine the number of
elements in the list will be high.</P>
<P>Because the BMessageQueue uses the link pointer which is a private part of the BMessage class,
the BMessageQueue must be a friend class of BMessage. Checking the headers, this is in fact the
case in Be's implementation. Although friendship in classes can cause some pretty serious long
term headaches if abused (and I am not convinced that this is an abuse), the OpenBeOS
implementation will follow the same implementation for now.</P>
</BODY>
</HTML>
@@ -0,0 +1,407 @@
<HTML>
<!-- $Id: BPropertyInfoUseCases.html 814 2002-08-19 05:26:56Z jrand $ -->
<HEAD>
<TITLE>BPropertyInfo Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>BPropertyInfo Use Cases and Implementation Details:</H1>
<P>This document describes the BPropertyInfo interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">BPropertyInfo Interface</A></LI>
<LI><A HREF="#usecases">BPropertyInfo Use Cases</A></LI>
<LI><A HREF="#implement">BPropertyInfo Implementation</A></LI>
</OL>
<A NAME="interface"></A><H2>BPropertyInfo Interface:</H2>
<P>The BPropertyInfo class is a simple class for describing the scripting interface which a
BHandler provides. It makes implementing the ResolveSpecifier() hook function easier to implement.
One source of information for the BPropertyInfo interface can be found
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Application%20Kit/PropertyInfo.html">here in the Be Book</A>.
Unfortunately, details of some changes to this interface introduced in BeOS 4 does not seem to have
made it into the BeBook. For the latest, refer to the
<A HREF="file:///boot/develop/headers/be/app/PropertyInfo.h">PropertyInfo.h</A> header file or the
<A HREF="http://www.acm.uiuc.edu/bug/Be%20Book/Release_Notes/R4RN_AppKit.html">BeOS 4 Developer Release Notes</A>.
</P>
<A NAME="usecases"></A><H2>BPropertyInfo Use Cases:</H2>
<P>The following use cases cover the BPropertyInfo functionality:</P>
<OL>
<LI><P><B>Construction 1:</B> A BPropertyInfo can be created with 0 arguments. In this case,
it will not have any property_info or value_info structures associated with it. The only
way to initialize it would be to Unflatten() a flattened BPropertyInfo instance (see Unflatten
use cases).</P></LI>
<LI><P><B>Construction 2:</B> A BPropertyInfo can be created with a single property_info argument.
In this case, there will be no value_info structure associated with it and the BPropertyInfo
will assume it does not need to de-allocate the property_info structure itself on
destruction.</P></LI>
<LI><P><B>Construction 3:</B> A BPropertyInfo can be created with a property_info argument and
a value_info argument. In this case, the BPropertyInfo will use both of these arguments to
determine its future behaviour. It will assume it does not need to de-allocate the property_info
structure or the value_info structure itself on destruction.</P></LI>
<LI><P><B>Construction 4:</B> A BPropertyInfo can be created with a property_info argument and
a value_info argument and a flag to indicate whether these structres were allocated on the heap.
If the flag is false, it will assume it does not need to de-allocate the property_info structure
or the value_info structure itself on destruction. If the flag is true, it will assume that
the property_info pointer and the value_info pointer and all pointers contained within them (ie
const char * instances) need to be free()'d when the BPropertyInfo is destructed.</P></LI>
<LI><P><B>Destruction:</B> On destruction, a BPropertyInfo class does nothing unless the third
argument (free_on_delete flag) at construction was true. If this argument was true, the
BPropertyInfo class performs a "free()" on the pointers passed in at construction time and all
pointers contained within these structures.</P></LI>
<LI><P><B>Properties:</B> The Properties() member function returns the first argument passed in
at construction time of the BPropertyInfo or NULL if it was constructed with no arguments.</P></LI>
<LI><P><B>Values:</B> The Values() member function returns the second argument passed in
at construction time of the BPropertyInfo or NULL if it was constructed with one or fewer
arguments.</P></LI>
<LI><P><B>Count Properties:</B> The CountProperties() member function returns the number of
elements in the NULL terminated array of property_info structures passed in as the first argument
at construction time. If the BPropertyInfo class was constructed with no arguments, 0 is
returned.</P></LI>
<LI><P><B>Count Values:</B> The CountValues() member function returns the number of
elements in the NULL terminated array of value_info structures passed in as the second argument
at construction time. If the BPropertyInfo class was constructed with one or fewer arguments, 0 is
returned.</P></LI>
<LI><P><B>Fixed Size:</B> The IsFixedSize() method always returns false indicating that a
BPropertyInfo class instance can be flattened but the size of that flattened instance depends on
the state of the BPropertyInfo class itself.</P></LI>
<LI><P><B>Type Code:</B> The TypeCode() method always returns B_PROPERTY_INFO_TYPE ('SCTD')
regardless of the state of the BPropertyInfo class instance indicating that the flattened instance
is of type B_PROPERTY_INFO_TYPE.</P></LI>
<LI><P><B>Allows Type Code:</B> The AllowsTypeCode() method returns false for all passed in type
codes unless B_PROPERTY_INFO_TYPE ('SCTD') is passed in when this method returns true. This
implies that a BPropertyInfo class instance can be unflattened from flattened data of
B_PROPERTY_INFO_TYPE only (NOTE: the Be implementation seems to return true for all values
passed in although that doesn't seem to make much sense).</P></LI>
<LI><P><B>Flattened Size:</B> The FlattenedSize() member function retures the number of bytes
required to store a flattened version of the BPropertyInfo instance. The size will be determined
by the description of the flattened data structure described in the "implementation" section
below.</P></LI>
<LI><P><B>Flatten:</B> The Flatten() member function turns the current BPropertyInfo instance into
a series of bytes which completely describes its state so it can be recreated from it later. The
actual description of this byte representation of BPropertyInfo is described in the "implementation"
section below.</P></LI>
<LI><P><B>Unflatten:</B> The Unflatten() member function takes a passed in series of bytes and
sets the current BPropertyInfo instance into a copy of the BPropertyInfo described by those
bytes (ie a flattened version of a previous BPropertyInfo). The old state of the current
BPropertyInfo is replaced by that described by the flattened representation. The actual description
of this byte representation of BPropertyInfo is described in the "implemenation" section
below.</P></LI>
<LI><P><B>Print To Stream:</B> The PrintToStream() member function sends the current state of
the BPropertyInfo instance to standard out for debugging purpose. The actual format of this output
isn't critical but it should describe the state of the object and be easy for a developer to
understand.</P></LI>
<LI><P><B>Find Match:</B> The FindMatch() member function takes a BMessage, a specifier (in the
form of a BMessage), a specifier type (called form, ie B_DIRECT_SPECIFIER), property name and an
index. The member returns -1 if no match can be found. A match will have the "what" code of the
message (not the specifier message) in its command list or have a wildcard command. It will also
have the property name as its property name. And, the specifier type will be listed as a valid
specifier, or the property will have a wildcard specifier. Note, if the index is non-zero, then
only properties with command wildcards will be a match (a wildcard is an empty list of commands,
similarly for specifier type). On a match, the result is a 0 based offset into the array of
properties.</P></LI>
</OL>
<A NAME="implement"></A><H2>BPropertyInfo Implementation:</H2>
<P>There is a key difference between the OpenBeOS BPropertyInfo class and the Be implementation
is support for BeOS R3 compiled executables. The elements in the property_info structure changed
in R4 versus the one which was used in R3. Be did the following to handle this:</P>
<UL>
<LI>The R3 constructor was made private. Existing R3 binaries would use this constructor. This
constructor would use static functions to convert between the old property_info structure passed
from the R3 binary to the new one.</LI>
<LI>A new constructor was introduced in R4. This constructor would be source code compatible with
existing code which compiled on R3. However, when that code was recompiled for R4, this new
constructor would be called because the old one was made private.</LI>
<LI>I expect that work was also done to ensure that the R4 BPropertyInfo class could unflatten
R3 based BPropertyInfo instances. I have not done serious checking on this however.</LI>
</UL>
<P>For the OpenBeOS implementation, we have decided not to implement this R3 compatibility at
this time but we are not going to rule it out. The header file for BPropertyInfo will be changed
to "remove" the R3 compatibility interfaces using an "ifdef R3_compatible". The interfaces will
still appear to the human reader but not be there as far as the compiler is concerned. If we
revise out decision in the future, it will be a simple matter of removing the ifdefs and implement
these R3 compatibility interfaces. For now, we have decided not to do this because:</P>
<UL>
<LI>There is no binary compatibility between R3 and R4 of BeOS Intel. The ability for OpenBeOS
to be binary compatible with these old R3 interfaces buys us nothing on Intel.</LI>
<LI>There is binary compatibility with R3 with R4 and R5 on BeOS PPC. Without these interfaces
implemented, it may not be possible for R3 compiled binaries for PPC to operate against the
OpenBeOS implementation. However, there are no specific plans to support PPC. Also, the informal
PPC ports that have been discussed were considering using the gcc toolset which I believe precludes
any backward compatibility, even with R5 binaries.</LI>
<LI>There is some risk that a flattened BPropertyInfo instance on someone's hard disk was created
against the old R3 implementation. The OpenBeOS implementation may not be able to read this
flattened BPropertyInfo. However, we believe the chance of this happening to be very low and
not worth the cost of the implementation.</LI>
</UL>
<P>The flattened format of BPropertyInfo looks like the following:</P>
<TABLE BORDER=1>
<TR><TH>Section</TH><TH>Size</TH><TH>Description</TH></TR>
<TR><TD ROWSPAN=3>Header</TD><TD>1</TD><TD>Endian flag, 1 for big endian, 0 for little
endian</TD></TR>
<TR><TD>4</TD><TD>Number of property_info elements in the flattened data.</TD></TR>
<TR><TD>4</TD><TD>Set to 3 if there are value_info in the flattened data, 1 otherwise</TD></TR>
<TR><TD ROWSPAN=5>property_info main section, one per property_info element</TD><TD>1 to n</TD><TD>NULL terminated property_name</TD></TR>
<TR><TD>1 to n</TD><TD>NULL terminated usage string.</TD></TR>
<TR><TD>4</TD><TD>The extra_data value</TD></TR>
<TR><TD>4 to 40</TD><TD>Up to 10 commands, each 4 bytes in size. A zero command indicates the end of
the commands.</TD></TR>
<TR><TD>4 to 40</TD><TD>Up to 10 specifiers, each 4 bytes in size. A zero specifier indicates the end of
the specifiers.</TD></TR>
<TR><TD ROWSPAN=2>property_info types section, one per property_info element</TD><TD>4 to 40</TD>
<TD>Up to 10 types, each 4 bytes in size. A zero type indicates the end of the types.</TD></TR>
<TR><TD>4 to n</TD><TD>A series of 0 to 15 name and type pairs from the "compound types" or ctypes
section of the property_info structure. Each is made up of a null terminated name followed by a
4 byte type. There are up to 15 because there is a three element array of five name/type pairs.
If fewer than 5 elements appear in any one set of the the three elements, four zero bytes are
in the stream where the "name" would be. Also, to indicate that there are fewer than three
compound types, four zero bytes are in the stream where the first name would be.</TD></TR>
<TR><TD ROWSPAN=1>value_info header, only appears if the flag in the header is set to "3"</TD>
<TD>2</TD><TD>Number of value_info elements in the flattened data.</TD></TR>
<TR><TD ROWSPAN=5>value_info section, one per value_info element</TD><TD>4</TD><TD>The "kind"
of this value_info element.</TD></TR>
<TR><TD>4</TD><TD>The "value" of this value_info element</TD></TR>
<TR><TD>1 to n</TD><TD>A NULL terminated name string</TD></TR>
<TR><TD>1 to n</TD><TD>A NULL terminated usage string</TD></TR>
<TR><TD>4</TD><TD>The "extra_data" of this value_info element</TD></TR>
</TABLE>
<P>The following is some information from Marc Flerackers sent in a series of emails which
describes his investigation into how BPropertyInfo instances are flattened. Note that the
implementation is very much based Marc's implementation elluded to in these messages, although
you will see some differences between the above description and Marc's messages. The above
table describes the actual format as it is implemented today and seems to match Be's
implementation. However, Marc's investigation, implementation and emails were critical to
getting this information and is therefore included here in this document:</P>
<H3>Message 1:</H3>
<P>I spend this morning some time to check how a BPropertyInfo is flattened,
here's the result for BControl (not such a good choice as there are no
compound types, however I added at the bottom how the layout looks if there
are). I'm implementing this now in my own BPropertyInfo class. How is the
OBOS BPropertyInfo class going BTW?<P>
<PRE>
// Header
4 6 chunk count
4 1 version
// Start of property_info chunks, without types
8 "Enabled" name
58 "" usage ("Returns whether or not the BControl is currently enabled.")
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
8 "Enabled" name
34 "" usage ("Enables or disables the BControl.")
4 0 extra_data
4 PSET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Label" name
30 "" usage ("Returns the BControl's label.")
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Label" name
32 "" usage ("Sets the label of the BControl.")
4 0 extra_data
4 PSET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Value" name
30 "" usage ("Returns the BControl's value.")
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
6 "Value" name
32 "" usage ("Sets the value of the BControl.")
4 0 extra_data
4 PSET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
// Start of property_info chunks, only types
4 BOOL type
4 0 end type list
4 0 end compound list
4 BOOL type
4 0 end type list
4 0 end compound list
4 CSTR type
4 0 end type list
4 0 end compound list
4 LONG type
4 0 end type list
4 0 end compound list
4 LONG type
4 0 end type list
4 0 end compound list
</PRE>
<P>If there would have been compound types, the layout of the type chunks would
be like this</P>
<PRE>
4 BOOL type
4 0 end type list
5 "name" compound name
4 LONG compound type
4 0 end compound list
</PRE>
<H3>Message 2:</H3>
<P>Layout of a flattened BPropertyInfo with compound members. Value info is
still missing, I will look at it when I implement support for it in my
BPropertyInfo class. BTabView and BRadioButton are coming to cvs soon BTW, I
only have to find some time to write decent Draw functions ^_^.</P>
<PRE>
// Header
4 3 chunk count
4 1 version
// Start of property_info chunks, without types
7 "Suites" name
1 0 usage
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
10 "Messenger" name
1 0 usage
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
13 "InternalName" name
1 0 usage
4 0 extra_data
4 PGET commands
4 0 end commands list
4 1 specifiers
4 0 end specifiers list
// Start of property_info chunks, only types
4 0 end type list
7 "suites" compound name
4 CSTR compound type
4 0 end compound sub list
9 "messages" compound name
4 SCTD compound type
4 0 end compound sub list
4 0 end compound list
4 MSNG type
4 0 end type list
4 0 end compound list
4 CSTR type
4 0 end type list
4 0 end compound list
</PRE>
<H3>Message 3:</H3>
<P>Some updated information about the flattened BPropertyInfo layout for people
who are interested ^_^.</P>
<PRE>
The header contains flags, not a version
flattened header
4 count
4 flags
0x1 : property_info structs are present
0x2 : value_info structs are present
flattened value_info chunks are appended at the end as follows
a small header
4 count
for every value_info
2 kind
4 value
x name
x usage
4 extra_data
where x is strlen + 1 of course.
</PRE>
<P>Value info structs are used to publish information about non-Be types and
scripting commands btw.</P>
<P>I tested my code against the Be implementation, and the flattened data
matches.</P>
</BODY>
</HTML>
@@ -0,0 +1,48 @@
<HTML>
<HEAD>
<TITLE>PortLink Use Cases and Implementation Details</TITLE>
</HEAD>
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
<H1>PortLink Use Cases:</H1>
<P>This document describes the PortLink interface and some basics of how it is implemented.
The document has the following sections:</P>
<OL>
<LI><A HREF="#interface">PortLink Interface</A></LI>
<LI><A HREF="#usecases">PortLink Use Cases</A></LI>
</OL>
<A NAME="interface"><H2>PortLink Interface:</H2>
<P>The PortLink class is a lightweight class designed to ease the pain of sending a message to a port. Normal use boils down to creating a PortLink object, setting the message code, attaching any extra data via Attach(), and calling Flush() to send it.
</P>
<P>While this class is designed to facilitate port-based messaging, it does not devise any protocols for such. The recipient will need to know if data is included in a message, for example. Likewise, all extra data must be freed by the recipient.
</P>
<A NAME="usecases"><H2>PortLink Use Cases:</H2>
<P>The following use cases cover the PortLink functionality:</P>
<OL>
<LI><P><B>Construction:</B> A PortLink is created by passing it a port ID. Error-checking is not performed on the port itself, so be sure it is a valid port.
</P></LI>
<LI><P><B>Destruction:</B> When a PortLink is destroyed, any data which is currently attached to a pending message is freed.</P></LI>
<LI><P><B>Creating a message:</B> Creating a message can be as simple as setting the message code (similar to BMessage's <i>what</i> member). Extra data is not required.</P></LI>
<LI><P><B>Attaching Data:</B> Adding extra data is as simple as calling the member function Attach(), which makes a copy of the parameter passed to it. B_ERROR is returned if the no more data can be attached before the message is sent or if the size is invalid. B_NO_MEMORY is returned when the attachments are larger than the target port's capacity.</P></LI>
<LI><P><B>Sending a message:</B> Call Flush(). Whatever opcode has been set will be sent to the target. Optionally, a timeout (in microseconds) of type bigtime_t can be specified. This can be useful in preventing deadlocks if the target has crashed and its port fills up. The function returns B_BAD_VALUE if the target port is invalid.</P></LI>
<LI><P><B>Synchronous Messaging:</B> This one requires a little more care in order to prevent deadlocks. Attachments may be used as with Flush(), but FlushWithReply() will wait until the target replies unless a timeout value is specified in microseconds of type bigtime_t. A return code of B_ERROR indicates an internal data error and your message is intact. If a reply times out, it will return B_TIMED_OUT. If the target port is invalid, B_BAD_VALUE is returned. Otherwise, it returns B_OK.
<P>
<i>Reply Protocol:</i> The target will receive the message with all attached data with one slight modification to the otherwise chosen message protocol - the first item will be a port_id which is the port to which the sender is to reply. All other attached data (if any) immediately follows this port id.
</li>
</OL>
<h6>HTML Documentation Format by Jeremy Rand</h6>
</BODY>
</HTML>