dwg_encode_xdata (Bit_Chain *restrict dat, Dwg_Object_XRECORD *restrict obj, int size)
{
  Dwg_Resbuf *rbuf = obj->xdata;
  enum RES_BUF_VALUE_TYPE type;
  int i, j = 0;

  while (rbuf)
    {
      bit_write_RS (dat, rbuf->type);
      type = get_base_value_type (rbuf->type);
      switch (type)
        {
        case VT_STRING:
          UNTIL (R_2007)
          {
            bit_write_RS (dat, rbuf->value.str.size);
            bit_write_RC (dat, rbuf->value.str.codepage);
            if (rbuf->value.str.u.data)
              bit_write_TF (dat, rbuf->value.str.u.data, rbuf->value.str.size);
            else
              bit_write_TF (dat, (char*)"", 0);
            LOG_TRACE ("xdata[%d]: \"%s\" [TF %d %d]\n", j,
                       rbuf->value.str.u.data, rbuf->value.str.size,
                       rbuf->type);
          }
          LATER_VERSIONS
          {
            bit_write_RS (dat, rbuf->value.str.size);
            for (i = 0; i < rbuf->value.str.size; i++)
              bit_write_RS (dat, rbuf->value.str.u.wdata[i]);
          }
          break;
        case VT_REAL:
          bit_write_RD (dat, rbuf->value.dbl);
          LOG_TRACE ("xdata[%d]: %f [RD %d]\n", j, rbuf->value.dbl,
                     rbuf->type);
          break;
        case VT_BOOL:
        case VT_INT8:
          bit_write_RC (dat, rbuf->value.i8);
          LOG_TRACE ("xdata[%d]: %d [RC %d]\n", j, (int)rbuf->value.i8,
                     rbuf->type);
          break;
        case VT_INT16:
          bit_write_RS (dat, rbuf->value.i16);
          LOG_TRACE ("xdata[%d]: %d [RS %d]\n", j, (int)rbuf->value.i16,
                     rbuf->type);
          break;
        case VT_INT32:
          bit_write_RL (dat, rbuf->value.i32);
          LOG_TRACE ("xdata[%d]: %ld [RL %d]\n", j, (long)rbuf->value.i32,
                     rbuf->type);
          break;
        case VT_INT64:
          bit_write_BLL (dat, rbuf->value.i64);
          LOG_TRACE ("xdata[%d]: " FORMAT_BLL " [BLL %d]\n", j,
                     rbuf->value.i64, rbuf->type);
          break;
        case VT_POINT3D:
          bit_write_RD (dat, rbuf->value.pt[0]);
          bit_write_RD (dat, rbuf->value.pt[1]);
          bit_write_RD (dat, rbuf->value.pt[2]);
          LOG_TRACE ("xdata[%d]: (%f,%f,%f) [3RD %d]\n", j, rbuf->value.pt[0],
                     rbuf->value.pt[1], rbuf->value.pt[2], rbuf->type);
          break;
        case VT_BINARY:
          bit_write_RC (dat, rbuf->value.str.size);
          bit_write_TF (dat, rbuf->value.str.u.data, rbuf->value.str.size);
          LOG_TRACE ("xdata[%d]: [TF %d %d] ", j, rbuf->value.str.size,
                     rbuf->type);
          LOG_TRACE_TF (rbuf->value.str.u.data, rbuf->value.str.size);
          break;
        case VT_HANDLE:
        case VT_OBJECTID:
          for (i = 0; i < 8; i++)
            bit_write_RC (dat, rbuf->value.hdl[i]);
          LOG_TRACE ("xdata[%d]: " FORMAT_H " [H %d]\n", j,
                     ARGS_H (rbuf->value.h), rbuf->type);
          break;
        case VT_INVALID:
        default:
          LOG_ERROR ("Invalid group code in xdata: %d", rbuf->type)
          return DWG_ERR_INVALIDEED;
        }
      rbuf = rbuf->next;
      j++;
    }
  return 0;
}
dwg_encode_xdata (Bit_Chain *restrict dat, Dwg_Object_XRECORD *restrict obj, int size)
{
  Dwg_Resbuf *rbuf = obj->xdata;
  enum RES_BUF_VALUE_TYPE type;
  int i, j = 0;

  while (rbuf)
    {
      bit_write_RS (dat, rbuf->type);
      type = get_base_value_type (rbuf->type);
      switch (type)
        {
        case VT_STRING:
          UNTIL (R_2007)
          {
            bit_write_RS (dat, rbuf->value.str.size);
            bit_write_RC (dat, rbuf->value.str.codepage);
            if (rbuf->value.str.u.data)
              bit_write_TF (dat, rbuf->value.str.u.data, rbuf->value.str.size);
            else
              bit_write_TF (dat, (char*)"", 0);
            LOG_TRACE ("xdata[%d]: \"%s\" [TF %d %d]\n", j,
                       rbuf->value.str.u.data, rbuf->value.str.size,
                       rbuf->type);
          }
          LATER_VERSIONS
          {
            bit_write_RS (dat, rbuf->value.str.size);
            for (i = 0; i < rbuf->value.str.size; i++)
              bit_write_RS (dat, rbuf->value.str.u.wdata[i]);
          }
          break;
        case VT_REAL:
          bit_write_RD (dat, rbuf->value.dbl);
          LOG_TRACE ("xdata[%d]: %f [RD %d]\n", j, rbuf->value.dbl,
                     rbuf->type);
          break;
        case VT_BOOL:
        case VT_INT8:
          bit_write_RC (dat, rbuf->value.i8);
          LOG_TRACE ("xdata[%d]: %d [RC %d]\n", j, (int)rbuf->value.i8,
                     rbuf->type);
          break;
        case VT_INT16:
          bit_write_RS (dat, rbuf->value.i16);
          LOG_TRACE ("xdata[%d]: %d [RS %d]\n", j, (int)rbuf->value.i16,
                     rbuf->type);
          break;
        case VT_INT32:
          bit_write_RL (dat, rbuf->value.i32);
          LOG_TRACE ("xdata[%d]: %ld [RL %d]\n", j, (long)rbuf->value.i32,
                     rbuf->type);
          break;
        case VT_INT64:
          bit_write_BLL (dat, rbuf->value.i64);
          LOG_TRACE ("xdata[%d]: " FORMAT_BLL " [BLL %d]\n", j,
                     rbuf->value.i64, rbuf->type);
          break;
        case VT_POINT3D:
          bit_write_RD (dat, rbuf->value.pt[0]);
          bit_write_RD (dat, rbuf->value.pt[1]);
          bit_write_RD (dat, rbuf->value.pt[2]);
          LOG_TRACE ("xdata[%d]: (%f,%f,%f) [3RD %d]\n", j, rbuf->value.pt[0],
                     rbuf->value.pt[1], rbuf->value.pt[2], rbuf->type);
          break;
        case VT_BINARY:
          bit_write_RC (dat, rbuf->value.str.size);
          bit_write_TF (dat, rbuf->value.str.u.data, rbuf->value.str.size);
          LOG_TRACE ("xdata[%d]: [TF %d %d] ", j, rbuf->value.str.size,
                     rbuf->type);
          LOG_TRACE_TF (rbuf->value.str.u.data, rbuf->value.str.size);
          break;
        case VT_HANDLE:
        case VT_OBJECTID:
          for (i = 0; i < 8; i++)
            bit_write_RC (dat, rbuf->value.hdl[i]);
          LOG_TRACE ("xdata[%d]: " FORMAT_H " [H %d]\n", j,
                     ARGS_H (rbuf->value.h), rbuf->type);
          break;
        case VT_INVALID:
        default:
          LOG_ERROR ("Invalid group code in xdata: %d", rbuf->type)
          return DWG_ERR_INVALIDEED;
        }
      rbuf = rbuf->next;
      j++;
    }
  return 0;
}