org.ccsds.moims.mo.mal.structures.Blob Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of api-mal Show documentation
Show all versions of api-mal Show documentation
An implementation of the Java API for the CCSDS MAL
/* ----------------------------------------------------------------------------
* Copyright (C) 2013 European Space Agency
* European Space Operations Centre
* Darmstadt
* Germany
* ----------------------------------------------------------------------------
* System : CCSDS MO MAL Java API
* ----------------------------------------------------------------------------
* Licensed under the European Space Agency Public License, Version 2.0
* You may not use this file except in compliance with the License.
*
* Except as expressly set forth in this License, the Software is provided to
* You on an "as is" basis and without warranties of any kind, including without
* limitation merchantability, fitness for a particular purpose, absence of
* defects or errors, accuracy or non-infringement of intellectual property rights.
*
* See the License for the specific language governing permissions and
* limitations under the License.
* ----------------------------------------------------------------------------
*/
package org.ccsds.moims.mo.mal.structures;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import org.ccsds.moims.mo.mal.MALDecoder;
import org.ccsds.moims.mo.mal.MALEncoder;
import org.ccsds.moims.mo.mal.MALException;
/**
* Class representing MAL Blob type.
*/
public class Blob implements Attribute {
private static final int T_BUFFER_SIZE = 4096;
private byte[] value;
private int offset;
private int length;
private String uvalue;
private URL urlValue;
/**
* Default constructor.
*/
public Blob() {
this.value = null;
this.uvalue = null;
this.offset = 0;
this.length = 0;
}
/**
* Byte array constructor, does not copy the passed array. The byte array
* should not be modified after the constructor has been called. If the byte
* array is modified after the constructor has been called then the Blob
* behaviour is unspecified.
*
* @param value Byte array to be wrapped.
* @throws java.lang.IllegalArgumentException If the argument is null.
*/
public Blob(final byte[] value) throws java.lang.IllegalArgumentException {
this.value = value;
this.uvalue = null;
this.offset = 0;
this.length = value.length;
}
/**
* Byte array constructor, does not copy the passed array. The byte array
* should not be modified after the constructor has been called. If the byte
* array is modified after the constructor has been called then the Blob
* behaviour is unspecified.
*
* @param value Byte array to be wrapped.
* @param offset Offset into supplied array to start from.
* @param length Length in supplied array to use.
* @throws java.lang.IllegalArgumentException If the argument is null.
*/
public Blob(final byte[] value, final int offset, final int length)
throws java.lang.IllegalArgumentException {
this.value = value;
this.uvalue = null;
this.offset = offset;
this.length = length;
}
/**
* URL constructor. The resource identified by the URL should not be
* modified until the method ‘detach’ is called. If the resource identified
* by the URL is modified after the constructor has been called then the
* Blob behaviour is unspecified.
*
* @param sourceUrl Source URL.
* @throws java.lang.IllegalArgumentException If the argument is null.
*/
public Blob(final String sourceUrl) throws java.lang.IllegalArgumentException {
this.value = null;
this.offset = 0;
this.length = 0;
this.uvalue = sourceUrl;
urlValue = null;
}
@Override
public Element createElement() {
return new Blob();
}
/**
* The method indicates whether the Blob is attached to a URL or not.
*
* @return TRUE if the Blob is attached to a URL otherwise FALSE.
*/
public boolean isURLBased() {
return uvalue != null;
}
// This might be required for XML serialisation and technologies that use that.
// public void setValue(byte[] value)
// {
// this.urlValue = null;
// this.uvalue = null;
// this.value = value;
// }
// public void setURL(String nvalue)
// {
// detach();
// this.urlValue = null;
// this.uvalue = nvalue;
// this.value = null;
// }
/**
* Return the value of this Blob as a byte array. If the Blob contains a URL
* then the designated content is loaded and copied in the returned byte
* array. The returned byte array should not be modified. If the returned
* byte array is modified then the Blob behaviour is unspecified.
*
* @return The Blob value as a byte array.
* @throws MALException if an internal error occurs.
*/
public byte[] getValue() throws MALException {
if (isURLBased()) {
final ByteArrayOutputStream buf = new ByteArrayOutputStream();
try {
final byte[] b = new byte[T_BUFFER_SIZE];
urlValue = new URL(uvalue);
final InputStream is = urlValue.openStream();
int read;
while ((read = is.read(b)) != -1) {
buf.write(b, 0, read);
}
} catch (Exception ex) {
ex.printStackTrace();
}
this.urlValue = null;
this.uvalue = null;
this.value = buf.toByteArray();
}
return value;
}
/**
* Returns the offset of the supplied byte array.
*
* @return The offset.
*/
public int getOffset() {
return offset;
}
/**
* Returns the length of the supplied array.
*
* @return The length.
*/
public int getLength() {
return length;
}
/**
* Returns the URL of this Blob.
*
* @return The URL if URL based, otherwise NULL.
*/
public String getURL() {
return uvalue;
}
/**
* The method detaches this Blob wrapper from the resource designated by the
* URL when this Blob is garbaged.
*/
public void detach() {
if (null != urlValue) {
urlValue = null;
}
}
@Override
public Long getShortForm() {
return Attribute.BLOB_SHORT_FORM;
}
@Override
public Integer getTypeShortForm() {
return Attribute.BLOB_TYPE_SHORT_FORM;
}
@Override
public UShort getAreaNumber() {
return UShort.ATTRIBUTE_AREA_NUMBER;
}
@Override
public org.ccsds.moims.mo.mal.structures.UOctet getAreaVersion() {
return UOctet.AREA_VERSION;
}
@Override
public UShort getServiceNumber() {
return UShort.ATTRIBUTE_SERVICE_NUMBER;
}
@Override
public void encode(final MALEncoder encoder) throws MALException {
encoder.encodeBlob(this);
}
@Override
public Element decode(final MALDecoder decoder) throws MALException {
return decoder.decodeBlob();
}
@Override
public boolean equals(final Object obj) {
if (null == obj) {
return false;
}
if (this == obj) {
return true;
}
if (!(obj instanceof Blob)) {
return false;
}
final Blob other = (Blob) obj;
if ((null != uvalue) || (null != other.uvalue)) {
try {
return Arrays.equals(this.getValue(), other.getValue());
} catch (MALException ex) {
return false;
}
}
return Arrays.equals(this.value, other.value);
}
@Override
public int hashCode() {
if (null != uvalue) {
return uvalue.hashCode();
} else {
if (null != value) {
return value.length;
}
}
return 0;
}
@Override
public String toString() {
if (isURLBased()) {
return "Blob(URL based, URL=" + uvalue + ")";
} else {
return "Blob(buffer based, length=" + value.length + ")";
}
}
private static final long serialVersionUID = Attribute.BLOB_SHORT_FORM;
}