blob: 1856828d9e634c57ea89e36931f119906c6427dd [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.qpid.protonj2.types.messaging;
import org.apache.qpid.protonj2.buffer.ProtonBuffer;
import org.apache.qpid.protonj2.buffer.ProtonByteBufferAllocator;
import org.apache.qpid.protonj2.types.Binary;
import org.apache.qpid.protonj2.types.Symbol;
import org.apache.qpid.protonj2.types.UnsignedLong;
public final class Data implements Section<byte[]> {
public static final UnsignedLong DESCRIPTOR_CODE = UnsignedLong.valueOf(0x0000000000000075L);
public static final Symbol DESCRIPTOR_SYMBOL = Symbol.valueOf("amqp:data:binary");
private final ProtonBuffer buffer;
private Binary cachedBinary;
public Data(Binary binary) {
this.buffer = binary != null ? binary.asProtonBuffer() : null;
this.cachedBinary = binary;
}
public Data(ProtonBuffer buffer) {
this.buffer = buffer;
}
public Data(byte[] value) {
this.buffer = value != null ? ProtonByteBufferAllocator.DEFAULT.wrap(value) : null;
}
public Data(byte[] value, int offset, int length) {
this.buffer = value != null ? ProtonByteBufferAllocator.DEFAULT.wrap(value, offset, length) : null;
}
public Data copy() {
return new Data(buffer == null ? null : buffer.copy());
}
public Binary getBinary() {
if (cachedBinary != null || buffer == null) {
return cachedBinary;
} else {
return cachedBinary = new Binary(buffer);
}
}
/**
* Returns the {@link ProtonBuffer} that contains the bytes carried in the {@link Data} section.
* If the section carries no bytes then this method returns null. This method allows the {@link Data}
* section to be considered a carrier of {@link ProtonBuffer} types instead of the {@link Binary}
* value it will encode as part of its body and avoids creation of a Binary object when one is not
* needed. If a Binary instance is required then calling the {@link #getBinary()} method will create
* an instance that wraps the internal {@link ProtonBuffer}.
*
* @return the {@link ProtonBuffer} that back this Data section.
*/
public ProtonBuffer getBuffer() {
return buffer;
}
/**
* Returns the backing array for this Data {@link Section} copying the contents into a new array
* instance if the backing array in the contained Binary is a subsequence of a larger referenced
* array instance.
*
* @return the byte array view of this Data {@link Section} {@link Binary} payload.
*/
@Override
public byte[] getValue() {
if (buffer != null && buffer.hasArray() && buffer.getArrayOffset() == 0 && buffer.getReadableBytes() == buffer.getArray().length) {
return buffer.getArray();
} else {
byte[] dataCopy = null;
if (buffer != null) {
dataCopy = new byte[buffer.getReadableBytes()];
buffer.getBytes(buffer.getReadIndex(), dataCopy);
}
return dataCopy;
}
}
@Override
public String toString() {
if (buffer == null) {
return "";
}
StringBuilder str = new StringBuilder();
str.append("Data{ ");
for (int i = 0; i < buffer.getReadableBytes(); i++) {
byte c = buffer.getByte(i);
if (c > 31 && c < 127 && c != '\\') {
str.append((char) c);
} else {
str.append(String.format("\\x%02x", c));
}
}
str.append(" }");
return str.toString();
}
@Override
public SectionType getType() {
return SectionType.Data;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((buffer == null) ? 0 : buffer.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
Data other = (Data) obj;
if (buffer == null) {
return other.buffer == null;
}
return buffer.equals(other.buffer);
}
}