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