org.apache.activemq.transport.amqp.message.UTF8BufferType Maven / Gradle / Ivy
/*
* 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.activemq.transport.amqp.message;
import java.util.Arrays;
import java.util.Collection;
import org.apache.qpid.proton.codec.DecoderImpl;
import org.apache.qpid.proton.codec.EncoderImpl;
import org.apache.qpid.proton.codec.EncodingCodes;
import org.apache.qpid.proton.codec.PrimitiveType;
import org.apache.qpid.proton.codec.PrimitiveTypeEncoding;
import org.apache.qpid.proton.codec.TypeEncoding;
import org.apache.qpid.proton.codec.WritableBuffer;
import org.fusesource.hawtbuf.UTF8Buffer;
/**
* AMQP Type used to allow to proton-j codec to deal with UTF8Buffer types as if
* they were String elements.
*/
public class UTF8BufferType implements PrimitiveType {
private final UTF8BufferEncoding largeBufferEncoding;
private final UTF8BufferEncoding smallBufferEncoding;
public UTF8BufferType(EncoderImpl encoder, DecoderImpl decoder) {
this.largeBufferEncoding = new LargeUTF8BufferEncoding(encoder, decoder);
this.smallBufferEncoding = new SmallUTF8BufferEncoding(encoder, decoder);
}
@Override
public Class getTypeClass() {
return UTF8Buffer.class;
}
@Override
public PrimitiveTypeEncoding getEncoding(UTF8Buffer value) {
return value.getLength() <= 255 ? smallBufferEncoding : largeBufferEncoding;
}
@Override
public PrimitiveTypeEncoding getCanonicalEncoding() {
return largeBufferEncoding;
}
@Override
public Collection> getAllEncodings() {
return Arrays.asList(smallBufferEncoding, largeBufferEncoding);
}
@Override
public void write(UTF8Buffer value) {
final TypeEncoding encoding = getEncoding(value);
encoding.writeConstructor();
encoding.writeValue(value);
}
public abstract class UTF8BufferEncoding implements PrimitiveTypeEncoding {
private final EncoderImpl encoder;
private final DecoderImpl decoder;
public UTF8BufferEncoding(EncoderImpl encoder, DecoderImpl decoder) {
this.encoder = encoder;
this.decoder = decoder;
}
@Override
public int getConstructorSize() {
return 1;
}
@Override
public boolean isFixedSizeVal() {
return false;
}
@Override
public boolean encodesJavaPrimitive() {
return false;
}
/**
* @return the number of bytes the size portion of the encoded value requires.
*/
public abstract int getSizeBytes();
@Override
public void writeConstructor() {
getEncoder().writeRaw(getEncodingCode());
}
@Override
public void writeValue(UTF8Buffer value) {
writeSize(value);
WritableBuffer buffer = getEncoder().getBuffer();
buffer.put(value.getData(), value.getOffset(), value.getLength());
}
/**
* Write the size of the buffer using the appropriate type (byte or int) depending
* on the encoding type being used.
*
* @param value
* The UTF8Buffer value that is being encoded.
*/
public abstract void writeSize(UTF8Buffer value);
@Override
public int getValueSize(UTF8Buffer value) {
return getSizeBytes() + value.getLength();
}
@Override
public Class getTypeClass() {
return UTF8Buffer.class;
}
@Override
public PrimitiveType getType() {
return UTF8BufferType.this;
}
@Override
public boolean encodesSuperset(TypeEncoding encoding) {
return (getType() == encoding.getType());
}
@Override
public UTF8Buffer readValue() {
throw new UnsupportedOperationException("No decoding to UTF8Buffer exists");
}
@Override
public void skipValue() {
throw new UnsupportedOperationException("No decoding to UTF8Buffer exists");
}
public DecoderImpl getDecoder() {
return decoder;
}
public EncoderImpl getEncoder() {
return encoder;
}
}
public class LargeUTF8BufferEncoding extends UTF8BufferEncoding {
public LargeUTF8BufferEncoding(EncoderImpl encoder, DecoderImpl decoder) {
super(encoder, decoder);
}
@Override
public byte getEncodingCode() {
return EncodingCodes.STR32;
}
@Override
public int getSizeBytes() {
return Integer.BYTES;
}
@Override
public void writeSize(UTF8Buffer value) {
getEncoder().getBuffer().putInt(value.getLength());
}
}
public class SmallUTF8BufferEncoding extends UTF8BufferEncoding {
public SmallUTF8BufferEncoding(EncoderImpl encoder, DecoderImpl decoder) {
super(encoder, decoder);
}
@Override
public byte getEncodingCode() {
return EncodingCodes.STR8;
}
@Override
public int getSizeBytes() {
return Byte.BYTES;
}
@Override
public void writeSize(UTF8Buffer value) {
getEncoder().getBuffer().put((byte) value.getLength());
}
}
}