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:
@@ -0,0 +1,193 @@
|
||||
Message header:
|
||||
Data Bytes Meaning
|
||||
FOB1 4 version
|
||||
4 checksum
|
||||
4 flattened size
|
||||
4 'what'
|
||||
1 flags
|
||||
|
||||
Data field:
|
||||
Data Bytes Meaning
|
||||
1 flags
|
||||
4 type
|
||||
// Mini data (all data less than 256 bytes total)
|
||||
1 item count (*if* there is more than one)
|
||||
1 data length
|
||||
// Maxi data (all data more than 255 bytes total)
|
||||
4 item count (*if* there is more than one)
|
||||
4 data length
|
||||
1 name length
|
||||
X name
|
||||
// Single item
|
||||
4 item size (*if* this is a variable sized item)
|
||||
Y item data - NULL padded to 8-byte boundary
|
||||
// Multiple items
|
||||
4 item size (*if* this is a variable sized item)
|
||||
Y item data - NULL padded to 8-byte boundary
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// An example
|
||||
//------------------------------------------------------------------------------
|
||||
// PrintToStream()
|
||||
Data Bytes Meaning
|
||||
|
||||
//BMessage: what = (0x0, or 0)
|
||||
FOB1 4 version
|
||||
0x90010001 4 checksum
|
||||
0x00000192 4 flattened size (402 bytes)
|
||||
0x0 4 'what' (none specified)
|
||||
0x01 1 flags
|
||||
|
||||
// entry ATTRIBUTE_MENU, type='LONG', c=5, size= 4,
|
||||
0x07 1 flags
|
||||
LONG 4 type
|
||||
0x05 1 item count
|
||||
0x14 1 data length
|
||||
0x0e 1 name length
|
||||
ATTRIBUTE_ 14 name (ATTRIBUTE_MENU)
|
||||
// data[0]: 0x8 (8, '')
|
||||
0x8 4 data[0]
|
||||
// data[1]: 0x8 (8, '')
|
||||
0x8 4 data[1]
|
||||
// data[2]: 0x6 (6, '')
|
||||
0x6 4 data[2]
|
||||
// data[3]: 0x8 (8, '')
|
||||
0x8 4 data[3]
|
||||
// data[4]: 0x6 (6, '')
|
||||
0x6 4 data[4]
|
||||
|
||||
// entry CRITERIA_MENU, type='LONG', c=5, size= 4,
|
||||
0x07 1 flags
|
||||
LONG 4 type
|
||||
0x05 1 item count
|
||||
0x14 1 data length
|
||||
0x0d 1 name length
|
||||
CRITERIA_ 13 name (CRITERIA_MENU)
|
||||
// data[0]: 0x0 (0, '')
|
||||
0x0 4 data[0]
|
||||
// data[1]: 0x0 (0, '')
|
||||
0x0 4 data[1]
|
||||
// data[2]: 0x0 (0, '')
|
||||
0x0 4 data[2]
|
||||
// data[3]: 0x0 (0, '')
|
||||
0x0 4 data[3]
|
||||
// data[4]: 0x0 (0, '')
|
||||
0x0 4 data[4]
|
||||
|
||||
// entry VALUE, type='CSTR', c=5,
|
||||
0x03 1 flags
|
||||
CSTR 4 type
|
||||
0x5 1 item count
|
||||
0x90 1 data length
|
||||
0x5 1 name length
|
||||
VALUE 5 name (VALUE)
|
||||
// size=18, data[0]: "listar@freelists."
|
||||
0x12 4 item size
|
||||
listar@fre 18 data[0]
|
||||
2 padding to 8-byte boundary
|
||||
// size=27, data[1]: "freelists-users@freelists."
|
||||
0x1b 4 item size
|
||||
freelists@ 27 data[1]
|
||||
1 padding to 8-byte boundary
|
||||
// size=27, data[2]: "freelists-users@freelists."
|
||||
0x1b 4 item size
|
||||
freelists@ 27 data[2]
|
||||
1 padding to 8-byte boundary
|
||||
// size=19, data[3]: "ecartis@freelists."
|
||||
0x13 4 item size
|
||||
ecartis@fr 19 data[3]
|
||||
1 padding to 8-byte boundary
|
||||
// size=26, data[4]: "freelists-news@freelists."
|
||||
0x1a 4 item size
|
||||
freelists@ 26 data[4]
|
||||
2 padding to 8-byte boundary
|
||||
|
||||
// entry AND_OR_MENU, type='LONG', c=5, size= 4,
|
||||
0x07 1 flags
|
||||
LONG 4 type
|
||||
0x5 1 item count
|
||||
0x14 1 data length
|
||||
0x0b 1 name length
|
||||
AND_OR_MEN 11 name (AND_OR_MENU)
|
||||
// data[0]: 0x1 (1, '')
|
||||
0x1 4 data[0]
|
||||
// data[1]: 0x1 (1, '')
|
||||
0x1 4 data[1]
|
||||
// data[2]: 0x1 (1, '')
|
||||
0x1 4 data[2]
|
||||
// data[3]: 0x1 (1, '')
|
||||
0x1 4 data[3]
|
||||
// data[4]: 0x0 (0, '')
|
||||
0x0 4 data[4]
|
||||
|
||||
// entry COUNT, type='LONG', c=1, size= 4, data[0]: 0x5 (5, '')
|
||||
0x0f 1 flags
|
||||
LONG 4 type
|
||||
0x4 1 data length
|
||||
0x5 1 name length
|
||||
COUNT 5 name (COUNT)
|
||||
0x5 4 data
|
||||
|
||||
// entry ACTION_MENU, type='LONG', c=1, size= 4, data[0]: 0x2 (2, '')
|
||||
0x0f 1 flags
|
||||
LONG 4 type
|
||||
0x4 1 data length
|
||||
0x0b 1 name length
|
||||
ACTION_MEN 11 name (ACTION_MENU)
|
||||
0x2 4 data
|
||||
|
||||
// entry ACTION_VALUE, type='CSTR', c=1, size=42, data[0]: "/boot/home/mail/Erik's Mail/freelists.org"
|
||||
0x0b 1 flags
|
||||
CSTR 4 type
|
||||
0x30 1 data length
|
||||
0x0c 1 name length
|
||||
ACTION_VAL 12 name (ACTION_VALUE)
|
||||
0x2a 4 item size
|
||||
/boot/home 42 data
|
||||
2 padding to 8-byte boundary
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// An old example
|
||||
Data Bytes Meaning
|
||||
|
||||
1BOF(ascii) 4 version
|
||||
?? 4 ??
|
||||
0x76 4 flattened size
|
||||
DPUQ 4 what(B_QUERY_UPDATE)
|
||||
?? 1 ??
|
||||
|
||||
0F 1 flags (including fixed chunk size)
|
||||
GNOL 4 type
|
||||
04 1 chunk size
|
||||
06 1 name length
|
||||
opcode 6 name
|
||||
1 4 data(B_ENTRY_CREATED)
|
||||
|
||||
0F 1 flags (including fixed chunk size)
|
||||
GNOL 4 type
|
||||
04 1 chunk size
|
||||
06 1 name length
|
||||
device 6 name
|
||||
4 4 data
|
||||
|
||||
0F 1 flags (including fixed chunk size)
|
||||
GNLL 4 type
|
||||
08 1 chunk size
|
||||
09 1 name length
|
||||
directory 9 name
|
||||
524992 8 data
|
||||
|
||||
0F 1 flags (including fixed chunk size)
|
||||
GNLL 4 type
|
||||
08 1 chunk size
|
||||
04 1 name length
|
||||
node 4 name
|
||||
524295 8 data
|
||||
|
||||
0B 1 flags (including variable chunk size)
|
||||
RTSC 4 type
|
||||
08 1 chunk size
|
||||
04 1 name length
|
||||
name 4 name
|
||||
08 1 chunk size?
|
||||
8 padded string?
|
||||
@@ -0,0 +1,169 @@
|
||||
/* The Dano Message Format
|
||||
|
||||
0. Disclaimer
|
||||
The information herein is based on reverse engeneering flattened BMessages.
|
||||
The conclusions might be wrong in the details, and an implementation can
|
||||
probably not be drawn right from this description, but the overall format
|
||||
described here should come close to the one found on Dano based systems.
|
||||
|
||||
1. Concept
|
||||
In the Dano message format, data is kept in a flat buffer and is organised
|
||||
in multiple "sections". Each section has a header that identifies the type
|
||||
of the section and it's size. Each section contains a field that then holds
|
||||
more information on the data and the data itself. Everything is usually
|
||||
padded to 8 byte boundaries.
|
||||
|
||||
2. Section Headers
|
||||
The section header looks like this:
|
||||
|
||||
typedef struct section_header_s {
|
||||
int32 code;
|
||||
ssize_t size;
|
||||
uint8 data[0];
|
||||
} SectionHeader;
|
||||
|
||||
The code identifies the type of the data following the header. Valid types
|
||||
are the following:
|
||||
|
||||
enum {
|
||||
SECTION_MESSAGE_HEADER = 'FOB2',
|
||||
SECTION_OFFSET_TABLE = 'STof',
|
||||
SECTION_TARGET_INFORMATION = 'ENwh',
|
||||
SECTION_SINGLE_ITEM_DATA = 'SGDa'
|
||||
SECTION_FIXED_SIZE_ARRAY_DATA = 'FADa',
|
||||
SECTION_VARIABLE_SIZE_ARRAY_DATA = 'VADa',
|
||||
SECTION_SORTED_INDEX_TABLE = 'DXIn',
|
||||
SECTION_END_OF_DATA = 'DDEn'
|
||||
};
|
||||
|
||||
The size field includes the size of the header itself and its data.
|
||||
|
||||
3. Message Header Section
|
||||
The message header section stores the what field of the message. Its code,
|
||||
conveniently at the very first 4 bytes, also identifies the message as a
|
||||
Dano message ('FOB2'). The layout is as follows:
|
||||
|
||||
typedef struct message_header_s {
|
||||
int32 what;
|
||||
int32 padding;
|
||||
} MessageHeader;
|
||||
|
||||
4. Offset Table Section
|
||||
The offset table stores the byte offsets to the sorted index table and to
|
||||
the end of data section. It looks like this:
|
||||
|
||||
typedef struct offset_table_s {
|
||||
int32 indexTable;
|
||||
int32 endOfData;
|
||||
int64 padding;
|
||||
} OffsetTable;
|
||||
|
||||
The index table offset is important since we will usually insert new fields
|
||||
before the index table. The end of data offset can be used to directly
|
||||
know where the index table ends. It's also possible that the end of index
|
||||
offset is actually the end of the index table.
|
||||
Both offsets are based on the beginning of the first data section and not
|
||||
from the top of the message.
|
||||
|
||||
5. Single Item Data Section
|
||||
The single item data section holds information on exactly one data item.
|
||||
Since when only dealing with one item it doesn't matter wether it is fixed
|
||||
size or not we do not distinct between these two types. The format is as
|
||||
follows:
|
||||
|
||||
typedef struct single_item_s {
|
||||
type_code type;
|
||||
ssize_t itemSize;
|
||||
uint8 nameLength;
|
||||
char name[0];
|
||||
} SingleItem;
|
||||
|
||||
The the name is padded to the next 8 byte boundary. After nameLength + 1
|
||||
bytes the item data begins. The nameLength field does not count the
|
||||
terminating 0 of the name, but the name is actually 0 terminated.
|
||||
|
||||
6. Fixed Size Item Array Data
|
||||
This type of section holds an array of fixed size items. Describing the
|
||||
format of this section in a struct is a bit harder, since the count
|
||||
variable is stored after the name field. In pseudo code it would look like
|
||||
this:
|
||||
|
||||
typedef struct fixed_size_s {
|
||||
type_code type;
|
||||
ssize_t sizePerItem;
|
||||
uint8 nameLength;
|
||||
char name[pad_to_8(nameLength + 1)];
|
||||
int32 count;
|
||||
int32 padding;
|
||||
uint8 data[0];
|
||||
} FixedSize;
|
||||
|
||||
7. Variable Sized Item Array Data
|
||||
The format is very similar to the one of the fixed size item array above.
|
||||
Again in pseudo code:
|
||||
|
||||
typedef struct variable_size_s {
|
||||
type_code type;
|
||||
int32 padding;
|
||||
uint8 nameLength;
|
||||
char name[pad_to_8(nameLength + 1)];
|
||||
int32 count;
|
||||
ssize_t totalSize;
|
||||
uint8 data[0];
|
||||
} VariableSize;
|
||||
|
||||
The data itself is constructed of the variable sized items, each padded to
|
||||
an eight byte boundary. Where they begin and where they end is not encoded
|
||||
in the data itself but in an "endpoint table" following the data (at data
|
||||
+ totalSize). The endpoint table is an array of int32 items each pointing
|
||||
to the end of an item (not including padding). As an example we take an
|
||||
array of three variable sized items layouted like this:
|
||||
|
||||
<data>
|
||||
76 61 72 69 61 62 6c 65 variable
|
||||
20 73 69 7a 65 64 20 64 sized d
|
||||
61 74 61 00 00 00 00 00 ata..... (pad)
|
||||
61 72 69 61 62 6c 65 20 ariable
|
||||
73 69 7a 65 64 20 64 61 sized da
|
||||
74 61 00 00 00 00 00 00 ta...... (pad)
|
||||
6c 61 73 74 20 69 6e 20 last in
|
||||
74 68 69 73 20 61 72 72 this arr
|
||||
61 79 21 00 00 00 00 00 ay!..... (pad)
|
||||
</data>
|
||||
|
||||
Then the endpoint table would look like this:
|
||||
|
||||
<endPointTable>
|
||||
<endPoint 20 />
|
||||
<endPoint 43 />
|
||||
<endPoint 68 />
|
||||
<endPointTable>
|
||||
|
||||
The first endpoint (20) means that the size of the first item is 20 bytes.
|
||||
The second endpoint (43) is constructed from the start of the second item
|
||||
which is at pad_to_8(endpoint[0]) plus the size of the item. In this case
|
||||
pad_to_8(endpoint[0]) results in 24, this is where the second item begins.
|
||||
So 43 - 24 gives us the unpadded length of item 2 (19). The third item
|
||||
starts at pad_to_8(endpoint[1]) and is in our case 48. The length of item
|
||||
three is therefor 68 - 48 = 20 bytes. Note that in this example we are
|
||||
talking about strings where the 0 termination is included in the item size.
|
||||
|
||||
8. Sorted Index Table
|
||||
The sorted index table is a list of direct offsets to the fields. It is
|
||||
binary sorted using the field names. This means that we can use it for
|
||||
name lookups with a O(log(n)) complexity instead of doing linear searches.
|
||||
The section data is composed directly out of the int32 array of offsets.
|
||||
No extra data is stored in this section. All offsets have the first data
|
||||
section as their base.
|
||||
|
||||
9. End Of Data Section
|
||||
This section terminates the section stream. No other data is stored in this
|
||||
section.
|
||||
|
||||
10. Target Information Section
|
||||
The target information section is used to hold the target team, handler,
|
||||
port information for message delivery. As this data is not relevant when
|
||||
handling disk stored messages only, the format of this section is not
|
||||
discussed here.
|
||||
|
||||
*/
|
||||
@@ -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>
|
||||
@@ -0,0 +1,14 @@
|
||||
- Need the ability to save crash reports.
|
||||
- CLI needs to be more fully implemented.
|
||||
- General expression evaluation parser. Once implemented, should supplant the primitive one currently used for C/C++ typecasting support, as well as being exposed for user expression input.
|
||||
- Conditional breakpoint/watchpoints. Contingent on above general expression parser.
|
||||
- Remote debug interface support.
|
||||
- Kernel debug support.
|
||||
- Architecture needs to be able to report back the hardware debugging capabilities/limitations of the target platform.
|
||||
- WatchpointManager needs to be able to use the aforementioned information from Architecture in order to more intelligently
|
||||
manage/restrict watchpoint usage (especially once expression watchpoints come into play).
|
||||
- More complete DWARF3/4 support.
|
||||
- x86-64 support.
|
||||
- Support for retrieving/displaying function return values (arch-specific).
|
||||
- Syntax highlighting in source view.
|
||||
- Detection of mouse hovering over a variable in SourceView and showing value in tooltip (probably requires expression parsing support).
|
||||
@@ -0,0 +1,660 @@
|
||||
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
|
||||
<html>
|
||||
<head>
|
||||
<title>BPicture specifications</title>
|
||||
<meta http-equiv="content-type"
|
||||
content="text/html; charset=ISO-8859-1">
|
||||
<meta name="author" content="Marc Flerackers([email protected])">
|
||||
<meta name="description"
|
||||
content="BPicture specifications for OpenBeOS">
|
||||
</head>
|
||||
<body>
|
||||
<span style="font-weight: bold; text-decoration: underline;"></span>Author:
|
||||
Marc Flerackers<br>
|
||||
Revision: 1.4<br>
|
||||
<span style="font-weight: bold; text-decoration: underline;"></span><span
|
||||
style="font-weight: bold; text-decoration: underline;"><br>
|
||||
Picture data</span><br>
|
||||
<br>
|
||||
The data of a BPicture is composed of instructions.<br>
|
||||
<br>
|
||||
These instructions have a small header, which looks as follows:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>int16</td>
|
||||
<td valign="top">id</td>
|
||||
<td valign="top">The instruction id</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">int32</td>
|
||||
<td valign="top">size</td>
|
||||
<td valign="top">The size of the data</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
After this header the data follows. There are two exceptions:
|
||||
EnterStateChange and EnterFontState. These are used to enclose state and
|
||||
font changes. For ExitStateChange and ExitFontState there are no
|
||||
instructions, this is not needed as we know the size of the instruction
|
||||
block in the header of the Enter* functions.<br>
|
||||
<br>
|
||||
These are the known instructions at the moment:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left; width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th valign="top">Id<br>
|
||||
</th>
|
||||
<th valign="top">Name<br>
|
||||
</th>
|
||||
<th valign="top">Size<br>
|
||||
</th>
|
||||
<th valign="top">Data<br>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0010<br>
|
||||
</td>
|
||||
<td valign="top">MovePenBy<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">BPoint where<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0100<br>
|
||||
</td>
|
||||
<td valign="top">StrokeLine<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BPoint start<br>
|
||||
BPoint end<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0101<br>
|
||||
</td>
|
||||
<td valign="top">StrokeRect<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0102<br>
|
||||
</td>
|
||||
<td valign="top">FillRect<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0103<br>
|
||||
</td>
|
||||
<td valign="top">StrokeRoundRect<br>
|
||||
</td>
|
||||
<td valign="top">24</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
BPoint radii<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0104<br>
|
||||
</td>
|
||||
<td valign="top">FillRoundRect</td>
|
||||
<td valign="top">24<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
BPoint radii</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0105<br>
|
||||
</td>
|
||||
<td valign="top">StrokeBezier<br>
|
||||
</td>
|
||||
<td valign="top">32<br>
|
||||
</td>
|
||||
<td valign="top">BPoint[4] control</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0106<br>
|
||||
</td>
|
||||
<td valign="top">FillBezier<br>
|
||||
</td>
|
||||
<td valign="top">32<br>
|
||||
</td>
|
||||
<td valign="top">BPoint[4] control</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010B<br>
|
||||
</td>
|
||||
<td valign="top">StrokePolygon<br>
|
||||
</td>
|
||||
<td valign="top">4 + point data size + 1<br>
|
||||
</td>
|
||||
<td valign="top">int32 numPoints<br>
|
||||
BPoint *points<br>
|
||||
bool isClosed<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010C<br>
|
||||
</td>
|
||||
<td valign="top">FillPolygon<br>
|
||||
</td>
|
||||
<td valign="top">4 + point data size </td>
|
||||
<td valign="top">int32 numPoints<br>
|
||||
BPoint *points<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010D<br>
|
||||
</td>
|
||||
<td valign="top">StrokeShape<br>
|
||||
</td>
|
||||
<td valign="top">shape data size<br>
|
||||
</td>
|
||||
<td valign="top">shape data, see below </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010E </td>
|
||||
<td valign="top">FillShape </td>
|
||||
<td valign="top">shape data size </td>
|
||||
<td valign="top">shape data, see below </td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x010F<br>
|
||||
</td>
|
||||
<td valign="top">DrawString<br>
|
||||
</td>
|
||||
<td valign="top">4 + string data size + 8<br>
|
||||
</td>
|
||||
<td valign="top">strlen<br>
|
||||
char *string<br>
|
||||
float deltax<br>
|
||||
float deltay<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0110 </td>
|
||||
<td valign="top">DrawPixels<br>
|
||||
</td>
|
||||
<td valign="top">56 + pixel data size<br>
|
||||
</td>
|
||||
<td valign="top">BRect src<br>
|
||||
BRect dest<br>
|
||||
int32 width<br>
|
||||
int32 height<br>
|
||||
int32 bytesPerRow<br>
|
||||
int32 pixelFormat<br>
|
||||
int32 flags<br>
|
||||
int32 length of pixel data<br>
|
||||
pixel data<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0112<br>
|
||||
</td>
|
||||
<td valign="top">DrawPicture<br>
|
||||
</td>
|
||||
<td valign="top">12<br>
|
||||
</td>
|
||||
<td valign="top">BPoint where?<br>
|
||||
????<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0113</td>
|
||||
<td valign="top">StrokeArc<br>
|
||||
</td>
|
||||
<td valign="top">24<br>
|
||||
</td>
|
||||
<td valign="top">BPoint center<br>
|
||||
BPoint radii<br>
|
||||
float startTheta<br>
|
||||
float arcTheta<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0114<br>
|
||||
</td>
|
||||
<td valign="top">FillArc<br>
|
||||
</td>
|
||||
<td valign="top">24<br>
|
||||
</td>
|
||||
<td valign="top">BPoint center<br>
|
||||
BPoint radii<br>
|
||||
float startTheta<br>
|
||||
float arcTheta</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0115<br>
|
||||
</td>
|
||||
<td valign="top">StrokeEllipse<br>
|
||||
</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0116</td>
|
||||
<td valign="top">FillEllipse</td>
|
||||
<td valign="top">16<br>
|
||||
</td>
|
||||
<td valign="top">BRect rect</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0200<br>
|
||||
</td>
|
||||
<td valign="top">EnterStateChange<br>
|
||||
</td>
|
||||
<td valign="top">size of state instructions<br>
|
||||
</td>
|
||||
<td valign="top">state instructions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0201</td>
|
||||
<td valign="top">SetClippingRects</td>
|
||||
<td valign="top">16 + size of rects<br>
|
||||
</td>
|
||||
<td valign="top">clipping_rect bound<br>
|
||||
clipping_rect *rect</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0202</td>
|
||||
<td valign="top">ClipToPicture</td>
|
||||
<td valign="top">7 + 8 + 1 </td>
|
||||
<td valign="top">zero bytes<br>
|
||||
BPoint pt<br>
|
||||
bool clip_to_inverse_picture<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0203<br>
|
||||
</td>
|
||||
<td valign="top">PushState<br>
|
||||
</td>
|
||||
<td valign="top">0<br>
|
||||
</td>
|
||||
<td valign="top"><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0204</td>
|
||||
<td valign="top">PopState</td>
|
||||
<td valign="top">0<br>
|
||||
</td>
|
||||
<td valign="top"><br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0205<br>
|
||||
</td>
|
||||
<td valign="top">SetClippingRects </td>
|
||||
<td valign="top">0 </td>
|
||||
<td valign="top">This is a shorter instruction for 0 clipping
|
||||
rects.<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0300<br>
|
||||
</td>
|
||||
<td valign="top">SetOrigin<br>
|
||||
</td>
|
||||
<td valign="top">8<br>
|
||||
</td>
|
||||
<td valign="top">BPoint pt<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0301<br>
|
||||
</td>
|
||||
<td valign="top">SetPenLocation<br>
|
||||
</td>
|
||||
<td valign="top">8<br>
|
||||
</td>
|
||||
<td valign="top">BPoint pt<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0302<br>
|
||||
</td>
|
||||
<td valign="top">SetDrawingMode<br>
|
||||
</td>
|
||||
<td valign="top">2<br>
|
||||
</td>
|
||||
<td valign="top">drawing_mode mode<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0303</td>
|
||||
<td valign="top">SetLineMode<br>
|
||||
</td>
|
||||
<td valign="top">2 + 2 + 4<br>
|
||||
</td>
|
||||
<td valign="top">cap_mode capMode<br>
|
||||
join_mode joinMode<br>
|
||||
float miterLimit<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0304<br>
|
||||
</td>
|
||||
<td valign="top">SetPenSize</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float size<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0305<br>
|
||||
</td>
|
||||
<td valign="top">SetScale<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float scale</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0306<br>
|
||||
</td>
|
||||
<td valign="top">SetForeColor<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">rgb_color color<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0307<br>
|
||||
</td>
|
||||
<td valign="top">SetBackColor<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">rgb_color color</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0308<br>
|
||||
</td>
|
||||
<td valign="top">SetStipplePattern<br>
|
||||
</td>
|
||||
<td valign="top">8<br>
|
||||
</td>
|
||||
<td valign="top">pattern p<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0309<br>
|
||||
</td>
|
||||
<td valign="top">EnterFontState<br>
|
||||
</td>
|
||||
<td valign="top">size of font instructions</td>
|
||||
<td valign="top">font instructions</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x030A<br>
|
||||
</td>
|
||||
<td valign="top">SetBlendingMode<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">source_alpha alphaSrcMode<br>
|
||||
alpha_function alphaFncMode<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0380<br>
|
||||
</td>
|
||||
<td valign="top">SetFontFamily<br>
|
||||
</td>
|
||||
<td valign="top">4 + string data size</td>
|
||||
<td valign="top">strlen<br>
|
||||
char *family<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0381<br>
|
||||
</td>
|
||||
<td valign="top">SetFontStyle<br>
|
||||
</td>
|
||||
<td valign="top">4 + string data size</td>
|
||||
<td valign="top">strlen<br>
|
||||
char style</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0382<br>
|
||||
</td>
|
||||
<td valign="top">SetFontSpacing<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 spacing<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0383<br>
|
||||
</td>
|
||||
<td valign="top">SetFontEncoding<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 encoding<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0384<br>
|
||||
</td>
|
||||
<td valign="top">SetFontFlags<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 flags<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0385<br>
|
||||
</td>
|
||||
<td valign="top">SetFontSize<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float size<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0386<br>
|
||||
</td>
|
||||
<td valign="top">SetFontRotate<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float rotation<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0387<br>
|
||||
</td>
|
||||
<td valign="top">SetFontShear<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">float shear(is 0 instead of 90?)<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x0389<br>
|
||||
</td>
|
||||
<td valign="top">SetFontFace<br>
|
||||
</td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top">int32 flags<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
There are a few undocumented instructions:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left;" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top">0x0388<br>
|
||||
</td>
|
||||
<td valign="top">SetFontBPP </td>
|
||||
<td valign="top">4<br>
|
||||
</td>
|
||||
<td valign="top"> int32 bpp (default 8)<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
Not all instructions where checked yet. The SetClippingRects has still
|
||||
to be documented.<br>
|
||||
<br>
|
||||
DrawPicture and ClipToPicture have an index to the sub-picture. In
|
||||
flattened data, these sub-pictures are stored in front of the main
|
||||
picture data, when archived to a BMessage, the sub-pictures are
|
||||
contained in a field called "piclib".<br>
|
||||
<br>
|
||||
<span style="font-weight: bold; text-decoration: underline;">Shape data</span><br>
|
||||
<br>
|
||||
The shape data contained in a BPicture is stored as follows:<br>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left;" width="100%">
|
||||
<tbody>
|
||||
<tr>
|
||||
<td valign="top">int32<br>
|
||||
</td>
|
||||
<td valign="top">instruction count<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top" rowspan="1" colspan="1">uint32 *instructions<br>
|
||||
</td>
|
||||
<td valign="top" rowspan="1" colspan="1">Each instruction looks
|
||||
like:<br>
|
||||
First byte is the instruction id<br>
|
||||
The next three bytes is the amount of points used*<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">int32<br>
|
||||
</td>
|
||||
<td valign="top">point count<br>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">BPoint *points </td>
|
||||
<td valign="top">points<br>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
<table cellpadding="2" cellspacing="2" border="1"
|
||||
style="text-align: left; width: 100%;">
|
||||
<tbody>
|
||||
<tr>
|
||||
<th valign="top">Id<br>
|
||||
</th>
|
||||
<th valign="top">Name<br>
|
||||
</th>
|
||||
<th valign="top">Points*<br>
|
||||
</th>
|
||||
<th valign="top">Notes<br>
|
||||
</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x80</td>
|
||||
<td valign="top">MoveTo</td>
|
||||
<td valign="top"><br>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>A "MoveTo" instruction doesn't stand alone, but is OR-ed
|
||||
with a "LineTo" or "BezierTo" instruction<br>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x10 </td>
|
||||
<td valign="top">LineTo</td>
|
||||
<td valign="top">point count in instruction<br>
|
||||
</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>One "LineTo" instruction draws "count" lines</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x90 </td>
|
||||
<td valign="top">MoveTo LineTo</td>
|
||||
<td valign="top">point count in instruction + 1</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>There is one extra point for the "MoveTo", which is not
|
||||
counted in the instruction.<br>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x20 </td>
|
||||
<td valign="top">BezierTo</td>
|
||||
<td valign="top">point count in instruction</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>One "BezierTo" instruction draws "count" lines</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0xA0 </td>
|
||||
<td valign="top">MoveTo BezierTo</td>
|
||||
<td valign="top">point count in instruction + 1</td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>There is one extra point for the "MoveTo", which is not
|
||||
counted in the instruction.<br>
|
||||
</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td valign="top">0x40 </td>
|
||||
<td valign="top">Close</td>
|
||||
<td valign="top">0 </td>
|
||||
<td valign="top">
|
||||
<ul>
|
||||
<li>"Close" can only follow a "LineTo" or "BezierTo" instruction</li>
|
||||
<li>If an instruction follows "Close", the new instruction is
|
||||
OR-ed with "Close" and replaces it instruction</li>
|
||||
<li>A shape never starts with "Close"</li>
|
||||
</ul>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<br>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,34 @@
|
||||
Tests executed on a Duron 1200
|
||||
|
||||
ikki:~/projects/current# tests/UnitTester BRegion
|
||||
------------------------------------------------------------------------------
|
||||
Tests
|
||||
------------------------------------------------------------------------------
|
||||
BRegion::Construction Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
BRegion::Exclude Test
|
||||
+ PASSED
|
||||
Clock time: 251 ms
|
||||
|
||||
BRegion::Include Test
|
||||
+ PASSED
|
||||
Clock time: 260 ms
|
||||
|
||||
BRegion::Intersect Test
|
||||
+ PASSED
|
||||
Clock time: 102 ms
|
||||
|
||||
BRegion::OffsetBy Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Results
|
||||
------------------------------------------------------------------------------
|
||||
+ PASSED
|
||||
|
||||
|
||||
As you can see, it may be worth optimizing especially the Exclude and Include methods.
|
||||
See RegionSupport.cpp (in particular RSub() and ROr()) for more info.
|
||||
@@ -0,0 +1,30 @@
|
||||
Tests executed on a Duron 1200
|
||||
|
||||
ikki:~/projects/current# tests/UnitTester -r5 BRegion
|
||||
------------------------------------------------------------------------------
|
||||
Tests
|
||||
------------------------------------------------------------------------------
|
||||
BRegion::Construction Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
BRegion::Exclude Test
|
||||
+ PASSED
|
||||
Clock time: 284 ms
|
||||
|
||||
BRegion::Include Test
|
||||
+ PASSED
|
||||
Clock time: 265 ms
|
||||
|
||||
BRegion::Intersect Test
|
||||
+ PASSED
|
||||
Clock time: 113 ms
|
||||
|
||||
BRegion::OffsetBy Test
|
||||
+ PASSED
|
||||
Clock time: 0 ms
|
||||
|
||||
------------------------------------------------------------------------------
|
||||
Results
|
||||
------------------------------------------------------------------------------
|
||||
+ PASSED
|
||||
@@ -0,0 +1,391 @@
|
||||
<HTML>
|
||||
<!-- $Id: UnitTestingInfo.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
|
||||
<HEAD>
|
||||
<TITLE>Unit Testing Information</TITLE>
|
||||
</HEAD>
|
||||
|
||||
<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
|
||||
<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
|
||||
|
||||
<H1>Unit Testing Information:</H1>
|
||||
|
||||
<P>This document describes the "why's" and "how's" of unit testing for the AppKit team of the
|
||||
OpenBeOS project. Although it is intended for the AppKit team, there is no reason other teams
|
||||
couldn't use this information to develop a similar unit testing strategy.</P>
|
||||
|
||||
<P>The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#what">What is unit testing?</A></LI>
|
||||
<LI><A HREF="#why">Why is unit testing important?</A></LI>
|
||||
<LI><A HREF="#when">When should I write my unit tests?</A></LI>
|
||||
<LI><A HREF="#whattests">What kinds of tests should be in a unit test?</A></LI>
|
||||
<LI><A HREF="#testframework">What framework is being used to do unit testing for the AppKit?</A></LI>
|
||||
<LI><A HREF="#frameworkmods">What AppKit specific modifications have been made to this framework?</A></LI>
|
||||
<LI><A HREF="#futuremods">What framework modifications might be required in the future?</A></LI>
|
||||
<LI><A HREF="#buildingtests">How do I build the framework and current tests for the AppKit?</A></LI>
|
||||
<LI><A HREF="#runningtests">How do I run tests?</A></LI>
|
||||
<LI><A HREF="#writingtests">How do I write tests for my component?</A></LI>
|
||||
<LI><A HREF="#exampletests">Are there example tests to base mine on?</A></LI>
|
||||
<LI><A HREF="#threadedtests">How do I write a test with multiple threads?</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="what"></A><H2>What is unit testing?</H2>
|
||||
|
||||
<P>Unit testing is the process of showing that a part of a software system works as far as the
|
||||
requirements created for that part of the system. Unit testing is best if it has the following
|
||||
characteristics:</P>
|
||||
|
||||
<UL>
|
||||
<LI>The software component is tested in isolation with as little interaction with other software
|
||||
components as possible.</LI>
|
||||
<LI>The software component is tested using automated tools so that unit tests can be run with
|
||||
every build of the software if required.</LI>
|
||||
<LI>All requirements of the software component are tested as part of the unit tests.</LI>
|
||||
</UL>
|
||||
|
||||
<P>Unit testing is not the only type of testing but is definitely a very important part of any
|
||||
testing strategy. Following unit testing, software should go through "integration testing" to
|
||||
show that the components work as expected when put together.</P>
|
||||
|
||||
<A NAME="why"></A><H2>Why is unit testing important?</H2>
|
||||
|
||||
<P>A basic concept of software engineering is that the cost of fixing a bug goes up by a factor
|
||||
of 2-10x (depending on the source of the information) the later in the development process it is
|
||||
found. Unit testing is critical to finding implementation bugs within a particular component as
|
||||
quickly as possible.</P>
|
||||
|
||||
<P>Unit testing will also help to find requirements problems also. If you write the requirements
|
||||
(or use cases) for your component from the BeBook, hopefully the BeBook and your use cases will
|
||||
match the actual Be implementation. A good way to confirm that the BeBook documentation matches
|
||||
Be's implementation is to write your unit tests and run them against the original Be code.</P>
|
||||
|
||||
<P>Unit tests will also continue to be maintained and run in the future also. As the mailing
|
||||
lists obviously show, many people are looking forward to OpenBeOS post-R1 when new features
|
||||
will be introduced above and beyond BeOS R5. These unit tests will be critical to ensuring that
|
||||
any new feature or even just a bug fix doesn't break existing functionality.</P>
|
||||
|
||||
<P>Speaking of bug fixes, consider adding unit tests for any bugs you identify that slipped
|
||||
through your original unit test suite. This will ensure that this bug or a similar one is not
|
||||
re-introduced in the future.</P>
|
||||
|
||||
<P>Finally, unit testing is not the be all, end all of testing. As mentioned above, integration
|
||||
testing must be done to show that software components work together. If all unit tests cover
|
||||
all requirements and have run successfully against all components, then a failure has to be
|
||||
due to a bug in the interaction of two or more known working software components.</P>
|
||||
|
||||
<A NAME="when"></A><H2>When should I write my unit tests?</H2></LI>
|
||||
|
||||
<P>As the AppKit process document describes the recommended order for implementing a component
|
||||
is:</P>
|
||||
|
||||
<OL>
|
||||
<LI>Write an interface specification</LI>
|
||||
<LI>Write the use case specifications</LI>
|
||||
<LI>Write the unit tests</LI>
|
||||
<LI>Write an implementation plan</LI>
|
||||
<LI>Write the code</LI>
|
||||
</OL>
|
||||
|
||||
<P>Please see the AppKit process document for more details about the entire sequence. The unit
|
||||
test are to be written once the use cases are written and before any implementation work is
|
||||
done. The use cases must be done because they determine what the tests will be. You need to
|
||||
write as many tests are required so that all use cases for that component are tested. The use
|
||||
cases should be detailed enough that you can write your unit tests from them.</P>
|
||||
|
||||
<P>The unit tests are to be done before implementation for a very good reason. You should be able
|
||||
to run these unit tests against the Be implementation and confirm that they all pass. If they do
|
||||
not pass, then either there is a bug in the unit test itself or you have found a difference
|
||||
between your use cases and the actual implementation. Even if your use cases match the BeBook,
|
||||
if that is not how the actual Be implementation works, we must match the current implementation and
|
||||
not the BeBook. You should go back and modify the use case. Change the use case so that it
|
||||
matches Be's implementation and consider adding a note indicating this doesn't match the
|
||||
BeBook.</P>
|
||||
|
||||
<P>Imagine if you completed the implementation and then wrote and ran the unit tests. If you run
|
||||
the tests against your implementation and Be's implementation, you will notice the test passes
|
||||
for your code but fails on Be's. At this point, you will have to change the implementation, change
|
||||
the unit test and change the use case which is more work that if you write the unit tests before
|
||||
the implementation. Worse, if you only ran the unit tests against your implementation and not
|
||||
Be's, you may not notice the problem at all.</P>
|
||||
|
||||
<A NAME="whattest"></A><H2>What kinds of tests should be in a unit test?</H2>
|
||||
|
||||
<P>The unit tests you write should cover all the functionality of your software module. That
|
||||
means your unit tests should include:</P>
|
||||
|
||||
<UL>
|
||||
<LI>All standard expected functionality of the software component</LI>
|
||||
<LI>All error conditions handled by the software component</LI>
|
||||
<LI>Interaction with software components which cannot be decoupled from the target software
|
||||
component</LI>
|
||||
<LI>Concurrency tests to show that a software component which is expected to be thread safe (most
|
||||
things are under BeOS) is safe and free from deadlocks.</LI>
|
||||
</UL>
|
||||
|
||||
<A NAME="testframework"></A><H2>What framework is being used to do unit testing for the AppKit?</H2>
|
||||
|
||||
<P>The AppKit team has chosen to use CppUnit version 1.5 as the basis of all of our unit tests.
|
||||
This framework provides very useful features and ensures that all unit tests for AppKit code
|
||||
are consistent and can be executed from a single environment.</P>
|
||||
|
||||
<P>There are two key components to the framework. First, there is a library called libCppUnit.so
|
||||
which provides all the C++ classes for defining your own testcases. Secondly, there is an
|
||||
executable called "TestRunner" which is capable of executing a set of testcases.</P>
|
||||
|
||||
<P>For more information on CppUnit, please refer to
|
||||
<A HREF="http://cppunit.sourceforge.net/">this website</A>
|
||||
|
||||
<A NAME="frameworkmods"></A><H2>What AppKit specific modifications have been made to this framework?</H2>
|
||||
|
||||
<P>The following are the modifications that have been introduced into the CppUnit v1.5
|
||||
framework:</P>
|
||||
|
||||
<UL>
|
||||
<LI>A makefile has been added for the library and the TestRunner.</LI>
|
||||
<LI>Some "bugs" in CppUnit v1.5 which lead to it not compiling under BeOS v5.</LI>
|
||||
<LI>The TestRunner has been modified to support BeOS based addons. Each test which you can
|
||||
select from the TestRunner is found in the "add-ons" directory at runtime. The original
|
||||
TestRunner required you to change the TestRunner when new tests were added to it.</LI>
|
||||
<LI>Changed the output from TestRunner. The output includes a name of the test being run and
|
||||
a run time for the test in microseconds.</LI>
|
||||
<LI>Changed the arguments of the assert functions in the TestCase class from std::string to
|
||||
const char *'s due to apparent concurrency problems with std::string under BeOS when testing
|
||||
threaded tests.</LI>
|
||||
<LI>Added locking to the TestResults class so that multiple threads can safely add result
|
||||
information at the same time for a single test.</LI>
|
||||
<LI>The ThreadedTestCaller class was written to allow us to write tests which contain multiple
|
||||
threads. This is an important class because many BeOS components are thread safe and we need
|
||||
to confirm that the OpenBeOS implementation is also thread safe.</LI>
|
||||
</UL>
|
||||
|
||||
<P>This is the list of the important modifications done to CppUnit v1.5 at the time this document
|
||||
is being written. For the latest information about modifications to CppUnit, check the code
|
||||
which can be found in the OpenBeOS CVS repository.</P>
|
||||
|
||||
<A NAME="futuremods"></A><H2>What framework modifications might be required in the future?</H2>
|
||||
|
||||
<P>This framework will have to evolve as our needs grow. The main issues I think we need to
|
||||
solve are:</P>
|
||||
|
||||
<UL>
|
||||
<LI>The format of the test name is an encoded string representing the class definition of the
|
||||
test class from gcc. It is not a very readable format but given that the test class is often
|
||||
a template class and you would like different names for different instances of the template,
|
||||
this seemed the best compromise. Suggestions welcome.</LI>
|
||||
|
||||
<LI>The threaded test support added into CppUnit forces you to specify the entry point for each
|
||||
thread in your test. If you are doing a test with a BLooper or a BWindow, these classes start
|
||||
a thread of their own. This thread will not be started through the standard entry point so
|
||||
doing "assert's" from one of these threads will not work. Perhaps we need TestBLooper and
|
||||
TestBWindow classes which will work with the assert's.</LI>
|
||||
</UL>
|
||||
|
||||
<P>If you find you need some other features, feel free to add them to CppUnit.</P>
|
||||
|
||||
<A NAME="buildingtests"></A><H2>How do I build the framework and current tests for the AppKit?</H2>
|
||||
|
||||
<P>As of writing this document, you can build the framework and all the current AppKit tests
|
||||
by performing the following steps:</P>
|
||||
|
||||
<OL>
|
||||
|
||||
<LI>Checkout the "app_kit" sources or the entire repository from the OpenBeOS CVS repository.
|
||||
There is information at the OpenBeOS site about how to access the CVS repository.</LI>
|
||||
|
||||
<LI>In a terminal, "cd" into the "app_kit" directory in the CVS files you checked out.</LI>
|
||||
|
||||
<LI>Type "make".</LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<P>Note that the build system for OpenBeOS is moving to jam so these steps may become obsolete.
|
||||
When you the make has finished, you should find the following files:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><CODE>app_kit/test/CppUnit/TestRunner</CODE> - this is the executable to use to execute
|
||||
tests.</LI>
|
||||
<LI><CODE>app_kit/test/CppUnit/lib/libCppUnit.so</CODE> - this is CppUnit library which your tests
|
||||
must link against.</LI>
|
||||
<LI><CODE>app_kit/test/CppUnit/lib/libopenbeos.so</CODE> - this is library which contains OpenBeOS
|
||||
implementation of some Be classes (usually found in libbe.so, called libopenbeos.so to avoid a name
|
||||
clash at runtime).</LI>
|
||||
<LI><CODE>app_kit/test/add-ons/BAutolockTests</CODE> - this is the addon which contains the tests
|
||||
which are run against the Be and OpenBeOS implementation of BAutolock.</LI>
|
||||
<LI><CODE>app_kit/test/add-ons/BLockerTests</CODE> - this is the addon which contains the tests
|
||||
which are run against the Be and OpenBeOS implementation of BLocker.</LI>
|
||||
<LI><CODE>app_kit/test/add-ons/BMessageQueueTests</CODE> - this is the addon which contains the tests
|
||||
which are run against the Be and OpenBeOS implementation of BMessageQueue.</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>These are the key files which ensure that the tests can be run.</P>
|
||||
|
||||
<A NAME="runningtests"></A><H2>How do I run tests?</H2>
|
||||
|
||||
<P>You have a few different options for how you run a test or a series of tests. Before you start
|
||||
however, you must build the code as describe <A HREF="#buildingtests">in this section</A>. Once
|
||||
it is built, you can run tests any of these ways:</P>
|
||||
|
||||
<UL>
|
||||
<LI>Run "make test" from the app_kit directory. This will lead to all of the tests defined in
|
||||
app_kit/test/add-ons directory to be run.</LI>
|
||||
<LI>From the "app_kit/test" directory, execute the command "CppUnit/TestRunner -all". This will
|
||||
lead to all of the tests defined in the app_kit/test/add-ons directory to be run and is the same
|
||||
as what happens in the "make" example above. However, recompile any code that has changed in the
|
||||
process.</LI>
|
||||
<LI>From the "app_kit/test" directory, execute the command "CppUnit/TestRunner <TestName>"
|
||||
where <TestName> is one of the addons found in the "app_kit/test/add-ons" directory. Only
|
||||
the tests defined in that add-on will be run.</LI>
|
||||
</UL>
|
||||
|
||||
<A NAME="writingtests"></A><H2>How do I write tests for my component?</H2>
|
||||
|
||||
<P>The first step to writing your tests is to develop a plan for how you will test the
|
||||
functionality. For ideas of the kinds of tests you may want to consider, you should reference
|
||||
<A HREF="#whattests">this section</A>.</P>
|
||||
|
||||
<P>Once you know the kinds of tests you want, you need to:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><P>For every test you want, define a class which derives from the "TestCase" class in the
|
||||
CppUnit framework.</P></LI>
|
||||
|
||||
<LI><P>Within each test class you define, create a "void setUp(void)" and "void tearDown(void)"
|
||||
member function if required. If before executing your test, you need to perform some actions,
|
||||
put those actions in the "setUp()" member. If you need to cleanup after your test, put those
|
||||
actions in the "tearDown()" member.</P></LI>
|
||||
|
||||
<LI><P>Within each test class you define, create a member function which takes "void" and
|
||||
returns "void". Within this member function, write the code to execute the test. Whenever you
|
||||
want to ensure that some condition is true during your test, add a line within the member function
|
||||
that looks like "assert(condition)". For example, if the variable "result" must have the value
|
||||
B_OK at a particular point in your test, you should add a line which reads
|
||||
"assert(result = B_OK)".</P></LI>
|
||||
|
||||
<LI><P>Create a constructor for all of your test classes that takes a "std::string name" argument
|
||||
and pass that onto the TestCase parent class. Add whatever actions you need to take in the
|
||||
constructor.</P></LI>
|
||||
|
||||
<LI><P>Create a destructor for all of your test classes and take whatever actions are
|
||||
appropriate.</P></LI>
|
||||
|
||||
<LI><P>Within each test class you define, create a member with the signature
|
||||
"static Test *suite(void)". For a simple test where only one test needs to be run for this class,
|
||||
the contents of this member should look like:</P>
|
||||
|
||||
<PRE>
|
||||
return(new TestCaller<ClassName>("", &ClassName::MemberName));
|
||||
</PRE>
|
||||
|
||||
<P>Replace "ClassName" with the name of your test class and "MemberName" with the name
|
||||
of the member function you defined your test in. If you need to define more than one test to run
|
||||
from this class, refer to instructions below on how to use the TestSuite class of CppUnit. If you
|
||||
are creating a threaded test, refer to <A HREF="#threadedtests">this section</A>.</P></LI>
|
||||
|
||||
<LI><P>Create one ".cpp" file for defining the "addonTestFunc()" function. This function must
|
||||
exist in global scope within your test addon. The contents of this ".cpp" file will look something
|
||||
like:</P>
|
||||
|
||||
<PRE>
|
||||
#include "TestAddon.h"
|
||||
|
||||
Test *addonTestFunc(void)
|
||||
{
|
||||
TestSuite *testSuite = new TestSuite("<TestSuiteName>");
|
||||
|
||||
testSuite->addTest(<ClassName1>::suite());
|
||||
testSuite->addTest(<ClassName2>::suite());
|
||||
/* etc */
|
||||
|
||||
return(testSuite);
|
||||
}
|
||||
</PRE>
|
||||
|
||||
<P>In the above example, replace <TestSuiteName> with an appropriate name for the group of
|
||||
tests and <ClassName1> and <ClassName2> with the names of the test classes you have
|
||||
defined.</P></LI>
|
||||
|
||||
<LI><P>Create a build system around a BeIDE project, Makefile or preferrably a jam file which
|
||||
builds all the necessary code you have written into an addon.</P></LI>
|
||||
|
||||
<LI><P>Put this addon into the app_kit/test/add-ons directory and follow the above instructions
|
||||
for how to run your tests.</P></LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<A NAME="exampletests"></A><H2>Are there example tests to base mine on?</H2>
|
||||
|
||||
<P>There are example tests which you can find in the following directories:</P>
|
||||
|
||||
<UL>
|
||||
<LI><CODE>app_kit/test/lib/application/BMessageQueue</CODE></LI>
|
||||
<LI><CODE>app_kit/test/lib/support/BAutolock</CODE></LI>
|
||||
<LI><CODE>app_kit/test/lib/support/BLocker</CODE></LI>
|
||||
</UL>
|
||||
|
||||
<P>There are some things done in these tests which make things a bit more complex, but you may
|
||||
want to do similar things:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI>Most tests use a ThreadedTestCaller class even in some situations when there aren't actually
|
||||
more than one thread in the test.</LI>
|
||||
|
||||
<LI>All tests are defined as a template class. The test class is a template of the class to test
|
||||
(if that makes sense to you). For example, to test both the Be and OpenBeOS BLocker and not
|
||||
end up with a symbol conflict, the OpenBeOS implementation of BLocker is actually in a namespace
|
||||
called "OpenBeOS". So, the tests must be run against the classes "::BLocker" and
|
||||
"OpenBeOS::BLocker". The easiest way to do this was to make the class to be tested a template
|
||||
and define it for both "::BLocker" and "OpenBeOS::BLocker".</LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>Even with the complexity, I think this code provides a pretty good example of how to write
|
||||
your tests.</P>
|
||||
|
||||
<A NAME="threadedtests"></A><H2>How do I write a test with multiple threads?</H2>
|
||||
|
||||
<P>If you have a test which you want to define that requires more than one thread of execution
|
||||
(most likely a concurrency test of you code), you need to use the ThreadedTestCaller class.
|
||||
The steps which differ from the above description on how to write a test case are:</P>
|
||||
|
||||
<UL>
|
||||
|
||||
<LI><P>In your test class, define a member function for each thread you will be starting. All of
|
||||
these member functions must take "void" and return "void". If all the threads in your test
|
||||
perform the exact same actions, it is OK to just define one member function. Usually in the
|
||||
tests I have written, I have called these member functions "TestThread1()", "TestThread2()",
|
||||
etc.</P></LI>
|
||||
|
||||
<LI><P>If your "static Test *suite()" function for your test class, you must return a
|
||||
ThreadedTestCaller. Imagine that the test class name is "MyTestClass" and you want two threads
|
||||
which run member functions "TestThread1()" and "TestThread2()". That code would look like:</P>
|
||||
|
||||
<PRE>
|
||||
Test *MyTestClass::suite(void)
|
||||
{
|
||||
MyTestClass *theTest = new MyTestClass("");
|
||||
ThreadedTestCaller<MyTestClass> *threadedTest = new TreadedTestCaller<MyTestClass>("", theTest);
|
||||
|
||||
threadedTest->addThread(":Thread1", &MyTestClass::TestThread1);
|
||||
threadedTest->addThread(":Thread2", &MyTestClass::TestThread2);
|
||||
|
||||
return(threadedTest);
|
||||
}
|
||||
</PRE>
|
||||
|
||||
<P>If you need to, you can put a number of ThreadedTestCaller instances into a TestSuite and return
|
||||
them in the suite() member function. Examples of this can be found in the BLocker and
|
||||
BMessageQueue test examples.</P></LI>
|
||||
|
||||
</UL>
|
||||
|
||||
<P>Otherwise the steps are the same as for other tests. The code gets much more complex if you
|
||||
define your test classes as templates as the examples do.</P>
|
||||
|
||||
</FONT>
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,341 @@
|
||||
<HTML>
|
||||
<!-- $Id: BDeskbarUseCases.html 1185 2002-09-26 02:21:31Z jrand $ -->
|
||||
<HEAD>
|
||||
<TITLE>BDeskbar 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>BDeskbar Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BDeskbar interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BDeskbar Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BDeskbar Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BDeskbar Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BDeskbar Interface:</H2>
|
||||
|
||||
<P>The BDeskbar class is a simple class for getting information from the deskbar and for modifying
|
||||
it from your application. The best source of source of information for the BDeskbar interface can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/Deskbar/Deskbar.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BDeskbar Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BDeskbar functionality:</P>
|
||||
|
||||
<OL>
|
||||
<LI><P><B>Construction:</B> A BDeskbar does not take any arguments when it is constructed. The
|
||||
BDeskbar instance creates a connection to the deskbar in order to get and change its state.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> When a BDeskbar is deconstructed, the application's connection to the
|
||||
deskbar is closed. However any change to the deskbar's state made through the BDeskbar instance
|
||||
persists.</P></LI>
|
||||
|
||||
<LI><P><B>Add Item 1:</B> The AddItem() member function can be used to take a passed in pointer to
|
||||
a BView and send it to the deskbar for inclusion in its shelf. This BView must be archivable
|
||||
and must be exported by the application (for details on how to do this,
|
||||
<A HREF="http://bedriven.be-in.org/articles/replicant/III_027-stepping%20up%20to%20the%20deskbar.html">this article</A>
|
||||
may help). The item will be added and the id of the new item will be passed back to the caller
|
||||
through a pointer to an int32.</P></LI>
|
||||
|
||||
<LI><P><B>Add Item 2:</B> The AddItem() member function can be used to add an item to the deskbar
|
||||
shelf by passing a pointer to an entry_ref. The file pointed to by this entry_ref should be
|
||||
an addon that exports the symbol "BView *instantiate_deskbar_item()". This entry point is used to
|
||||
get a BView which it can display in the shelf. More information on this mechanism can be found in
|
||||
the <A HREF="file:///boot/beos/documentation/Be%20Book/Release%20Notes/Deskbar.html">Deskbar Release Notes</A>
|
||||
but not in the Be Book proper. The item id of the added item is passed back in an int32 pointer
|
||||
provided by the caller. NOTE: The source code for the deskbar found in
|
||||
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/StatusView.cpp?rev=1.5&content-type=text/vnd.viewcvs-markup">TReplicantTray::LoadAddon()</A>
|
||||
indicates that it also looks for a symbol called "BView *instantiate_deskbar_entry(image_id, entry_ref *)"
|
||||
first, but there is no documentation on this.</P></LI>
|
||||
|
||||
<LI><P><B>Remove Item 1:</B> The RemoveItem() member function takes an integer id and removes it
|
||||
from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is
|
||||
not running or some communication failure occurs). A B_OK result does not mean that an item was
|
||||
actually removed.</P></LI>
|
||||
|
||||
<LI><P><B>Remove Item 2:</B> The RemoveItem() member function also takes a string name and removes
|
||||
it from the deskbar shelf if it exists. The member returns B_OK at all times (unless the deskbar is
|
||||
not running or some communication failure occurs). A B_OK result does not mean that an item was
|
||||
actually removed.</P></LI>
|
||||
|
||||
<LI><P><B>Count Items:</B> The CountItems() member function takes no arguments. It returns the
|
||||
number of "items" in the deskbar shelf. For example, the small email icon often found in the
|
||||
deskbar is one such item.</P></LI>
|
||||
|
||||
<LI><P><B>Has Item 1:</B> The HasItem() member function takes a integer id and returns a true or
|
||||
false value which indicates whether or not an item exists in the deskbar shelf on that id. For
|
||||
example, the small email icon often found in the deskbar is one such item.</P></LI>
|
||||
|
||||
<LI><P><B>Has Item 2:</B> The HasItem() member function also takes a string name parameter and
|
||||
returns a true or false value which indicates whether or not an item by than name exists in
|
||||
the deskbar shelf. For example, the small email icon often found in the deskbar is named
|
||||
"mail".</P></LI>
|
||||
|
||||
<LI><P><B>Get Item Info 1:</B> The GetItemInfo() member function takes an integer id and a pointer
|
||||
to a const char * (ie a string). It checks to see if the id passed in exists in the deskbar and
|
||||
sets the value of the const char * to point to a allocated buffer which contains the name of the
|
||||
item which corresponds to this id and the function returns B_OK. Ownership of this allocated
|
||||
buffer is assigned to the caller of this member function so it is up to the caller to free the
|
||||
memory. If the id doesn't exist, then it still returns B_OK but the pointer to the string is set
|
||||
to NULL. If the pointer to the string passed in is NULL, the function returns B_BAD_VALUE.</P></LI>
|
||||
|
||||
<LI><P><B>Get Item Info 2:</B> The GetItemInfo() member also takes a string (const char *) name
|
||||
and a pointer to an int. If the name matches an item in the deskbar shelf, the id of this
|
||||
item is returned at the location pointed to by the integer pointer and the member returns B_OK.
|
||||
If the name doesn't match an item in the deskbar shelf, the id is set to -1. If the pointer
|
||||
passed in is NULL, the function returns B_BAD_VALUE.</P></LI>
|
||||
|
||||
<LI><P><B>Frame:</B> The Frame() member function returns a BRect which describes the location and
|
||||
size of the deskbar on the screen.</P></LI>
|
||||
|
||||
<LI><P><B>Location:</B> The Location() member function returns one of B_DESKBAR_TOP,
|
||||
B_DESKBAR_BOTTOM, B_DESKBAR_LEFT_BOTTOM, B_DESKBAR_RIGHT_BOTTOM, B_DESKBAR_LEFT_TOP or
|
||||
B_DESKBAR_RIGHT_TOP. The return value describes where the deskbar currently is located. Also,
|
||||
the Location() member function takes an optional argument which is a pointer to a boolean.
|
||||
If supplied, the boolean which is pointed to is set to true if the deskbar is expanded and false
|
||||
otherwise. A deskbar can only be contracted (ie not expanded) when in the left or right top
|
||||
position.</P></LI>
|
||||
|
||||
<LI><P><B>Is Expanded:</B> The IsExpanded() member function returns true if the deskbar is
|
||||
expanded and false if it is contracted. Note, the deskbar can only be contracted when in
|
||||
left or right top position.</P></LI>
|
||||
|
||||
<LI><P><B>Set Location:</B> The SetLocation() member function takes the same values returned
|
||||
by the Location() member. The value passed in the first argument sets the position of the deskbar.
|
||||
If the optional second argument is supplied, it is a boolean which indicates whether or not the
|
||||
deskbar is expanded (true) or contracted (false). Note, the deskbar can only be contracted when in
|
||||
left or right top position.</P></LI>
|
||||
|
||||
<LI><P><B>Expand:</B> The Expand() member function takes a single boolean argument which sets the
|
||||
deskbar to expanded (true) or contracted (false) mode. Note, the deskbar can only be contracted
|
||||
when in left or right top position.</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BDeskbar Implementation:</H2>
|
||||
|
||||
<P>Internally, the BDeskbar uses a BMessenger to communicate with the deskbar itself.
|
||||
The source code from the OpenTracker project will be used as a reference for this effort.
|
||||
You can find the deskbar source code here:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/">http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/</A>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>Specifically, the code which handles communicating with the BDeskbar class can be found
|
||||
here:</P>
|
||||
|
||||
<BLOCKQUOTE>
|
||||
<A HREF="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup</A>
|
||||
</BLOCKQUOTE>
|
||||
|
||||
<P>The following describes the messages used to communicate between BDeskbar and the deskbar
|
||||
itself.</P>
|
||||
|
||||
|
||||
<H3>AddItem:</H3>
|
||||
|
||||
<P>The AddItem() member sends the following message to the deskbar to add an item from an
|
||||
archived BView:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
BMessage viewMsg;
|
||||
theView.Archive(&viewMsg); // This takes the target BView to place in the shelf and archives it into viewMsg
|
||||
theMsg.what = 'icon'
|
||||
theMsg.AddMessage("view", &viewMsg); // This puts the archived view in the viewMsg and puts it in the message to the deskbar
|
||||
</PRE>
|
||||
|
||||
<P>Or, the AddItem() member sends the following message to the deskbar to add an item from a file
|
||||
that exports the "BView *instantiate_deskbar_item(void)" function:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'adon'
|
||||
theMsg.AddRef("addon", &theAddonRef); // This is the addon which contains the hook function to get the view to add
|
||||
</PRE>
|
||||
|
||||
<P>The /boot/app/Pulse application exports the necessary symbol for this mechanism to work and
|
||||
is a good candidate to test with.</P>
|
||||
|
||||
<P>In either case, the deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.AddInt32("id", theID); // This is the id of the new item
|
||||
</PRE>
|
||||
|
||||
<P>Note that in both cases, the deskbar does not set the what code of the reply. Checking the
|
||||
source code for
|
||||
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::AddItem()</A>
|
||||
confirms this.
|
||||
|
||||
|
||||
<H3>HasItem:</H3>
|
||||
|
||||
<P>The HasItem() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'exst'
|
||||
theMsg.AddInt32("id", theID); // This is the id to check for
|
||||
// OR, only one of id or name should be in the message
|
||||
theMsg.AddString("name", theName); // This is the name to check for
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.AddBool("exists", IDorNameExists()); // This is a true/false value which indicates whether or not the name/id exists in the shelf
|
||||
</PRE>
|
||||
|
||||
<P>Note that the deskbar does not set the what code of the reply. Checking the source code
|
||||
for
|
||||
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::ItemExists()</A>
|
||||
confirms this.</P>
|
||||
|
||||
|
||||
<H3>GetItemInfo:</H3>
|
||||
|
||||
<P>The GetItemInfo() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'info'
|
||||
theMsg.AddInt32("id", theID); // This is the id to check for
|
||||
// OR, only one of id or name should be in the message
|
||||
theMsg.AddString("name", theName); // This is the name to check for
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.AddString("name", theName); // This is the name corresponding to the id of the original request
|
||||
// OR, only one of id or name should be in the response message depending on the request sent
|
||||
theMsg.AddInt32("id", theID); // This is the id corresponding to the name of the original request
|
||||
</PRE>
|
||||
|
||||
<P>Note that the deskbar does not set the what code of the reply. Checking the source code
|
||||
for
|
||||
<A href="http://cvs.sourceforge.net/cgi-bin/viewcvs.cgi/opentracker/opentracker/deskbar/BarWindow.cpp?rev=1.2&content-type=text/vnd.viewcvs-markup">TBarWindow::ItemInfo()</A>
|
||||
confirms this.</P>
|
||||
|
||||
|
||||
<H3>CountItems:</H3>
|
||||
|
||||
<P>The CountItems() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'cwnt'
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'rply'; // This means reply
|
||||
theMsg.AddInt32("count", ItemCount()); // This is the number of items in the deskbar shelf
|
||||
</PRE>
|
||||
|
||||
|
||||
<H3>RemoveItem:</H3>
|
||||
|
||||
<P>The RemoveItem() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'remv'
|
||||
theMsg.AddInt32("id", theID); // This is the id to remove
|
||||
// OR, only one of id or name should be in the message
|
||||
theMsg.AddString("name", theName); // This is the name to remove
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar does not send a response.</P>
|
||||
|
||||
|
||||
<H3>Frame:</H3>
|
||||
|
||||
<P>The Frame() member sends a standard scripting message to get the frame from the deskbar. It
|
||||
sends a B_GET_PROPERTY message to the deskbar asking for the "Frame" property specifying the
|
||||
window by name. The window name is "Deskbar".</P>
|
||||
|
||||
<P>The response from deskbar has a what code of B_REPLY and a BRect describing the frame in a
|
||||
value called "result". This is standard BeOS scripting.</P>
|
||||
|
||||
|
||||
<H3>Location:</H3>
|
||||
|
||||
<P>The Location() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'gloc'; // This means get location
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'rply'; // This means reply
|
||||
theMsg.AddInt32("location", DeskbarLocation()); // This is the number which represents the location of the deskbar
|
||||
theMsg.AddBool("expanded", Expanded()); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
|
||||
<H3>IsExpanded:</H3>
|
||||
|
||||
<P>The IsExpanded() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'gexp'; // This means get expanded state
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar responds with a message which looks like:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'rply'; // This means reply
|
||||
theMsg.AddBool("expanded", Expanded()); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
|
||||
<H3>SetLocation:</H3>
|
||||
|
||||
<P>The SetLocation() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'sloc'; // This means set location
|
||||
theMsg.AddInt32("location", newLocation); // This is the number which represents the location of the deskbar
|
||||
theMsg.AddBool("expand", isExpanded); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar does not send a reply to this message.</P>
|
||||
|
||||
|
||||
<H3>Expand:</H3>
|
||||
|
||||
<P>The Expand() member sends the following message to the deskbar:</P>
|
||||
|
||||
<PRE>
|
||||
BMessage theMsg;
|
||||
theMsg.what = 'sexp'; // This means set expanded state
|
||||
theMsg.AddBool("expand", isExpanded); // This is true if the deskbar is expanded, false otherwise
|
||||
</PRE>
|
||||
|
||||
<P>The deskbar does not send a reply to this message.</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,89 @@
|
||||
<HTML>
|
||||
<!-- $Id: BPolygonUseCases.html 1727 2002-10-28 02:50:08Z jrand $ -->
|
||||
<HEAD>
|
||||
<TITLE>BPolygon 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>BPolygon Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BPolygon interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BPolygon Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BPolygon Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BPolygon Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BPolygon Interface:</H2>
|
||||
|
||||
<P>The BPolygon class is used to hold information about a shape composed of a series of straight
|
||||
lines (ie a polygon). On its own, it just describes the shape and can only be drawn by passing
|
||||
it to a BView. The best source of source of information for the BPolygon interface can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Interface%20Kit/Polygon.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BPolygon Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BPolygon functionality:</P>
|
||||
|
||||
<OL>
|
||||
<LI><P><B>Construction 1:</B> A BPolygon can be constructed without passing it any arguments. When
|
||||
this is done, the polygon will have no points in it (ie no shape) until they are added through
|
||||
AddPoints().</P></LI>
|
||||
|
||||
<LI><P><B>Construction 2:</B> A BPolygon can be constructed by passing it a pointer to an existing
|
||||
BPolygon (ie a copy constructor). The resulting copy will have the exact same state as the
|
||||
one passed in. That means it will have the same number of points in the same locations resulting
|
||||
in the same shape.</P></LI>
|
||||
|
||||
<LI><P><B>Construction 3:</B> A BPolygon can be constructed by passing it a pointer to an array of
|
||||
BPoints and an integer which describes the number of points in that array. The BPolygon will be
|
||||
constructed such that it holds the shape described by that array of points.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> When a BPolygon is deconstructed any memory allocated in order to hold
|
||||
the state of the BPolygon is freed and the state of the polygon is lost.</P></LI>
|
||||
|
||||
<LI><P><B>Add Points:</B> The AddPoints() member function appends a number of passed in points to
|
||||
the existing set of points already in the polygon. It takes a pointer to an array of BPoints and
|
||||
an integer count of the number of points to append. This is similar to the "Construction 3" use
|
||||
case except in that case there is no existing points so the passed in points describe the entire
|
||||
polygon.</P></LI>
|
||||
|
||||
<LI><P><B>Count Points:</B> The CountPoints() member function returns the number of points which
|
||||
describe the polygon. The result is an integer.</P></LI>
|
||||
|
||||
<LI><P><B>Frame:</B> The Frame() member function returns the smallest BRect which contains all of
|
||||
the points which describes the BPolygon.</P></LI>
|
||||
|
||||
<LI><P><B>Map To:</B> The MapTo() member function applies a translation (ie move) and a scale (ie
|
||||
grow/shrink) operation to the existing polygon, adjusting all points according to the passed in
|
||||
rule. The operation to apply depends on two passed in BRect's. The translation and scale
|
||||
adjustment which turns the first BRect into the second BRect is applied to all points in the
|
||||
BPolygon.</P></LI>
|
||||
|
||||
<LI><P><B>Print To Stream:</B> The PrintToStream() member function sends the set of points which
|
||||
make up the BPolygon to standard output. It does so by performing a PrintToStream() on the
|
||||
individual BPoint's which make up the polygon. This member is generally used for debugging and
|
||||
the output is primarily human readable and not sensitive to changes which could risk backward
|
||||
compatibility.</P></LI>
|
||||
|
||||
<LI><P><B>Assignment Operator</B> The operator=() operator is defined for BPolygon's. It takes
|
||||
a source BPolygon and assigns it to another existing BPolygon target. The state of the target
|
||||
BPolygon is lost and replaced with that of the source. The source retains its state so the outcome
|
||||
is two BPolygons with the same state (ie set of points).</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BPolygon Implementation:</H2>
|
||||
|
||||
<P>Internally, the BPolygon contains an array of BPoint's which it uses to track the shape it
|
||||
holds. The implementation of BPolygon is fairly simple since it is a fairly basic container
|
||||
class for a set of points.</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,136 @@
|
||||
Posted by Rudolf Nov 22, 2005 to the haiku-appsever ML:
|
||||
http://www.freelists.org/post/haiku-appserver/new-drawing-bug-Rudolf-some-stuff-for-you,10
|
||||
|
||||
More good info @ http://www.freelists.org/archive/haiku-appserver
|
||||
|
||||
Be Docs (file: R4_Graphics_Driver_Docs):
|
||||
|
||||
Engine Synchronization
|
||||
|
||||
B_ACCELERANT_ENGINE_COUNT - No feature specific data required.
|
||||
Return the number of acceleration engines that the device may operate in parallel.
|
||||
It's not required for all engines to be equally capable (i.e. support the same
|
||||
acceleration features).
|
||||
|
||||
B_ACQUIRE_ENGINE - No feature specific data required.
|
||||
Request exclusive ownership of an acceleration engine with the capabilities mask specified.
|
||||
The caller is willing to wait up to max_wait micro(milli?)-seconds. If the request can't be
|
||||
fullfilled before that time expires, the accelerant should return B_WOULD_BLOCK immediatly.
|
||||
If non-zero, sync_token points to a synchronization token retrieved from either
|
||||
release_engine() or get_sync_token() to which the engine should be synchronized before
|
||||
engine acquisition succeeds. See B_SYNC_TO_TOKEN for more details. The engine_token for
|
||||
the successfully acquired engine is returned in engine_token **et.
|
||||
|
||||
B_RELEASE_ENGINE - No feature specific data required.
|
||||
Relinquish exclusive ownership of the engine specified by engine_token et. If
|
||||
sync_token *st is non-zero, return a sync_token which can be utilized to ensure that the
|
||||
specified engine has completed all acceleration operations issued up this point in time.
|
||||
|
||||
B_WAIT_ENGINE_IDLE - No feature specific data required.
|
||||
Wait for the graphics device to be completely idle (i.e. no current running or pending
|
||||
acceleration primitives, DMA transfers, etc.).
|
||||
|
||||
B_GET_SYNC_TOKEN - No feature specific data required.
|
||||
Return a synchronization token for the specified engine. sync_token *st must point at
|
||||
a sync_token which will be updated with the information required to ensure that a call to
|
||||
sync_to_token() will be able to ensure that the specified engine has completed all of the
|
||||
acceleration primitives, DMA transfers, etc. that have been issued up to this point in time.
|
||||
|
||||
B_SYNC_TO_TOKEN - No feature specific data required.
|
||||
Ensure that the engine specified in sync_token *st has completed the acceleration
|
||||
primitives, DMA transfers, etc., issued up to the point in time specified in the sync_token.
|
||||
|
||||
|
||||
Rudolf's notes.
|
||||
info on engine_token:
|
||||
|
||||
uint32 ACCELERANT_ENGINE_COUNT(void)
|
||||
exists because in theory a single card can have multiple independant acceleration engines.
|
||||
For instance one that can do 2D, and one that can do 3D (or combinations). See
|
||||
'engine capabilities' flags in Accelerant.h.
|
||||
(note: never seen multiple engines per card yet though. Was this meant for some very old
|
||||
hardware with seperate 2D and 3D 'blocks'? Although I guess it's thinkable that multiple
|
||||
equally capable engines would exist as well..)
|
||||
|
||||
In order to distinquish between multiple engines all acceleration commands are given along
|
||||
with an engine_token *et, aquired when
|
||||
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait, sync_token *st, engine_token **et)
|
||||
was called.
|
||||
status_t SYNC_TO_TOKEN(sync_token *st)
|
||||
is an exeption: here the engine is ID'd by member: (defined in Accelerant.h)
|
||||
uint32 engine_id.
|
||||
void WAIT_ENGINE_IDLE(void)
|
||||
is an exeption also because this function returns only when *ALL* engines are completely
|
||||
idle. Hence no need for distinction.
|
||||
|
||||
Furthermore the absense of the use of engine_token in both SYNC_TO_TOKEN and WAIT_ENGINE_IDLE
|
||||
would seem to indicate these hooks may be used *without having acquired the engine*. (?).
|
||||
|
||||
|
||||
info on sync_token:
|
||||
|
||||
-- How does the acceleration cmd interface work? There's a circular buffer that stores cmd's.
|
||||
There's a hardware pointer that points 'at' the command currently being executed (think
|
||||
of stacks: some architectures point to the first 'free' location, some to the 'last used'
|
||||
location.)
|
||||
There's also a second pointer which points at the first free location, i.e. where new cmd's
|
||||
will be stored pending execution. This second pointer is a software maintained pointer (in
|
||||
the driver).
|
||||
|
||||
-- What's a sync_token? A Sync_token in nothing more than a extra pointer (one per token). This
|
||||
pointer points at the first free location in the cmd buffer at that point in time the
|
||||
sync_token was 'filled'. In theory it doesn't change during the (rest of the) life-time of
|
||||
the token, although the driver-implementation could (?) do that anyway for some internal
|
||||
reason.
|
||||
Driver users (i.e. app_server) are responsible for reserving memory for a sync_token. They
|
||||
pass a pointer to it to the driver (if they want to use it). The driver in turns fills it
|
||||
with the needed info. Driver users may never modify the content of the sync_token(s).
|
||||
|
||||
-- When would a user be interested in a sync_token? If multiple independant (so non-overlapping)
|
||||
'regions' require multiple updates each alternatingly done by software and acceleration engine,
|
||||
it might be interesting to use sync_tokens (for instance).
|
||||
It would be possible to issue all engine commands concerning area #1, ask for a sync token,
|
||||
issue all engine commands concerning area #2, and then do this:
|
||||
- SYNC_TO_TOKEN (so waiting until all engine commands concerning area #1 are done);
|
||||
- Draw in area #1 using software (while the acc engine is in the process of updating area #2:
|
||||
(so some 'parallel processing' is done here).
|
||||
|
||||
If no sync token would be used, instead of syncing to token, wait_engine_idle would be used.
|
||||
This of course would mean that no 'parallel processing' could be done...
|
||||
Worse yet: if some seperate user is also using the engine (between RELEASE and AQUIRE engine
|
||||
done by 'user #1' (i.e. app_server), the acc engine might *never* become fully idle.
|
||||
A nice example here would be 3D acceleration: as long as no non-accelerated drawing has to be
|
||||
done there, there's no reason the engine would need to be idle at all for this (apart from
|
||||
processing 'user-input' like joystick controls).
|
||||
You see: an acceleration engine automatically serializes it's cmd processing so update errors
|
||||
because of out-of-order execution wouldn't happen.
|
||||
|
||||
-- Why didn't I implement sync_token stuff in the matrox, nvidia and neomagic drivers?
|
||||
Lack of 'known specs' yet. You see, even if the pointers in the cmd buffer are known: that's
|
||||
not enough yet:
|
||||
- The fact that an command is fetched from the buffer does *not* mean it's
|
||||
execution is completely done.
|
||||
- The implementation via just a pointer is not enough: if you wait too long, the current
|
||||
free pointer might have cycled around the buffer. This means a simple compare to that
|
||||
pointer is not conclusive. Much better would be actually inserting 'dummy commands' inside
|
||||
the command buffer at the place a sync_token is generated. This dummy commands would be
|
||||
executed just once, when we reached our goal. If the dummy command clears a variable
|
||||
especially setup for the sync_token in question: we would have a conclusive result without
|
||||
even the use of an actual pointer in the sync_token. AND: updating the tokens would have no
|
||||
software overhead, as the acc engine would do it. (via 'pointers only' some invalidation
|
||||
code has to be executed once the hardware pointer cycles around).
|
||||
|
||||
NOTE PLEASE:
|
||||
This information is based upon my understanding of hardware inner workings. As this
|
||||
understanding grows and is corrected over time, I might contradict myself later on if
|
||||
asked again. :-)
|
||||
|
||||
|
||||
//actual hooks:
|
||||
uint32 ACCELERANT_ENGINE_COUNT(void);
|
||||
status_t ACQUIRE_ENGINE(uint32 capabilities, uint32 max_wait,
|
||||
sync_token *st, engine_token **et);
|
||||
status_t RELEASE_ENGINE(engine_token *et, sync_token *st);
|
||||
status_t GET_SYNC_TOKEN(engine_token *et, sync_token *st);
|
||||
status_t SYNC_TO_TOKEN(sync_token *st);
|
||||
void WAIT_ENGINE_IDLE(void);
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 68 KiB |
@@ -0,0 +1,66 @@
|
||||
Haiku OpenGL kit developers introduction
|
||||
|
||||
The Haiku OpenGL kit is made up of the folwing pieces:
|
||||
|
||||
* The "OpenGL Kit" aka libGL.so and supporting libraries.
|
||||
This is what the user applications interact with.
|
||||
|
||||
* The "OpenGL Add-ons" (which do the real work)
|
||||
These are chosen by the OpenGL kit and utilized
|
||||
|
||||
In the traditional BeOS sense, the OpenGL Add-ons are the
|
||||
vendor provided OpenGL drivers. This actually doesn't
|
||||
mesh well with the current open source OpenGL stack.
|
||||
|
||||
Our "OpenGL Add-ons" are really self contained Mesa and
|
||||
Gallium renderers. On the old Mesa side of the house,
|
||||
swrast is a bunch of wrapper code. On the Gallium side,
|
||||
swpipe is a Gallium target.
|
||||
|
||||
Mesa drivers are the classical Mesa software rasterizers,
|
||||
Gallium drivers are the new-school software and hardware
|
||||
drivers.
|
||||
|
||||
|
||||
**********
|
||||
Mesa versions
|
||||
|
||||
The Haiku project uses two different versions of Mesa.
|
||||
|
||||
* Mesa 7.9.2 for gcc2 OpenGL Add-ons
|
||||
* Mesa 10.2.0+ for gcc4 OpenGL Add-ons.
|
||||
|
||||
The reasoning behind this is that any version of Mesa
|
||||
above 7.9.2 will require a *massive* porting effort to
|
||||
make it compile under gcc2. Given this fact, it makes
|
||||
sense to bump the gcc2 version of Mesa as far as it will
|
||||
go and set it there statically. Think of Mesa 7.9.2
|
||||
as the "stable" version Haiku R1 will use :)
|
||||
|
||||
Hardware 3D rendering and llvm-based software rendering
|
||||
will never work for legacy gcc2 applications. Period.
|
||||
|
||||
However! If you're running a gcc2 hybrid version of
|
||||
Haiku, llvm or hardware based rendering should be possible
|
||||
on gcc4 applications.
|
||||
|
||||
It's essential someone from the Haiku project keeps up
|
||||
with the upstream Mesa changes pushing build fixes to
|
||||
upstream Mesa to keep Haiku relevant.
|
||||
|
||||
|
||||
|
||||
**********
|
||||
The packages
|
||||
|
||||
Haiku has several packages for Mesa:
|
||||
|
||||
mesa-x.x.x-x-x86.hpkg Core Mesa package, provides libGL
|
||||
mesa_devel-x.x.x-x-x86.hpkg Provides development headers and "OpenGL kit"
|
||||
mesa_swrast-x.x.x-x-x86.hpkg Mesa "Software Rasterization" renderer
|
||||
mesa_swpipe-x.x.x-x-x86.hpkg Gallium "Software pipe" LLVM enhanced renderer
|
||||
|
||||
Future :3
|
||||
mesa_radeonhd-x.x.x-x-x86.hpkg Gallium "Radeon HD" hardware renderer
|
||||
mesa_intel-x.x.x-x-x86.hpkg Gallium "Intel" hardware renderer
|
||||
mesa_nvidia-x.x.x-x-x86.hpkg Gallium "nVidia" hardware renderer (unlikely)
|
||||
@@ -0,0 +1,6 @@
|
||||
PrintServerApp::MessageReceived(): BMessage: what = selp (0x73656c70, or 1936026736)
|
||||
entry driver, type='CSTR', c=1, size=17, data[0]: "EPSON C40 Series"
|
||||
entry transport, type='CSTR', c=1, size=12, data[0]: "Serial Port"
|
||||
entry transport path, type='CSTR', c=1, size=8, data[0]: "serial1"
|
||||
entry printer name, type='CSTR', c=1, size=8, data[0]: "my_test"
|
||||
entry connection, type='CSTR', c=1, size=6, data[0]: "Local"
|
||||
@@ -0,0 +1,19 @@
|
||||
2x PageSetup
|
||||
1x Print
|
||||
|
||||
|
||||
config_page((null),0x80013478)
|
||||
BMessage: what = pgst (0x70677374, or 1885827956)
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80013218 (-2147405288, ী2')
|
||||
|
||||
|
||||
config_page((null),0x80013478)
|
||||
BMessage: what = pgst (0x70677374, or 1885827956)
|
||||
entry current_printer, type='CSTR', c=1, size=12, data[0]: "DemoPrinter"
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80013218 (-2147405288, ী2')
|
||||
|
||||
|
||||
config_job((null),0x80013478)
|
||||
BMessage: what = ppst (0x70707374, or 1886417780)
|
||||
entry current_printer, type='CSTR', c=1, size=12, data[0]: "DemoPrinter"
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80013218 (-2147405288, ী2')
|
||||
@@ -0,0 +1,72 @@
|
||||
BMessage: what = okok (0x6f6b6f6b, or 1869311851)
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x8003b390 (-2147241072, ')
|
||||
entry page_format, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
|
||||
entry xres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
|
||||
entry yres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
|
||||
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
|
||||
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:18.0, t:18.0, r:594.0, b:774.0)
|
||||
entry current_printer, type='CSTR', c=1, size=27, data[0]: "HPLaserJetPCL3Driver_BeInc"
|
||||
|
||||
BMessage: what = GOOD (0x474f4f44, or 1196379972)
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x800131a8 (-2147405400, ী౨')
|
||||
entry EPST_copies, type='LONG', c=1, size= 4, data[0]: 0x1 (1, '')
|
||||
entry EPST_dst_idx_page, type='LONG', c=1, size= 4, data[0]: 0x5 (5, '')
|
||||
entry EPST_src_idx_page, type='LONG', c=1, size= 4, data[0]: 0x7 (7, '')
|
||||
entry EPST_orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_page_order, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_centered, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_extended, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_rotate180, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_page_state, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_logic_userdef_width, type='FLOT', c=1, size= 4, data[0]: 0.0000
|
||||
entry EPST_logic_userdef_height, type='FLOT', c=1, size= 4, data[0]: 0.0000
|
||||
entry EPST_page_name, type='CSTR', c=1, size=3, data[0]: "A4"
|
||||
entry EPST_scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
|
||||
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:595.2, b:841.8)
|
||||
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:8.4, t:8.4, r:586.8, b:802.2)
|
||||
entry EPST_page_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:2976.0, b:4209.0)
|
||||
entry EPST_printer_rect, type='RECT', c=1, size=16, data[0]: BRect(l:42.0, t:42.0, r:2934.0, b:4011.0)
|
||||
entry EPST_page_settings_dpi, type='FLOT', c=1, size= 4, data[0]: 72.0000
|
||||
entry EPST_printer_settings_dpi, type='FLOT', c=1, size= 4, data[0]: 360.0000
|
||||
entry EPST_paper_feed, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_quality, type='LONG', c=1, size= 4, data[0]: 0x1 (1, '')
|
||||
entry EPST_resolution, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_paper_type, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_color, type='LONG', c=1, size= 4, data[0]: 0x6 (6, '')
|
||||
entry EPST_microweave, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry EPST_unidirectionnal, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry xres, type='LONG', c=1, size= 4, data[0]: 0x168 (360, '')
|
||||
entry yres, type='LONG', c=1, size= 4, data[0]: 0x168 (360, '')
|
||||
entry EPST_BEATWARE, type='BOOL', c=1, size= 1, data[0]: 0
|
||||
entry first_page, type='LONG', c=1, size= 4, data[0]: 0x1 (1, '')
|
||||
entry last_page, type='LONG', c=1, size= 4, data[0]: 0x7fffffff (2147483647, '')
|
||||
entry EPST_preview, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry current_printer, type='CSTR', c=1, size=24, data[0]: "EPSONStylusDriver_BeInc"
|
||||
|
||||
BMessage: what = okok (0x6f6b6f6b, or 1869311851)
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x8003b498 (-2147240808, ഘ')
|
||||
entry bitmap, type='BOOL', c=1, size= 1, data[0]: 0
|
||||
entry HighQuality, type='BOOL', c=1, size= 1, data[0]: 0
|
||||
entry in_color, type='BOOL', c=1, size= 1, data[0]: 0
|
||||
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry page size, type='CSTR', c=1, size=7, data[0]: "Letter"
|
||||
entry ppd_item, type='MSGG', c=1, size= 0,
|
||||
entry xres, type='LLNG', c=1, size= 8, data[0]: 0x12c (300, '')
|
||||
entry yres, type='LLNG', c=1, size= 8, data[0]: 0x12c (300, '')
|
||||
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
|
||||
entry units, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:14.4, t:21.6, r:597.6, b:784.8)
|
||||
entry first up, type='BOOL', c=1, size= 1, data[0]: 1
|
||||
entry current_printer, type='CSTR', c=1, size=23, data[0]: "PostScriptDriver_BeInc"
|
||||
|
||||
BMessage: what = okok (0x6f6b6f6b, or 1869311851)
|
||||
entry printer, type='LONG', c=1, size= 4, data[0]: 0x80018af0 (-2147382544, 瀊')
|
||||
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
|
||||
entry xres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
|
||||
entry yres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
|
||||
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
|
||||
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
|
||||
entry current_printer, type='CSTR', c=1, size=20, data[0]: "PreviewDriver_BeInc"
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
@@ -0,0 +1,40 @@
|
||||
$ print_server
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
PAGE SETUP.........
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
PrintServerApp::MessageReceived(): BMessage: what = pgst (0x70677374, or 1885827956)
|
||||
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
|
||||
entry active, type='BOOL', c=1, size= 1, data[0]: 1
|
||||
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
|
||||
entry active, type='BOOL', c=1, size= 1, data[0]: 0
|
||||
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
PRINT.........
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
PrintServerApp::MessageReceived(): BMessage: what = ppst (0x70707374, or 1886417780)
|
||||
entry orientation, type='LONG', c=1, size= 4, data[0]: 0x0 (0, '')
|
||||
entry scale, type='FLOT', c=1, size= 4, data[0]: 100.0000
|
||||
entry xres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
|
||||
entry yres, type='LONG', c=1, size= 4, data[0]: 0x12c (300, '')
|
||||
entry paper_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
|
||||
entry printable_rect, type='RECT', c=1, size=16, data[0]: BRect(l:0.0, t:0.0, r:612.0, b:792.0)
|
||||
entry current_printer, type='CSTR', c=1, size=20, data[0]: "PreviewDriver_BeInc"
|
||||
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
|
||||
entry active, type='BOOL', c=1, size= 1, data[0]: 1
|
||||
PrintServerApp::MessageReceived(): BMessage: what = BRAW (0x42524157, or 1112686935)
|
||||
entry active, type='BOOL', c=1, size= 1, data[0]: 0
|
||||
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
After spooling:
|
||||
----------------------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
PrintServerApp::MessageReceived(): BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
PrintServerApp::MessageReceived(): BMessage: what = psns (0x70736e73, or 1886613107)
|
||||
entry JobName, type='CSTR', c=1, size=15, data[0]: "InterestFields"
|
||||
entry Spool File, type='CSTR', c=1, size=79, data[0]: "/boot/home/config/settings/printers/PreviewDriver_BeInc/InterestFields@8257001"
|
||||
@@ -0,0 +1 @@
|
||||
BRect(78.0, 71.0, 561.0, 409.0)
|
||||
@@ -0,0 +1,5 @@
|
||||
Information from BeOS R5 implementation:
|
||||
|
||||
BPrintJob::ConfigPage()
|
||||
BPrintJob::ConfigJob()
|
||||
BPrintJob::TakeJob()
|
||||
Binary file not shown.
@@ -0,0 +1,18 @@
|
||||
$ print_server
|
||||
Loaded addon /boot/home/config/add-ons/Print/DemoDriver
|
||||
Loaded addon /boot/beos/system/add-ons/Print/transport/Serial Port
|
||||
Loaded addon /boot/beos/system/add-ons/Print/EPSON Stylus Driver
|
||||
Loaded addon /boot/beos/system/add-ons/Print/transport/Parallel Port
|
||||
Loaded addon /boot/beos/system/add-ons/Print/HP PCL3 LaserJet Compatible
|
||||
Loaded addon /boot/beos/system/add-ons/Print/transport/USB Port
|
||||
Loaded addon /boot/beos/system/add-ons/Print/PostScript
|
||||
Loaded addon /boot/beos/system/add-ons/Print/transport/Print To File
|
||||
Loaded addon /boot/beos/system/add-ons/Print/Preview
|
||||
BMessage: what = pgst (0x70677374, or 1885827956)
|
||||
BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
-------------------------------------------------
|
||||
BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
BMessage: what = ppst (0x70707374, or 1886417780)
|
||||
entry current_printer, type='CSTR', c=1, size=24, data[0]: "EPSONStylusDriver_BeInc"
|
||||
BMessage: what = pdef (0x70646566, or 1885627750)
|
||||
BMessage: what = pgcp (0x70676370, or 1885823856)
|
||||
Binary file not shown.
@@ -0,0 +1,542 @@
|
||||
# Annotations
|
||||
# ===========
|
||||
#
|
||||
# This file contains a list of miscellaneous annotations.
|
||||
# An entry has the following tags:
|
||||
# * OS: the concerned "operating system" (BeOS R5, OBOS POSIX)
|
||||
# * Module: the concerned class or file
|
||||
# * Location: a more precise location, e.g. a function
|
||||
# * Description: a description of the item
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BEntry
|
||||
Location: BEntry(const BDirectory*, const char*),
|
||||
SetTo(const BDirectory*, const char*)
|
||||
Description: Crash when passing a NULL BDirectory.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BEntry
|
||||
Location: MoveTo()
|
||||
Description: Crashs when passing a NULL BDirectory.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BPath
|
||||
Location: BPath(const BDirectory*, const char*, bool),
|
||||
SetTo(const BDirectory*, const char*, bool)
|
||||
Description: Crash when passing a NULL BDirectory.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BPath
|
||||
Location: GetParent()
|
||||
Description: Crashs when called on an uninitialized object or when passing
|
||||
a NULL BPath.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BPath
|
||||
Location: operator==(), operator!=()
|
||||
Description: Uninitialized paths are not equal. An initialized path equals
|
||||
a (const char*)NULL, an uninitialized path does not.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BPath
|
||||
Location: Flatten()
|
||||
Description: Crashs when passing a NULL buffer and doesn't check the buffer
|
||||
size.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BStatable
|
||||
Location: destructor
|
||||
Description: Is not virtual.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BStatable
|
||||
Location: GetAccessTime(), SetAccessTime()
|
||||
Description: Access time unused.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BStatable
|
||||
Location: GetPermissions()
|
||||
Description: Doesn't filter the mode flags, thus not only the permissions are
|
||||
returned.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BStatable
|
||||
Location: Get*()
|
||||
Description: Crash when passing a NULL pointer.
|
||||
|
||||
|
||||
OS: OBOS POSIX
|
||||
Module: BStatable
|
||||
Location: SetPermissions/ModificationTime/CreationTime()
|
||||
Description: Don't work due to set_stat(FileDescriptor, StatMember)
|
||||
limitations.
|
||||
|
||||
|
||||
OS: OBOS POSIX
|
||||
Module: kernel_interface
|
||||
Location: set_stat(FileDescriptor, StatMember)
|
||||
Description: WSTAT_MODE, WSTAT_*TIME can't be implemented due to missing
|
||||
fchmod()/FD time setters.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: libroot
|
||||
Location: fchown()
|
||||
Description: fchown(file, 0xFFFFFFFF, gid) sets the UID to 0xFFFFFFFF, which
|
||||
is a bug.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: libroot
|
||||
Location: readdir(), fs_read_attr_dir()
|
||||
Description: The d_reclen field of a dirent structure does not contain the
|
||||
length of the whole structure (unlike stated in
|
||||
BeBook::BEntryList), but only the length of the d_name field.
|
||||
If the terminating '\0' is counted or not seems to depend on the
|
||||
file system.
|
||||
|
||||
|
||||
OS: OBOS POSIX
|
||||
Module: kernel_interface
|
||||
Location: read_link(FileDescriptor, char*, size_t)
|
||||
Description: Can't be implemented due to the lack of an FD readlink() version.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BSymLink
|
||||
Location: MakeLinkedPath(const char*, BPath*)
|
||||
Description: The dirPath seems to be converted into a BDirectory, which
|
||||
causes links to be resolved, i.e. a "/tmp" dirPath expands to
|
||||
"/boot/var/tmp". That does also mean, that the dirPath must
|
||||
exists!
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BSymLink
|
||||
Location: MakeLinkedPath()
|
||||
Description: Crashs when passing a NULL const char* or BDirectory.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNode
|
||||
Location: GetNextAttrName()
|
||||
Description: Crashs when passing a NULL buffer.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNode
|
||||
Location: Read/WriteAttrString()
|
||||
Description: Crash when passing a NULL BString.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNode
|
||||
Location: Lock()
|
||||
Description: Given two BNode objects initialized to the same node, it is
|
||||
possible to Lock() one of them, although the BeBook says it isn't.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BDirectory
|
||||
Location: BDirectory(const node_ref*), SetTo(const node_ref*)
|
||||
Description: Crash when passing a NULL node_ref.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BDirectory
|
||||
Location: GetEntry()
|
||||
Description: Crashs when passing a NULL BEntry.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BDirectory
|
||||
Location: FindEntry()
|
||||
Description: Crashs when passing a NULL BEntry.
|
||||
|
||||
|
||||
OS: BeOS R5 (OBOS)
|
||||
Module: BDirectory
|
||||
Location: Contains(const char*, int32)
|
||||
Description: If the supplied path is absolute and refers to an existing
|
||||
entry, true is returned, even if the directory does not contain
|
||||
the entry or is not even initialized.
|
||||
(The OBOS implementation makes the behavior more consistent
|
||||
with the BEntry* version, which returns false when the
|
||||
directory is not initialized and true only if the directory
|
||||
actually contains the entry.)
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BDirectory
|
||||
Location: Contains(const BEntry*, int32)
|
||||
Description: Crashs when passing a NULL BEntry.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BDirectory
|
||||
Location: Contains(const BEntry*, bool)
|
||||
Description: Bug: Tests with a directory, contained file/dir/symlink and
|
||||
the respective node kind (B_FILE_NODE/B_DIRECTORY_NODE/
|
||||
B_SYMLINK_NODE) result false.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BDirectory
|
||||
Location: GetNextDirents()
|
||||
Description: Crashs when passing a NULL buffer.
|
||||
|
||||
|
||||
OS: OBOS
|
||||
Module: BQuery
|
||||
Location: Push*()
|
||||
Description: Return status_t instead of void. Fail, if Fetch() has already
|
||||
been called.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BQuery
|
||||
Location: PushOp()
|
||||
Description: Crashs when pushing B_CONTAINS/B_BEGINS/ENDS_WITH on an empty
|
||||
stack.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BQuery
|
||||
Location: PushUInt64()
|
||||
Description: Doesn't work. Predicates constructed using it are invalid.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BQuery
|
||||
Location: Get/SetPredicate()
|
||||
Description: Crash when passing a NULL BString/char*.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BQuery
|
||||
Location: SetVolume()
|
||||
Description: Crashs when passing a NULL BVolume.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BQuery
|
||||
Location: GetNextEntry/Ref()
|
||||
Description: Crash when passing a NULL BEntry/entry_ref.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: {Get,Set}LongDescription()
|
||||
Description: Crashes when passed a NULL description
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetLongDescription()
|
||||
Description: The contents of the description string are modified even if
|
||||
the function fails.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: SetShortDescription()
|
||||
Description: When passed a NULL description, doesn't crash, but does
|
||||
appear to make the result of following calls to SetShortDescription
|
||||
unreliable (sometimes they work, sometimes they don't).
|
||||
|
||||
|
||||
OS: BeOS R5 vs. OBOS
|
||||
Module: BMimeType
|
||||
Location:
|
||||
Description: R5: The maximal MIME string length, BMimeType accepts is
|
||||
B_MIME_TYPE_LENGTH *not* including terminating null. Note, that
|
||||
app_info reserves only B_MIME_TYPE_LENGTH chars for the
|
||||
signature field.
|
||||
OBOS: That's why we support strings that fit into a buffer of
|
||||
size B_MIME_TYPE_LENGTH only. This is consistent with the use
|
||||
of the other *_LENGTH constants.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: SetAppHint()
|
||||
Description: The entry_ref passed to SetAppHint() must be valid but is not
|
||||
required to refer to a file that actually exists; furthermore,
|
||||
if it does exist, the MIME type of the file is not required to
|
||||
match the BMimeType object's type.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: SetIcon()
|
||||
Description: The BBitmap passed to BMimeType::SetIcon() must be in the B_CMAP8
|
||||
color space, or the application will crash. We should remember
|
||||
to be smarter about this.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetIcon()
|
||||
Description: The BBitmap passed to BMimeType::GetIcon() must be in the B_CMAP8
|
||||
color space. If not, the call returns B_OK but doesn't actually
|
||||
modify the bitmap. We should remember to be smarter about this.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: IsValid(const char*), GetSupertype(), Contains()
|
||||
Description: Crash when passing NULL.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: {Get,Set}IconForType(char*, BBitmap*, icon_size)
|
||||
Description: Passing NULL as the first parameter is the same as calling
|
||||
{Get,Set}Icon() with the second two parameters (i.e. {gets,sets}
|
||||
the icon for the type itself).
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: SetFileExtensions()
|
||||
Description: Passing a NULL message does not clear the File Extensions field
|
||||
for the MIME type as indicated by the Be Book; instead, it crashes
|
||||
the application :-)
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetFileExtensions()
|
||||
Description: A B_STRING_TYPE field of name "type" is *added* to the result
|
||||
containing the MIME type of the BMimeType object. Since the
|
||||
BMessage passed to SetFileExtensions() appears to be simply
|
||||
flattened into the appropriate attribute, the "type" field is
|
||||
appended to any such "type" fields that may already exist in
|
||||
the original BMessage.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: Install()
|
||||
Description: From the Be Book: "Currently, Install() may return a random value
|
||||
if the object is already installed."
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location:
|
||||
Description: MIME Type strings are converted to lowercase before being used
|
||||
as filenames in the MIME database.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: Start/StopWatching()
|
||||
Description: An invalid messenger (BMessenger::Invalid()) is fine as parameter.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: Mime.h/cpp
|
||||
Location: get_device_icon()
|
||||
Description: KDL when passing a NULL buffer!
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: CheckSnifferRule()
|
||||
Description: Crashes when passing a NULL rule.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetSnifferRule()
|
||||
Description: Crashes when passing a NULL BString.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: Check/Get/SetSnifferRule()
|
||||
Description: The sniffer rules description in the BeBook deviates considerably
|
||||
from the actual implementation:
|
||||
- + masks
|
||||
- + top level ORs: (patterns...) | (patterns...) | ...
|
||||
- - range overriding: [range1] ([range2]pattern)
|
||||
- either no or complete ranges: (pattern1 | pattern2)
|
||||
or ([range1]pattern1 | [range2]pattern2), but not
|
||||
([range1]pattern1 | pattern2)
|
||||
- CheckSnifferRule() doesn't check some of the values, e.g.
|
||||
ranges (negative values, or begin > end) or 0 <= priority <= 1.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GuessMimeType(const entry_ref *, BMimeType *)
|
||||
Description: When passing an uninitialized entry_ref, B_OK and
|
||||
"application/octet-stream" are returned.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: SetAttrInfo
|
||||
Description: Crashes when passed a NULL BMessage.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetInstalledTypes(BMessage*)
|
||||
Description: The set of types returned by this function is determined as follows:
|
||||
+ All *entries* (files, dirs, or symlinks) in the root MIME database
|
||||
directory treated as MIME types, except those that begin with an
|
||||
underscore; only dirs are treated as supertypes (unless the dir's
|
||||
META:TYPE attribute is different than its filename, in which case
|
||||
it's not treated as a supertype).
|
||||
+ For each supertype, all *entries* (files, dirs, or symlinks) in the
|
||||
corresponding supertype subdirectory are treated as a MIME type, except
|
||||
those that begin with an underscore.
|
||||
+ The MIME type for supertypes is taken from the name of the supertype
|
||||
subdirectory.
|
||||
+ The MIME type for non-supertypes is take from the entry's META:TYPE
|
||||
attribute. If the entry has no META:TYPE attribute, the MIME type is
|
||||
derived by concatentating the name of the supertype directory to the
|
||||
name of the entry, separated by a "/" character. Either way, the MIME
|
||||
string returned is not checked to be valid.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetInstalledTypes(char *super, BMessage*)
|
||||
Description: The set of types returned by this function is determined as follows:
|
||||
+ All *entries* (files, dirs, or symlinks) in the MIME database directory
|
||||
corresponding to the "super" argument are treated as subtypes, *except*
|
||||
those whose filenames begin with an underscore. It does not matter if
|
||||
the supertype directory has a META:TYPE attribute or not.
|
||||
+ The MIME type is taken from the entry's META:TYPE attribute. If the entry
|
||||
has no such attribute, the MIME type is derived by concatentating the name
|
||||
of the supertype directory (the directory's META:TYPE attribute is ignored
|
||||
if present) to the name of the entry, separated by a "/" character. Either
|
||||
way, the MIME string returned is not checked to be valid.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetInstalledSupertypes(BMessage*)
|
||||
Description: The set of types returned by this function is determined as follows:
|
||||
+ All directories in the root MIME database directory are treated as
|
||||
supertypes (even directories beginning with an underscore).
|
||||
+ The MIME type is derived from the directory name, which is not
|
||||
checked to be a valid MIME string.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BMimeType
|
||||
Location: GetWildcardApps()
|
||||
Description: This code:
|
||||
BMessage msg;
|
||||
status_t error = BMimeType::GetWildcardApps(&msg);
|
||||
is the same as:
|
||||
BMessage msg;
|
||||
BMimeType mime("application/octet-stream");
|
||||
status_t error = mime.InitCheck();
|
||||
if (!error)
|
||||
error = mime.GetSupportingApps(&msg);
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNodeInfo
|
||||
Location: {Set,Get}AppHint()
|
||||
Description: The file attribute the path of the "app hint" application
|
||||
("BEOS:PPATH") is of type B_MIME_STRING_TYPE instead of
|
||||
B_STRING_TYPE.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNodeInfo
|
||||
Location: GetType()
|
||||
Description: When the string stored in the "BEOS:TYPE" attribute is longer
|
||||
than B_MIME_TYPE_LENGTH, the returned string is one character
|
||||
shorter than the actual string.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNodeInfo
|
||||
Location: GetIcon()
|
||||
Description: Crashes when passing a NULL BBitmap.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BNodeInfo
|
||||
Location: GetIcon()
|
||||
Description: Crashes when getting B_LARGE_ICON and passing a BBitmap with
|
||||
B_RGB32 color space. B_MINI_ICON works just fine.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: GetSupportedTypes()
|
||||
Description: Crashes when passing a NULL BMessage.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: Supports()
|
||||
Description: Crashes when passing a NULL BMimeType.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: SetSupportedTypes(const BMessage *types, bool syncAll)
|
||||
Description: Crashes when passing a NULL BMessage and syncAll = true.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: SetSupportedTypes()
|
||||
Description: Sometimes installs a supported type, also when the file's
|
||||
signature is not installed in the MIME database. This happens
|
||||
e.g. when setting two supported types and then setting two
|
||||
different types. The second of the new types is installed.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: SetSupportedTypes(const BMessage *types)
|
||||
Description: Returns B_ENTRY_NOT_FOUND when the file's signature is not
|
||||
installed in the MIME database, although the operation is
|
||||
carried out successfully.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: SetSupportedTypes()
|
||||
Description: Don't check whether the supplied types are valid MIME types. And
|
||||
don't fail, if they are not. OBOS checks them.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: GetIcon(), GetIconForType()
|
||||
Description: Crashes when getting B_LARGE_ICON and passing a BBitmap with
|
||||
B_RGB32 color space. B_MINI_ICON works just fine.
|
||||
|
||||
|
||||
OS: BeOS R5
|
||||
Module: BAppFileInfo
|
||||
Location: GetVersionInfo(), SetVersionInfo()
|
||||
Description: Crash when passing a NULL version_info.
|
||||
|
||||
|
||||
Module: BTest
|
||||
Location: SetName()
|
||||
Description: Should also rename the mount point.
|
||||
Priority: medium
|
||||
|
||||
|
||||
@@ -0,0 +1,159 @@
|
||||
# Completed
|
||||
# =========
|
||||
#
|
||||
# This file contains completed ToDo items.
|
||||
|
||||
Module: BEntry
|
||||
Location: SetTo(const BDirectory *, const char *, bool)
|
||||
Description: Reimplement! Concatenating dir and leaf to an absolute path
|
||||
prevents the user from accessing entries with longer absolute
|
||||
path. R5 handles this without problems.
|
||||
Priority: medium
|
||||
Requires: - OBOS kernel?
|
||||
|
||||
|
||||
Module: BEntry
|
||||
Location: SetTo(const BDirectory *, const char *, bool)
|
||||
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BVolume
|
||||
Location: operator==()
|
||||
Description: Implement.
|
||||
Priority: high
|
||||
|
||||
|
||||
Module: StatableTest
|
||||
Location: GetXYZTest()
|
||||
Description: Uncomment GetVolume() test, when BVolume::==() is implemented.
|
||||
Priority: low
|
||||
Requires: - implementation of BVolume::operator==()
|
||||
|
||||
|
||||
Module: kernel_interface
|
||||
Location: set_stat(const char*, StatMember)
|
||||
Description: Implement WSTAT_CRTIME.
|
||||
Priority: medium
|
||||
Comment: not longer necessary as we use the Haiku kernel syscalls now
|
||||
|
||||
|
||||
Module: BeOS R5::libroot
|
||||
Location:
|
||||
Description: Propose a project wide common handling of the
|
||||
B_FILE/PATH_NAME_LENGTH (+ 1?) issue.
|
||||
Priority: low
|
||||
Comment: B_FILE/PATH_NAME_LENGTH already include the terminating null
|
||||
|
||||
|
||||
Module: BSymLink
|
||||
Location:
|
||||
Description: Remove the work-around introduced because of the missing FD
|
||||
version of readlink().
|
||||
Priority: medium
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BNode
|
||||
Location: SetTo(const entry_ref *)
|
||||
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BNode
|
||||
Location: SetTo(const BEntry *)
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
SetTo(const entry_ref*).
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BNode
|
||||
Location: SetTo(const BDirectory*, const char*)
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
SetTo(const BEntry*).
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BNode
|
||||
Location: Lock(), Unlock()
|
||||
Description: Implement when kernel support is available.
|
||||
Priority: medium
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BFile
|
||||
Location: SetTo(const entry_ref *, uint32)
|
||||
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BFile
|
||||
Location: SetTo(const BEntry *, uint32)
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
SetTo(const entry_ref*, uint32).
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BFile
|
||||
Location: SetTo(const BDirectory*, const char*, uint32)
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
SetTo(const BEntry*, uint32).
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BDirectory
|
||||
Location: SetTo(const entry_ref *)
|
||||
Description: Reimplement! Implemented using StorageKit::entry_ref_to_path().
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BDirectory
|
||||
Location: SetTo(const BEntry *)
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
SetTo(const entry_ref*).
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BDirectory
|
||||
Location: SetTo(const BDirectory*, const char*)
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
SetTo(const BEntry*).
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BDirectory
|
||||
Location: GetEntry()
|
||||
Description: Check if necessary to reimplement! Implemented using
|
||||
StorageKit::dir_to_self_entry_ref().
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BQuery
|
||||
Location: SetTarget()
|
||||
Description: Used a bad hack to get port and token of the BMessenger. Fix it.
|
||||
Priority: low
|
||||
Requires: - respective function(s) to be provided by the IK team
|
||||
|
||||
|
||||
Module: kernel_interface
|
||||
Location: remove_attr()
|
||||
Description: Verify return behavior of fs_remove_attr().
|
||||
Priority: medium
|
||||
Comment: not longer necessary as we use the Haiku kernel syscalls now
|
||||
|
||||
|
||||
Module: BVolume
|
||||
Location: SetName()
|
||||
Description: Should also rename the mount point.
|
||||
Priority: medium
|
||||
@@ -0,0 +1,90 @@
|
||||
Disk Device Protocols
|
||||
=====================
|
||||
|
||||
disk device job scheduled message
|
||||
|
||||
target: Registered job update BMessengers
|
||||
message: B_DISK_DEVICE_JOB_SCHEDULED
|
||||
"job_id": B_INT32_TYPE
|
||||
reply: none (asynchronous message)
|
||||
|
||||
message fields:
|
||||
- job_id: Unique job identifier
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
disk device job initiated message
|
||||
|
||||
target: Registered job update BMessengers
|
||||
message: B_DISK_DEVICE_JOB_INITIATED
|
||||
"job_id": B_INT32_TYPE
|
||||
reply: none (asynchronous message)
|
||||
|
||||
message fields:
|
||||
- job_id: Unique job identifier
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
disk device job canceled message
|
||||
|
||||
target: Registered job update BMessengers
|
||||
message: B_DISK_DEVICE_JOB_CANCELED
|
||||
"job_id": B_INT32_TYPE
|
||||
reply: none (asynchronous message)
|
||||
|
||||
message fields:
|
||||
- job_id: Unique job identifier
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
disk device job finished message
|
||||
|
||||
target: Registered job update BMessengers
|
||||
message: B_DISK_DEVICE_JOB_FINISHED
|
||||
"job_id": B_INT32_TYPE
|
||||
"succeeded": B_BOOL_TYPE
|
||||
[ "info": B_STRING_TYPE ]
|
||||
reply: none (asynchronous message)
|
||||
|
||||
message fields:
|
||||
- job_id: Unique job identifier
|
||||
- info: Optional description of success or failure
|
||||
|
||||
notes:
|
||||
A separate job finished message is needed, as rounding error in
|
||||
the computation of job progress may result in multiple
|
||||
B_DISK_DEVICE_JOB_UPDATE messages with "progress" fields of 100.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
disk device job simple progress update message
|
||||
|
||||
target: Registered job simple progress update BMessengers
|
||||
message: B_DISK_DEVICE_JOB_SIMPLE_PROGRESS
|
||||
"job_id": B_INT32_TYPE
|
||||
"progress": B_UINT8_TYPE
|
||||
"info": B_STRING_TYPE
|
||||
reply: none (asynchronous message)
|
||||
|
||||
message fields:
|
||||
- job_id: Unique job identifier
|
||||
- progress: Percent of job completed (0 to 100)
|
||||
- info: Description of current action being taken, i.e.
|
||||
"allocating inodes", "writing superblock", etc.
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
|
||||
disk device job extra progress update message
|
||||
|
||||
target: Registered job extra progress update BMessengers
|
||||
message: B_DISK_DEVICE_JOB_EXTRA_PROGRESS
|
||||
"job_id": B_INT32_TYPE
|
||||
"info": B_STRING_TYPE
|
||||
reply: none (asynchronous message)
|
||||
|
||||
message fields:
|
||||
- job_id: Unique job identifier
|
||||
- info: Extended progress info string, i.e. "block 123: found
|
||||
invalid inode; fixing"
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
@@ -0,0 +1,102 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Registrar Notes</title>
|
||||
</head>
|
||||
<body bgcolor='#ffffff'>
|
||||
<font face='Tahoma,Arial,SansSerif'>
|
||||
|
||||
<!-- Tasks -->
|
||||
<hr>
|
||||
<b>Registrar Tasks:</b>
|
||||
<ul>
|
||||
<li> MIME Database chores (note that BMimeType appears to read from the database directly for <code>Get*()</code> calls.)<br>
|
||||
<ul>
|
||||
<li> Writes to the database -- <code>SetLongDescription(), SetPreferredApp(), create_app_meta_mime(), etc</code>
|
||||
<li> Monitoring of the database -- <code>{Start,Stop}Watching()</code> <br>
|
||||
<li> Sniffer duties -- Sniffer code plus <code>{Get,Set,Check}SnifferRule()</code>
|
||||
</ul>
|
||||
<br>
|
||||
|
||||
<li> Timing chores
|
||||
<ul>
|
||||
<li> BMessageRunner functionality
|
||||
</ul>
|
||||
<li> System Shutdown chores <br>
|
||||
<ul>
|
||||
<li> Shutdown cycle
|
||||
<li> System shutdown window
|
||||
</ul>
|
||||
<li> Roster chores
|
||||
<ul>
|
||||
<li> Recent documents, folders, and apps
|
||||
<li> Info about running applications
|
||||
<li> etc...
|
||||
</ul>
|
||||
</ul>
|
||||
|
||||
<!-- Internals -->
|
||||
<hr>
|
||||
<b>Registrar Internals:</b><br>
|
||||
<br>
|
||||
|
||||
The registrar is a non-standard <code>BApplication</code>. It has a shadow app in the <code>app_server</code>
|
||||
like a normal <code>BApplication</code>, but one of its ports is slightly different:
|
||||
|
||||
<ul>
|
||||
<li> Standard ports -- snd, rcv, AppLooperPort
|
||||
<li> Registrar ports -- snd, rcv, _roster_port_
|
||||
</ul>
|
||||
|
||||
Since <code>BLooper::port_id</code> is private to <code>BLooper</code> (to whom <code>BApplication</code>
|
||||
is a friend), and since you can't rename a port after it's been created,
|
||||
it's likely that the only way to rename the <code>AppLooperPort</code> and have the registrar
|
||||
still be a <code>BApplication</code> is to have <code>BApplication</code> check if it's the
|
||||
registrar when it's created, and use <code>_roster_port_</code> as the name for what would
|
||||
otherwise be its <code>AppLooperPort</code>.
|
||||
<br>
|
||||
<br>
|
||||
The rationale behind having a port with a specific name is that the registrar
|
||||
implements the roster functionality. Thus one can't address it using the app signature
|
||||
constructor of BMessenger, but rather must send the message directly to
|
||||
a named port (for example, upon creation, a BApplication object must find and contact
|
||||
the registrar to notify it of another running application; if the registrar
|
||||
cannot be found, the application putzes out).
|
||||
|
||||
<br>
|
||||
<br>
|
||||
|
||||
The Registrar has three threads:
|
||||
<ul>
|
||||
<li> _roster_thread_
|
||||
<li> timer_thread
|
||||
<li> main_mime
|
||||
</ul>
|
||||
|
||||
<!-- BMimeType Notes -->
|
||||
<hr>
|
||||
<b>BMimeType Notes:</b>
|
||||
<ul>
|
||||
<li> The <code>Get*()</code> methods directly access the MIME database.
|
||||
<li> The <code>Set*()</code> methods send a message to another entity which does the job.
|
||||
The function that does the sending is called <code>_send_to_roster_()</code>, so I
|
||||
suppose the roster is the one. Since the registrar has a thread named
|
||||
<code>_roster_thread_</code>, I assume the roster lives in the registrar.
|
||||
<li> <code>Start/StopWatching()</code> call <code>BRoster::_Start/_StopWatching()</code>.
|
||||
<li>Adding/removing a MIME type file in <code>~/config/settings/beos_mime/*/</code> does
|
||||
not trigger a notification message. So obviously no node monitoring is
|
||||
done and changes to the database are supposed to be done using the API.
|
||||
</ul>
|
||||
<!-- Links -->
|
||||
<hr>
|
||||
<b>Links:</b>
|
||||
<ul>
|
||||
<li> <a href='http://www.beatjapan.org/mirror/www.be.com/users/iconworld/icon5.html'>Icon World -- The Registrar</a>
|
||||
<li> <a href='http://www.beosbible.com/exc_filetype.html'>The BeOS Bible -- File Typing and The Registrar</a>
|
||||
<li> <a href='http://bang.dhs.org/be/bebook/The%20Application%20Kit/Application.html'>BApplication</a>
|
||||
<li> <a href='http://bang.dhs.org/be/bebook/The%20Storage%20Kit/MimeType.html'>BMimeType</a>
|
||||
<li> <a href='http://bang.dhs.org/be/bebook/Release%20Notes/StorageKit.html'>BMimeType (sniffer docs)</a>
|
||||
<li> <a href='http://bang.dhs.org/be/bebook/The%20Application%20Kit/Roster.html'>BRoster</a>
|
||||
|
||||
</font>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,96 @@
|
||||
# ToDo
|
||||
# ====
|
||||
#
|
||||
# This file lists items that have to be worked on.
|
||||
# An entry for an item has the following tags:
|
||||
# * Module: the concerned class or file
|
||||
# * Location: a more precise location, e.g. a function
|
||||
# * Description: a description of the item
|
||||
# * Priority: the priority of the item, may be
|
||||
# deferrable: of no/little relevance for OBOS R1 (to be future compatible:
|
||||
# the next release)
|
||||
# low: of relevance for the next release, but not needed in the
|
||||
# near future
|
||||
# medium: of relevance for the next release, needed in the near future
|
||||
# high: of relevance for the next release, needed as soon as possible
|
||||
# urgent: of relevance for the next release, needed yesterday, i.e.
|
||||
# some people depend on it being finished and can't continue
|
||||
# with their tasks otherwise
|
||||
#
|
||||
# * Requires: a list of prerequisites needed for the item to be worked on,
|
||||
# omitted, when empty
|
||||
# * Responsible: a list of people working on the item, omitted, when empty
|
||||
#
|
||||
|
||||
Module: BEntry
|
||||
Location: Entry.cpp
|
||||
Description: Definition of SYMLINK_MAX belongs to some header file. Remove it.
|
||||
Priority: low
|
||||
|
||||
|
||||
Module: EntryTest
|
||||
Location: InitTest1(), InitTest2()
|
||||
Description: Enable tests with strlen(dir + leaf) > B_PATH_NAME_LENGTH.
|
||||
Priority: low
|
||||
Requires: - reimpl. of SetTo(const BDirectory *, const char *, bool)
|
||||
|
||||
|
||||
Module: BPath
|
||||
Location: Flatten()
|
||||
Description: Reimplement for performance reasons. Don't call FlattenedSize().
|
||||
Priority: low
|
||||
|
||||
|
||||
Module: NodeTest
|
||||
Location: SyncTest()
|
||||
Description: Add more thorough tests.
|
||||
Priority: low
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: NodeTest
|
||||
Location: LockTest()
|
||||
Description: Implement when kernel support is available.
|
||||
Priority: medium
|
||||
Requires: - OBOS kernel
|
||||
|
||||
|
||||
Module: BFile
|
||||
Location: Read/Write[At]()
|
||||
Description: Verify behavior of B_OPEN_AT_END.
|
||||
Priority: medium
|
||||
|
||||
|
||||
Module: FileTest
|
||||
Location: PositionTest()
|
||||
Description: Uncomment test, when B_OPEN_AT_END behavior is understood.
|
||||
Priority: medium
|
||||
Requires: - verification of B_OPEN_AT_END behavior
|
||||
|
||||
|
||||
Module: fs_info.h
|
||||
Location: struct fs_info
|
||||
Description: Change "char device_name[128]" to "char device_name[B_DEV_NAME_LENGTH]"
|
||||
whenever appropriate, since B_DEV_NAME_LENGTH is now declared in
|
||||
StorageDefs.h.
|
||||
Priority: low
|
||||
Requires: - filesystem support files in the source hierarchy
|
||||
|
||||
|
||||
Module: BMimeType/MimeTypeTest
|
||||
Location: update_mime_info(), create_app_meta_mime()
|
||||
Description: Find out, what is the meaning of the force parameter. It does
|
||||
obviously not mean, that calling the function twice, the second
|
||||
time with force, has the same effect as calling it only at the
|
||||
second time. At least the tests indicate, that the second call,
|
||||
though with force, does not have any effect at all.
|
||||
Priority: medium
|
||||
Requires:
|
||||
|
||||
|
||||
Module: VolumeTest
|
||||
Location: SetNameTest()
|
||||
Description: Check whether the mount point is renamed properly.
|
||||
Priority: low
|
||||
|
||||
|
||||
@@ -0,0 +1,691 @@
|
||||
# Doxyfile 1.2.1
|
||||
|
||||
# This file describes the settings to be used by doxygen for a project
|
||||
#
|
||||
# All text after a hash (#) is considered a comment and will be ignored
|
||||
# The format is:
|
||||
# TAG = value [value, ...]
|
||||
# For lists items can also be appended using:
|
||||
# TAG += value [value, ...]
|
||||
# Values that contain spaces should be placed between quotes (" ")
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
||||
# by quotes) that should identify the project.
|
||||
|
||||
PROJECT_NAME = "OpenBeOS Storage Kit"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY =
|
||||
|
||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all constant output in the proper language.
|
||||
# The default language is English, other supported languages are:
|
||||
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
|
||||
# Spanish, Russian, Croatian, Polish, and Portuguese.
|
||||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
|
||||
# documentation are documented, even if no documentation was available.
|
||||
# Private class members and static file members will be hidden unless
|
||||
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
|
||||
|
||||
EXTRACT_ALL = NO
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_PRIVATE = YES
|
||||
|
||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_STATIC = YES
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||
# undocumented members of documented classes, files or namespaces.
|
||||
# If set to NO (the default) these members will be included in the
|
||||
# various overviews, but no documentation section is generated.
|
||||
# This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
|
||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
|
||||
# undocumented classes that are normally visible in the class hierarchy.
|
||||
# If set to NO (the default) these class will be included in the various
|
||||
# overviews. This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
|
||||
# include brief member descriptions after the members that are listed in
|
||||
# the file and class documentation (similar to JavaDoc).
|
||||
# Set to NO to disable this.
|
||||
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
|
||||
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
|
||||
# the brief description of a member or function before the detailed description.
|
||||
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
||||
# brief descriptions will be completely suppressed.
|
||||
|
||||
REPEAT_BRIEF = YES
|
||||
|
||||
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||
# Doxygen will generate a detailed section even if there is only a brief
|
||||
# description.
|
||||
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
|
||||
# path before files name in the file list and in the header files. If set
|
||||
# to NO the shortest path that makes the file name unique will be used.
|
||||
|
||||
FULL_PATH_NAMES = YES
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
|
||||
# can be used to strip a user defined part of the path. Stripping is
|
||||
# only done if one of the specified strings matches the left-hand part of
|
||||
# the path. It is allowed to use relative paths in the argument list.
|
||||
|
||||
STRIP_FROM_PATH = /cvsroot/open-beos/current
|
||||
|
||||
# The INTERNAL_DOCS tag determines if documentation
|
||||
# that is typed after a \internal command is included. If the tag is set
|
||||
# to NO (the default) then the documentation will be excluded.
|
||||
# Set it to YES to include the internal documentation.
|
||||
|
||||
INTERNAL_DOCS = NO
|
||||
|
||||
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
|
||||
# generate a class diagram (in Html and LaTeX) for classes with base or
|
||||
# super classes. Setting the tag to NO turns the diagrams off.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
|
||||
# be generated. Documented entities will be cross-referenced with these sources.
|
||||
|
||||
SOURCE_BROWSER = YES
|
||||
|
||||
# Setting the INLINE_SOURCES tag to YES will include the body
|
||||
# of functions and classes directly in the documentation.
|
||||
|
||||
INLINE_SOURCES = NO
|
||||
|
||||
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
|
||||
# doxygen to hide any special comment blocks from generated source code
|
||||
# fragments. Normal C and C++ comments will always remain visible.
|
||||
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen
|
||||
# will only generate file names in lower case letters. If set to
|
||||
# YES upper case letters are also allowed. This is useful if you have
|
||||
# classes or files whose names only differ in case and if your file system
|
||||
# supports case sensitive file names.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
|
||||
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
|
||||
# will show members with their full class and namespace scopes in the
|
||||
# documentation. If set to YES the scope will be hidden.
|
||||
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
|
||||
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
|
||||
# will generate a verbatim copy of the header file for each class for
|
||||
# which an include is specified. Set to NO to disable this.
|
||||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
|
||||
# will put list of the files that are included by a file in the documentation
|
||||
# of that file.
|
||||
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
|
||||
# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen
|
||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||
# comment as the brief description. If set to NO, the Javadoc-style will
|
||||
# behave just like the Qt-style comments.
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||
# member inherits the documentation from any documented member that it
|
||||
# reimplements.
|
||||
|
||||
INHERIT_DOCS = YES
|
||||
|
||||
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
|
||||
# is inserted in the documentation for inline members.
|
||||
|
||||
INLINE_INFO = YES
|
||||
|
||||
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
|
||||
# will sort the (detailed) documentation of file and class members
|
||||
# alphabetically by member name. If set to NO the members will appear in
|
||||
# declaration order.
|
||||
|
||||
SORT_MEMBER_DOCS = YES
|
||||
|
||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
||||
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
||||
|
||||
TAB_SIZE = 4
|
||||
|
||||
# The ENABLE_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
||||
ENABLED_SECTIONS =
|
||||
|
||||
# The GENERATE_TODOLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the todo list. This list is created by putting \todo
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_TODOLIST = YES
|
||||
|
||||
# The GENERATE_TESTLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the test list. This list is created by putting \test
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_TESTLIST = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The QUIET tag can be used to turn on/off the messages that are generated
|
||||
# by doxygen. Possible values are YES and NO. If left blank NO is used.
|
||||
|
||||
QUIET = NO
|
||||
|
||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||
# generated by doxygen. Possible values are YES and NO. If left blank
|
||||
# NO is used.
|
||||
|
||||
WARNINGS = YES
|
||||
|
||||
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
|
||||
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
|
||||
# automatically be disabled.
|
||||
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
|
||||
# The WARN_FORMAT tag determines the format of the warning messages that
|
||||
# doxygen can produce. The string should contain the $file, $line, and $text
|
||||
# tags, which will be replaced by the file and line number from which the
|
||||
# warning originated and the warning text.
|
||||
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The INPUT tag can be used to specify the files and/or directories that contain
|
||||
# documented source files. You may enter file names like "myfile.cpp" or
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = ../../../src/kits/storage ../../../headers/os/storage ../../../headers/private/storage
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank all files are included.
|
||||
|
||||
FILE_PATTERNS = *.cpp *.h
|
||||
|
||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
||||
# should be searched for input files as well. Possible values are YES and NO.
|
||||
# If left blank NO is used.
|
||||
|
||||
RECURSIVE = YES
|
||||
|
||||
# The EXCLUDE tag can be used to specify files and/or directories that should
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE =
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||
# certain files from those directories.
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank all files are included.
|
||||
|
||||
EXAMPLE_PATTERNS =
|
||||
|
||||
# The IMAGE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain image that are included in the documentation (see
|
||||
# the \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
||||
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
||||
# input file. Doxygen will then use the output that the filter program writes
|
||||
# to standard output.
|
||||
|
||||
INPUT_FILTER =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
|
||||
# of all compounds will be generated. Enable this if the project
|
||||
# contains a lot of classes, structs, unions or interfaces.
|
||||
|
||||
ALPHABETICAL_INDEX = NO
|
||||
|
||||
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
|
||||
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
||||
# in which this list will be split (can be a number in the range [1..20])
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all
|
||||
# classes will be put under the same header in the alphabetical index.
|
||||
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
|
||||
# should be ignored while generating the index headers.
|
||||
|
||||
IGNORE_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
|
||||
# generate HTML output.
|
||||
|
||||
GENERATE_HTML = YES
|
||||
|
||||
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `html' will be used as the default path.
|
||||
|
||||
HTML_OUTPUT = html
|
||||
|
||||
# The HTML_HEADER tag can be used to specify a personal HTML header for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard header.
|
||||
|
||||
HTML_HEADER =
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard footer.
|
||||
|
||||
HTML_FOOTER =
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
|
||||
# style sheet that is used by each HTML page. It can be used to
|
||||
# fine-tune the look of the HTML output. If the tag is left blank doxygen
|
||||
# will generate a default style sheet
|
||||
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
|
||||
# files or namespaces will be aligned in HTML using tables. If set to
|
||||
# NO a bullet list will be used.
|
||||
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||
# will be generated that can be used as input for tools like the
|
||||
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
|
||||
# of the generated HTML documentation.
|
||||
|
||||
GENERATE_HTMLHELP = NO
|
||||
|
||||
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
||||
# top of each HTML page. The value NO (the default) enables the index and
|
||||
# the value YES disables it.
|
||||
|
||||
DISABLE_INDEX = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||
# generate Latex output.
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
|
||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `latex' will be used as the default path.
|
||||
|
||||
LATEX_OUTPUT = latex
|
||||
|
||||
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
||||
# LaTeX documents. This may be useful for small projects and may help to
|
||||
# save some trees in general.
|
||||
|
||||
COMPACT_LATEX = NO
|
||||
|
||||
# The PAPER_TYPE tag can be used to set the paper type that is used
|
||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||
# executive. If left blank a4wide will be used.
|
||||
|
||||
PAPER_TYPE = a4wide
|
||||
|
||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
||||
# packages that should be included in the LaTeX output.
|
||||
|
||||
EXTRA_PACKAGES =
|
||||
|
||||
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
|
||||
# the generated latex document. The header should contain everything until
|
||||
# the first chapter. If it is left blank doxygen will generate a
|
||||
# standard header. Notice: only use this tag if you know what you are doing!
|
||||
|
||||
LATEX_HEADER =
|
||||
|
||||
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
|
||||
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
|
||||
# contain links (just like the HTML output) instead of page references
|
||||
# This makes the output suitable for online browsing using a pdf viewer.
|
||||
|
||||
PDF_HYPERLINKS = NO
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
|
||||
# plain latex in the generated Makefile. Set this option to YES to get a
|
||||
# higher quality PDF documentation.
|
||||
|
||||
USE_PDFLATEX = NO
|
||||
|
||||
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
|
||||
# command to the generated LaTeX files. This will instruct LaTeX to keep
|
||||
# running if errors occur, instead of asking the user for help.
|
||||
# This option is also used when generating formulas in HTML.
|
||||
|
||||
LATEX_BATCHMODE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
|
||||
# The RTF output is optimised for Word 97 and may not look very pretty with
|
||||
# other RTF readers or editors.
|
||||
|
||||
GENERATE_RTF = NO
|
||||
|
||||
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `rtf' will be used as the default path.
|
||||
|
||||
RTF_OUTPUT = rtf
|
||||
|
||||
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
|
||||
# RTF documents. This may be useful for small projects and may help to
|
||||
# save some trees in general.
|
||||
|
||||
COMPACT_RTF = NO
|
||||
|
||||
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
|
||||
# will contain hyperlink fields. The RTF file will
|
||||
# contain links (just like the HTML output) instead of page references.
|
||||
# This makes the output suitable for online browsing using a WORD or other.
|
||||
# programs which support those fields.
|
||||
# Note: wordpad (write) and others do not support links.
|
||||
|
||||
RTF_HYPERLINKS = NO
|
||||
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||
# config file, i.e. a series of assigments. You only have to provide
|
||||
# replacements, missing definitions are set to their default value.
|
||||
|
||||
RTF_STYLESHEET_FILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
|
||||
# generate man pages
|
||||
|
||||
GENERATE_MAN = NO
|
||||
|
||||
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `man' will be used as the default path.
|
||||
|
||||
MAN_OUTPUT = man
|
||||
|
||||
# The MAN_EXTENSION tag determines the extension that is added to
|
||||
# the generated man pages (default is the subroutine's section .3)
|
||||
|
||||
MAN_EXTENSION = .3
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_XML tag is set to YES Doxygen will
|
||||
# generate an XML file that captures the structure of
|
||||
# the code including all documentation. Warning: This feature
|
||||
# is still experimental and very incomplete.
|
||||
|
||||
GENERATE_XML = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
|
||||
# evaluate all C-preprocessor directives found in the sources and include
|
||||
# files.
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
|
||||
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
|
||||
# names in the source code. If set to NO (the default) only conditional
|
||||
# compilation will be performed. Macro expansion can be done in a controlled
|
||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||
# then the macro expansion is limited to the macros specified with the
|
||||
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
|
||||
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
|
||||
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
|
||||
# in the INCLUDE_PATH (see below) will be search if a #include is found.
|
||||
|
||||
SEARCH_INCLUDES = YES
|
||||
|
||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||
# contain include files that are not input files but should be processed by
|
||||
# the preprocessor.
|
||||
|
||||
INCLUDE_PATH =
|
||||
|
||||
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||
# directories. If left blank, the patterns specified with FILE_PATTERNS will
|
||||
# be used.
|
||||
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
|
||||
# The PREDEFINED tag can be used to specify one or more macro names that
|
||||
# are defined before the preprocessor is started (similar to the -D option of
|
||||
# gcc). The argument of the tag is a list of macros of the form: name
|
||||
# or name=definition (no spaces). If the definition and the = are
|
||||
# omitted =1 is assumed.
|
||||
|
||||
PREDEFINED =
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
# The macro definition that is found in the sources will be used.
|
||||
# Use the PREDEFINED tag if you want to use a different macro definition.
|
||||
|
||||
EXPAND_AS_DEFINED =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The TAGFILES tag can be used to specify one or more tagfiles.
|
||||
|
||||
TAGFILES =
|
||||
|
||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
||||
# a tag file that is based on the input files it reads.
|
||||
|
||||
GENERATE_TAGFILE =
|
||||
|
||||
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
||||
# in the class index. If set to NO only the inherited external classes
|
||||
# will be listed.
|
||||
|
||||
ALLEXTERNALS = NO
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of `which perl').
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz, a graph visualization
|
||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||
# have no effect if this option is set to NO (the default)
|
||||
|
||||
HAVE_DOT = NO
|
||||
|
||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
# indirect inheritance relations. Setting this tag to YES will force the
|
||||
# the CLASS_DIAGRAMS tag to NO.
|
||||
|
||||
CLASS_GRAPH = YES
|
||||
|
||||
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
# indirect implementation dependencies (inheritance, containment, and
|
||||
# class references variables) of the class with other documented classes.
|
||||
|
||||
COLLABORATION_GRAPH = YES
|
||||
|
||||
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
|
||||
# YES then doxygen will generate a graph for each documented file showing
|
||||
# the direct and indirect include dependencies of the file with other
|
||||
# documented files.
|
||||
|
||||
INCLUDE_GRAPH = YES
|
||||
|
||||
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
|
||||
# YES then doxygen will generate a graph for each documented header file showing
|
||||
# the documented files that directly or indirectly include this file
|
||||
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
|
||||
# will graphical hierarchy of all classes instead of a textual one.
|
||||
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
|
||||
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
||||
# found. If left blank, it is assumed the dot tool can be found on the path.
|
||||
|
||||
DOT_PATH =
|
||||
|
||||
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
|
||||
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The SEARCHENGINE tag specifies whether or not a search engine should be
|
||||
# used. If set to NO the values of all tags below this one will be ignored.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
|
||||
# The CGI_NAME tag should be the name of the CGI script that
|
||||
# starts the search engine (doxysearch) with the correct parameters.
|
||||
# A script with this name will be generated by doxygen.
|
||||
|
||||
CGI_NAME = search.cgi
|
||||
|
||||
# The CGI_URL tag should be the absolute URL to the directory where the
|
||||
# cgi binaries are located. See the documentation of your http daemon for
|
||||
# details.
|
||||
|
||||
CGI_URL =
|
||||
|
||||
# The DOC_URL tag should be the absolute URL to the directory where the
|
||||
# documentation is located. If left blank the absolute path to the
|
||||
# documentation, with file:// prepended to it, will be used.
|
||||
|
||||
DOC_URL =
|
||||
|
||||
# The DOC_ABSPATH tag should be the absolute path to the directory where the
|
||||
# documentation is located. If left blank the directory on the local machine
|
||||
# will be used.
|
||||
|
||||
DOC_ABSPATH =
|
||||
|
||||
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
|
||||
# is installed.
|
||||
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
|
||||
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
|
||||
# documentation generated for other projects. This allows doxysearch to search
|
||||
# the documentation for these projects as well.
|
||||
|
||||
EXT_DOC_PATHS =
|
||||
@@ -0,0 +1,614 @@
|
||||
\documentclass[12pt, a4paper]{article}
|
||||
|
||||
\usepackage{amssymb,amsmath,latexsym}
|
||||
\usepackage[english]{babel}
|
||||
\usepackage{hhline}
|
||||
|
||||
\newcommand{\code}[1]{{\tt #1}}
|
||||
|
||||
\newenvironment{nitemize}{
|
||||
\newdimen\oldparindent
|
||||
\oldparindent=\parindent
|
||||
\begin{itemize}
|
||||
\itemindent=-\oldparindent
|
||||
}{
|
||||
\end{itemize}
|
||||
}
|
||||
|
||||
%\newcommand{\codeblockspace}{\vspace{12pt}}
|
||||
|
||||
% begin/end a code block
|
||||
\newcommand{\codeblockbegin}{\begin{flushleft}\begin{minipage}{\textwidth}}
|
||||
\newcommand{\codeblockend}{\end{minipage}\end{flushleft}}
|
||||
|
||||
|
||||
\begin{document}
|
||||
|
||||
\sloppy
|
||||
|
||||
\title{The Resources Format}
|
||||
%\date{}
|
||||
\author{Ingo Weinhold ([email protected])}
|
||||
|
||||
\maketitle
|
||||
\tableofcontents
|
||||
|
||||
|
||||
\section{Introduction}
|
||||
\label{introduction}
|
||||
|
||||
Resources provide a means to store structured but flat data in files. Unlike
|
||||
attributes resources are part of the file contents and thus do not require a
|
||||
special file system handling, but rather a special file format.
|
||||
On the one hand there are formats of files that exclusively contain resources
|
||||
(resource files), on the other hand these are file formats extended to
|
||||
additionally contain resources -- namely the ELF and PEF object formats.
|
||||
In either case the format of the chunk of data that frames the resources
|
||||
themselves is the same. We call it the resources format.
|
||||
|
||||
Section \ref{file-formats} explains how the resources format is embedded in
|
||||
different file formats. Section \ref{resources-format} discusses the resources
|
||||
format itself. In section \ref{implementations} we focus on robustness of
|
||||
resources reading/writing implementations.
|
||||
The final section says some words about the status of the information provided
|
||||
by this document.
|
||||
|
||||
|
||||
|
||||
\section{File Formats}
|
||||
\label{file-formats}
|
||||
|
||||
In all file formats described in this section the resources are being located
|
||||
at the end of the files. They are completely independent of their location.
|
||||
|
||||
|
||||
\subsection{x86 Resource Files}
|
||||
|
||||
x86 resource files introduce the least overhead. The resources start directly
|
||||
after the magic number identifying the file format:
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
const char kX86ResourceFileMagic[4] = { 'R', 'S', 0, 0 };
|
||||
const uint32 kX86ResourcesOffset = 0x00000004;
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
The resources start at \code{kX86ResourcesOffset}.
|
||||
|
||||
|
||||
\subsection{PPC Resource Files}
|
||||
|
||||
PPC resource files begin with a PEF container header, after which the
|
||||
resources start.
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
typedef char PefOSType[4];
|
||||
|
||||
struct PEFContainerHeader {
|
||||
PefOSType tag1;
|
||||
PefOSType tag2;
|
||||
PefOSType architecture;
|
||||
uint32 formatVersion;
|
||||
uint32 dateTimeStamp;
|
||||
uint32 oldDefVersion;
|
||||
uint32 oldImpVersion;
|
||||
uint32 currentVersion;
|
||||
uint16 sectionCount;
|
||||
uint16 instSectionCount;
|
||||
uint32 reservedA;
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
const char kPEFFileMagic1[4] = { 'J', 'o', 'y', '!' };
|
||||
const char kPPCResourceFileMagic[4] = { 'r', 'e', 's', 'f' };
|
||||
const uint32 kPPCResourcesOffset = 0x00000028;
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
|
||||
\begin{nitemize}
|
||||
\item{\code{tag1}:
|
||||
Must be \code{kPEFFileMagic1}.}
|
||||
\item{\code{tag2}:
|
||||
Must be \code{kPPCResourceFileMagic}.}
|
||||
\item{All other fields must be set to 0.}
|
||||
\end{nitemize}
|
||||
|
||||
\noindent
|
||||
The resources start at \code{kPPCResourcesOffset}.
|
||||
|
||||
|
||||
\subsection{ELF Object Files}
|
||||
|
||||
In an ELF file, resources are appended to rather than contained in the
|
||||
regular data of the file. That is adding resources to an existing ELF file
|
||||
will not cause any modification to its data (i.e. ELF header, program header
|
||||
table, section header table or sections), but will enlarge the file by some
|
||||
alignment padding and, of course, the resources themselves.
|
||||
|
||||
Therefore two values have to be known: The size of the actual ELF file and the
|
||||
block size to which the resources must be aligned. As ELF files do not contain
|
||||
a size field, it has to be deduced, where the file ends. This end offset is
|
||||
supposed to be the maximum of the end offsets of ELF header, program header
|
||||
table (if any), section header table (if any), sections and segments.
|
||||
|
||||
The block size to which the resources have to be aligned is the maximum of
|
||||
\code{kELFMinResourceAlignment} and the alignments of the segments in the file.
|
||||
%
|
||||
\begin{verbatim}
|
||||
const uint32 kELFMinResourceAlignment = 32;
|
||||
\end{verbatim}
|
||||
%
|
||||
The data used for the padding between the end of the actual ELF data and the
|
||||
beginning of the resources may be arbitrary.
|
||||
|
||||
|
||||
\subsection{PEF Object Files}
|
||||
|
||||
Similar to ELF files the resources are simply appended to the regular data of
|
||||
a PEF file, but they are not aligned to any value. That is the resources
|
||||
start directly after the last PEF section without any padding.
|
||||
As no field exists, that tells about the size of the PEF container (the
|
||||
regular data), it has to be deduced by iterating through the PEF section
|
||||
headers.
|
||||
|
||||
|
||||
|
||||
\section{The Resources Format}
|
||||
\label{resources-format}
|
||||
|
||||
This section describes the resources format. After a subsection that outlines
|
||||
their general layout, it follow subsections discussing the major parts.
|
||||
|
||||
A general remark regarding the byte ordering: Resources have no standard
|
||||
endianess, that is the resources created by little endian and big endian
|
||||
machines differ. Usually it should be possible, to deduce the used endianess
|
||||
from the type of the file. x86 resource files contain little endian, PPC
|
||||
resource files big endian data. The endianess of an ELF file is encoded in
|
||||
its header.
|
||||
|
||||
As there is in fact no good reason to have different resource file formats,
|
||||
even if they differ only in the format of the header (see section
|
||||
\ref{file-formats}), it may be decided to use the x86 resource file format
|
||||
also for big endian machines. Therefore the endianess may be deduced by the
|
||||
first field of the resources header (\code{rh\_resources\_magic}, see
|
||||
subsection \ref{resources-header}).
|
||||
|
||||
|
||||
\subsection{Resources Layout}
|
||||
|
||||
The layout of the resources in a file is shown in figure
|
||||
\ref{fig:resources-layout}.
|
||||
|
||||
\begin{figure}[h!tb]
|
||||
\begin{center}
|
||||
\begin{tabular}{|c|c|c|}
|
||||
\hline
|
||||
& \multicolumn{2}{c|}{resources header}\\
|
||||
\hhline{|~==|}
|
||||
admin section & & index section header \\
|
||||
\hhline{~~|-|}
|
||||
& index section & resource index \\
|
||||
\hhline{~~|-|}
|
||||
& & padding \\
|
||||
\hhline{:===:}
|
||||
\multicolumn{3}{|c|}{unknown section}\\
|
||||
\hhline{:===:}
|
||||
\multicolumn{3}{|c|}{data section}\\
|
||||
\hhline{|~~~|}
|
||||
\hhline{:===:}
|
||||
\multicolumn{3}{|c|}{info section}\\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\end{center}
|
||||
\caption{The Resources Layout.}
|
||||
\label{fig:resources-layout}
|
||||
\end{figure}
|
||||
|
||||
\noindent
|
||||
There are four sections:
|
||||
%
|
||||
\begin{itemize}
|
||||
\item{An administrative section which comprises the resources header and the
|
||||
resource index subsection. The latter locates all other data in the file.
|
||||
}
|
||||
\item{An unknown section, whose purpose is (unsurprisingly) unknown, but which
|
||||
seems to be unused, always containing the same data.
|
||||
}
|
||||
\item{A data section holding the actual resource data.
|
||||
}
|
||||
\item{An info section, which provides aditional information for each resource,
|
||||
such as type, id and name.
|
||||
}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\subsection{Resources Header}
|
||||
\label{resources-header}
|
||||
|
||||
The resources header has the following structure:
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resources_header {
|
||||
uint32 rh_resources_magic;
|
||||
uint32 rh_resource_count;
|
||||
uint32 rh_index_section_offset;
|
||||
uint32 rh_admin_section_size;
|
||||
uint32 rh_pad[13];
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
const uint32 kResourcesHeaderMagic = 0x444f1000;
|
||||
const uint32 kResourceIndexSectionOffset = 0x00000044;
|
||||
const uint32 kResourceIndexSectionAlignment = 0x00000600;
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
|
||||
\begin{nitemize}
|
||||
\item{\code{rh\_resources\_magic}:
|
||||
Must be \code{kResourcesHeaderMagic}.
|
||||
}
|
||||
\item{\code{rh\_resource\_count}:
|
||||
Specifies the number of resources stored in this file. May be 0.
|
||||
}
|
||||
\item{\code{rh\_index\_section\_offset}:
|
||||
Specifies the offset of the resource index section relative to the beginning
|
||||
of the resources. An alternative interpretation may be the size of the
|
||||
resources header.
|
||||
Must be \code{kResourceIndexSectionOffset}.
|
||||
}
|
||||
\item{\code{rh\_admin\_section\_size}:
|
||||
Specifies the size of the administrative section.
|
||||
Must be \code{kResourceIndexSectionOffset} plus a multiple of
|
||||
\code{kResourceIndexSectionAlignment}.
|
||||
}
|
||||
\item{\code{rh\_pad}:
|
||||
Padding. \code{0x00000000} words.
|
||||
}
|
||||
\end{nitemize}
|
||||
|
||||
|
||||
\subsection{Resource Index Section}
|
||||
\label{resources-index}
|
||||
|
||||
The resource index section starts with a header, it follows a table of
|
||||
\code{resource\_index\_entry} structures, that locates the data of each
|
||||
resource, and the section ends with a special padding.
|
||||
|
||||
\noindent
|
||||
The resource index header has the following structure:
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resource_index_section_header {
|
||||
uint32 rish_index_section_offset;
|
||||
uint32 rish_index_section_size;
|
||||
uint32 rish_unused_data1;
|
||||
uint32 rish_unknown_section_offset;
|
||||
uint32 rish_unknown_section_size;
|
||||
uint32 rish_unused_data2[25];
|
||||
uint32 rish_info_table_offset;
|
||||
uint32 rish_info_table_size;
|
||||
uint32 rish_unused_data3;
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
|
||||
\begin{verbatim}
|
||||
const uint32 kUnknownResourceSectionSize = 0x00000168;
|
||||
\end{verbatim}
|
||||
%
|
||||
\begin{nitemize}
|
||||
\item{\code{rish\_index\_section\_offset}:
|
||||
Specifies the offset of the resource index section relative to the beginning
|
||||
of the resources. An alternative interpretation may be the size of the
|
||||
resources header.
|
||||
Must be \code{kResourceIndexSectionOffset}.
|
||||
}
|
||||
\item{\code{rish\_index\_section\_size}:
|
||||
Specifies the size of the resource index section.
|
||||
Must be a multiple of \code{kResourceIndexSectionAlignment}.
|
||||
}
|
||||
\item{\code{rish\_unused\_data1}:
|
||||
Contains special data as described in section \ref{resources-unknown}.
|
||||
}
|
||||
\item{\code{rish\_unknown\_section\_offset}:
|
||||
Specifies the offset of the unknown section relative to the beginning
|
||||
of the resources.
|
||||
Must be the same value as given in the resources header for
|
||||
\code{rh\_admin\_section\_size}.
|
||||
}
|
||||
\item{\code{rish\_unknown\_section\_size}:
|
||||
Specifies the offset of the unknown section relative to the beginning
|
||||
of the resources.
|
||||
Must be \code{kUnknownResourceSectionSize};
|
||||
}
|
||||
\item{\code{rish\_unused\_data2}:
|
||||
Contains special data as described in section \ref{resources-unknown}.
|
||||
}
|
||||
\item{\code{rish\_info\_table\_offset}:
|
||||
Specifies the offset of the resource info table relative to the beginning
|
||||
of the resources.
|
||||
}
|
||||
\item{\code{rish\_info\_table\_size}:
|
||||
Specifies the size of the resource info table.
|
||||
}
|
||||
\item{\code{rish\_unused\_data3}:
|
||||
Contains special data as described in section \ref{resources-unknown}.
|
||||
}
|
||||
\end{nitemize}
|
||||
|
||||
Directly, without padding, it follows a table of \code{resource\_index\_entry}
|
||||
structures. The number of entries in the table is the number of resources
|
||||
stored in the file, that is the value specified by the
|
||||
\code{rh\_resource\_count} member of the resources header. Since the entries
|
||||
are stored without padding, the size of the table is exactly the product of
|
||||
the size of \code{resource\_index\_entry} and the number of resources.
|
||||
If the latter is 0, the table takes no space.
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resource_index_entry {
|
||||
uint32 rie_offset;
|
||||
uint32 rie_size;
|
||||
uint32 rie_pad;
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
\begin{nitemize}
|
||||
\item{\code{rie\_offset}:
|
||||
Specifies the offset of the resource data relative to the beginning
|
||||
of the resources.
|
||||
}
|
||||
\item{\code{rie\_size}:
|
||||
Specifies the size of the resource data.
|
||||
}
|
||||
\item{\code{rie\_pad}:
|
||||
Padding. Must be \code{0x00000000}.
|
||||
}
|
||||
\end{nitemize}
|
||||
|
||||
Since the size of the resource index section must be a multiple of
|
||||
\code{kResourceIndexSectionAlignment}, some padding may be needed at the end
|
||||
of this section. How this padding looks like is described in section
|
||||
\ref{resources-unknown}.
|
||||
|
||||
|
||||
\subsection{Unknown Section}
|
||||
\label{resources-unknown}
|
||||
|
||||
The meaning of this section is unknown. It does not seem to be used at all.
|
||||
It always contains the same data given by \code{kUnusedResourceDataPattern}:
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
const uint32 kUnusedResourceDataPattern[3] = {
|
||||
0xffffffff, 0x000003e9, 0x00000000
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
In section \ref{resources-index} some members where named \code{unused\_data}.
|
||||
These fields contain the same kind of data. To understand what the value for a
|
||||
certain field of this type is, it may help to imagine, that before the
|
||||
resources are written to a file, the space they will take is filled with the
|
||||
pattern specified by \code{kUnusedResourceDataPattern}, and that only those
|
||||
fields are written that are not unused. Thus the original pattern can be seen
|
||||
through at the unused locations.
|
||||
|
||||
To be precise: Let \verb|uint32 resources[]| be the resources and
|
||||
\code{index} the index of an unused field in \code{resources}, then it holds:
|
||||
%
|
||||
\begin{verbatim}
|
||||
resources[index] == kUnusedResourceDataPattern[index % 3];
|
||||
\end{verbatim}
|
||||
%
|
||||
|
||||
|
||||
\subsection{Resource Info Table}
|
||||
\label{resources-infotable}
|
||||
|
||||
The resource info table features exactly one entry for each resource.
|
||||
Such an entry (resource info) specifies the ID and name of a
|
||||
resource. Subsequent infos for resources of the same type are collected in
|
||||
a block that starts with a type field.
|
||||
|
||||
The following grammar specifies the layout of the resource info table.
|
||||
Nonterminals start with an upper case, terminals with a lower case letter.
|
||||
%
|
||||
\begin{verbatim}
|
||||
ResourceInfoTable ::= [ ResourceBlockList ]
|
||||
ResourceInfoSeparator
|
||||
ResourceInfoTableEnd
|
||||
|
||||
ResourceBlockList ::= ResourceBlock
|
||||
[ ResourceInfoSeparator
|
||||
ResourceBlockList ]
|
||||
|
||||
ResourceBlock ::= type ResourceInfoList
|
||||
|
||||
ResourceInfoList ::= ResourceInfo [ ResourceInfoList ]
|
||||
|
||||
ResourceInfo ::= id index name_size name
|
||||
|
||||
ResourceInfoSeparator ::= 0xffffffff 0xffffffff
|
||||
|
||||
ResourceInfoTableEnd ::= check_sum 0x00000000
|
||||
\end{verbatim}
|
||||
%
|
||||
The relevant structures follow:
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resource_info_block {
|
||||
type_code rib_type;
|
||||
resource_info rib_info[1];
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
\begin{nitemize}
|
||||
\item{\code{rib\_type}:
|
||||
Specifies the type of the resources in the block.
|
||||
}
|
||||
\item{\code{rib\_info}:
|
||||
Is the first resource info of the block. More infos may follow.
|
||||
}
|
||||
\end{nitemize}
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resource_info {
|
||||
int32 ri_id;
|
||||
int32 ri_index;
|
||||
uint16 ri_name_size;
|
||||
char ri_name[1];
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
|
||||
\begin{verbatim}
|
||||
const uint32 kMinResourceInfoSize = 10;
|
||||
\end{verbatim}
|
||||
%
|
||||
\begin{nitemize}
|
||||
\item{\code{ri\_id}:
|
||||
Specifies the ID of the resource.
|
||||
}
|
||||
\item{\code{ri\_index}:
|
||||
Specifies the index of the resource this resource info refers to.
|
||||
}
|
||||
\item{\code{ri\_name\_size}:
|
||||
Specifies the size of the resource name. May be 0 -- then the resource does
|
||||
not have a name and \code{ri\_name} has a size of 0.
|
||||
}
|
||||
\item{\code{ri\_name}:
|
||||
Specifies the name of the resource. The name must be null terminated.
|
||||
\code{ri\_name\_size} specifies the size of this field (including the
|
||||
terminating null). If it is 0, the resource does not have a name and
|
||||
\code{ri\_name} is empty, i.e. has size 0.
|
||||
}
|
||||
\item{\code{kMinResourceInfoSize}:
|
||||
Is the minimal size of a resource info. That is the size it has, if the
|
||||
resource does not have a name.
|
||||
}
|
||||
\end{nitemize}
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resource_info_separator {
|
||||
uint32 ris_value1;
|
||||
uint32 ris_value2;
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
\begin{nitemize}
|
||||
\item{\code{ris\_value1}:
|
||||
Specifies the first word of the separator.
|
||||
Must be \code{0xffffffff}.
|
||||
}
|
||||
\item{\code{ris\_value2}:
|
||||
Specifies the second word of the separator.
|
||||
Must be \code{0xffffffff}.
|
||||
}
|
||||
\end{nitemize}
|
||||
%
|
||||
\codeblockbegin
|
||||
\begin{verbatim}
|
||||
struct resource_info_table_end {
|
||||
uint32 rite_check_sum;
|
||||
uint32 rite_terminator;
|
||||
};
|
||||
\end{verbatim}
|
||||
\codeblockend
|
||||
%
|
||||
\begin{nitemize}
|
||||
\item{\code{rite\_check\_sum}:
|
||||
Contains the check sum for the resource info table. The check sum is
|
||||
calculated from all bytes of the resource info table not including
|
||||
\code{rite\_check\_sum} and \code{rite\_terminator}. The data are grouped
|
||||
into four byte blocks, which are interpreted as big endian unsigned words
|
||||
and summed up, ignoring carry. If the number of bytes to be considered is
|
||||
not dividable by four, the remaining bytes are interpreted as the lower
|
||||
bytes of a big endian unsigned word (the upper byte(s) set to 0).
|
||||
}
|
||||
\item{\code{rite\_terminator}:
|
||||
Terminates the resource info table.
|
||||
Must be \code{0x00000000}.
|
||||
}
|
||||
\end{nitemize}
|
||||
|
||||
|
||||
|
||||
\section{Implementations}
|
||||
\label{implementations}
|
||||
|
||||
Code that writes resources should strictly stick to the specification
|
||||
presented in the preceding sections to achieve maximal compatibility.
|
||||
|
||||
Resources reading implementations may tolerate certain deviations that
|
||||
for instance happen to occur in several files of the BeOS R5 distribution
|
||||
and that are handled gracefully by xres and QuickRes. It follows a, possibly
|
||||
incomplete, list:
|
||||
%
|
||||
\begin{itemize}
|
||||
\item{The third and fourth byte of the x86 resource file magic (the 0 bytes)
|
||||
may be arbitrary bytes.}
|
||||
\item{\code{rh\_resource\_count} may be unreliable. The resource index table
|
||||
should be read until its end, which is either marked by the unused data
|
||||
pattern (see section \ref{resources-unknown}) or at the latest by the
|
||||
beginning of the unknown section.}
|
||||
\item{The resource info table may contain entries for indices that are out
|
||||
of range, i.e. greater than the number of resources induced by the resource
|
||||
index table. Those entries should be ignored.}
|
||||
\item{The resource info table may contain multiple entries for an index.
|
||||
Any such entry after the first one should be ignored.}
|
||||
\item{The resource info table may not contain an entry for an index.
|
||||
The respective resource should be ignored.}
|
||||
\item{The resource info table may not contain a \code{ResourceInfoTableEnd}
|
||||
(see section \ref{resources-infotable}) and thus no check sum. The table
|
||||
should be accepted nevertheless. Note, that a table containing a wrong check
|
||||
sum is {\em not} to be accepted.}
|
||||
\end{itemize}
|
||||
|
||||
|
||||
|
||||
\section{Status of this Document}
|
||||
\label{status}
|
||||
|
||||
The information contained in this document are obtained by analyzing
|
||||
resources-containing files created or modified by tools available for BeOS R5,
|
||||
namely QuickRes and xres. They are incomplete and may even be partially wrong,
|
||||
where being based on incorrect assumptions.
|
||||
|
||||
\noindent
|
||||
It follows a list of items with a low degree of reliance:
|
||||
\begin{itemize}
|
||||
\item{Resources alignment in ELF files: Several tests with linker object files
|
||||
have shown, that QuickRes aligns their resources offset to 32 bytes.
|
||||
For executables on the other hand the alignment was always 4096, which is
|
||||
the usual memory page size of current x86 architectures and therefore the
|
||||
preferred program segment alignment. From these two information it has been
|
||||
deduced, that the alignment is, if present, the maximum of
|
||||
the segment alignments to be found in the program header table,
|
||||
but at minimum 32.}
|
||||
\item{The resources layout: The general layout of the resources is not very
|
||||
well understood. The layout presented in figure \ref{fig:resources-layout}
|
||||
resulted from the attempt to assign all the fields a reasonable meaning, but
|
||||
in fact not even the exact length and meaning of the fields of the resources
|
||||
header is unclear. The same holds for the resource index section header.}
|
||||
\item{The unknown section: The contents of the unknown section and of unknown
|
||||
fields is base on educated guesses.}
|
||||
\end{itemize}
|
||||
|
||||
\end{document}
|
||||
@@ -0,0 +1,691 @@
|
||||
# Doxyfile 1.2.1
|
||||
|
||||
# This file describes the settings to be used by doxygen for a project
|
||||
#
|
||||
# All text after a hash (#) is considered a comment and will be ignored
|
||||
# The format is:
|
||||
# TAG = value [value, ...]
|
||||
# For lists items can also be appended using:
|
||||
# TAG += value [value, ...]
|
||||
# Values that contain spaces should be placed between quotes (" ")
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# General configuration options
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
|
||||
# by quotes) that should identify the project.
|
||||
|
||||
PROJECT_NAME = "OpenBeOS Support Kit"
|
||||
|
||||
# The PROJECT_NUMBER tag can be used to enter a project or revision number.
|
||||
# This could be handy for archiving the generated documentation or
|
||||
# if some version control system is used.
|
||||
|
||||
PROJECT_NUMBER =
|
||||
|
||||
# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
|
||||
# base path where the generated documentation will be put.
|
||||
# If a relative path is entered, it will be relative to the location
|
||||
# where doxygen was started. If left blank the current directory will be used.
|
||||
|
||||
OUTPUT_DIRECTORY =
|
||||
|
||||
# The OUTPUT_LANGUAGE tag is used to specify the language in which all
|
||||
# documentation generated by doxygen is written. Doxygen will use this
|
||||
# information to generate all constant output in the proper language.
|
||||
# The default language is English, other supported languages are:
|
||||
# Dutch, French, Italian, Czech, Swedish, German, Finnish, Japanese,
|
||||
# Spanish, Russian, Croatian, Polish, and Portuguese.
|
||||
|
||||
OUTPUT_LANGUAGE = English
|
||||
|
||||
# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
|
||||
# documentation are documented, even if no documentation was available.
|
||||
# Private class members and static file members will be hidden unless
|
||||
# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
|
||||
|
||||
EXTRACT_ALL = NO
|
||||
|
||||
# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_PRIVATE = YES
|
||||
|
||||
# If the EXTRACT_STATIC tag is set to YES all static members of a file
|
||||
# will be included in the documentation.
|
||||
|
||||
EXTRACT_STATIC = YES
|
||||
|
||||
# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
|
||||
# undocumented members of documented classes, files or namespaces.
|
||||
# If set to NO (the default) these members will be included in the
|
||||
# various overviews, but no documentation section is generated.
|
||||
# This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_MEMBERS = NO
|
||||
|
||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
|
||||
# undocumented classes that are normally visible in the class hierarchy.
|
||||
# If set to NO (the default) these class will be included in the various
|
||||
# overviews. This option has no effect if EXTRACT_ALL is enabled.
|
||||
|
||||
HIDE_UNDOC_CLASSES = NO
|
||||
|
||||
# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
|
||||
# include brief member descriptions after the members that are listed in
|
||||
# the file and class documentation (similar to JavaDoc).
|
||||
# Set to NO to disable this.
|
||||
|
||||
BRIEF_MEMBER_DESC = YES
|
||||
|
||||
# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
|
||||
# the brief description of a member or function before the detailed description.
|
||||
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
|
||||
# brief descriptions will be completely suppressed.
|
||||
|
||||
REPEAT_BRIEF = YES
|
||||
|
||||
# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
|
||||
# Doxygen will generate a detailed section even if there is only a brief
|
||||
# description.
|
||||
|
||||
ALWAYS_DETAILED_SEC = NO
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
|
||||
# path before files name in the file list and in the header files. If set
|
||||
# to NO the shortest path that makes the file name unique will be used.
|
||||
|
||||
FULL_PATH_NAMES = YES
|
||||
|
||||
# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
|
||||
# can be used to strip a user defined part of the path. Stripping is
|
||||
# only done if one of the specified strings matches the left-hand part of
|
||||
# the path. It is allowed to use relative paths in the argument list.
|
||||
|
||||
STRIP_FROM_PATH = /cvsroot/open-beos/current
|
||||
|
||||
# The INTERNAL_DOCS tag determines if documentation
|
||||
# that is typed after a \internal command is included. If the tag is set
|
||||
# to NO (the default) then the documentation will be excluded.
|
||||
# Set it to YES to include the internal documentation.
|
||||
|
||||
INTERNAL_DOCS = NO
|
||||
|
||||
# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
|
||||
# generate a class diagram (in Html and LaTeX) for classes with base or
|
||||
# super classes. Setting the tag to NO turns the diagrams off.
|
||||
|
||||
CLASS_DIAGRAMS = YES
|
||||
|
||||
# If the SOURCE_BROWSER tag is set to YES then a list of source files will
|
||||
# be generated. Documented entities will be cross-referenced with these sources.
|
||||
|
||||
SOURCE_BROWSER = YES
|
||||
|
||||
# Setting the INLINE_SOURCES tag to YES will include the body
|
||||
# of functions and classes directly in the documentation.
|
||||
|
||||
INLINE_SOURCES = NO
|
||||
|
||||
# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
|
||||
# doxygen to hide any special comment blocks from generated source code
|
||||
# fragments. Normal C and C++ comments will always remain visible.
|
||||
|
||||
STRIP_CODE_COMMENTS = YES
|
||||
|
||||
# If the CASE_SENSE_NAMES tag is set to NO (the default) then Doxygen
|
||||
# will only generate file names in lower case letters. If set to
|
||||
# YES upper case letters are also allowed. This is useful if you have
|
||||
# classes or files whose names only differ in case and if your file system
|
||||
# supports case sensitive file names.
|
||||
|
||||
CASE_SENSE_NAMES = YES
|
||||
|
||||
# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
|
||||
# will show members with their full class and namespace scopes in the
|
||||
# documentation. If set to YES the scope will be hidden.
|
||||
|
||||
HIDE_SCOPE_NAMES = NO
|
||||
|
||||
# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
|
||||
# will generate a verbatim copy of the header file for each class for
|
||||
# which an include is specified. Set to NO to disable this.
|
||||
|
||||
VERBATIM_HEADERS = YES
|
||||
|
||||
# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
|
||||
# will put list of the files that are included by a file in the documentation
|
||||
# of that file.
|
||||
|
||||
SHOW_INCLUDE_FILES = YES
|
||||
|
||||
# If the JAVADOC_AUTOBRIEF tag is set to YES (the default) then Doxygen
|
||||
# will interpret the first line (until the first dot) of a JavaDoc-style
|
||||
# comment as the brief description. If set to NO, the Javadoc-style will
|
||||
# behave just like the Qt-style comments.
|
||||
|
||||
JAVADOC_AUTOBRIEF = YES
|
||||
|
||||
# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
|
||||
# member inherits the documentation from any documented member that it
|
||||
# reimplements.
|
||||
|
||||
INHERIT_DOCS = YES
|
||||
|
||||
# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
|
||||
# is inserted in the documentation for inline members.
|
||||
|
||||
INLINE_INFO = YES
|
||||
|
||||
# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
|
||||
# will sort the (detailed) documentation of file and class members
|
||||
# alphabetically by member name. If set to NO the members will appear in
|
||||
# declaration order.
|
||||
|
||||
SORT_MEMBER_DOCS = YES
|
||||
|
||||
# The TAB_SIZE tag can be used to set the number of spaces in a tab.
|
||||
# Doxygen uses this value to replace tabs by spaces in code fragments.
|
||||
|
||||
TAB_SIZE = 4
|
||||
|
||||
# The ENABLE_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
||||
ENABLED_SECTIONS =
|
||||
|
||||
# The GENERATE_TODOLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the todo list. This list is created by putting \todo
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_TODOLIST = YES
|
||||
|
||||
# The GENERATE_TESTLIST tag can be used to enable (YES) or
|
||||
# disable (NO) the test list. This list is created by putting \test
|
||||
# commands in the documentation.
|
||||
|
||||
GENERATE_TESTLIST = YES
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to warning and progress messages
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The QUIET tag can be used to turn on/off the messages that are generated
|
||||
# by doxygen. Possible values are YES and NO. If left blank NO is used.
|
||||
|
||||
QUIET = NO
|
||||
|
||||
# The WARNINGS tag can be used to turn on/off the warning messages that are
|
||||
# generated by doxygen. Possible values are YES and NO. If left blank
|
||||
# NO is used.
|
||||
|
||||
WARNINGS = YES
|
||||
|
||||
# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
|
||||
# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
|
||||
# automatically be disabled.
|
||||
|
||||
WARN_IF_UNDOCUMENTED = YES
|
||||
|
||||
# The WARN_FORMAT tag determines the format of the warning messages that
|
||||
# doxygen can produce. The string should contain the $file, $line, and $text
|
||||
# tags, which will be replaced by the file and line number from which the
|
||||
# warning originated and the warning text.
|
||||
|
||||
WARN_FORMAT = "$file:$line: $text"
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the input files
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The INPUT tag can be used to specify the files and/or directories that contain
|
||||
# documented source files. You may enter file names like "myfile.cpp" or
|
||||
# directories like "/usr/src/myproject". Separate the files or directories
|
||||
# with spaces.
|
||||
|
||||
INPUT = ../../../src/kits/support ../../../headers/os/support
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank all files are included.
|
||||
|
||||
FILE_PATTERNS = *.cpp *.h
|
||||
|
||||
# The RECURSIVE tag can be used to turn specify whether or not subdirectories
|
||||
# should be searched for input files as well. Possible values are YES and NO.
|
||||
# If left blank NO is used.
|
||||
|
||||
RECURSIVE = YES
|
||||
|
||||
# The EXCLUDE tag can be used to specify files and/or directories that should
|
||||
# excluded from the INPUT source files. This way you can easily exclude a
|
||||
# subdirectory from a directory tree whose root is specified with the INPUT tag.
|
||||
|
||||
EXCLUDE =
|
||||
|
||||
# If the value of the INPUT tag contains directories, you can use the
|
||||
# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
|
||||
# certain files from those directories.
|
||||
|
||||
EXCLUDE_PATTERNS =
|
||||
|
||||
# The EXAMPLE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain example code fragments that are included (see
|
||||
# the \include command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
|
||||
# and *.h) to filter out the source-files in the directories. If left
|
||||
# blank all files are included.
|
||||
|
||||
EXAMPLE_PATTERNS =
|
||||
|
||||
# The IMAGE_PATH tag can be used to specify one or more files or
|
||||
# directories that contain image that are included in the documentation (see
|
||||
# the \image command).
|
||||
|
||||
IMAGE_PATH =
|
||||
|
||||
# The INPUT_FILTER tag can be used to specify a program that doxygen should
|
||||
# invoke to filter for each input file. Doxygen will invoke the filter program
|
||||
# by executing (via popen()) the command <filter> <input-file>, where <filter>
|
||||
# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
|
||||
# input file. Doxygen will then use the output that the filter program writes
|
||||
# to standard output.
|
||||
|
||||
INPUT_FILTER =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the alphabetical class index
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
|
||||
# of all compounds will be generated. Enable this if the project
|
||||
# contains a lot of classes, structs, unions or interfaces.
|
||||
|
||||
ALPHABETICAL_INDEX = NO
|
||||
|
||||
# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
|
||||
# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
|
||||
# in which this list will be split (can be a number in the range [1..20])
|
||||
|
||||
COLS_IN_ALPHA_INDEX = 5
|
||||
|
||||
# In case all classes in a project start with a common prefix, all
|
||||
# classes will be put under the same header in the alphabetical index.
|
||||
# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
|
||||
# should be ignored while generating the index headers.
|
||||
|
||||
IGNORE_PREFIX =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the HTML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
|
||||
# generate HTML output.
|
||||
|
||||
GENERATE_HTML = YES
|
||||
|
||||
# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `html' will be used as the default path.
|
||||
|
||||
HTML_OUTPUT = html
|
||||
|
||||
# The HTML_HEADER tag can be used to specify a personal HTML header for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard header.
|
||||
|
||||
HTML_HEADER =
|
||||
|
||||
# The HTML_FOOTER tag can be used to specify a personal HTML footer for
|
||||
# each generated HTML page. If it is left blank doxygen will generate a
|
||||
# standard footer.
|
||||
|
||||
HTML_FOOTER =
|
||||
|
||||
# The HTML_STYLESHEET tag can be used to specify a user defined cascading
|
||||
# style sheet that is used by each HTML page. It can be used to
|
||||
# fine-tune the look of the HTML output. If the tag is left blank doxygen
|
||||
# will generate a default style sheet
|
||||
|
||||
HTML_STYLESHEET =
|
||||
|
||||
# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
|
||||
# files or namespaces will be aligned in HTML using tables. If set to
|
||||
# NO a bullet list will be used.
|
||||
|
||||
HTML_ALIGN_MEMBERS = YES
|
||||
|
||||
# If the GENERATE_HTMLHELP tag is set to YES, additional index files
|
||||
# will be generated that can be used as input for tools like the
|
||||
# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
|
||||
# of the generated HTML documentation.
|
||||
|
||||
GENERATE_HTMLHELP = NO
|
||||
|
||||
# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
|
||||
# top of each HTML page. The value NO (the default) enables the index and
|
||||
# the value YES disables it.
|
||||
|
||||
DISABLE_INDEX = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the LaTeX output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
|
||||
# generate Latex output.
|
||||
|
||||
GENERATE_LATEX = NO
|
||||
|
||||
# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `latex' will be used as the default path.
|
||||
|
||||
LATEX_OUTPUT = latex
|
||||
|
||||
# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
|
||||
# LaTeX documents. This may be useful for small projects and may help to
|
||||
# save some trees in general.
|
||||
|
||||
COMPACT_LATEX = NO
|
||||
|
||||
# The PAPER_TYPE tag can be used to set the paper type that is used
|
||||
# by the printer. Possible values are: a4, a4wide, letter, legal and
|
||||
# executive. If left blank a4wide will be used.
|
||||
|
||||
PAPER_TYPE = a4wide
|
||||
|
||||
# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
|
||||
# packages that should be included in the LaTeX output.
|
||||
|
||||
EXTRA_PACKAGES =
|
||||
|
||||
# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
|
||||
# the generated latex document. The header should contain everything until
|
||||
# the first chapter. If it is left blank doxygen will generate a
|
||||
# standard header. Notice: only use this tag if you know what you are doing!
|
||||
|
||||
LATEX_HEADER =
|
||||
|
||||
# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
|
||||
# is prepared for conversion to pdf (using ps2pdf). The pdf file will
|
||||
# contain links (just like the HTML output) instead of page references
|
||||
# This makes the output suitable for online browsing using a pdf viewer.
|
||||
|
||||
PDF_HYPERLINKS = NO
|
||||
|
||||
# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
|
||||
# plain latex in the generated Makefile. Set this option to YES to get a
|
||||
# higher quality PDF documentation.
|
||||
|
||||
USE_PDFLATEX = NO
|
||||
|
||||
# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
|
||||
# command to the generated LaTeX files. This will instruct LaTeX to keep
|
||||
# running if errors occur, instead of asking the user for help.
|
||||
# This option is also used when generating formulas in HTML.
|
||||
|
||||
LATEX_BATCHMODE = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the RTF output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
|
||||
# The RTF output is optimised for Word 97 and may not look very pretty with
|
||||
# other RTF readers or editors.
|
||||
|
||||
GENERATE_RTF = NO
|
||||
|
||||
# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `rtf' will be used as the default path.
|
||||
|
||||
RTF_OUTPUT = rtf
|
||||
|
||||
# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
|
||||
# RTF documents. This may be useful for small projects and may help to
|
||||
# save some trees in general.
|
||||
|
||||
COMPACT_RTF = NO
|
||||
|
||||
# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
|
||||
# will contain hyperlink fields. The RTF file will
|
||||
# contain links (just like the HTML output) instead of page references.
|
||||
# This makes the output suitable for online browsing using a WORD or other.
|
||||
# programs which support those fields.
|
||||
# Note: wordpad (write) and others do not support links.
|
||||
|
||||
RTF_HYPERLINKS = NO
|
||||
|
||||
# Load stylesheet definitions from file. Syntax is similar to doxygen's
|
||||
# config file, i.e. a series of assigments. You only have to provide
|
||||
# replacements, missing definitions are set to their default value.
|
||||
|
||||
RTF_STYLESHEET_FILE =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the man page output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
|
||||
# generate man pages
|
||||
|
||||
GENERATE_MAN = NO
|
||||
|
||||
# The MAN_OUTPUT tag is used to specify where the man pages will be put.
|
||||
# If a relative path is entered the value of OUTPUT_DIRECTORY will be
|
||||
# put in front of it. If left blank `man' will be used as the default path.
|
||||
|
||||
MAN_OUTPUT = man
|
||||
|
||||
# The MAN_EXTENSION tag determines the extension that is added to
|
||||
# the generated man pages (default is the subroutine's section .3)
|
||||
|
||||
MAN_EXTENSION = .3
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# configuration options related to the XML output
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the GENERATE_XML tag is set to YES Doxygen will
|
||||
# generate an XML file that captures the structure of
|
||||
# the code including all documentation. Warning: This feature
|
||||
# is still experimental and very incomplete.
|
||||
|
||||
GENERATE_XML = NO
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the preprocessor
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
|
||||
# evaluate all C-preprocessor directives found in the sources and include
|
||||
# files.
|
||||
|
||||
ENABLE_PREPROCESSING = YES
|
||||
|
||||
# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
|
||||
# names in the source code. If set to NO (the default) only conditional
|
||||
# compilation will be performed. Macro expansion can be done in a controlled
|
||||
# way by setting EXPAND_ONLY_PREDEF to YES.
|
||||
|
||||
MACRO_EXPANSION = NO
|
||||
|
||||
# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
|
||||
# then the macro expansion is limited to the macros specified with the
|
||||
# PREDEFINED and EXPAND_AS_PREDEFINED tags.
|
||||
|
||||
EXPAND_ONLY_PREDEF = NO
|
||||
|
||||
# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
|
||||
# in the INCLUDE_PATH (see below) will be search if a #include is found.
|
||||
|
||||
SEARCH_INCLUDES = YES
|
||||
|
||||
# The INCLUDE_PATH tag can be used to specify one or more directories that
|
||||
# contain include files that are not input files but should be processed by
|
||||
# the preprocessor.
|
||||
|
||||
INCLUDE_PATH =
|
||||
|
||||
# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
|
||||
# patterns (like *.h and *.hpp) to filter out the header-files in the
|
||||
# directories. If left blank, the patterns specified with FILE_PATTERNS will
|
||||
# be used.
|
||||
|
||||
INCLUDE_FILE_PATTERNS =
|
||||
|
||||
# The PREDEFINED tag can be used to specify one or more macro names that
|
||||
# are defined before the preprocessor is started (similar to the -D option of
|
||||
# gcc). The argument of the tag is a list of macros of the form: name
|
||||
# or name=definition (no spaces). If the definition and the = are
|
||||
# omitted =1 is assumed.
|
||||
|
||||
PREDEFINED =
|
||||
|
||||
# If the MACRO_EXPANSION and EXPAND_PREDEF_ONLY tags are set to YES then
|
||||
# this tag can be used to specify a list of macro names that should be expanded.
|
||||
# The macro definition that is found in the sources will be used.
|
||||
# Use the PREDEFINED tag if you want to use a different macro definition.
|
||||
|
||||
EXPAND_AS_DEFINED =
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to external references
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The TAGFILES tag can be used to specify one or more tagfiles.
|
||||
|
||||
TAGFILES =
|
||||
|
||||
# When a file name is specified after GENERATE_TAGFILE, doxygen will create
|
||||
# a tag file that is based on the input files it reads.
|
||||
|
||||
GENERATE_TAGFILE =
|
||||
|
||||
# If the ALLEXTERNALS tag is set to YES all external classes will be listed
|
||||
# in the class index. If set to NO only the inherited external classes
|
||||
# will be listed.
|
||||
|
||||
ALLEXTERNALS = NO
|
||||
|
||||
# The PERL_PATH should be the absolute path and name of the perl script
|
||||
# interpreter (i.e. the result of `which perl').
|
||||
|
||||
PERL_PATH = /usr/bin/perl
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration options related to the dot tool
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
|
||||
# available from the path. This tool is part of Graphviz, a graph visualization
|
||||
# toolkit from AT&T and Lucent Bell Labs. The other options in this section
|
||||
# have no effect if this option is set to NO (the default)
|
||||
|
||||
HAVE_DOT = NO
|
||||
|
||||
# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
# indirect inheritance relations. Setting this tag to YES will force the
|
||||
# the CLASS_DIAGRAMS tag to NO.
|
||||
|
||||
CLASS_GRAPH = YES
|
||||
|
||||
# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
|
||||
# will generate a graph for each documented class showing the direct and
|
||||
# indirect implementation dependencies (inheritance, containment, and
|
||||
# class references variables) of the class with other documented classes.
|
||||
|
||||
COLLABORATION_GRAPH = YES
|
||||
|
||||
# If the ENABLE_PREPROCESSING, INCLUDE_GRAPH, and HAVE_DOT tags are set to
|
||||
# YES then doxygen will generate a graph for each documented file showing
|
||||
# the direct and indirect include dependencies of the file with other
|
||||
# documented files.
|
||||
|
||||
INCLUDE_GRAPH = YES
|
||||
|
||||
# If the ENABLE_PREPROCESSING, INCLUDED_BY_GRAPH, and HAVE_DOT tags are set to
|
||||
# YES then doxygen will generate a graph for each documented header file showing
|
||||
# the documented files that directly or indirectly include this file
|
||||
|
||||
INCLUDED_BY_GRAPH = YES
|
||||
|
||||
# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
|
||||
# will graphical hierarchy of all classes instead of a textual one.
|
||||
|
||||
GRAPHICAL_HIERARCHY = YES
|
||||
|
||||
# The tag DOT_PATH can be used to specify the path where the dot tool can be
|
||||
# found. If left blank, it is assumed the dot tool can be found on the path.
|
||||
|
||||
DOT_PATH =
|
||||
|
||||
# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_WIDTH = 1024
|
||||
|
||||
# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height
|
||||
# (in pixels) of the graphs generated by dot. If a graph becomes larger than
|
||||
# this value, doxygen will try to truncate the graph, so that it fits within
|
||||
# the specified constraint. Beware that most browsers cannot cope with very
|
||||
# large images.
|
||||
|
||||
MAX_DOT_GRAPH_HEIGHT = 1024
|
||||
|
||||
#---------------------------------------------------------------------------
|
||||
# Configuration::addtions related to the search engine
|
||||
#---------------------------------------------------------------------------
|
||||
|
||||
# The SEARCHENGINE tag specifies whether or not a search engine should be
|
||||
# used. If set to NO the values of all tags below this one will be ignored.
|
||||
|
||||
SEARCHENGINE = NO
|
||||
|
||||
# The CGI_NAME tag should be the name of the CGI script that
|
||||
# starts the search engine (doxysearch) with the correct parameters.
|
||||
# A script with this name will be generated by doxygen.
|
||||
|
||||
CGI_NAME = search.cgi
|
||||
|
||||
# The CGI_URL tag should be the absolute URL to the directory where the
|
||||
# cgi binaries are located. See the documentation of your http daemon for
|
||||
# details.
|
||||
|
||||
CGI_URL =
|
||||
|
||||
# The DOC_URL tag should be the absolute URL to the directory where the
|
||||
# documentation is located. If left blank the absolute path to the
|
||||
# documentation, with file:// prepended to it, will be used.
|
||||
|
||||
DOC_URL =
|
||||
|
||||
# The DOC_ABSPATH tag should be the absolute path to the directory where the
|
||||
# documentation is located. If left blank the directory on the local machine
|
||||
# will be used.
|
||||
|
||||
DOC_ABSPATH =
|
||||
|
||||
# The BIN_ABSPATH tag must point to the directory where the doxysearch binary
|
||||
# is installed.
|
||||
|
||||
BIN_ABSPATH = /usr/local/bin/
|
||||
|
||||
# The EXT_DOC_PATHS tag can be used to specify one or more paths to
|
||||
# documentation generated for other projects. This allows doxysearch to search
|
||||
# the documentation for these projects as well.
|
||||
|
||||
EXT_DOC_PATHS =
|
||||
@@ -0,0 +1,79 @@
|
||||
<HTML>
|
||||
<!-- $Id: BAutolockUseCases.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
|
||||
<HEAD>
|
||||
<TITLE>BAutolock 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>BAutolock Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BAutolock interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BAutolock Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BAutolock Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BAutolock Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BAutolock Interface:</H2>
|
||||
|
||||
<P>The BAutolock class is a simple class for handling synchronization between threads. The best
|
||||
source of information for the BAutolock interface can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/Autolock.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BAutolock Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BAutolock functionality:</P>
|
||||
|
||||
<OL>
|
||||
<LI><P><B>Construction 1:</B> A BAutolock can be created by passing a pointer to a BLocker object.
|
||||
An attempt will be made to Lock() this BLocker during the construction of the BAutolock object.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Construction 2:</B> A BAutolock can be created by passing a reference to a BLocker object.
|
||||
An attempt will be made to Lock() this BLocker during the construction of the BAutolock object.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Construction 3:</B> A BAutolock can be created by passing a pointer to a BLooper object.
|
||||
An attempt will be made to Lock() this BLooper during the construction of the BAutolock object.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Is Locked:</B> When the BAutolock is constructed, a lock is attempted on the BLocker or
|
||||
BLooper passed in. The result of that lock attempt is returned by calling IsLocked() on the
|
||||
BAutolock. The result is a boolean. True is returned if the lock was successfully acquired.
|
||||
False is returned if the lock could not be acquired. See the docs for BLocker and BLooper to
|
||||
find out why the lock acquisition may fail.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction 1:</B> If the lock acquisition on the BLocker or BLooper was successful at
|
||||
construction time, when the BAutolock is destructed, the lock will be released by calling Unlock()
|
||||
on the BLocker or BLooper.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction 2:</B> If the lock acquisition on the BLocker or BLooper failed at
|
||||
construction time, when the BAutolock is destructed, nothing is done to the BLocker or the BLooper.
|
||||
An Unlock() is not attempted because the lock at construction time failed.</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BAutolock Implementation:</H2>
|
||||
|
||||
<P>The entire BAutolock implementation is inline. Because BAutolock is implemented inline, there
|
||||
is no code for BAutolock in libbe.so. The code is all in Be's Autolock.h header file and compiled
|
||||
at build time directly into any object being built.</P>
|
||||
|
||||
<P>This has some interesting implications from a backwards compatibility perspective. Because
|
||||
there are no references from existing non-Be executables and libraries to libbe.so expecting
|
||||
to find the BAutolock class, the entire definition of BAutolock can be changed almost without risk
|
||||
of breaking compatibility. This gives anyone wishing to expand and build on the current BAutolock
|
||||
class a great deal of flexibility.</P>
|
||||
|
||||
<P>However, it may be worthwhile when changing BAutolock in the future to try and stay source
|
||||
compatible. That way, existing source code will continue to compile without having to update
|
||||
it.</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,130 @@
|
||||
<HTML>
|
||||
<!-- $Id: BLockerUseCases.html 10 2002-07-09 12:24:59Z ejakowatz $ -->
|
||||
<HEAD>
|
||||
<TITLE>BLocker 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>BLocker Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BLocker interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BLocker Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BLocker Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BLocker Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BLocker Interface:</H2>
|
||||
|
||||
<P>The BLocker class is a simple class for handling synchronization between threads. The best
|
||||
source of information for the BLocker interface can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/Locker.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BLocker Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BLocker functionality:</P>
|
||||
|
||||
<OL>
|
||||
<LI><P><B>Construction 1:</B> A BLocker can be created by specifying a name for the semaphore used
|
||||
internally. If a name is specified during construction, then that name is given to the internal
|
||||
semaphore. If no name is given at construction, the semaphore is given the name "some BLocker".
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Construction 2:</B> A BLocker can use a semaphore or a "benaphore" internally depending
|
||||
on a flag passed when the BLocker is created. If the flag is false, the BLocker uses a semaphore
|
||||
to do synchronization. If the flag is true, the BLocker uses a benaphore internally to do
|
||||
synchronization. If no flag is specified, the BLocker uses a benaphore internally.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> When a BLocker is destructed, any threads waiting for the lock are
|
||||
immediately unblocked. The threads are notified by the return code of the locking member function
|
||||
that the lock was not successfully acquired. Any threads blocked on Lock() will return with
|
||||
a false value. Any threads blocked on LockWithTimeout() will return with B_BAD_SEM_ID.</P></LI>
|
||||
|
||||
<LI><P><B>Locking 1:</B> When a thread acquires the BLocker using the Lock() or LockWithTimeout()
|
||||
member functions, no other thread can acquire the lock until this thread releases it.</P></LI>
|
||||
|
||||
<LI><P><B>Locking 2:</B> When a thread holds the BLocker and it calls Lock() or LockWithTimeout(),
|
||||
the member function returns immediately. The thread must call Unlock() the same number of times
|
||||
it calls Lock...() before the BLocker is released. At any time, the thread can call CountLocks()
|
||||
to get the number of times it must call Unlock() to release the BLocker.</P></LI>
|
||||
|
||||
<LI><P><B>Locking 3:</B> When a thread calls Lock(), the thread blocks until it can acquire the
|
||||
lock. Once the lock has been acquired or an unrecoverable error has occurred, the Lock() member
|
||||
function completes. If the lock has been acquired, Lock() returns true. If the lock has not
|
||||
been acquired, Lock() returns false.</P></LI>
|
||||
|
||||
<LI><P><B>Locking 4:</B> When a thread calls LockWithTimeout(), the thread blocks until it can
|
||||
acquire the lock, the time specified in microseconds expires, or an unrecoverable error occurs.
|
||||
If the timeout specified is B_INFINTE_TIMEOUT, there is no timeout and the member function will
|
||||
either acquire the lock or fail due to an unrecoverable error. If the lock is acquired, the
|
||||
member function returns B_OK. If the timeout is reached, B_TIMED_OUT is returned and the lock is
|
||||
not acquired. If a serious error occurs, a non B_OK code is returned.</P></LI>
|
||||
|
||||
<LI><P><B>Unlocking:</B> The Unlock() member function takes no arguments and returns no value.
|
||||
If the thread currently holds the lock, the lock count is reduced by the call to Unlock(). If
|
||||
the lock count reaches zero, then another thread may acquire the lock. If the thread does not
|
||||
hold the lock and it calls Unlock(), the call will have no affect at all on the BLocker.</P></LI>
|
||||
|
||||
<LI><P><B>Locking Thread:</B> The LockingThread() member function returns the thread_id of the
|
||||
thread that is holding the lock. If no thread holds the lock, then B_ERROR is returned.</P></LI>
|
||||
|
||||
<LI><P><B>Is Locked:</B> The IsLocked() member function returns true if the BLocker is currently
|
||||
held by the calling thread. If the BLocker is not acquired by any thread or it is acquired by a
|
||||
different thread, IsLocked() returns false.</P></LI>
|
||||
|
||||
<LI><P><B>Count Locks:</B> The CountLocks() member function returns the number of times the lock
|
||||
has been acquired by the thread which holds the lock. If no thread holds the lock, then 0 is
|
||||
returned. If the BLocker is held by any thread, including a thread which is not the thread
|
||||
making the CountLocks() request, the number of times the lock has been acquired by the thread which
|
||||
holds the lock is returned.</P></LI>
|
||||
|
||||
<LI><P><B>Count Lock Requests:</B> The CountLockRequests() member function returns the number of
|
||||
threads currently attempting to lock the BLocker. If no thread holds the lock and no thread is
|
||||
waiting for the lock, then 0 is returned. If one thread holds the lock and no other threads
|
||||
are waiting for the lock, then 1 is returned. If one thread holds the lock and x threads are
|
||||
waiting for the lock, then x+1 is returned. The call to CountLockRequests() can be made by any
|
||||
thread including threads which do not have the lock.</P>
|
||||
|
||||
<P><B>NOTE:</B> Reading the Be Book, that would seem like what is returned by this member
|
||||
function. In actuality, the value returned is just the "benaphore count" for the BLocker.
|
||||
If the BLocker is semaphore style, then the benaphore count is set to 1 at construction time
|
||||
to ensure that the semaphore is always tested when a lock is acquired. The return value is
|
||||
just this count. So, the return value for benaphore style is:</P>
|
||||
|
||||
<PRE>
|
||||
numThreadsWaitingForTheLock + numThreadsHoldingTheLock + numOfTimeoutsOccuredOnTheLock
|
||||
</PRE>
|
||||
|
||||
<P>The return value for a semaphore style is:</P>
|
||||
|
||||
<PRE>
|
||||
numThreadsWaitingForTheLock + numThreadsHoldingTheLock + numOfTimeoutsOccuredOnTheLock + 1
|
||||
</PRE>
|
||||
|
||||
<P>Again, this is what we are implementing but the above description is what appears in the
|
||||
BeBook as far as I understand it.</P>
|
||||
</LI>
|
||||
|
||||
<LI><P><B>Sem:</B> The Sem() member function returns the sem_id of the semaphore used by the
|
||||
BLocker. If the BLocker is a benaphore, then the sem_id returned is the semaphore used to
|
||||
implement the benaphore. If the BLocker is a not a benaphore, then the sem_id returned is the
|
||||
semaphore which the BLocker represents.</P></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BLocker Implementation:</H2>
|
||||
|
||||
<P>For more information about how to implement a benaphore, you can reference an implementation
|
||||
found on Be's website at
|
||||
|
||||
<A HREF="http://www-classic.be.com/aboutbe/benewsletter/Issue26.html">http://www-classic.be.com/aboutbe/benewsletter/Issue26.html</A>.</P>
|
||||
|
||||
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,104 @@
|
||||
<!-- saved from url=(0022)http://internet.e-mail -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>BMallocIO 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>BMallocIO Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BMallocIO interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BMallocIO Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BMallocIO Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BMallocIO Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BMallocIO Interface:</H2>
|
||||
|
||||
<P>The BMallocIO class represent a buffer of dynamically allocated memory. The buffer is
|
||||
automatically allocated by multiplies of a blocksize you can specify, so it will always be
|
||||
big enough to contain the data. The best source of information for the BMallocIO interface
|
||||
can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/MemoryIO.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BMallocIO Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BMallocIO functionality:</P>
|
||||
|
||||
<OL>
|
||||
|
||||
<LI><P><B>Construction 1:</B> The BMallocIO constructor set the blocksize to 256.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> The BMallocIO destructor frees the allocated memory.</P></LI>
|
||||
|
||||
<LI><P><B>Reading 1:</B> When ReadAt() is called, the BMallocIO returns the number of bytes read from the specified
|
||||
position. ReadAt() takes three arguments: the position where to begin the read operation, the buffer where to put the read data,
|
||||
and the number of bytes to read. This function does not read outside of the buffer.
|
||||
If the specified position is invalid (i.e. outside bounds) this function returns 0. If the read operation
|
||||
begins at a valid position, but the sum of position and bytes to read is bigger than the size of the buffer, BMallocIO
|
||||
returns just the available data.</P></LI>
|
||||
|
||||
<LI><P><B>Reading 2.</B> BMallocIO inherits the Read() function from BPositionIO. This function read the specified amount
|
||||
of data from the current position, and put it into the specified buffer, then it moves the I/O index forward of the number of read bytes.
|
||||
This function behaves like the above. </P></LI>
|
||||
|
||||
<LI><P><B>Writing 1:</B> When WriteAt() is called, BMallocIO returns the number of bytes written to the specified position.
|
||||
WriteAt() takes three arguments: the position where to begin the write operation, the buffer from which to read the data to write, and the
|
||||
number of bytes to write.
|
||||
If the write position is beyond the buffer length, BMallocIO enlarges the buffer to accomodate the data. If enlarging fails, the function
|
||||
returns B_NO_MEMORY.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Writing 2.</B> BMallocIO inherits the Write() function from BPositionIO. This function write the specified amount
|
||||
of data to the current position of the BMallocIO object, reading from the specified buffer, then it moves the I/O index forward
|
||||
of the number of read bytes.
|
||||
This function behaves like the above. </P></LI>
|
||||
|
||||
<LI><P><B>Size Changes:</B> The SetSize() member function enlarges or shrink the amount of data which can be read/write.
|
||||
Shrinking the buffer is always possible, and the function returns B_OK. Zero frees the memory, while negative values are
|
||||
not allowed, and the function returns B_ERROR.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Seeking.</B> Seek() sets the position in the data buffer where the Read() and Write() functions (inherited from
|
||||
BPositionIO) begin reading and writing. How the position argument is understood depends on the mode flag. There are three possible modes:
|
||||
<UL>
|
||||
<LI><P>
|
||||
SEEK_SET. The position passed is an offset from the beginning of allocated memory; in other
|
||||
words, the current position is set to position. For this mode, position should be a positive
|
||||
value.
|
||||
</P></LI>
|
||||
<LI><P>
|
||||
SEEK_CUR. The position argument is an offset from the current position; the value of the
|
||||
argument is added to the current position. </P></LI>
|
||||
<LI><P>
|
||||
SEEK_END. The position argument is an offset from the end of the buffer for a BMallocIO
|
||||
object. Positive values seek beyond the end of the buffer or data; negative
|
||||
values seek backwards into the data. </P></LI>
|
||||
</UL>
|
||||
Seek() Always return the new position.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Position:</B> The Position() call always return the current position.</P></LI>
|
||||
|
||||
<LI><P><B>Setting the BlockSize:</B> The SetBlockSize() call let you specify
|
||||
the blocksize which BMallocIO uses to allocate memory.</P></LI>
|
||||
|
||||
<LI><P><B>Getting the Buffer:</B> The Buffer() call returns the buffer used internally
|
||||
by BMallocIO.</P></LI>
|
||||
|
||||
<LI><P><B>Getting the Buffer Lenght:</B> The BufferLength() call returns the length
|
||||
of the buffer.</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BMallocIO Implementation:</H2>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,106 @@
|
||||
<!-- saved from url=(0022)http://internet.e-mail -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>BMemoryIO 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>BMemoryIO Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BMemoryIO interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BMemoryIO Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BMemoryIO Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BMemoryIO Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BMemoryIO Interface:</H2>
|
||||
|
||||
<P>The BMemoryIO class represent a buffer of dynamically allocated memory. You assign the
|
||||
buffer to a BMemoryIO object on construction. The best source of information for the BMemoryIO interface
|
||||
can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/MemoryIO.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BMemoryIO Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BMemoryIO functionality:</P>
|
||||
|
||||
<OL>
|
||||
|
||||
<LI><P><B>Construction 1:</B> A BMemoryIO can be created by specifying a void pointer
|
||||
and a ssize_t option. These options are used to determine the buffer to assign to the BMemoryIO object and its
|
||||
size. No check is done to determine if the buffer is valid or if it contains at least the number of byte specified.</P></LI>
|
||||
|
||||
<LI><P><B>Construction 2:</B> As the one above, but the buffer is specified with a const void pointer.
|
||||
The BMemoryIO object becomes read only, and every subsequent Write(), WriteAt() and SetSize() calls will
|
||||
return B_NOT_ALLOWED.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> The BMemoryIO destructor does nothing. It's up to the caller the responsibility
|
||||
to free the buffer assigned on construction.</P></LI>
|
||||
|
||||
<LI><P><B>Reading 1:</B> When ReadAt() is called, the BMemoryIO returns the number of bytes read from the specified
|
||||
position. ReadAt() takes three arguments: the position where to begin the read operation, the buffer where to put the read data,
|
||||
and the number of bytes to read. This function does not read outside of the buffer.
|
||||
If the specified position is invalid (i.e. outside bounds) this function returns 0. If the read operation
|
||||
begins at a valid position, but the sum of position and bytes to read is bigger than the max size (specified on construction), BMemoryIO
|
||||
returns just the available data.</P></LI>
|
||||
|
||||
<LI><P><B>Reading 2.</B> BMemoryIO inherits the Read() function from BPositionIO. This function read the specified amount
|
||||
of data from the current position, and put it into the specified buffer, then it moves the I/O index forward of the number of read bytes.
|
||||
This function behaves like the above. </P></LI>
|
||||
|
||||
<LI><P><B>Writing 1:</B> When WriteAt() is called, BMemoryIO returns the number of bytes written to the specified position.
|
||||
WriteAt() takes three arguments: the position where to begin the write operation, the buffer from which to read the data to write, and the
|
||||
number of bytes to write. If the BMemoryIO object was constructed with the const constructor, this function returns B_NOT_ALLOWED.
|
||||
This function does not write outside of the buffer bounds. If the specified position is invalid (i.e. outside bounds) this function returns 0. If the write operation begins at a valid position, but the sum of position and bytes to write is bigger than the max size (specified on construction), BMemoryIO
|
||||
returns just the amount of data which can be written.
|
||||
If the BMemoryIO object has been shrunk (see the Size Change case), and the write operation is outside the current bounds (but inside the
|
||||
bounds specified on construction) this function re-enlarge it to accomodate the data.</P></LI>
|
||||
|
||||
<LI><P><B>Writing 2.</B> BMemoryIO inherits the Write() function from BPositionIO. This function write the specified amount
|
||||
of data to the current position of the BMemoryIO object, reading from the specified buffer, then it moves the I/O index forward
|
||||
of the number of read bytes.
|
||||
This function behaves like the above. </P></LI>
|
||||
|
||||
<LI><P><B>Size Changes:</B> The SetSize() member function enlarges or shrink the amount of data which can be read/write.
|
||||
If the BMemoryIO object was constructed with the const constructor, this function always returns B_NOT_ALLOWED.
|
||||
Any SetSize call with a size parameter bigger than the size specified on construction will fail and return B_ERROR. Shrinking the buffer
|
||||
is always possible, and the function returns B_OK. Negative values are not allowed, and the function returns B_ERROR.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Seeking.</B> Seek() sets the position in the data buffer where the Read() and Write() functions (inherited from
|
||||
BPositionIO) begin reading and writing. How the position argument is understood depends on the mode flag. There are three possible modes:
|
||||
<UL>
|
||||
<LI><P>
|
||||
SEEK_SET. The position passed is an offset from the beginning of allocated memory; in other
|
||||
words, the current position is set to position. For this mode, position should be a positive
|
||||
value.
|
||||
</P></LI>
|
||||
<LI><P>
|
||||
SEEK_CUR. The position argument is an offset from the current position; the value of the
|
||||
argument is added to the current position. </P></LI>
|
||||
<LI><P>
|
||||
SEEK_END. The position argument is an offset from the end of the buffer for a BMemoryIO
|
||||
object. Positive values seek beyond the end of the buffer or data; negative
|
||||
values seek backwards into the data. </P></LI>
|
||||
</UL>
|
||||
Seek() Always return the new position.
|
||||
</P></LI>
|
||||
|
||||
<LI><P><B>Position:</B> The Position() call always return the current position.</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BMemoryIO Implementation:</H2>
|
||||
|
||||
<P>The implementation of the BMemoryIO is simple. It consist in implementing memory read/write on a buffer
|
||||
with an index.</P>
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
@@ -0,0 +1,61 @@
|
||||
<!-- saved from url=(0022)http://internet.e-mail -->
|
||||
<HTML>
|
||||
<HEAD>
|
||||
<TITLE>BString 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>BString Use Cases and Implementation Details:</H1>
|
||||
|
||||
<P>This document describes the BString interface and some basics of how it is implemented.
|
||||
The document has the following sections:</P>
|
||||
|
||||
<OL>
|
||||
<LI><A HREF="#interface">BString Interface</A></LI>
|
||||
<LI><A HREF="#usecases">BString Use Cases</A></LI>
|
||||
<LI><A HREF="#implement">BString Implementation</A></LI>
|
||||
</OL>
|
||||
|
||||
<A NAME="interface"></A><H2>BString Interface:</H2>
|
||||
|
||||
<P>The BString is as string allocation and manipulation class. The object allocates and deallocates
|
||||
memory for you so the buffer will always be "big enough" to contain the data.
|
||||
BString provides a number of charachter search, comparison, and manipulation functions in
|
||||
a variety of flavors. The best source of information about the BString class can be found
|
||||
<A HREF="file:///boot/beos/documentation/Be%20Book/The%20Support%20Kit/String.html">here in the Be Book</A>.
|
||||
</P>
|
||||
|
||||
<A NAME="usecases"></A><H2>BString Use Cases:</H2>
|
||||
|
||||
<P>The following use cases cover the BString functionality:</P>
|
||||
|
||||
<OL>
|
||||
|
||||
<LI><P><B>Construction 1:</B> A BString can be created with an empty constructor.
|
||||
This way the created BString is empty.</P></LI>
|
||||
|
||||
<LI><P><B>Construction 2:</B> You can create a BString object with a const char pointer as
|
||||
parameter. After the construction, the BString object contains a copy of the string pointed
|
||||
by the const char pointer.</P></LI>
|
||||
|
||||
<LI><P><B>Construction 3:</B> BString can be created using a copy constructor.
|
||||
The parameter is another BString. After the construction, your BString will contain a
|
||||
copy of the other BString.</P></LI>
|
||||
|
||||
<LI><P><B>Construction 4:</B> You can create a BString object with a const char pointer as
|
||||
parameter and an int32 parameter, which specifies the maximum bytes BString will consider.
|
||||
After the construction, the BString object contains a maximum of bytes (specified by the int32
|
||||
parameter) of the string pointed by the pointer.</P></LI>
|
||||
|
||||
<LI><P><B>Destruction:</B> The BString destructor frees the allocated memory.</P></LI>
|
||||
|
||||
</OL>
|
||||
|
||||
<A NAME="implement"></A><H2>BString Implementation:</H2>
|
||||
|
||||
|
||||
</BODY>
|
||||
</HTML>
|
||||
Reference in New Issue
Block a user