Close

Relief for ODA Team in Ukraine

Learn more
ODA Drawings SDK
Example of Entering and Displaying the Group Code and Data Value for XData

This example demonstrates working with tagged data of extended data technology. The resbuf-object implements an instance of the tagged data containing a group code and data value. This example implements the following:

  • Three functions for displaying information about a group code:
    • AboutXDataType() — Displays the data type.
    • AboutXDataValue() — Displays the data value.
    • AboutXData() — Displays the tagged data (code and value).
  • Three functions for entering a group code:
    • EntryXDataType() — Enters the data type.
    • EntryXDataValue() — Enters the data value.
    • EntryXData() — Enters the tagged data (code and value).

All functions use the instance of the OdResBuf type for working with tagged data belonging to the extended data.

The AboutXDataType() function displays information about the group code stored in the passed tagged data. The function requires a pointer to an existing resbuf-instance as an argument and returns information about its group code as a value of the OdString type. The function gets the current group code using the restype() method and uses the switch statement to select the information string comparing the obtained code with values admissible for the extended data technology. The function concatenates the information string with the obtained code in the resulting string. If the group code is undefined, the function returns the string "nonXData".

The AboutXDataType() function has the following implementation:


OdString AboutXDataType(OdResBuf *pRb)
{
  OdString sInfo;
  sInfo.format(L"[%d,", pRb->restype());

  switch(pRb->restype())
  {
    case OdResBuf::kDxfXdAsciiString   :   sInfo += L"String";            break;
    case OdResBuf::kDxfRegAppName      :   sInfo += L"AppName";           break;
    case OdResBuf::kDxfXdControlString :   sInfo += L"Block";             break;
    case OdResBuf::kDxfXdLayerName     :   sInfo += L"LayerName";         break;
    case OdResBuf::kDxfXdBinaryChunk   :   sInfo += L"BinaryChunk";       break;
    case OdResBuf::kDxfXdHandle        :   sInfo += L"Handle";            break;
    case OdResBuf::kDxfXdXCoord        :   sInfo += L"3D Point";          break;
    case OdResBuf::kDxfXdYCoord        :   sInfo += L"Coordinate";        break;
    case OdResBuf::kDxfXdZCoord        :   sInfo += L"Coordinate";        break;
    case OdResBuf::kDxfXdWorldXCoord   :   sInfo += L"3D Position";       break;
    case OdResBuf::kDxfXdWorldYCoord   :   sInfo += L"World";             break;
    case OdResBuf::kDxfXdWorldZCoord   :   sInfo += L"World";             break;
    case OdResBuf::kDxfXdWorldXDisp    :   sInfo += L"3D Displacement";   break;
    case OdResBuf::kDxfXdWorldYDisp    :   sInfo += L"Displacement";      break;
    case OdResBuf::kDxfXdWorldZDisp    :   sInfo += L"Displacement";      break;
    case OdResBuf::kDxfXdWorldXDir     :   sInfo += L"3D Direction";      break;
    case OdResBuf::kDxfXdWorldYDir     :   sInfo += L"Direction";         break;
    case OdResBuf::kDxfXdWorldZDir     :   sInfo += L"Direction";         break;
    case OdResBuf::kDxfXdReal          :   sInfo += L"Real";              break;
    case OdResBuf::kDxfXdDist          :   sInfo += L"Distance";          break;
    case OdResBuf::kDxfXdScale         :   sInfo += L"Scale";             break;
    case OdResBuf::kDxfXdInteger16     :   sInfo += L"Short";             break;
    case OdResBuf::kDxfXdInteger32     :   sInfo += L"Long";              break;
    case OdResBuf::kRtNone             :   sInfo += L"None";              break;
    default:                               sInfo += L"nonXData";
  }
  sInfo += L"]";
  return sInfo;
}

The AboutXDataValue() function displays information about a data value stored in the passed tagged data. The function requires a pointer to an existing resbuf-instance as an argument and returns information about its data value as a value of the OdString type. The function gets a group code using the restype() method and uses the switch statement to select the method for converting the data value depending on the data type:

  • Handle — The function uses the getHandle() method.
  • Arbitrary string, control string, application name, or layer name— The function uses the getString() method.
  • Three-dimensional point or vector — The function uses the getPoint3d() method and an instance of the OdGePoint3d type for getting the point and converting the X,Y,Z-coordinates.
  • Y, Z-coordinate, distance, scale, or real value — The function uses the getDouble() method.
  • 16-bit integer value — The function uses the getInt16() method.
  • 32-bit integer value — The function uses the getInt32() method.
  • Binary chunk — The function uses the getBinaryChunk() method and the AboutBinaryChunk() function for converting a chunk to a string value.
  • Undefined — The function returns the string "?".

The AboutXDataValue() function has the following implementation:


OdString AboutXDataValue(OdResBuf *pRb)
{
  OdString sInfo;
  OdGePoint3d point;

  switch(pRb->restype())
  {
    case OdResBuf::kDxfXdHandle:   
      sInfo = pRb->getHandle().ascii();           
      break;
    case OdResBuf::kDxfRegAppName:   
    case OdResBuf::kDxfXdLayerName:   
    case OdResBuf::kDxfXdAsciiString:   
    case OdResBuf::kDxfXdControlString:   
      sInfo.format(L"\"%s\"", pRb->getString().c_str());           
      break;
    case OdResBuf::kDxfXdXCoord: 
    case OdResBuf::kDxfXdWorldXDir:
    case OdResBuf::kDxfXdWorldXDisp:
    case OdResBuf::kDxfXdWorldXCoord:
      point = pRb->getPoint3d();
      sInfo.format(L"(%g,%g,%g)", point.x, point.y, point.z);
      break;
    case OdResBuf::kDxfXdReal:
    case OdResBuf::kDxfXdDist:
    case OdResBuf::kDxfXdScale:
    case OdResBuf::kDxfXdYCoord:   
    case OdResBuf::kDxfXdZCoord:  
    case OdResBuf::kDxfXdWorldYDir:
    case OdResBuf::kDxfXdWorldZDir:
    case OdResBuf::kDxfXdWorldYDisp:
    case OdResBuf::kDxfXdWorldZDisp:
    case OdResBuf::kDxfXdWorldYCoord:
    case OdResBuf::kDxfXdWorldZCoord:
      sInfo.format(L"%g", pRb->getDouble());           
      break;
    case OdResBuf::kDxfXdInteger16:
      sInfo.format(L"%d", pRb->getInt16());           
      break;
    case OdResBuf::kDxfXdInteger32:
      sInfo.format(L"%ld", pRb->getInt32());           
      break;
    case OdResBuf::kDxfXdBinaryChunk:
      sInfo = AboutBinaryChunk(pRb->getBinaryChunk());
      break;
    default:
      sInfo = L"?";
  }
  return sInfo;
}

The AboutXData() function displays information about a group code and data value stored in the passed tagged data. The function requires a pointer to an existing resbuf-instance as the first argument, a sign which defines whether information is whole (True) or short (False) as the second argument, and returns information about the group code, data type, and data value as a value of the OdString type. The function uses the AboutXDataType() function for displaying information about a group code and the AboutXDataValue() function for displaying information about a data value. When the second argument is False, the function returns a string: "code = value" using the toString() function for converting the group code.

The AboutXData() function has the following implementation:


OdString AboutXData(OdResBuf *pRb, bool isWhole)
{
  return ((pRb->restype() == OdResBuf::kRtNone) ? L"[None]" :
          ((isWhole) ? AboutXDataType(pRb) : L"[" + toString(pRb->restype()) + L"]") 
          + L" = " + AboutXDataValue(pRb));
}

The EntryXDataType() function selects and sets the group code for the passed tagged data. The function requires a pointer to an existing resbuf-instance as an argument and returns True when the passed tagged data is changed or False when the user cancels entry. The function organizes a loop for selecting the group code. If an entered code is incorrect or is inadmissible, the function displays an error message and repeats entry. If the entered code is correct, the function sets it in the resbuf-instance using the setRestype() method and returns True. If the entered code is zero or the user cancels entry, the function returns False for the remaining and the current group code and data value.

The EntryXDataType() function has the following implementation:


bool EntryXDataType(OdResBuf* pRb)
{
  OdInt16 codetype;
  do {
    wcout << L"\nAccessible group codes:";
    wcout << L"\n1000 - Arbitrary string";
    wcout << L"\n1002 - Block brace - { or }";
    wcout << L"\n1003 - Layer name";
    wcout << L"\n1004 - Binary chunk";
    wcout << L"\n1005 - Handle";
    wcout << L"\n1010 - 3D Point";
    wcout << L"\n1011 - 3D Position";
    wcout << L"\n1012 - 3D Displacement";
    wcout << L"\n1013 - 3D Direction";
    wcout << L"\n1040 - Real value";
    wcout << L"\n1041 - Distance";
    wcout << L"\n1042 - Scale factor";
    wcout << L"\n1070 - Short integer";
    wcout << L"\n1071 - Long integer";
    wcout << L"\n0 - Quit";
    wcout << L"\nEntry group code:>";
    wcin >> codetype;
    if(!wcin.fail() && wcin.peek() == 10)
    {
      if((codetype >= 1002 && codetype <= 1005) ||
         (codetype >= 1010 && codetype <= 1013) || 
         (codetype >= 1040 && codetype <= 1042) ||
          codetype == 1000 || codetype == 1070 || codetype == 1071)
      {
        pRb->setRestype(codetype);
        return true;
      }
      else if(codetype != 0) wcout << L"Error: Unknown code\n";
    }
    else 
    {
      wcin.sync();
      wcin.clear();  
      wcout << L"Error: Invalid entered code";
    }
  } 
  while(codetype != 0);

  return false;
}

The EntryXDataValue() function sets the data value for the passed tagged data. The function requires a pointer to an existing resbuf-instance as an argument and returns True when the data value is set or False when the user cancels entry. The function organizes a loop for selecting the group code and entering the data value corresponding to the group code. The function gets the current group code using the restype() method and uses the switch statement to select the method of working with the data value, depending on the data type:

  • Arbitrary string (1000) — The function enters a value as a wide-character string value in the buffer using the getline() method and sets the data value using the setString() method.
  • Control string (1002) — The function enters a value as the character '{' or '}', saves the entered character in the buffer as a string from one character, and sets the data value using the setString() method.
  • 16-bit integer value (1070) — The function enters a value as an integer variable and sets the data value using the setInt16() method.
  • 32-bit integer value (1071) — The function enters a value as an integer variable and sets the data value using the setInt32() method.
  • Handle (1005) — The function enters a value as an integer variable using the hexadecimal format and sets the data value using the setHandle() method.
  • Real (1040), distance (1041), or scale (1042) — The function enters a value as a double value and sets the data value using the setDouble() method.
  • Three-dimensional point (1010), position (1011), displacement (1012), or direction (1013) — The function enters a value as an instance of the OdGePoint3d type requesting the X, Y, Z coordinates and sets the data value using the setPoint3d() method.
  • Binary chunk (1004) — The function enters a value as an instance of the OdBinaryData type and sets the data value using the setBinaryChunk() method.

After setting a data value, the function returns True. If the group code is inadmissible, the function uses the EntryXDataType() function for selecting and setting the group code and repeats entry of the data value. If the data value is incorrect, the function displays an error message and repeats the entry. If the user enters 'Q' after incorrect entry, the user cancels entry and the function returns False.

The EntryXDataValue() function has the following implementation:


bool EntryXDataValue(OdResBuf* pRb)
{
  wchar_t buffer[64],ch;
  double value;
  OdInt16 int16;
  OdInt32 int32;
  OdUInt64 int64;
  OdGePoint3d point;
  OdBinaryData chunk;

  do {
    switch(pRb->restype())
    {
      case 1000:
        wcin.sync();
        wcout << L"String:>";
        wcin.getline(buffer, 64, 10);
        pRb->setString(buffer);
        return true;

      case 1002:
        wcout << L"Entry { or }:>";
        wcin >> ch;
        if(ch == L'{' || ch == L'}')
        {
          buffer[0]=ch;
          buffer[1]=L'\0';
          pRb->setString(buffer);
          return true;
        }
        break;

      case 1004:
        if(ModifyBinaryChunk(chunk))
        {
          pRb->setBinaryChunk(chunk);
          return true;
        }
        break;

      case 1005:
        wcout << L"Handle:>";
        wcin >> hex >> int64 >> dec;
        if(!wcin.fail() && wcin.peek() == 10)
        {
          pRb->setHandle(int64);
          return true;
        }
        break;

      case 1071:
        wcout << L"32-bit integer value:>";
        wcin >> int32;
        if(!wcin.fail() && wcin.peek() == 10)
        {
          pRb->setInt32(int32);
          return true;
        }
        break;

      case 1070:
        wcout << L"16-bit integer value:>";
        wcin >> int16;
        if(!wcin.fail() && wcin.peek() == 10)
        {
          pRb->setInt16(int16);
          return true;
        }
        break;

      case 1040:
      case 1041:
      case 1042:
        wcout << L"Double value:>";
        wcin >> value;
        if(!wcin.fail() && wcin.peek() == 10)
        {
          pRb->setDouble(value);
          return true;
        }
        break;

      case 1010:
      case 1011:
      case 1012:
      case 1013:
        wcout << L"Entry X-coordinate:>";
        wcin >> point.x;
        if(!wcin.fail() && wcin.peek() == 10)
        {
          wcout << L"Entry Y-coordinate:>";
          wcin >> point.y;
          if(!wcin.fail() && wcin.peek() == 10)
          {
            wcout << L"Entry Z-coordinate:>";
            wcin >> point.z;
            if(!wcin.fail() && wcin.peek() == 10)
            {
              pRb->setPoint3d(point);
              return true;
            }
          }
        }
        break;

      default:
        if(EntryXDataType(pRb)) continue;
        return false;
    }
    wcin.sync();
    wcin.clear();  
    wcout << L"Error: Invalid entered value\nPress any key to repeat [or Q-quit]:>";
    wcin >> ch;
  } 
  while(ch != L'Q' && ch != L'q');

  return false;
}

The EntryXData() function either enters a group code and data value or enters only a data value for the specified tagged data. The function requires a pointer to an existing resbuf-instance as the first argument, a sign that defines whether the function enters a group code and data value (True) or only a data value (False) as the second argument, and returns True when the tagged data is changed or False when the user cancels entry. The function uses the EntryXDataType() function for entering a group code and the EntryXDataValue() function for entering a data value.

The EntryXData() function has the following implementation:


bool EntryXData(OdResBuf* pRb, bool isWhole)
{
  if(isWhole)
  {
    if(EntryXDataType(pRb))
      if(EntryXDataValue(pRb))
        return true;
  }
  else if(EntryXDataValue(pRb))
         return true;
  return false;
}

The IsXDataMarker() function checks whether the specified group code is the specific marker. The function requires a pointer to an existing resbuf-instance as the first argument and returns True when the group code is a marker or False when the group code is ordinary. The function gets the group code using the restype() method and compares it with 1001, which defines the starting of the sequence of the extended data associated with a registered application.

The IsXDataMarker() function has the following implementation:


bool IsXDataMarker(OdResBuf* pRb)
{ 
  return (pRb->restype() == OdResBuf::kDxfRegAppName);
}

See Also

Working with Extended Data

Available XData Group Codes

Example of Working with Extended Data

Copyright © 2002 – 2022. Open Design Alliance. All rights reserved.