void
FieldInstructionDecimal::encodeConstant(
  Codecs::DataDestination & /*destination*/,
  Codecs::PresenceMap & pmap,
  Codecs::Encoder & encoder,
  const Messages::MessageAccessor & accessor) const
{
  if(!isMandatory())
  {
    // get the value from the application data
    Decimal value;
    if(accessor.getDecimal(*identity_, ValueType::DECIMAL, value))
    {
      if(value != typedValue_)
      {
        encoder.reportFatal("[ERR U10]", "Constant value does not match application data.", *identity_);
      }

      pmap.setNextField(true);
    }
    else // not defined by accessor
    {
      pmap.setNextField(false);
    }
  }
}
void
FieldInstructionDecimal::encodeDefault(
  Codecs::DataDestination & destination,
  Codecs::PresenceMap & pmap,
  Codecs::Encoder & encoder,
  const Messages::MessageAccessor & accessor) const
{
  // get the value from the application data
  Decimal value;
  if(accessor.getDecimal(*identity_, ValueType::DECIMAL, value))
  {
    if(typedValueIsDefined_ &&
      value == typedValue_)
    {
      pmap.setNextField(false); // not in stream. use default
    }
    else
    {
      pmap.setNextField(true); // != default.  Send value

      if(isMandatory())
      {
        encodeDecimal(destination, encoder.getWorkingBuffer(), value.getExponent(), value.getMantissa());
      }
      else
      {
        encodeNullableDecimal(destination, encoder.getWorkingBuffer(), value.getExponent(), value.getMantissa());
      }
    }
  }
  else // not defined by accessor
  {
    if(isMandatory())
    {
      encoder.reportFatal("[ERR U01]", "Missing mandatory field.", *identity_);
    }
    // if there is a default value
    // you have to cancel this by sending a null.
    if(fieldOp_->hasValue())
    {
      pmap.setNextField(true);
      destination.putByte(nullDecimal);
    }
    else
    {
      pmap.setNextField(false);
    }
  }
}
예제 #3
0
void
FieldInstructionGroup::decodeNop(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & messageBuilder) const
{
  bool present = true;

  if(! isMandatory())
  {
    present = pmap.checkNextField();
  }

  if(present)
  {
    if(!segmentBody_)
    {
      decoder.reportFatal("[ERR U08}", "Segment not defined for Group instruction.");
    }
    if(messageBuilder.getApplicationType() != segmentBody_->getApplicationType())
    {
//      std::cout << "Decoding group into new segment: " << segmentBody_->getApplicationType() << std::endl;
      Messages::ValueMessageBuilder & groupBuilder(
        messageBuilder.startGroup(
          identity_,
          segmentBody_->getApplicationType(),
          segmentBody_->getApplicationTypeNamespace(),
          segmentBody_->fieldCount()));

      decoder.decodeGroup(source, segmentBody_, groupBuilder);
      messageBuilder.endGroup(
        identity_,
        groupBuilder);
    }
    else
    {
//      std::cout << "Folding group into parent segment: " << segmentBody_->getApplicationType() << std::endl;
      // Because the application types match,
      // the group fields are decoded directly into to the current
      // field set.  As a result the group "disappears" completely
      // from the application message.  This is a good thing.  Groups
      // are an artifact of the template used to encode the message
      // rather than being an attribute of the actual message being
      // encoded.  In fact, the same message encoded with different
      // templates could be transmitted with different sets of fields
      // in groups.
      decoder.decodeGroup(source, segmentBody_, messageBuilder);
    }
  }
}
예제 #4
0
void
FieldInstructionGroup::encodeNop(
  Codecs::DataDestination & destination,
  Codecs::PresenceMap & pmap,
  Codecs::Encoder & encoder,
  const Messages::MessageAccessor & messageAccessor) const
{
  if(!segmentBody_)
  {
    encoder.reportFatal("[ERR U08}", "Segment not defined for Group instruction.");
  }
  // retrieve the field corresponding to this group
  // Note that applications may support merging groups
  // by returning true from getGroup but using the same accessor.
  const Messages::MessageAccessor * group;
  if(messageAccessor.getGroup(*identity_, group))
  {
    if(! isMandatory())
    {
      pmap.setNextField(true);
    }
    encoder.encodeGroup(destination, segmentBody_, *group);
    messageAccessor.endGroup(*identity_, group);
  }
  else
  {
    if(isMandatory())
    {
      encoder.reportFatal("[ERR U01]", "Missing mandatory group.");
      encoder.encodeGroup(destination, segmentBody_, messageAccessor);
    }
    else
    {
      pmap.setNextField(false);
    }
  }
}
void
FieldInstructionDecimal::decodeConstant(
  Codecs::DataSource & /*source*/,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & /*decoder*/,
  Messages::ValueMessageBuilder & accessor) const
{
  PROFILE_POINT("decimal::decodeConstant");
  if(isMandatory() || pmap.checkNextField())
  {
    accessor.addValue(
      identity_,
      ValueType::DECIMAL,
      typedValue_);
  }
}
void
FieldInstructionDecimal::decodeDefault(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & accessor) const
{
  PROFILE_POINT("decimal::decodeDefault");
  if(pmap.checkNextField())
  {
    exponent_t exponent = 0;
    decodeSignedInteger(source, decoder, exponent, identity_->name());
    if(!isMandatory())
    {
      if(checkNullInteger(exponent))
      {
        return;
      }
    }
    mantissa_t mantissa;
    decodeSignedInteger(source, decoder, mantissa, identity_->name());
    Decimal value(mantissa, exponent);
    accessor.addValue(
      identity_,
      ValueType::DECIMAL,
      value);
  }
  else // field not in stream
  {
    if(typedValueIsDefined_)
    {
      accessor.addValue(
        identity_,
        ValueType::DECIMAL,
        typedValue_);
    }
    else if(isMandatory())
    {
      decoder.reportFatal("[ERR D5]", "Mandatory default operator with no value.", *identity_);
    }
  }
}
void
FieldInstructionDecimal::encodeCopy(
  Codecs::DataDestination & destination,
  Codecs::PresenceMap & pmap,
  Codecs::Encoder & encoder,
  const Messages::MessageAccessor & accessor) const
{
  Decimal previousValue(0,0);
  Context::DictionaryStatus previousStatus = fieldOp_->getDictionaryValue(encoder, previousValue);
  if(previousStatus == Context::UNDEFINED_VALUE)
  {
    if(fieldOp_->hasValue())
    {
      previousValue = typedValue_;
      fieldOp_->setDictionaryValue(encoder, previousValue);
      // pretend we got the data from the dictionary
      previousStatus = Context::OK_VALUE;
    }
    else
    {
      // pretend we got a null from the dictionary
      fieldOp_->setDictionaryValueNull(encoder);
      previousStatus = Context::NULL_VALUE;
    }
  }

  // get the value from the application data
  Decimal value;
  if(accessor.getDecimal(*identity_, ValueType::DECIMAL, value))
  {
    if(previousStatus == Context::OK_VALUE && previousValue == value)
    {
      pmap.setNextField(false); // not in stream, use copy
    }
    else
    {
      pmap.setNextField(true);// value in stream
      if(isMandatory())
      {
        encodeDecimal(destination, encoder.getWorkingBuffer(), value.getExponent(), value.getMantissa());
      }
      else
      {
        encodeNullableDecimal(destination, encoder.getWorkingBuffer(), value.getExponent(), value.getMantissa());
      }
      fieldOp_->setDictionaryValue(encoder, value);
    }
  }
  else // not defined by accessor
  {
    if(isMandatory())
    {
      encoder.reportFatal("[ERR U01]", "Missing mandatory decimal field.", *identity_);
      // if reportFatal returns we're being lax about encoding rules
      // let the copy happen.
      pmap.setNextField(false);
    }
    else
    {
      // Missing optional field.  If we have a previous, non-null value
      // we need to explicitly null it out.  Otherwise just don't send it.
      if(previousValue != Context::NULL_VALUE)
      {
        pmap.setNextField(true);// value in stream
        destination.putByte(nullDecimal);
        fieldOp_->setDictionaryValueNull(encoder);
      }
      else
      {
        pmap.setNextField(false);
      }
    }
  }
}
void
FieldInstructionDecimal::decodeCopy(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & accessor) const
{
  PROFILE_POINT("decimal::decodeCopy");
  exponent_t exponent = 0;
  mantissa_t mantissa = 0;
  if(pmap.checkNextField())
  {
    decodeSignedInteger(source, decoder, exponent, identity_->name());
    if(isMandatory())
    {
      decodeSignedInteger(source, decoder, mantissa, identity_->name());
      Decimal value(mantissa, exponent, false);
      accessor.addValue(
        identity_,
        ValueType::DECIMAL,
        value);
      fieldOp_->setDictionaryValue(decoder, value);
    }
    else
    {
      // not mandatory means it's nullable
      if(checkNullInteger(exponent))
      {
        fieldOp_->setDictionaryValueNull(decoder);
      }
      else
      {
        decodeSignedInteger(source, decoder, mantissa, identity_->name());
        Decimal value(mantissa, exponent, false);
        accessor.addValue(
          identity_,
          ValueType::DECIMAL,
          value);
        fieldOp_->setDictionaryValue(decoder, value);
      }
    }

  }
  else // pmap says not present, use copy
  {
    Decimal value(0,0);
    Context::DictionaryStatus previousStatus = fieldOp_->getDictionaryValue(decoder, value);
    if(previousStatus == Context::UNDEFINED_VALUE)
    {
      // value not found in dictionary
      // not a problem..  use initial value if it's available
      if(fieldOp_->hasValue())
      {
        accessor.addValue(
          identity_,
          ValueType::DECIMAL,
          typedValue_);
        fieldOp_->setDictionaryValue(decoder, typedValue_);
      }
      else
      {
        if(isMandatory())
        {
          decoder.reportFatal("[ERR D5]", "Copy operator missing mandatory Decimal field/no initial value", *identity_);
        }
      }
    }
    else if(previousStatus == Context::OK_VALUE)
    {
      accessor.addValue(
        identity_,
        ValueType::DECIMAL,
        value);
    }
    //else previous was null so don't put anything in the record
  }
}