
net.named_data.jndn.Data Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jndn-android-with-async-io Show documentation
Show all versions of jndn-android-with-async-io Show documentation
jNDN is a new implementation of a Named Data Networking client library written in Java. It is wire format compatible with the new NDN-TLV encoding, with NDNx and PARC's CCNx.
/**
* Copyright (C) 2013-2017 Regents of the University of California.
* @author: Jeff Thompson
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see .
* A copy of the GNU Lesser General Public License is in the file COPYING.
*/
package net.named_data.jndn;
import java.nio.ByteBuffer;
import net.named_data.jndn.encoding.EncodingException;
import net.named_data.jndn.encoding.WireFormat;
import net.named_data.jndn.encoding.SignatureHolder;
import net.named_data.jndn.lp.IncomingFaceId;
import net.named_data.jndn.lp.LpPacket;
import net.named_data.jndn.util.Blob;
import net.named_data.jndn.util.ChangeCounter;
import net.named_data.jndn.util.ChangeCountable;
import net.named_data.jndn.util.Common;
import net.named_data.jndn.util.SignedBlob;
public class Data implements ChangeCountable, SignatureHolder {
/**
* Create a new Data object with default values and where the signature is a
* blank Sha256WithRsaSignature.
*/
public Data()
{
}
/**
* Create a new Data object with the given name and default values and where
* the signature is a blank Sha256WithRsaSignature.
* @param name The name which is copied.
*/
public Data(Name name)
{
name_.set(new Name(name));
}
/**
* Create a deep copy of the given data object, including a clone of the
* signature object.
* @param data The data object to copy.
*/
public Data(Data data)
{
try {
signature_.set(data.signature_ == null ?
new Sha256WithRsaSignature() : (Signature)data.getSignature().clone());
}
catch (CloneNotSupportedException e) {
// We don't expect this to happen, so just treat it as if we got a null pointer.
throw new NullPointerException
("Data.setSignature: unexpected exception in clone(): " + e.getMessage());
}
name_.set(new Name(data.getName()));
metaInfo_.set(new MetaInfo(data.getMetaInfo()));
content_ = data.content_;
setDefaultWireEncoding(data.getDefaultWireEncoding(), null);
defaultFullName_ = new Name(data.defaultFullName_);
}
/**
* Encode this Data for a particular wire format. If wireFormat is the default
* wire format, also set the defaultWireEncoding field to the encoded result.
* @param wireFormat A WireFormat object used to encode the input.
* @return The encoded buffer.
*/
public final SignedBlob
wireEncode(WireFormat wireFormat)
{
if (!getDefaultWireEncoding().isNull() &&
getDefaultWireEncodingFormat() == wireFormat)
// We already have an encoding in the desired format.
return getDefaultWireEncoding();
int[] signedPortionBeginOffset = new int[1];
int[] signedPortionEndOffset = new int[1];
Blob encoding = wireFormat.encodeData
(this, signedPortionBeginOffset, signedPortionEndOffset);
SignedBlob wireEncoding = new SignedBlob
(encoding, signedPortionBeginOffset[0], signedPortionEndOffset[0]);
if (wireFormat == WireFormat.getDefaultWireFormat())
// This is the default wire encoding.
setDefaultWireEncoding(wireEncoding, WireFormat.getDefaultWireFormat());
return wireEncoding;
}
/**
* Encode this Data for the default wire format WireFormat.getDefaultWireFormat().
* Also set the defaultWireEncoding field to the encoded result.
* @return The encoded buffer.
*/
public final SignedBlob
wireEncode()
{
return wireEncode(WireFormat.getDefaultWireFormat());
}
/**
* Decode the input using a particular wire format and update this Data. If
* wireFormat is the default wire format, also set the defaultWireEncoding
* field another pointer to the input Blob.
* @param input The input Blob to decode. This reads from buf().position() to
* buf().limit(), but does not change the position.
* @param wireFormat A WireFormat object used to decode the input.
* @throws EncodingException For invalid encoding.
*/
public void
wireDecode(Blob input, WireFormat wireFormat) throws EncodingException
{
int[] signedPortionBeginOffset = new int[1];
int[] signedPortionEndOffset = new int[1];
wireFormat.decodeData
(this, input.buf(), signedPortionBeginOffset, signedPortionEndOffset,
false);
if (wireFormat == WireFormat.getDefaultWireFormat())
// This is the default wire encoding.
setDefaultWireEncoding
(new SignedBlob(input, signedPortionBeginOffset[0],
signedPortionEndOffset[0]), WireFormat.getDefaultWireFormat());
else
setDefaultWireEncoding(new SignedBlob(), null);
}
/**
* Decode the input using the default wire format
* WireFormat.getDefaultWireFormat() and update this Data. Also set the
* defaultWireEncoding field another pointer to the input Blob.
* @param input The input Blob to decode. This reads from buf().position() to
* buf().limit(), but does not change the position.
* @throws EncodingException For invalid encoding.
*/
public final void
wireDecode(Blob input) throws EncodingException
{
wireDecode(input, WireFormat.getDefaultWireFormat());
}
/**
* Decode the input using a particular wire format and update this Data. If
* wireFormat is the default wire format, also set the defaultWireEncoding
* field to a copy of the input. (To not copy the input, see
* wireDecode(Blob).)
* @param input The input buffer to decode. This reads from position() to
* limit(), but does not change the position.
* @param wireFormat A WireFormat object used to decode the input.
* @throws EncodingException For invalid encoding.
*/
public final void
wireDecode(ByteBuffer input, WireFormat wireFormat) throws EncodingException
{
wireDecode(new Blob(input, true), wireFormat);
}
/**
* Decode the input using the default wire format
* WireFormat.getDefaultWireFormat() and update this Data. Also set the
* defaultWireEncoding field to the input.
* @param input The input buffer to decode. This reads from position() to
* limit(), but does not change the position.
* @throws EncodingException For invalid encoding.
*/
public final void
wireDecode(ByteBuffer input) throws EncodingException
{
wireDecode(input, WireFormat.getDefaultWireFormat());
}
public final Signature
getSignature() { return (Signature)signature_.get(); }
public final Name
getName() { return (Name)name_.get(); }
public final MetaInfo
getMetaInfo() { return (MetaInfo)metaInfo_.get(); }
public final Blob
getContent() { return content_; }
/**
* Get the incoming face ID according to the incoming packet header.
* @return The incoming face ID. If not specified, return -1.
*/
public final long
getIncomingFaceId()
{
IncomingFaceId field =
lpPacket_ == null ? null : IncomingFaceId.getFirstHeader(lpPacket_);
return field == null ? -1 : field.getFaceId();
}
/**
* Get the Data packet's full name, which includes the final
* ImplicitSha256Digest component based on the wire encoding for a particular
* wire format.
* @param wireFormat A WireFormat object used to encode the Data packet.
* @return The full name. You must not change the Name object - if you need
* to change it then make a copy.
*/
public final Name
getFullName(WireFormat wireFormat) throws EncodingException
{
// The default full name depends on the default wire encoding.
if (!getDefaultWireEncoding().isNull() && defaultFullName_.size() > 0 &&
getDefaultWireEncodingFormat() == wireFormat)
// We already have a full name. A non-null default wire encoding means
// that the Data packet fields have not changed.
return defaultFullName_;
Name fullName = new Name(getName());
// wireEncode will use the cached encoding if possible.
fullName.appendImplicitSha256Digest
(Common.digestSha256(wireEncode(wireFormat).buf()));
if (wireFormat == WireFormat.getDefaultWireFormat())
// wireEncode has already set defaultWireEncodingFormat_.
defaultFullName_ = fullName;
return fullName;
}
/**
* Get the Data packet's full name, which includes the final
* ImplicitSha256Digest component based on the wire encoding for the default
* wire format.
* @return The full name. You must not change the Name objects - if you need
* to change it then make a copy.
*/
public final Name
getFullName() throws EncodingException
{
return getFullName(WireFormat.getDefaultWireFormat());
}
/**
* Return a pointer to the defaultWireEncoding, which was encoded with
* getDefaultWireEncodingFormat().
* @return The default wire encoding. Its pointer may be null.
*/
public final SignedBlob
getDefaultWireEncoding()
{
if (getDefaultWireEncodingChangeCount_ != getChangeCount()) {
// The values have changed, so the default wire encoding is invalidated.
defaultWireEncoding_ = new SignedBlob();
defaultWireEncodingFormat_ = null;
getDefaultWireEncodingChangeCount_ = getChangeCount();
}
return defaultWireEncoding_;
}
/**
* Get the WireFormat which is used by getDefaultWireEncoding().
* @return The WireFormat, which is only meaningful if the
* getDefaultWireEncoding() does not have a null pointer.
*/
WireFormat
getDefaultWireEncodingFormat() { return defaultWireEncodingFormat_; }
/**
* Set the signature to a copy of the given signature.
* @param signature The signature object which is cloned.
* @return This Data so that you can chain calls to update values.
*/
public final Data
setSignature(Signature signature)
{
try {
signature_.set(signature == null ?
new Sha256WithRsaSignature() : (Signature)signature.clone());
}
catch (CloneNotSupportedException e) {
// We don't expect this to happen, so just treat it as if we got a null
// pointer.
throw new NullPointerException
("Data.setSignature: unexpected exception in clone(): " + e.getMessage());
}
++changeCount_;
return this;
}
/**
* Set name to a copy of the given Name. This is not final so that a subclass
* can override to validate the name.
* @param name The Name which is copied.
* @return This Data so that you can chain calls to update values.
*/
public Data
setName(Name name)
{
name_.set(name == null ? new Name() : new Name(name));
++changeCount_;
return this;
}
/**
* Set metaInfo to a copy of the given MetaInfo.
* @param metaInfo The MetaInfo which is copied.
* @return This Data so that you can chain calls to update values.
*/
public final Data
setMetaInfo(MetaInfo metaInfo)
{
metaInfo_.set(metaInfo == null ? new MetaInfo() : new MetaInfo(metaInfo));
++changeCount_;
return this;
}
public final Data
setContent(Blob content)
{
content_ = (content == null ? new Blob() : content);
++changeCount_;
return this;
}
/**
* An internal library method to set the LpPacket for an incoming packet. The
* application should not call this.
* @param lpPacket The LpPacket. This does not make a copy.
* @return This Data so that you can chain calls to update values.
* @note This is an experimental feature. This API may change in the future.
*/
final Data
setLpPacket(LpPacket lpPacket)
{
lpPacket_ = lpPacket;
// Don't update changeCount_ since this doesn't affect the wire encoding.
return this;
}
/**
* Get the change count, which is incremented each time this object
* (or a child object) is changed.
* @return The change count.
*/
public final long
getChangeCount()
{
// Make sure each of the checkChanged is called.
boolean changed = signature_.checkChanged();
changed = name_.checkChanged() || changed;
changed = metaInfo_.checkChanged() || changed;
if (changed)
// A child object has changed, so update the change count.
++changeCount_;
return changeCount_;
}
private void
setDefaultWireEncoding
(SignedBlob defaultWireEncoding, WireFormat defaultWireEncodingFormat)
{
defaultWireEncoding_ = defaultWireEncoding;
defaultWireEncodingFormat_ = defaultWireEncodingFormat;
// Set getDefaultWireEncodingChangeCount_ so that the next call to
// getDefaultWireEncoding() won't clear defaultWireEncoding_.
getDefaultWireEncodingChangeCount_ = getChangeCount();
}
private final ChangeCounter signature_ =
new ChangeCounter(new Sha256WithRsaSignature());
private final ChangeCounter name_ = new ChangeCounter(new Name());
private final ChangeCounter metaInfo_ =
new ChangeCounter(new MetaInfo());
private Blob content_ = new Blob();
private LpPacket lpPacket_ = null;
private SignedBlob defaultWireEncoding_ = new SignedBlob();
private Name defaultFullName_ = new Name();
private WireFormat defaultWireEncodingFormat_;
private long getDefaultWireEncodingChangeCount_ = 0;
private long changeCount_ = 0;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy