2.1.3.1 Best Body Algorithm

The Best Body Algorithm specifies the algorithm that the client uses to determine the best body format of a message.

Step 1. Issue a RopGetPropertiesSpecific ROP request ([MS-OXCROPS] section 2.2.8.3) for the following properties: PidTagBody ([MS-OXPROPS] section 2.618), PidTagRtfCompressed ([MS-OXPROPS] section 2.942), PidTagHtml ([MS-OXPROPS] section 2.734), and PidTagRtfInSync ([MS-OXPROPS] section 2.943). The client SHOULD also request PidTagNativeBody ([MS-OXPROPS] section 2.806).

If the RopGetPropertiesSpecific ROP returns a status code that indicates a failure, then the body type is undefined and the algorithm exits.

If the client does not request all three of the body type properties (PidTagBody, PidTagRtfCompressed, and PidTagHtml), the server SHOULD<2> return the best value for the PidTagNativeBody property that fits one of the requested body types.

If the client retrieves all five property values and the value of the PidTagNativeBody property is as specified in the following table, then the server has already saved the best body format to use in the value of the PidTagNativeBody property. In this case, it is not necessary to perform the remainder of the algorithm specified in this section.

If the server returns a value for the PidTagNativeBody property, the client SHOULD use this value to determine the best body. Otherwise, the client proceeds to step 2. The following table identifies the best body format that corresponds to the value. If the PidTagNativeBody property is missing or the value is not provided in the following table, proceed to the remaining steps of the algorithm.

Property value

Property identifier

Body format

1

PidTagBody

Plain

2

PidTagRtfCompressed

RTF

3

PidTagHtml

HTML

If the server does not return the PidTagNativeBody property but does return the remaining four property values, then the RopGetPropertiesSpecific ROP returns a StandardPropertyRow structure ([MS-OXCDATA] section 2.8.1.1). If any of the four property values were not retrieved, then the RopGetPropertiesSpecific ROP returns a FlaggedPropertyRow structure ([MS-OXCDATA] section 2.8.1.2).

Step 2. Create four variables: PlainStatus, RtfStatus, HtmlStatus, and RtfInSync. Examine the returned property values and assign values to the corresponding variables as follows. In each case, if there is an error code, then the value for the variable is either NotFound or NotEnoughMemory.

  • PlainStatus – If the RopGetPropertiesSpecific ROP returned a StandardPropertyRow structure, or the value of the PidTagBody property is a PtypString ([MS-OXCDATA] section 2.11.1), then assign the NoError error code to the PlainStatus variable; else copy the error code from the FlaggedPropertyValue structure to the PlainStatus variable.

  • RtfStatus - If the RopGetPropertiesSpecific ROP returned a StandardPropertyRow structure, or the value of the PidTagRtfCompressed property is a PtypBinary ([MS-OXCDATA] section 2.11.1) value, then assign the NoError error code to the RtfStatus variable; else copy the error code from the FlaggedPropertyValue structure to the RtfStatus variable.

  • HtmlStatus - If the RopGetPropertiesSpecific ROP returned a StandardPropertyRow structure, or the value of the PidTagHtml property is a PtypBinary value, then assign the NoError error code to the HtmlStatus variable; else copy the error code from the FlaggedPropertyValue structure to the HtmlStatus variable.

  • RtfInSync - If the RopGetPropertiesSpecific ROP returned a StandardPropertyRow structure, or the value of the PidTagRtfInSync property is PtypBoolean ([MS-OXCDATA] section 2.11.1), then copy the PtypBoolean value to the RtfInSync variable; else assign FALSE to the RtfInSync variable.

Step 3. Determine the body format based on values of the four variables created in step 2. The following table can be implemented as an "if-then-else" chain, in exactly the order specified.

PlainStatus

RtfStatus

HtmlStatus

RtfInSync

Body format

1

NotFound

NotFound

NotFound

Any

Undefined

2

NotEnoughMemory

NotFound

NotFound

Any

Plain text

3

NotEnoughMemory

NotEnoughMemory

NotFound

Any

RTF

4

NotEnoughMemory

NotEnoughMemory

NotEnoughMemory

True

RTF

5

NotEnoughMemory

NotEnoughMemory

NotEnoughMemory

False

HTML

6

Any

NoError or NotEnoughMemory

NoError or NotEnoughMemory

True

RTF

7

Any

NoError or NotEnoughMemory

NoError or NotEnoughMemory

False

HTML

8

NoError or NotEnoughMemory

NoError or NotEnoughMemory

Any

True

RTF

9.1

NoError or NotEnoughMemory

NoError or NotEnoughMemory

Any

False

Plain text

9.2

NotFound

NoError or NotEnoughMemory

NotFound

Any

RTF

9.3

NoError or NotEnoughMemory

NotFound

NotFound

Any

Plain text

9.4

NotFound

NotFound

NoError or NotEnoughMemory

Any

HTML

10

If no other case fits

Plain text

This table can be implemented by using the following pseudocode. Each row of the table is one clause of an "if-else-if" chain. Within a row, each column is ANDed together to form the condition of an "if" clause. If there is a case that is not defined, then the BodyFormat is plain text.

Code to implement

 If   PidTagNativeBody <> NotFound Then
       BodyFormat = PidTagNativeBody
 Else

1

 If   ((PlainStatus = NotFound) And
       (RtfStatus = NotFound) And
       (HtmlStatus = NotFound)) Then
           BodyFormat = Undefined 

2

 ElseIf   ((PlainStatus = NotEnoughMemory) And
       (RtfStatus = NotFound) And
       (HtmlStatus = NotFound)) Then
           BodyFormat = Plain

3

 ElseIf   ((PlainStatus = NotEnoughMemory) And
       (RtfStatus = NotEnoughMemory) And
       (HtmlStatus = NotFound)) Then
           BodyFormat = Rtf

4

 ElseIf   ((PlainStatus = NotEnoughMemory) And
       (RtfStatus = NotEnoughMemory) And
       (HtmlStatus = NotEnoughMemory) And
       (RtfInSync = True)) Then
           BodyFormat = Rtf

5

 ElseIf   ((PlainStatus = NotEnoughMemory) And
       (RtfStatus = NotEnoughMemory) And
       (HtmlStatus = NotEnoughMemory) And
       (RtfInSync = False)) Then
           BodyFormat = Html

6

 ElseIf   ((RtfStatus = NoError or RtfStatus = NotEnoughMemory) And
       (HtmlStatus = NoError or HtmlStatus = NotEnoughMemory) And
       (RtfInSync = True)) Then
           BodyFormat = Rtf

7

 ElseIf   ((RtfStatus = NoError or RtfStatus = NotEnoughMemory) And
       (HtmlStatus = NoError or HtmlStatus = NotEnoughMemory) And
       (RtfInSync = False)) Then
           BodyFormat = Html

8

 ElseIf   ((PlainStatus = NoError or PlainStatus = NotEnoughMemory) And
       (RtfStatus = NoError or RtfStatus = NotEnoughMemory) And
       (RtfInSync = True)) Then
           BodyFormat = Rtf

9.1

 ElseIf   ((PlainStatus = NoError or PlainStatus = NotEnoughMemory) And
       (RtfStatus = NoError or RtfStatus = NotEnoughMemory) And
       (RtfInSync = False)) Then
           BodyFormat = Plain

9.2

 ElseIf   ((PlainStatus = NotFound) And
       (RtfStatus = NoError or RtfStatus = NotEnoughMemory) And
       (HtmlStatus = NotFound) Then
           BodyFormat = Rtf

9.3

 ElseIf   ((PlainStatus = NoError or PlainStatus = NotEnoughMemory) And
       (RtfStatus = NotFound) And
       (HtmlStatus = NotFound) Then
           BodyFormat = Plain

9.4

 ElseIf   ((PlainStatus = NotFound) And
       (RtfStatus = NotFound) And
       (HtmlStatus = NoError or HtmlStatus = NotEnoughMemory) Then
           BodyFormat = Html

10

 Else
       BodyFormat = Plain

 End   If
 End   If