xref: /haiku/docs/develop/kits/app/usecases/BPropertyInfoUseCases.html (revision 13581b3d2a71545960b98fefebc5225b5bf29072)
1<HTML>
2<!-- $Id: BPropertyInfoUseCases.html 814 2002-08-19 05:26:56Z jrand $ -->
3<HEAD>
4<TITLE>BPropertyInfo Use Cases and Implementation Details</TITLE>
5</HEAD>
6
7<BODY BGCOLOR="white" LINK="#000067" VLINK="#000067" ALINK="#0000FF">
8
9<FONT FACE="Verdana,Arial,Helvetica,sans-serif" SIZE="-1">
10
11<H1>BPropertyInfo Use Cases and Implementation Details:</H1>
12
13<P>This document describes the BPropertyInfo interface and some basics of how it is implemented.
14The document has the following sections:</P>
15
16<OL>
17<LI><A HREF="#interface">BPropertyInfo Interface</A></LI>
18<LI><A HREF="#usecases">BPropertyInfo Use Cases</A></LI>
19<LI><A HREF="#implement">BPropertyInfo Implementation</A></LI>
20</OL>
21
22<A NAME="interface"></A><H2>BPropertyInfo Interface:</H2>
23
24<P>The BPropertyInfo class is a simple class for describing the scripting interface which a
25BHandler provides.  It makes implementing the ResolveSpecifier() hook function easier to implement.
26One source of information for the BPropertyInfo interface can be found
27<A HREF="https://www.haiku-os.org/legacy-docs/bebook/BPropertyInfo.html">here in the Be Book</A>.
28Unfortunately, details of some changes to this interface introduced in BeOS 4 does not seem to have
29made it into the BeBook.  For the latest, refer to the
30<A HREF="file:///system/develop/headers/be/app/PropertyInfo.h">PropertyInfo.h</A> header file or the
31<A HREF="http://pulkomandy.tk/~beosarchive/unsorted/cypresstwist/BeOS/Docs/BeBook/Release_Notes/R4RN_AppKit.html ">BeOS 4 Developer Release Notes</A>.
32</P>
33
34<A NAME="usecases"></A><H2>BPropertyInfo Use Cases:</H2>
35
36<P>The following use cases cover the BPropertyInfo functionality:</P>
37
38<OL>
39
40<LI><P><B>Construction 1:</B> A BPropertyInfo can be created with 0 arguments.  In this case,
41it will not have any property_info or value_info structures associated with it.  The only
42way to initialize it would be to Unflatten() a flattened BPropertyInfo instance (see Unflatten
43use cases).</P></LI>
44
45<LI><P><B>Construction 2:</B> A BPropertyInfo can be created with a single property_info argument.
46In this case, there will be no value_info structure associated with it and the BPropertyInfo
47will assume it does not need to de-allocate the property_info structure itself on
48destruction.</P></LI>
49
50<LI><P><B>Construction 3:</B> A BPropertyInfo can be created with a property_info argument and
51a value_info argument.  In this case, the BPropertyInfo will use both of these arguments to
52determine its future behaviour.  It will assume it does not need to de-allocate the property_info
53structure or the value_info structure itself on destruction.</P></LI>
54
55<LI><P><B>Construction 4:</B> A BPropertyInfo can be created with a property_info argument and
56a value_info argument and a flag to indicate whether these structres were allocated on the heap.
57If the flag is false, it will assume it does not need to de-allocate the property_info structure
58or the value_info structure itself on destruction.  If the flag is true, it will assume that
59the property_info pointer and the value_info pointer and all pointers contained within them (ie
60const char * instances) need to be free()'d when the BPropertyInfo is destructed.</P></LI>
61
62<LI><P><B>Destruction:</B> On destruction, a BPropertyInfo class does nothing unless the third
63argument (free_on_delete flag) at construction was true.  If this argument was true, the
64BPropertyInfo class performs a "free()" on the pointers passed in at construction time and all
65pointers contained within these structures.</P></LI>
66
67<LI><P><B>Properties:</B> The Properties() member function returns the first argument passed in
68at construction time of the BPropertyInfo or NULL if it was constructed with no arguments.</P></LI>
69
70<LI><P><B>Values:</B> The Values() member function returns the second argument passed in
71at construction time of the BPropertyInfo or NULL if it was constructed with one or fewer
72arguments.</P></LI>
73
74<LI><P><B>Count Properties:</B> The CountProperties() member function returns the number of
75elements in the NULL terminated array of property_info structures passed in as the first argument
76at construction time.  If the BPropertyInfo class was constructed with no arguments, 0 is
77returned.</P></LI>
78
79<LI><P><B>Count Values:</B> The CountValues() member function returns the number of
80elements in the NULL terminated array of value_info structures passed in as the second argument
81at construction time.  If the BPropertyInfo class was constructed with one or fewer arguments, 0 is
82returned.</P></LI>
83
84<LI><P><B>Fixed Size:</B> The IsFixedSize() method always returns false indicating that a
85BPropertyInfo class instance can be flattened but the size of that flattened instance depends on
86the state of the BPropertyInfo class itself.</P></LI>
87
88<LI><P><B>Type Code:</B> The TypeCode() method always returns B_PROPERTY_INFO_TYPE ('SCTD')
89regardless of the state of the BPropertyInfo class instance indicating that the flattened instance
90is of type B_PROPERTY_INFO_TYPE.</P></LI>
91
92<LI><P><B>Allows Type Code:</B> The AllowsTypeCode() method returns false for all passed in type
93codes unless B_PROPERTY_INFO_TYPE ('SCTD') is passed in when this method returns true.  This
94implies that a BPropertyInfo class instance can be unflattened from flattened data of
95B_PROPERTY_INFO_TYPE only (NOTE: the Be implementation seems to return true for all values
96passed in although that doesn't seem to make much sense).</P></LI>
97
98<LI><P><B>Flattened Size:</B> The FlattenedSize() member function retures the number of bytes
99required to store a flattened version of the BPropertyInfo instance.  The size will be determined
100by the description of the flattened data structure described in the "implementation" section
101below.</P></LI>
102
103<LI><P><B>Flatten:</B> The Flatten() member function turns the current BPropertyInfo instance into
104a series of bytes which completely describes its state so it can be recreated from it later.  The
105actual description of this byte representation of BPropertyInfo is described in the "implementation"
106section below.</P></LI>
107
108<LI><P><B>Unflatten:</B> The Unflatten() member function takes a passed in series of bytes and
109sets the current BPropertyInfo instance into a copy of the BPropertyInfo described by those
110bytes (ie a flattened version of a previous BPropertyInfo).  The old state of the current
111BPropertyInfo is replaced by that described by the flattened representation.  The actual description
112of this byte representation of BPropertyInfo is described in the "implemenation" section
113below.</P></LI>
114
115<LI><P><B>Print To Stream:</B> The PrintToStream() member function sends the current state of
116the BPropertyInfo instance to standard out for debugging purpose.  The actual format of this output
117isn't critical but it should describe the state of the object and be easy for a developer to
118understand.</P></LI>
119
120<LI><P><B>Find Match:</B> The FindMatch() member function takes a BMessage, a specifier (in the
121form of a BMessage), a specifier type (called form, ie B_DIRECT_SPECIFIER), property name and an
122index.  The member returns -1 if no match can be found.  A match will have the "what" code of the
123message (not the specifier message) in its command list or have a wildcard command.  It will also
124have the property name as its property name.  And, the specifier type will be listed as a valid
125specifier, or the property will have a wildcard specifier.  Note, if the index is non-zero, then
126only properties with command wildcards will be a match (a wildcard is an empty list of commands,
127similarly for specifier type).  On a match, the result is a 0 based offset into the array of
128properties.</P></LI>
129
130</OL>
131
132<A NAME="implement"></A><H2>BPropertyInfo Implementation:</H2>
133
134<P>There is a key difference between the OpenBeOS BPropertyInfo class and the Be implementation
135is support for BeOS R3 compiled executables.  The elements in the property_info structure changed
136in R4 versus the one which was used in R3.  Be did the following to handle this:</P>
137
138<UL>
139<LI>The R3 constructor was made private.  Existing R3 binaries would use this constructor.  This
140constructor would use static functions to convert between the old property_info structure passed
141from the R3 binary to the new one.</LI>
142<LI>A new constructor was introduced in R4.  This constructor would be source code compatible with
143existing code which compiled on R3.  However, when that code was recompiled for R4, this new
144constructor would be called because the old one was made private.</LI>
145<LI>I expect that work was also done to ensure that the R4 BPropertyInfo class could unflatten
146R3 based BPropertyInfo instances.  I have not done serious checking on this however.</LI>
147</UL>
148
149<P>For the OpenBeOS implementation, we have decided not to implement this R3 compatibility at
150this time but we are not going to rule it out.  The header file for BPropertyInfo will be changed
151to "remove" the R3 compatibility interfaces using an "ifdef R3_compatible".   The interfaces will
152still appear to the human reader but not be there as far as the compiler is concerned.  If we
153revise out decision in the future, it will be a simple matter of removing the ifdefs and implement
154these R3 compatibility interfaces.  For now, we have decided not to do this because:</P>
155
156<UL>
157<LI>There is no binary compatibility between R3 and R4 of BeOS Intel.  The ability for OpenBeOS
158to be binary compatible with these old R3 interfaces buys us nothing on Intel.</LI>
159<LI>There is binary compatibility with R3 with R4 and R5 on BeOS PPC.  Without these interfaces
160implemented, it may not be possible for R3 compiled binaries for PPC to operate against the
161OpenBeOS implementation.  However, there are no specific plans to support PPC.  Also, the informal
162PPC ports that have been discussed were considering using the gcc toolset which I believe precludes
163any backward compatibility, even with R5 binaries.</LI>
164<LI>There is some risk that a flattened BPropertyInfo instance on someone's hard disk was created
165against the old R3 implementation.  The OpenBeOS implementation may not be able to read this
166flattened BPropertyInfo.  However, we believe the chance of this happening to be very low and
167not worth the cost of the implementation.</LI>
168</UL>
169
170<P>The flattened format of BPropertyInfo looks like the following:</P>
171
172<TABLE BORDER=1>
173<TR><TH>Section</TH><TH>Size</TH><TH>Description</TH></TR>
174
175<TR><TD ROWSPAN=3>Header</TD><TD>1</TD><TD>Endian flag, 1 for big endian, 0 for little
176endian</TD></TR>
177<TR><TD>4</TD><TD>Number of property_info elements in the flattened data.</TD></TR>
178<TR><TD>4</TD><TD>Set to 3 if there are value_info in the flattened data, 1 otherwise</TD></TR>
179
180<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>
181<TR><TD>1 to n</TD><TD>NULL terminated usage string.</TD></TR>
182<TR><TD>4</TD><TD>The extra_data value</TD></TR>
183<TR><TD>4 to 40</TD><TD>Up to 10 commands, each 4 bytes in size.  A zero command indicates the end of
184the commands.</TD></TR>
185<TR><TD>4 to 40</TD><TD>Up to 10 specifiers, each 4 bytes in size.  A zero specifier indicates the end of
186the specifiers.</TD></TR>
187
188<TR><TD ROWSPAN=2>property_info types section, one per property_info element</TD><TD>4 to 40</TD>
189<TD>Up to 10 types, each 4 bytes in size.  A zero type indicates the end of the types.</TD></TR>
190<TR><TD>4 to n</TD><TD>A series of 0 to 15 name and type pairs from the "compound types" or ctypes
191section of the property_info structure.  Each is made up of a null terminated name followed by a
1924 byte type.  There are up to 15 because there is a three element array of five name/type pairs.
193If fewer than 5 elements appear in any one set of the the three elements, four zero bytes are
194in the stream where the "name" would be.  Also, to indicate that there are fewer than three
195compound types, four zero bytes are in the stream where the first name would be.</TD></TR>
196
197<TR><TD ROWSPAN=1>value_info header, only appears if the flag in the header is set to "3"</TD>
198<TD>2</TD><TD>Number of value_info elements in the flattened data.</TD></TR>
199
200<TR><TD ROWSPAN=5>value_info section, one per value_info element</TD><TD>4</TD><TD>The "kind"
201of this value_info element.</TD></TR>
202<TR><TD>4</TD><TD>The "value" of this value_info element</TD></TR>
203<TR><TD>1 to n</TD><TD>A NULL terminated name string</TD></TR>
204<TR><TD>1 to n</TD><TD>A NULL terminated usage string</TD></TR>
205<TR><TD>4</TD><TD>The "extra_data" of this value_info element</TD></TR>
206
207</TABLE>
208
209
210<P>The following is some information from Marc Flerackers sent in a series of emails which
211describes his investigation into how BPropertyInfo instances are flattened.  Note that the
212implementation is very much based Marc's implementation elluded to in these messages, although
213you will see some differences between the above description and Marc's messages.  The above
214table describes the actual format as it is implemented today and seems to match Be's
215implementation.  However, Marc's investigation, implementation and emails were critical to
216getting this information and is therefore included here in this document:</P>
217
218<H3>Message 1:</H3>
219
220<P>I spend this morning some time to check how a BPropertyInfo is flattened,
221here's the result for BControl (not such a good choice as there are no
222compound types, however I added at the bottom how the layout looks if there
223are). I'm implementing this now in my own BPropertyInfo class. How is the
224OBOS BPropertyInfo class going BTW?<P>
225
226<PRE>
227// Header
2284		6		chunk count
2294		1		version
230
231// Start of property_info chunks, without types
2328		"Enabled"	name
23358		""		usage ("Returns whether or not the BControl is currently enabled.")
2344		0		extra_data
2354		PGET		commands
2364		0		end commands list
2374		1		specifiers
2384		0		end specifiers list
239
2408		"Enabled"	name
24134		""		usage ("Enables or disables the BControl.")
2424		0		extra_data
2434		PSET		commands
2444		0		end commands list
2454		1		specifiers
2464		0		end specifiers list
247
2486		"Label"	name
24930		""		usage ("Returns the BControl's label.")
2504		0		extra_data
2514		PGET		commands
2524		0		end commands list
2534		1		specifiers
2544		0		end specifiers list
255
2566		"Label"	name
25732		""		usage ("Sets the label of the BControl.")
2584		0		extra_data
2594		PSET		commands
2604		0		end commands list
2614		1		specifiers
2624		0		end specifiers list
263
2646		"Value"	name
26530		""		usage ("Returns the BControl's value.")
2664		0		extra_data
2674		PGET		commands
2684		0		end commands list
2694		1		specifiers
2704		0		end specifiers list
271
2726		"Value"	name
27332		""		usage ("Sets the value of the BControl.")
2744		0		extra_data
2754		PSET		commands
2764		0		end commands list
2774		1		specifiers
2784		0		end specifiers list
279
280// Start of property_info chunks, only types
2814		BOOL		type
2824		0		end type list
2834		0		end compound list
284
2854		BOOL		type
2864		0		end type list
2874		0		end compound list
288
2894		CSTR		type
2904		0		end type list
2914		0		end compound list
292
2934		LONG		type
2944		0		end type list
2954		0		end compound list
296
2974		LONG		type
2984		0		end type list
2994		0		end compound list
300</PRE>
301
302<P>If there would have been compound types, the layout of the type chunks would
303be like this</P>
304
305<PRE>
3064		BOOL		type
3074		0		end type list
3085		"name"	compound name
3094		LONG		compound type
3104		0		end compound list
311</PRE>
312
313<H3>Message 2:</H3>
314
315<P>Layout of a flattened BPropertyInfo with compound members. Value info is
316still missing, I will look at it when I implement support for it in my
317BPropertyInfo class. BTabView and BRadioButton are coming to cvs soon BTW, I
318only have to find some time to write decent Draw functions ^_^.</P>
319
320<PRE>
321// Header
3224		3			chunk count
3234		1			version
324
325// Start of property_info chunks, without types
3267		"Suites"		name
3271		0			usage
3284		0			extra_data
3294		PGET			commands
3304		0			end commands list
3314		1			specifiers
3324		0			end specifiers list
333
33410		"Messenger"	name
3351		0			usage
3364		0			extra_data
3374		PGET			commands
3384		0			end commands list
3394		1			specifiers
3404		0			end specifiers list
341
34213		"InternalName"	name
3431		0			usage
3444		0			extra_data
3454		PGET			commands
3464		0			end commands list
3474		1			specifiers
3484		0			end specifiers list
349
350// Start of property_info chunks, only types
3514		0			end type list
3527		"suites"		compound name
3534		CSTR			compound type
3544		0			end compound sub list
3559		"messages"		compound name
3564		SCTD			compound type
3574		0			end compound sub list
3584		0			end compound list
359
3604		MSNG		type
3614		0			end type list
3624		0			end compound list
363
3644		CSTR			type
3654		0			end type list
3664		0			end compound list
367</PRE>
368
369<H3>Message 3:</H3>
370
371<P>Some updated information about the flattened BPropertyInfo layout for people
372who are interested ^_^.</P>
373
374<PRE>
375The header contains flags, not a version
376
377flattened header
378
3794		count
3804		flags
381
3820x1 : property_info structs are present
3830x2 : value_info structs are present
384
385flattened value_info chunks are appended at the end as follows
386
387a small header
3884		count
389
390for every value_info
3912		kind
3924		value
393x		name
394x		usage
3954		extra_data
396
397where x is strlen + 1 of course.
398</PRE>
399
400<P>Value info structs are used to publish information about non-Be types and
401scripting commands btw.</P>
402
403<P>I tested my code against the Be implementation, and the flattened data
404matches.</P>
405
406</BODY>
407</HTML>
408