void
PresenceMap::decode(Codecs::DataSource & source)
{
  reset();

  uchar byte = 0;
  if(!source.getByte(byte))
  {
    throw EncodingError("[ERR U03] EOF while decoding presence map.");
  }
  size_t pos = 0;
  while((byte & stopBit) == 0)
  {
    appendByte(pos, byte);
    if(!source.getByte(byte))
    {
      throw EncodingError("[ERR U03] EOF while decoding presence map.");
    }
  }
  appendByte(pos, byte);

  if(vout_)
  {
    (*vout_) << "pmap["  <<  byteCapacity_ << "]<-" << std::hex;
    for(size_t iter = 0; iter < pos; ++iter)
    {
      (*vout_) << ' ' << std::setw(2) <<  static_cast<unsigned short>(bits_[iter]);
    }
    (*vout_) << std::dec << std::endl;
  }
}
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);
  }
}
bool
FieldInstruction::decodeAscii(
  Codecs::DataSource & source,
  WorkingBuffer & workingBuffer)
{
  workingBuffer.clear(false);
  uchar byte = 0;
  if(!source.getByte(byte))
  {
    return false;
  }
  while((byte & stopBit) == 0)
  {
    workingBuffer.push(byte);
    if(!source.getByte(byte))
    {
      // todo: exception?
      return false;
    }
  }
  workingBuffer.push(byte & dataBits);
  return true;
}
void
FieldInstruction::decodeByteVector(
  Codecs::Context & decoder,
  Codecs::DataSource & source,
  const std::string & name,
  WorkingBuffer & buffer,
  size_t length)
{
  buffer.clear(false, length);
  for(size_t pos = 0;
    pos < length;
    ++pos)
  {
    uchar byte = 0;
    if(!source.getByte(byte))
    {
      decoder.reportFatal("[ERR U03]", "End of file: Too few bytes in ByteVector.", name);
    }
    buffer.push(byte);
  }
}