blob: b650aed269152c1f3870e44a3cc1ba20e00d330e [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.proton.codec.impl;
import static org.junit.Assert.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import org.apache.qpid.proton.amqp.Binary;
import org.apache.qpid.proton.amqp.Symbol;
import org.apache.qpid.proton.codec.Data;
import org.junit.Test;
public class DataImplTest
{
@Test
public void testEncodeDecodeSymbolArrayUsingPutArray()
{
Symbol symbol1 = Symbol.valueOf("testRoundtripSymbolArray1");
Symbol symbol2 = Symbol.valueOf("testRoundtripSymbolArray2");
Data data1 = new DataImpl();
data1.putArray(false, Data.DataType.SYMBOL);
data1.enter();
data1.putSymbol(symbol1);
data1.putSymbol(symbol2);
data1.exit();
Binary encoded = data1.encode();
encoded.asByteBuffer();
Data data2 = new DataImpl();
data2.decode(encoded.asByteBuffer());
assertEquals("unexpected array length", 2, data2.getArray());
assertEquals("unexpected array length", Data.DataType.SYMBOL, data2.getArrayType());
Object[] array = data2.getJavaArray();
assertNotNull("Array should not be null", array);
assertEquals("Expected a Symbol array", Symbol[].class, array.getClass());
assertEquals("unexpected array length", 2, array.length);
assertEquals("unexpected value", symbol1, array[0]);
assertEquals("unexpected value", symbol2, array[1]);
}
@Test
public void testEncodeDecodeSymbolArrayUsingPutObject()
{
Symbol symbol1 = Symbol.valueOf("testRoundtripSymbolArray1");
Symbol symbol2 = Symbol.valueOf("testRoundtripSymbolArray2");
Symbol[] input = new Symbol[]{symbol1, symbol2};
Data data1 = new DataImpl();
data1.putObject(input);
Binary encoded = data1.encode();
encoded.asByteBuffer();
Data data2 = new DataImpl();
data2.decode(encoded.asByteBuffer());
assertEquals("unexpected array length", 2, data2.getArray());
assertEquals("unexpected array length", Data.DataType.SYMBOL, data2.getArrayType());
Object[] array = data2.getJavaArray();
assertArrayEquals("Array not as expected", input, array);
}
@Test
public void testEncodeArrayOfLists()
{
// encode an array of two empty lists
Data data = new DataImpl();
data.putArray(false, Data.DataType.LIST);
data.enter();
data.putList();
data.putList();
data.exit();
int expectedEncodedSize = 4; // 1b type + 1b size + 1b length + 1b element constructor
Binary encoded = data.encode();
assertEquals("unexpected encoding size", expectedEncodedSize, encoded.getLength());
ByteBuffer expectedEncoding = ByteBuffer.allocate(expectedEncodedSize);
expectedEncoding.put((byte)0xe0); // constructor
expectedEncoding.put((byte)2); // size
expectedEncoding.put((byte)2); // count
expectedEncoding.put((byte)0x45); // element constructor
assertEquals("unexpected encoding", new Binary(expectedEncoding.array()), encoded);
data = new DataImpl();
data.putArray(false, Data.DataType.LIST);
data.enter();
data.putList();
data.putList();
data.putList();
data.enter();
data.putNull();
data.exit();
data.exit();
expectedEncodedSize = 11; // 1b type + 1b size + 1b length + 1b element constructor + 3 * (1b size + 1b count) + 1b null elt
encoded = data.encode();
assertEquals("unexpected encoding size", expectedEncodedSize, encoded.getLength());
expectedEncoding = ByteBuffer.allocate(expectedEncodedSize);
expectedEncoding.put((byte)0xe0); // constructor
expectedEncoding.put((byte)9); // size
expectedEncoding.put((byte)3); // count
expectedEncoding.put((byte)0xc0); // element constructor
expectedEncoding.put((byte)1); // size
expectedEncoding.put((byte)0); // count
expectedEncoding.put((byte)1); // size
expectedEncoding.put((byte)0); // count
expectedEncoding.put((byte)2); // size
expectedEncoding.put((byte)1); // count
expectedEncoding.put((byte)0x40); // null value
assertEquals("unexpected encoding", new Binary(expectedEncoding.array()), encoded);
data = new DataImpl();
data.putArray(false, Data.DataType.LIST);
data.enter();
data.putList();
data.putList();
data.putList();
data.enter();
for(int i = 0; i < 256; i++)
{
data.putNull();
}
data.exit();
data.exit();
expectedEncodedSize = 290; // 1b type + 4b size + 4b length + 1b element constructor + 3 * (4b size + 4b count) + (256 * 1b) null elt
encoded = data.encode();
assertEquals("unexpected encoding size", expectedEncodedSize, encoded.getLength());
expectedEncoding = ByteBuffer.allocate(expectedEncodedSize);
expectedEncoding.put((byte)0xf0); // constructor
expectedEncoding.putInt(285); // size
expectedEncoding.putInt(3); // count
expectedEncoding.put((byte)0xd0); // element constructor
expectedEncoding.putInt(4); // size
expectedEncoding.putInt(0); // count
expectedEncoding.putInt(4); // size
expectedEncoding.putInt(0); // count
expectedEncoding.putInt(260); // size
expectedEncoding.putInt(256); // count
for(int i = 0; i < 256; i++)
{
expectedEncoding.put((byte)0x40); // null value
}
assertEquals("unexpected encoding", new Binary(expectedEncoding.array()), encoded);
}
@Test
public void testEncodeArrayOfMaps()
{
// encode an array of two empty maps
Data data = new DataImpl();
data.putArray(false, Data.DataType.MAP);
data.enter();
data.putMap();
data.putMap();
data.exit();
int expectedEncodedSize = 8; // 1b type + 1b size + 1b length + 1b element constructor + 2 * (1b size + 1b count)
Binary encoded = data.encode();
assertEquals("unexpected encoding size", expectedEncodedSize, encoded.getLength());
ByteBuffer expectedEncoding = ByteBuffer.allocate(expectedEncodedSize);
expectedEncoding.put((byte) 0xe0); // constructor
expectedEncoding.put((byte) 6); // size
expectedEncoding.put((byte) 2); // count
expectedEncoding.put((byte) 0xc1); // element constructor
expectedEncoding.put((byte)1); // size
expectedEncoding.put((byte)0); // count
expectedEncoding.put((byte)1); // size
expectedEncoding.put((byte)0); // count
assertEquals("unexpected encoding", new Binary(expectedEncoding.array()), encoded);
}
@Test
public void testEncodeString32()
{
byte[] strPayload = createStringPayloadBytes(256);
String content = new String(strPayload, StandardCharsets.UTF_8);
assertTrue("Length must be over 255 to ensure use of str32 encoding", content.length() > 255);
int encodedSize = 1 + 4 + strPayload.length; // 1b type + 4b length + content
ByteBuffer expectedEncoding = ByteBuffer.allocate(encodedSize);
expectedEncoding.put((byte) 0xB1);
expectedEncoding.putInt(strPayload.length);
expectedEncoding.put(strPayload);
Data data = new DataImpl();
data.putString(content);
Binary encoded = data.encode();
assertEquals("unexpected encoding", new Binary(expectedEncoding.array()), encoded);
}
@Test
public void testEncodeDecodeString32()
{
byte[] payload = createStringPayloadBytes(1025);
String content = new String(payload, StandardCharsets.UTF_8);
assertTrue("Length must be over 255 to ensure use of str32 encoding", content.length() > 255);
doEncodeDecodeStringTestImpl(content);
}
@Test
public void testEncodeDecodeString8()
{
String content = "testRoundTripString8";
assertTrue("Length must be <= 255 to allow use of str8 encoding", content.length() <= 255);
doEncodeDecodeStringTestImpl("testRoundTripString8");
}
private void doEncodeDecodeStringTestImpl(String string)
{
Data data = new DataImpl();
data.putString(string);
Binary encoded = data.encode();
Data data2 = new DataImpl();
data2.decode(encoded.asByteBuffer());
assertEquals("unexpected type", Data.DataType.STRING, data2.type());
assertEquals("unexpected string", string, data2.getString());
}
private byte[] createStringPayloadBytes(int length)
{
byte[] payload = new byte[length];
for (int i = 0; i < length; i++) {
payload[i] = (byte) ((i % 10) + 48);
}
return payload;
}
}