void
FieldInstructionSequence::decodeNop(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & builder) const
{
  if(!segment_)
  {
    decoder.reportFatal("[ERR U07]", "SegmentBody not defined for Sequence instruction.");
  }
  size_t length = 0;
  Codecs::FieldInstructionCPtr lengthInstruction;
  Messages::SingleValueBuilder<uint32> lengthSet;
  if(segment_->getLengthInstruction(lengthInstruction))
  {
    source.beginField(lengthInstruction->getIdentity()->name());
    lengthInstruction->decode(source, pmap, decoder, lengthSet);
  }
  else
  {
    FieldInstructionUInt32 defaultLengthInstruction;
    defaultLengthInstruction.setPresence(isMandatory());
    defaultLengthInstruction.decode(source, pmap, decoder, lengthSet);
  }
  if(lengthSet.isSet())
  {
    length = lengthSet.value();

    Messages::ValueMessageBuilder & sequenceBuilder = builder.startSequence(
      identity_,
      segment_->getApplicationType(),
      segment_->getApplicationTypeNamespace(),
      segment_->fieldCount(),
      lengthSet.identity(),
      length);

    for(size_t nEntry = 0; nEntry < length; ++nEntry)
    {
      if(decoder.getLogOut())
      {
        std::stringstream msg;
        msg << "Sequence entry #" << nEntry << " of " << length << std::ends;
        decoder.logMessage(msg.str());
      }

      Messages::ValueMessageBuilder & entrySet(
        sequenceBuilder.startSequenceEntry(
          segment_->getApplicationType(),
          segment_->getApplicationTypeNamespace(),
          segment_->fieldCount()));
      decoder.decodeGroup(source, segment_, entrySet);
      sequenceBuilder.endSequenceEntry(entrySet);
    }
    builder.endSequence(identity_, sequenceBuilder);
  }
}
Example #2
0
void
Decoder::decodeNestedTemplate(
   DataSource & source,
   Messages::ValueMessageBuilder & messageBuilder,
   Messages::FieldIdentityCPtr & identity)
{
  Codecs::PresenceMap pmap(getTemplateRegistry()->presenceMapBits());
  if(this->verboseOut_)
  {
    pmap.setVerbose(verboseOut_);
  }

  static const std::string pmp("PMAP");
  source.beginField(pmp);
  pmap.decode(source);

  static const std::string tid("templateID");
  source.beginField(tid);
  if(pmap.checkNextField())
  {
    template_id_t id;
    FieldInstruction::decodeUnsignedInteger(source, *this, id, tid);
    setTemplateId(id);
  }
  if(verboseOut_)
  {
    (*verboseOut_) << "Nested Template ID: " << getTemplateId() << std::endl;
  }
  Codecs::TemplateCPtr templatePtr;
  if(getTemplateRegistry()->getTemplate(getTemplateId(), templatePtr))
  {
    if(templatePtr->getReset())
    {
      reset(false);
    }
    Messages::ValueMessageBuilder & groupBuilder(
      messageBuilder.startGroup(
        identity,
        templatePtr->getApplicationType(),
        templatePtr->getApplicationTypeNamespace(),
        templatePtr->fieldCount()));

    decodeSegmentBody(source, pmap, templatePtr, groupBuilder);
    messageBuilder.endGroup(identity, groupBuilder);
  }
  else
  {
    std::string error =  "Unknown template ID:";
    error += boost::lexical_cast<std::string>(getTemplateId());
    reportError("[ERR D9]", error);
  }
  return;
}
void
FieldInstructionDecimal::decodeNop(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & accessor) const
{
  PROFILE_POINT("decimal::decodeNop");

  if(bool(exponentInstruction_))
  {
    Messages::SingleValueBuilder<int32> exponentBuilder;
    exponentInstruction_->decode(source, pmap, decoder, exponentBuilder);
    if(!exponentBuilder.isSet())
    {
      // null field
      return;
    }
    exponent_t exponent = static_cast<exponent_t>(exponentBuilder.value());

    Messages::SingleValueBuilder<mantissa_t> mantissaBuilder;
    mantissaInstruction_->decode(source, pmap, decoder, mantissaBuilder);
    mantissa_t mantissa = 0;
    if(mantissaBuilder.isSet())
    {
      mantissa = mantissaBuilder.value();
    }

    Decimal value(mantissa, exponent, false);
    accessor.addValue(identity_, ValueType::DECIMAL, value);
  }
  else
  {
    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);
  }
  return;
}
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);
    }
  }
}
void
FieldInstructionDecimal::decodeDelta(
  Codecs::DataSource & source,
  Codecs::PresenceMap & /*pmap*/,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & accessor) const
{
  PROFILE_POINT("decimal::decodeDelta");
  int64 exponentDelta;
  decodeSignedInteger(source, decoder, exponentDelta, identity_->name(), true);
  if(!isMandatory())
  {
    if(checkNullInteger(exponentDelta))
    {
      // nothing in Message; no change to saved value
      return;
    }
  }
  int64 mantissaDelta;
  decodeSignedInteger(source, decoder, mantissaDelta, identity_->name(), true);

  Decimal value(typedValue_);
  (void)fieldOp_->getDictionaryValue(decoder, value);
  value.setExponent(exponent_t(value.getExponent() + exponentDelta));
  value.setMantissa(mantissa_t(value.getMantissa() + mantissaDelta));
  accessor.addValue(
    identity_,
    ValueType::DECIMAL,
    value);
  fieldOp_->setDictionaryValue(decoder, value);
}
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
FieldInstructionStaticTemplateRef::decodeNop(
  Codecs::DataSource & source,
  Codecs::PresenceMap & pmap,
  Codecs::Decoder & decoder,
  Messages::ValueMessageBuilder & messageBuilder) const
{
  TemplateCPtr target;
  if(!decoder.findTemplate(templateName_, templateNamespace_, target))
  {
    decoder.reportFatal("[ERR D9]", "Unknown template name for static templateref.", *identity_);
  }

  if(messageBuilder.getApplicationType() != target->getApplicationType())
  {
    Messages::ValueMessageBuilder & groupBuilder(
      messageBuilder.startGroup(
        identity_,
        target->getApplicationType(),
        target->getApplicationTypeNamespace(),
        target->fieldCount()));

    decoder.decodeSegmentBody(source, pmap, target, groupBuilder);
    messageBuilder.endGroup(
      identity_,
      groupBuilder);

  }
  else
  {
    // Because the application types match,
    // the templateRef fields are decoded directly into to the current
    // field set.  As a result the templateRef "disappears" completely
    // from the application message.  This is a good thing.
    // The same message encoded with different
    // templates could be transmitted with different sets of fields defined
    // by templateRefs, but the underlying application type should not reflect
    // the technique used to encode/decode it.
    decoder.decodeSegmentBody(source, pmap, target, messageBuilder);
  }
}
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::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
  }
}