1.14.2. Creating a WAP Binary XML parser

When you create a parser you must take care to set up the token values for your tags correctly. These values only have a limited range. And the range also varies if attributtes are used or if it is an empty element.

ulxr_wbxmlparse.h contains constants for the ranges.

wbxml_TAG_FIRST, wbxml_TAG_LAST

boundaries for empty elements without attributes

wbxml_TAG_C_FIRST, wbxml_TAG_C_LAST

boundaries for elements with content but without attributes

wbxml_TAG_A_FIRST, wbxml_TAG_A_LAST

boundaries for empty elements with attributes. Currently not used as attributes are not supported.

wbxml_TAG_AC_FIRST, wbxml_TAG_AC_LAST

boundaries for elements with content and attributes. Currently not used as attributes are not supported.

ulxmlrpcpp uses this technique to model the parsers for the XML-RPC tags MethodResponse or MethodCall which both include Value.


  class ValueParserWb : public WbXmlParser
  {
    enum ValueWellKnownToken 1
    {
      wbToken_Value     = wbxml_TAG_C_FIRST,   // 0x45 2
      wbToken_Array,                           // 0x46
      ...
      wbToken_Date,                            // 0x51
      wbToken_ValueParserLast                  // 0x52 3
    }
  ...


  class MethodResponseParserWb : public ValueParserWb,
  {
    enum RespWellKnownToken
    {
      wbToken_MethodResponse = ValueParserWb::wbToken_ValueParserLast, // 0x52 4
      wbToken_Fault,                                                   // 0x53
      wbToken_Params,                                                  // 0x54
      wbToken_Param,                                                   // 0x55
      wbToken_ResponseParserLast                                       // 0x56
    };

1

It is advisable to define the token values as enum structures.

2

The first item is assigned a defined start value.

3

You should also create an entry for the token beyond the last one.

4

This allows to create the start token for a potential deriving parser which uses the parent parser as "inner" element.

For more examples on the working method see the various *parse_wb.cpp files.

[Caution]There is one pitfall:

1

The first constructor in a chain of derived parsers must push an appropriate element onto the state stack because the parser methods rely upon being able to retrieve information about the current state.

2

The destructor on the other hand must clean up the stack.


  WbXmlParser::WbXmlParser()
  {
    states.push(new ValueState(eNone)); 1
  }

  WbXmlParser::~WbXmlParser()
  {
    while (states.size() != 0)2
    {
      delete getTopValueState()->getValue();
      delete getTopValueState();
      states.pop();
    }
  }