ndn_Error ndn_decodeOptionalBinaryXmlPublisherPublicKeyDigest
  (struct ndn_PublisherPublicKeyDigest *publisherPublicKeyDigest, struct ndn_BinaryXmlDecoder *decoder)
{
  int gotExpectedTag;
  ndn_Error error; 
  if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_PublisherPublicKeyDigest, &gotExpectedTag)))
    return error;
  if (gotExpectedTag) {
    if ((error = ndn_decodeBinaryXmlPublisherPublicKeyDigest(publisherPublicKeyDigest, decoder)))
      return error;
  }
  else {
    publisherPublicKeyDigest->publisherPublicKeyDigest.value = 0;
    publisherPublicKeyDigest->publisherPublicKeyDigest.length = 0;
  }
  
  return NDN_ERROR_success;
}
ndn_Error ndn_decodeBinaryXmlName
  (struct ndn_Name *name, size_t *signedPortionBeginOffset,
   size_t *signedPortionEndOffset, struct ndn_BinaryXmlDecoder *decoder)
{
  ndn_Error error;
  if ((error = ndn_BinaryXmlDecoder_readElementStartDTag(decoder, ndn_BinaryXml_DTag_Name)))
    return error;

  *signedPortionBeginOffset = decoder->offset;
  // In case there are no components, set signedPortionEndOffset arbitrarily.
  *signedPortionEndOffset = *signedPortionBeginOffset;
  
  name->nComponents = 0;
  while (1) {
    int gotExpectedTag;
    struct ndn_Blob component;

    if ((error = ndn_BinaryXmlDecoder_peekDTag(decoder, ndn_BinaryXml_DTag_Component, &gotExpectedTag)))
      return error;

    if (!gotExpectedTag)
      // No more components.
      break;

    *signedPortionEndOffset = decoder->offset;

    if ((error = ndn_BinaryXmlDecoder_readBinaryDTagElement(decoder, ndn_BinaryXml_DTag_Component, 0, &component)))
      return error;
    if ((error = ndn_Name_appendBlob(name, &component)))
      return error;
  }

  if ((error = ndn_BinaryXmlDecoder_readElementClose(decoder)))
    return error;

  return NDN_ERROR_success;
}