Method and system for generating and maintaining property sets with unique format identifiers5680616Abstract A method and system for generating and maintaining property sets is provided. In a preferred embodiment, a property set stream is generated. The stream comprises three parts: a header, a section locator array, and one or more sections. The header contains information for uniquely identifying the property set and for identifying the number of sections within the property set. The section locator array contains a unique identifier for each section and an offset indicating where the section resides within the stream. The third part, the section definitions, contains the information necessary to maintain groups of properties for each section. Each section contains a section header, a property locator array, and an array of property type/value pairs. The section header indicates both the size of the section and the number of properties defined within the section. The property locator array contains unique property identifiers for each property defined in the section and a relative offset, from the beginning of the section, to the property definition. Each property definition appears as a type/value pair, the type indicator indicating the data format for the property and the value field containing or referencing the data. In a preferred embodiment, a property set is generated by allocating appropriate storage and by storing values in the standard structure for a property set. Claims We claim: Description TECHNICAL FIELD
TABLE 1
______________________________________
Type Indicator Code Value Representation
______________________________________
VT.sub.-- EMPTY
0 None. A property set with a type
indicator of VT.sub.-- EMPTY has no
data associated with it; that is,
the size of the value is zero.
VT.sub.-- NULL 1 None. This is like a pointer to
NULL.
VT.sub.-- I2 2 Two bytes representing a
WORD value. This value will be
zero-padded to a 32-bit
boundary.
VT.sub.-- I4 3 Four bytes representing a
DWORD value.
VT.sub.-- R4 4 Four bytes representing a 32-bit
IEEE floating point value.
VT.sub.-- R8 5 Eight bytes representing a 64-bit
IEEE floating point value.
VT.sub.-- CY 6 Eight-byte two's complement
integer (scaled by 10,000). This
type is commonly used for
currency amounts.
VT.sub.-- DATE 7 Time format used by many
applications, it is a 64-bit
floating point number represent-
ing seconds since January 1,
1900. This is stored in the same
representation as VT.sub.-- R8.
VT.sub.-- BSTR 8 Counted, zero-terminated binary
string; represented as a DWORD
byte count (including the
terminating null character)
followed by the bytes of data.
VT.sub.-- BOOL 11 Two bytes representing a
Boolean (WORD) value contain-
ing 0 (FALSE) or -1 (TRUE).
This type must be zero-padded
to a 32-bit boundary.
VT.sub.-- VARIANT
12 Four-byte indicator followed by
the corresponding value. This is
only used in conjunction with
VT.sub.-- VECTOR.
VT.sub.-- I8 20 Eight bytes representing a signed
integer.
VT.sub.-- LPSTR
30 Same as VT.sub.-- BSTR; this is the
representation of most strings.
VT.sub.-- LPWSTR
31 A counted and zero-terminated
Unicode string; a DWORD
character count (where the count
includes the terminating null
character) followed by that many
Unicode (16-bit) characters.
Note that the count is not a
byte count, but a word count.
VT.sub.-- FILETIME
64 64-bit FILETIME structure, as
defined by the Windows 32-Bit
Operating System:
typedef struct FILETIME{
DWORD dwLowDataTime:
DWORD dwHighDateTime:
} FILETIME:
VT.sub.-- MISC 65 DWORD count of bytes, fol-
lowed by that many bytes of
data. The byte count does not
include the four bytes for the
length of the count itself; an
empty MISC would have a count
of zero, followed by zero bytes.
This is similar to
VT.sub.-- BSTR but does not
guarantee a null byte at the
end of the data.
VT.sub.-- STREAM
66 A VT.sub.-- LPSTR (DWORD count
of bytes followed by a zero-
terminated string that many
bytes long) that names the
stream containing the data.
The real value for this property
is stored in an object supporting
the IStream interface, which is a
sibling to the CONTENTS
stream. This type is only valid
for property sets stored in the
CONTENTS stream of an object
supporting the IStorage
interface.
VT.sub.-- STORAGE
67 A VT.sub.-- LPSTR (DWORD
count of bytes followed by a
zero-terminated string that many
bytes long) that names the
storage containing the data. The
real value for this property is
stored in an object supporting
the IStorage interface, which
is a sibling to the CONTENTS
stream that contains the property
set. This type is only valid for
property sets stored in the
CONTENTS stream of an object
supporting the IStorage
interface.
VT.sub.-- STREAMED.sub.-- OBJECT
68 Same as VT.sub.-- STREAM, but
indicates that the Stream object
named in this property contains
a serialized object, which is a
CLSID followed by initialization
data for the class. The named
Stream object is a sibling to the
CONTENTS stream that con-
tains the property set. This type
is only valid for property sets
stored in the CONTENTS
stream of an object supporting
the IStorage interface.
VT.sub.-- STORED.sub.-- OBJECT
69 Same as VT.sub.-- STORAGE, but
indicates that the Storage object
named in this property contains
an object. This type is only valid
for property sets stored in the
CONTENTS stream of an object
supporting the IStorage
interface.
VT.sub.-- MISC.sub.-- OBJECT
70 An array of bytes containing
a serialized object in
the same representation as
would appear in a
VT.sub.-- STREAMED.sub.-- OBJECT
(VT.sub.-- LPSTR). The only
significant difference
between this type and
VT.sub.-- STREAMED.sub.-- OBJECT
is that VT.sub.-- MISC.sub.-- OBJECT
does not have the system-
level storage overhead as
VT.sub.-- STREAMED.sub.-- OBJECT.
VT.sub.-- MISC.sub.-- OBJECT is more
suitable for scenarios involving
numerous small objects.
VT.sub.-- CF 71 An array of bytes containing a
clipboard format identifier
followed by the data in that
format. That is, following the
VT.sub.-- CF identifier is the data in
the format of a VT.sub.-- MISC.
This is a DWORD count of
bytes followed by that many
bytes of data in the following
format: a LONG followed by an
appropriate clipboard identifier
and a property whose value is
plain text should use
VT.sub.-- LPSTR, not VT.sub.-- CF to
represent the text. Notice also
that an application should
choose a single clipboard format
for a property's value when
using VT.sub.-- CF.
VT.sub.-- CLSID
72 A CLSID, which is a DWORD,
two WORDS, and eight bytes.
VT.sub.-- VECTOR
0x1000 If the type indicator is
one of the previous
values in addition to this
bit being set, then the
value is a DWORD count
of elements, followed by that
many repetitions of the value.
When VT.sub.-- VECTOR is
combined with VT.sub.-- VARIANT
the value contains a DWORD
element count, a DWORD type
indicator, the first value,
a DWORD type indicator, the
second value, and so on.
Examples:
VT.sub.-- LPSTR.vertline.VT.sub.-- VECTOR
has a DWORD element count,
a DWORD byte count, the
first string data, a DWORD
byte count, the second string
data, and so on.
VT.sub.-- I2.vertline.VT.sub.-- VECTOR has a
DWORD element count fol-
lowed by a sequence of two-byte
integers, with no padding
between them.
______________________________________
The meaning of each type indicator and its size is described in the Value Representation column in Table 1. Most of the table entries are self-explanatory, however, a few merit additional explanation. First, there are several types of property values that are stored as complex hierarchical structures within the object-oriented environment. These type indicators are VT.sub.-- STREAM, VT.sub.-- STORAGE, VT.sub.-- STREAMED.sub.-- OBJECT, VT.sub.-- STORED.sub.-- OBJECT, and VT.sub.-- MISC.sub.-- OBJECT. These types of property values are preferably only used when a property set stream is stored within its own hierarchical object structure. The storage of property set streams is discussed in greater detail below. At this point, it is sufficient to note that these types are preferably available in some situations and not others. Second, the VT.sub.-- CF type indicator allows a property value to be stored in a clipboard format (e.g., an operating system defined format for data to be exchanged using, for example, an operating system supplied clipboard). The property value corresponding to a VT.sub.-- CF type indicator should be arranged as follows: a count of the bytes that follow, a tag indicating the kind of clipboard format identifiers used (see Table 2 below), an array of bytes representing the particular clipboard format identifier, and the data in the specified clipboard format. Table 2 lists possible values for the tag indicating the kind of clipboard format identifiers.
TABLE 2
______________________________________
First
Four Bytes
Following Value Size
Meaning
______________________________________
-1L 4 bytes (DWORD)
Windows built-in Clipboard
Format Value (e.g., CF.sub.-- TEXT).
-2L 4 bytes (DWORD)
Macintosh Format Value (4-byte
tag).
-3L 16 bytes (Format ID)
An FMTID.
Length Variable Clipboard format name that has
of String been previously registered with the
underlying operating system.
0L Zero No format name.
______________________________________
As shown in Table 2, there are five kinds of clipboard format identifiers that can occur in VT.sub.-- CF values: Windows clipboard format values corresponding to clipboard formats on the Windows operating system, Macintosh format values corresponding to clipboard formats on the Macintosh operating system, FMTIDs, clipboard format names previously registered, and no format name. One skilled in the art will recognize that the kinds of clipboard format identifiers can vary and that the VT-CF value can be extended to other operating systems. Third, the VT.sub.-- VECTOR type indicator used in conjunction with the VT.sub.-- VARIANT type indicator enables a program to arbitrarily extend the preferred data types. Property sets are designed to be partially self-describing so that code that does not recognize everything in a property set can at least read the types of the values contained within the set. A program desiring to define a new type can do so by creating a structure which is essentially a vector of varying data, where each data entry in the vector is self-describing. This self-describing nature is possible became the VT.sub.-- VARIANT data type includes as its first element another data type indicator. For example, if a program desires to store a special kind of packed data structure consisting of a 32-bit value, followed by 16 bits of flags, followed by another 16-bit value, the program can define a structure as follows:
______________________________________
typedef struct tagPACKED
DWORD dwValue1; 32 bit value
WORD wFlag; 16 bits of flags
WORD wValue2; 16 bit value
} PACKED:
______________________________________
This 64-bit data structure can then be stored, using the VT.sub.-- VARIANT.vertline.VT.sub.-- VECTOR data type, as the following property value:
______________________________________
DWORD // dwTypeIndicator = VT.sub.-- VARIENT .vertline. VT.sub.--
VECTOR;
DWORD // dwElementCount = 3;
DWORD // dwTypeIndicator = VT.sub.-- I4;
DWORD // dwValue1;
DWORD // dwTypeIndicator = VT.sub.-- I2;
WORD // wFlag;
DWORD // dwTypeIndicator = VT.sub.-- I2;
WORD // wValue2;
______________________________________
As shown above, the type indicator of the "new" format is VT.sub.-- VARIANT.vertline.VT.sub.-- VECTOR. The property value consists of an element count (as required by the VT.sub.-- VECTOR type indicator) followed by three elements. The first element has a type indicator specifying a 32-bit integer type followed by the first value in the data structure. The second element has a type indicator specifying a 16-bit integer followed by the second value in the data structure. The third element has a type indicator indicating a 16-bit integer followed by the third value in the data structure. At this point, it is useful to examine how the standard structure is used in an example property set. FIG. 5 is a block diagram of the property set stream corresponding to the formatting property set of the paragraph object discussed with reference to FIG. 2. Recall that the formatting property set of the paragraph object as described earlier contains three properties: an alignment property, a line spacing property, and a picture sample of the combined paragraph format. In FIG. 5, property set stream 501 comprises three parts numbered according to their corresponding parts in FIG. 4. Header 502 has five fields (not shown) as described with reference to FIG. 4, with the section count field indicating that there is presently one section in the property set. The section locator array 503 has one entry corresponding to section 1. The first field of this entry is a unique FormatID identifying the section 1 group of properties. The second field is an offset (pointing to address "x") where section 1 begins in property set stream 501, relative to the beginning of the stream. As labeled in FIG. 5, section 1 begins at absolute address "x". Section 1 occupies the remainder of the property set stream and is organized as follows. First, the section 1 header 506 contains the size in bytes of the entire section (the size=the end of stream address--absolute address "x" in the case where only 1 section exists). Section 1 header 506 also contains a property count indicating that there are three properties in this section (neither of which are shown). Second, the property locator array follows and contains three elements. The first element contains the PropertyID for the alignment property followed by an offset to the alignment property type/value pair in property set stream 501. Recall that the offsets in this array are relative to the beginning of this section (i.e., relative to absolute address x). The second element contains the PropertyID for the line spacing property followed by an offset from the beginning of the section to the location of the line spacing property type/value pair. The third element contains the PropertyID for the sample property followed by an offset from the beginning of the section to the location of the sample property type/value pair. Section 1 also contains a third part, an array of type/value pairs corresponding to the PropertyID/offset pairs. The type indicator for the alignment property is located at absolute address "w." In this example, the value for the alignment property (center) is stored as a number. The corresponding type indicator is VT.sub.-- I4 to indicate a 32-bit value. The type indicator for the line spacing property is stored at absolute address "u." In this example, the value of the line spacing property is stored as the string "Double." Thus, a corresponding type indicator for the line spacing property is VT.sub.-- LPSTR. The type indicator for the property referred to as "Sample" is stored at absolute address "v". In this example, the value of the sample property is stored as a bitmap image. Thus, a corresponding type indicator for the Sample property is a VT.sub.-- MISC for storing a bitmap. (Alternatively, the Sample property could be stored in a VT-CF clipboard format.) The procedure for creating a property set stream such as that shown in FIG. 5 is fundamentally application specific because it depends upon how the properties are stored internally by the program. However, programs desiring to create property set streams typically follow a set of steps for generating the stream. FIGS. 6 and 7 are example routines for setting up a property set stream given an already created group or groups of properties. These figures assume that the created properties are stored for internal use in a more traditional programming style data structure such as a list data structure or other such data structure. One skilled in the art will recognize that, if the groups of properties are instead stored as a property set object and property section objects, then instead of the steps identified below, the program would preferably invoke methods on these objects requesting them to copy themselves out to a given property set stream. FIG. 6 is an overview flow diagram of a typical routine for creating a property set stream given existing groups of properties. The routine stores the header information, creates and stores a unique FormatID for each group (section) of properties, stores the section information for each section, and stores the section offset for each section in the section locator array once it has determined the section size. In step 601, the routine stores the header information, including the CLSID of a program capable of displaying or providing programmatic access to the stream (if one exists), and the number of sections to be stored. In steps 602-605, the routine fills in the FormatID fields of the section locator array. Specifically, in step 602, the routine selects the next section number starting with the first section number. In step 603, the routine determines whether it has created an entry in the array for all of the sections and, if so continues in step 606, else continues in step 604. In step 604, the routine obtains a globally unique identifier from the underlying system (a GUID) and stores this value as the FormatID of the current entry in the section locator array. In step 605, the routine calculates the location of the next available entry in the section locator array and returns to step 602. In steps 606-609, the routine stores each section of properties in the property set stream. Specifically, in step 606, the routine selects the next section starting with the fast section. In step 607, the routine determines whether all the sections to be added to the stream have been processed and, if so returns, else continues in step 608. In step 608, the routine stores the section information for the current selected section. This step is further expanded in FIG. 7. In step 609, the routine calculates and stores the offset for the selected section in the corresponding entry in the section locator array and returns to step 606. FIG. 7 is a flow diagram of a typical routine for storing the section information for a particular section in a property set stream. The routine stores each property type and value, keeping track of the total section size and the offsets of the property type/value pairs. In step 701, the routine stores out the number of properties contained in the section, leaving room for the total section size. In step 702, the routine reserves space for the property locator array. In steps 703-708, the routine processes each property, updating the property locator army as information becomes available. Specifically, in step 703, the routine selects the next property in the section starting with the first property. In step 704, the routine determines whether it has processed all properties within the section and, if so, continues in step 709, else continues in step 705. In step 705, the routine calculates the size of the property type/value pair and adds this value to a running count of the section size. In step 706, the routine stores the PropertyID for the selected property in the corresponding entry of the property locator array. Thus, for example, a property stored in the second entry of the array of type/value pairs has its corresponding entry as the second entry of the property locator array. Recall that PropertyIDs need not appear in order. In step 707, the routine calculates and stores the offset of the selected property type/value pair. In step 708, the routine stores the type indicator and value for the selected property and returns to step 703. In step 709, the routine stores the total section size in the section header and returns. Extending Existing Property Sets In addition to creating a new property set stream for a group of properties, a program can extend an already existing property set by adding a new section to a property set stream. An extension to an existing property set can be defined by allocating a new FormatID and new PropertyIDs that do not conflict with the base group of properties (the properties stored in the first section). Preferably, the first section in a property set stream identifies the base group of properties for the property set, and succeeding sections define extensions of the preceding sections. Also, preferably the PropertyIDs chosen for properties in an extended group do not conflict with the property identifiers chosen for properties in the preceding sections. Using this convention, several extensions can be defined by different programs, such extensions having potentially conflicting PropertyIDs. However, because there is a unique FormatID for every extension, these independently defined groups of properties won't Conflict in practice. (At any one time, the property set stream will contain preferably sections with PropertyIDs that do not conflict.) By extending property sets in this manner, client programs can skip over extension sections they do not understand (as identified by the FormatID for the section), but still access properties in the base section and any other extension section that the client program understands. When extending an existing property set, the new section information and appropriate entries in the section locator array are added to the property set stream. A program accomplishes this task by changing the section count in the header, moving the currently defined sections to make space for another entry in the section locator array, inserting a new FormatID and offset for the new section in the section locator array, adding the section information corresponding to the extension properties in a new section, and updating the section offsets in the section locator array to reflect the new locations of any previously existing sections. Note that because all offsets within a section are relative to the beginning of the section, the sections can be copied as byte arrays without any translation of internal structure or updating of internal offsets. One skilled in the art will recognize that this procedure assumes that a stream can be indefinitely extended. Alternatively, a new stream can be allocated and the relevant parts of the existing stream copied over at appropriate points to create the new extended stream. FIG. 8 is a flow diagram of a typical routine for extending an existing property set stream. This routine assumes that the program has an already existing group of properties to be added as a new section to the existing stream and that the stream can be appropriately extended. The routine has one input parameter, pstream, a pointer to an existing property set stream. Specifically, in step 801, the routine updates the section count in the property set stream header (see, e.g., structure 402 in FIG. 4). In step 802, the routine allocates enough space for another entry in the section locator array and moves all of the section definitions down further in the stream to make room for a new entry in the section locator array (see, e.g., structure 403 in FIG. 4). In step 803, the routine obtains a unique FormatID preferably from the underlying system, and stores it as the FormatID of the new entry of the section locator array. In step 804, the routine allocates space for and stores all of the section information for the extension properties (e.g., see, FIG. 7). In step 805, the routine updates the offset in the section locator array and returns. As a specific example of using this extension capability, the property set discussed with reference to FIG. 2 can be extended to add properties to the existing base property, set of formatting properties. For example, formatting properties pertaining to the font characteristics of a paragraph can be added to the existing formatting properties of a paragraph object. FIG. 9 is an example display of current values for a property set comprising the formatting base and extension properties of a paragraph object. Item 901 is a display window containing fields of output 902-907, each displaying a property value. Fields 902-904 display properties belonging to the base property set shown in FIG. 2. Fields 905-907 display a group of extension properties. Field 905 corresponds to a typeface property whose current value indicates a "Times Roman" font. Field 906 corresponds to a font size property whose current value indicates a 12-point font. Field 907 corresponds to a font color property whose current value indicates blue. In the extended property set shown in FIG. 9, the formatting properties for a paragraph object include all of the properties displayed in fields 902-907. FIG. 10 is a high level block diagram illustrating the addition to an existing property set stream of a new section corresponding to the extended properties shown in FIG. 9. In FIG. 10, a new entry 1001 has been added to the section locator array. New entry 1001 contains a new FormatID corresponding to section 2 and an offset corresponding to the address of section 2 within the stream (address "z"). Note that the section 1 information has been moved and that the offset for section I in the section locator array has been changed to reflect the new location (address "y"). Section 1 information follows the new entry in the section locator array and includes all of the information discussed with reference to FIG. 5. At address location "z", a new section 1002 has been added to correspond to the three new properties of typeface, point size, and color. As with other sections, section 2 contains a section header, followed by a property locator array containing PropertyIDs and offset pairs for the three new properties, and followed by an array of type/value pairs with three entries corresponding to the new properties. Special PropertyIDs As mentioned earlier, two PropertyIDs are preferably reserved for special purposes. PropertyID "0" is reserved for property set dictionaries containing human-readable names describing the properties in the property set. PropertyID "1" is reserved for indicating the character set used in the property set. More specifically, PropertyID "0" is reserved for an optional dictionary of human-readable names for the property set. Preferably, not all of the names of the properties in the set need to appear in the dictionary. The dictionary in PropertyID "0" can omit entries for properties assumed to be universally known by client programs that manipulate the property set. Typically, names for the base properties (the properties in section 1) for widely accepted standards are omitted. However, extensions or special purpose property sets preferably include dictionaries for use by tools that display the properties in the property set without knowledge of their meaning. If a dictionary exists, it preferably contains at least one entry corresponding to the name of the property set. PropertyID "0" is anomalous in that it preferably does not have a type indicator. Instead, the DWORD typically used to store the type indicator in the array of type/value pairs is used to indicate the number of entries in the dictionary. The property value corresponding to PropertyID "0" is an array of PropertyID/string pairs, where the first entry in the array corresponds to the name of the entire property set. That is, the first entry contains a pair of values: a PropertyID of zero and a string name corresponding to the name of the property set. The remaining entries in this array are the PropertyIDs and corresponding names of the properties. Although not indicated in the type indicator field for PropertyID "0," the dictionary property value is stored as type VT.sub.-- MISC.vertline.VT.sub.-- VECTOR. Each MISC structure in the vector contains a DWORD count of bytes, followed by a DWORD indicating the PropertyID, followed by the name corresponding to that PropertyID. Specifically, PropertyID "0" is preferably in the following format: DWORD count of the number of dictionary entries (PropertyID/string pairs); and an unsorted sequence of pairs of the form: DWORD byte count, DWORD PropertyID, LPSTR property name. For example, a dictionary corresponding to the formatting property set of the paragraph object discussed earlier could include a humanreadable name of "Formatting" for the entire property set, "Alignment" for the alignment property, and "Line Spacing" for the line spacing property. Table 3 shows a portion of the byte stream for a property set section corresponding to the formatting properties example that includes a dictionary.
TABLE 3
______________________________________
(start of section)
DWORD size of section
DWORD number of properties in section
(start of property locator array)
DWORD PropertyID = 0
DWORD Offset to PropertyID0
DWORD PropertyID (e.g., PID.sub.-- Alignment)
DWORD Offset to PropertyID
DWORD PropertyID (e.g., PID.sub.-- LineSpacing)
DWORD Offset to PropertyID
DWORD PropertyID (e.g., PID.sub.-- Sample)
DWORD Offset to PropertyID
(start of property type/value pairs)
DWORD Number of dictionary entries (=4)
DWORD PropertyID (=0)
DWORD Length of string (=11)
Char sz›11! String (="Formatting")
DWORD PropertyID (=PID.sub.-- Alignment)
DWORD Length of string (=10)
Char sz›10! string (="Alignment")
(dictionary entries continue)
(start of next property type/value pair)
DWORD Type indicator (e.g., VT.sub.-- 14)
DWORD Value (e.g., 0 .times. 02 = center)
______________________________________
PropertyID "1" is reserved as an indicator of the character set (known as a code page in the Windows operating system) that was used to create the strings in the property set. Preferably, all string values within a property set are stored using the same character set. If a program does not understand this indicator, it preferably does not modify the character set property. When a program that is not the author of a property set changes a property of type string, it preferably examines the character set property and either writes the changed string values out consistently or rewrites all of the other string values in the property set to a new character set and modifies the value of PropertyID "1" accordingly. PropertyID "1" begins with a VT.sub.-- I2 type indicator. Storing Property Sets In a preferred embodiment, the underlying operating environment provides structured storage for storing objects. In the Microsoft OLE 2.0 environment, persistent storage for objects is provided through IStorage and IStream interfaces. These interfaces are discussed in detail in U.S. patent application Ser. No. 07/909,533, entitled "Method and System for Storing and On-Demand Loading of Objects," which is hereby incorporated by reference. For the purposes of understanding the present invention, the IStorage interface is supported by storage objects, which can contain other storage objects or stream objects. Stream objects are objects that support the IStream interface. The IStorage interface defines methods, among others, for creating and opening child storage and stream objects and for committing transactions to the storage object. The IStream interface defines methods, among others, for reading and writing stream objects. Roughly speaking, the IStream and IStorage interfaces as implemented by specific object implementations support the storage of objects in an analogous manner to the way files and directories support the hierarchical storage of files in a file system. Typically, objects within the Microsoft OLE 2.0 environment are stored in storage objects that support the IStorage interface even if the object only makes use of one stream within the storage object (for its persistent data). Preferably, a property set is stored as an object connected to the same storage object to which the object "owning" the properties is connected (the "parent" storage object). That is, in an abstract sense, both the object and its property sets are connected to the same parent storage object. Within this type of structured storage system, a property set can be stored as either a storage object supporting the IStorage interface or as a stream object supporting the IStream interface. Preferably, the name of the object used to store a common property set (defined by the underlying object-oriented environment) that can be shared among programs is prepended with the byte value ".backslash.0.times.05" for recognition purposes. One skilled in the art will recognize that other names are possible and that names prepended with values reserved by the underlying object-oriented environment will preferably be used as defined by the underlying environment. In the case where a property set is stored as a storage object the actual property set stream (serialized data) is stored in a child stream object preferably named "CONTENTS." If the property values stored within the "CONTENTS" stream object represent complicated data structures requiring additional structured storage, then these additional storage or stream objects are stored as children of the property set storage object. For example, a property value might be another object. One purpose in storing such complex values within a single property set storage object is to keep all of the property values separate from the other objects relating to the parent storage object. FIGS. 11A and 11B depict these two scenarios for storing property sets. FIG. 11A is a block diagram of the structured storage layout for a property set created as an instance of a stream object. The structured storage layout comprises three objects possibly connected to other objects within a storage hierarchy. The objects in FIGS. 11A and 11B are labeled with an appropriate interface name to indicate that the circle represents an object supporting that interface. Storage object 11A01 is the parent storage object for the particular object of interest. Stream object 11A02 stores the data for the object. Stream object 11A03 stores a property set stream belonging to object 11A01. For example, the structured storage objects shown in FIG. 11A can be mapped to the paragraph object of the example discussed with reference to FIGS. 3 and 5. Accordingly, the stream object 11A02 represents the data for the paragraph object, and stream object 11A03 is the storage for the formatting property set as discussed in the example. FIG. 11B is a block diagram Of the structured storage layout for a property set created as an instance of a storage object. Objects 11B01 and 11B02 represent the same objects as 11A01 and 11A02 described with reference to FIG. 11A. Storage object 11B04 provides storage for a property set belonging to object 11B02. As shown, storage object 11B04 points to three other structured storage objects. Stream object 11B05, labeled "CONTENTS," is the equivalent of stream object 11A03 in FIG. 11A. This stream object stores the property set stream data. Storage object 11B06 and stream object 11B07 are displayed to show that other sibling objects can be stored within the structured storage allocated for a property set. These objects are preferably objects referenced by a property value within the property set stream 11B05. As discussed earlier, several type indicators are available for storing complex property values. The type indicators VT.sub.-- STREAM, VT.sub.-- STORAGE, VT.sub.-- STREAM.sub.13 OBJECT, VT.sub.-- STORAGE.sub.-- OBJECT, and VT.sub.-- MISC.sub.-- OBJECT are preferably only utilized when a property set is stored in a storage object as shown in FIG. 11B. As indicated in Table 1, these type indicators specify that the corresponding property value is stored in a sibling stream object or storage object. Storage object 11B06 and stream object 11B07 represent such sibling objects used to represent complex property values. Example Uses of Property Sets Many uses exist for property sets generated by the present invention beyond the examples discussed so far. First, special property sets can be created to support standardization efforts. For example, the preferred embodiment provides a standard property set (a base set) for document summary information. This document summary information property set is an example of a common property set shared among programs that manipulate documents. A client program, using the embodiments described, can extend this base set of properties for its own purposes. Table 4 lists the property names for the Document Summary Information property set, along with their respective PropertyIDs and type indicators.
TABLE 4
__________________________________________________________________________
Property Name
Property ID Property ID Code
Type
__________________________________________________________________________
Title PID.sub.-- TITLE
0x00000002
VT.sub.-- LPSTR
Subject PID.sub.-- SUBJECT
0x00000003
VT.sub.-- LPSTR
Author PID.sub.-- AUTHOR
0x00000004
VT.sub.-- LPSTR
Keywords PID.sub.-- KEYWORDS
0x00000005
VT.sub.-- LPSTR
Comments PID.sub.-- COMMENTS
0x00000006
VT.sub.-- LPSTR
Template PID.sub.-- TEMPLATE
0x00000007
VT.sub.-- LPSTR
Last Saved By
PID.sub.-- LASTAUTHOR
0x00000008
VT.sub.-- LPSTR
Revision Number
PID.sub.-- REVNUMBER
0x00000009
VT.sub.-- LPSTR
Total Editing Time
PID.sub.-- EDITTIME
0x0000000A
VT.sub.-- FILETIME
Last Printed
PID.sub.-- LASTPRINTED
0x0000000B
VT.sub.-- FILETIME
Create Time/Date*
PID.sub.-- CREATE.sub.-- DTM
0x0000000C
VT.sub.-- FILETIME
Last saved Time/Date*
PID.sub.-- LASTSAVE.sub.-- DTM
0x0000000D
VT.sub.-- FILETIME
Number of Pages
PID.sub.-- PAGECOUNT
0x0000000E
VT.sub.-- I4
Number of Words
PID.sub.-- WORDCOUNT
0x0000000F
VT.sub.-- I4
Number of Characters
PID.sub.-- CHARCOUNT
0x000000010
VT.sub.-- I4
Thumbnail PID.sub.-- THUMBNAIL
0x000000011
VT.sub.-- CF
Name of Creating
PID.sub.-- APPNANE
0x000000012
VT.sub.-- LPSTR
Application
Security PID.sub.-- SECURITY
0x000000013
VT.sub.-- I4
__________________________________________________________________________
*Some methods of file transfer (such as a download from a BBS) do not
maintain the file system's version of this information correctly.
Second, tools can be developed that manipulate property sets generally without having any understanding of the semantics of the properties stored within the property sets. For example, a browsing tool can be created for displaying the properties of an object without understanding anything about the object. Third, property sets can be used to provide a surrounding context for the properties of other objects. The surrounding properties are sometimes referred to as ambient properties. Other objects may respond to changes in such ambient properties by modifying the values of their properties. Such behavior is typically desirable in an environment where one object contains one or more subobjects, and the program implementing these subobjects desires to change properties of the subobjects when certain properties of the containing object change. For example, a compound document, which is an object that can contain objects implemented by multiple applications, may contain a paragraph object with an equation object appearing within the paragraph object. FIG. 12 is a block diagram of a compound document. Document object 1201 contains two paragraph objects 1202 and 1203 implemented by a word processing program. In addition, paragraph object 1203 contains an equation object 1204 implemented by a (different) mathematical program. In this scenario, it may be desirable to cause certain properties of the equation object to change when certain ambient properties are changed in the surrounding paragraph object. For example, when the point size of the characters in paragraph 1203 is enlarged, it may be desirable to change the corresponding point size property (assuming one exists) in the equation object 1204. In order to implement ambient property capabilities, the standard structure for representing property sets is combined with some kind of data transfer mechanism that can transfer the relevant properties from one application to another (as with any other data format). For example, the data transfer mechanism provided by the Microsoft OLE 2.0 environment can be used to support the transfer of the point size property from the paragraph object 1203 to the equation object 1204. This data transfer mechanism is discussed in further detail in U.S. application Ser. No. 08/632,307, entitled "Uniform Data Transfer," which is herein incorporated by reference. This data transfer mechanism supports a method for getting data from an object ("GetData") and a method for sending data to an object ("SendData"). It also supports a mechanism for a first object to set up a notification connection with a second object such that, upon the occurrence of some registered event, the second object notifies the first object that a particular event has occurred. Using a data transfer mechanism such as that described, in response to notification that a particular event has occurred, the first object can request the desired property set from the second object using the second object's GetData method. Fourth, property sets, due to their partially self-describing nature, can be used generally for transferring data between applications. Each property within a property set identifies its own data format through the type indicator. As with ambient properties, using property sets for generally transferring data depends upon combining the present invention with an underlying data transfer mechanism. Fifth, property sets provide an application-independent mechanism for providing a thumbnail sketch of the contents of an object for browsing purposes by defining a property to hold the thumbnail sketch. Typically, a thumbnail sketch is used to display information regarding the contents of an object without knowledge of its contents. A thumbnail sketch that is implemented as a property value within a property set is easily changed as the contents of an object are modified. Thus, the thumbnail sketch can provide an up-to-date quick view of the contents of an object without any knowledge of the object. Sixth, using property sets, a user can extend the capabilities of an object by making use of other programs that implement behavior based upon attached properties independent of the object to which they are attached. For example, suppose a chart object has a drop shadow property attached to the object through the structured storage for the chart object. Even though the application implementing the chart object may know nothing about the drop shadow property or how to implement drop shadows, when a user embeds the chart object in an object implemented by a program knowing how to draw drop shadows, the chart object can be drawn with a surrounding drop shadow. To a user, the capabilities of the chart object appear to be extended by placing the object in an environment that can respond in an intelligent way to its attached properties. Seventh, data from a database can be stored naturally in a property set stream for later access. The standard structure for storing a property set is sufficiently general to support many mappings between the data stored in a database and property sets. For example, each record in a database can be stored as a separate property set. One skilled in the art will recognize that many other uses of the present invention are possible beyond those discussed. Although the present invention has been described in terms of preferred embodiments, it is not intended that the invention be limited to these embodiments. Equivalent methods, structures, processes, steps, and other modifications within the spirit of the invention fall within the scope of the invention. The scope of the present invention is defined by the claims which follow.
|
Same subclass Same class Consider this |
||||||||||
