| /* |
| * |
| * 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.framing; |
| |
| import java.math.BigDecimal; |
| import java.nio.ByteBuffer; |
| import java.util.AbstractCollection; |
| import java.util.ArrayList; |
| import java.util.Arrays; |
| import java.util.Collection; |
| import java.util.Date; |
| import java.util.HashSet; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.qpid.util.ByteBufferUtils; |
| |
| public class FieldArray<T> extends AbstractCollection<T> |
| { |
| |
| private final Collection<T> _underlying; |
| |
| private FieldArray(final Collection<T> underlying) |
| { |
| _underlying = underlying; |
| } |
| |
| @Override |
| public Iterator<T> iterator() |
| { |
| return _underlying.iterator(); |
| } |
| |
| @Override |
| public int size() |
| { |
| return _underlying.size(); |
| } |
| |
| public int getEncodingSize() |
| { |
| int size = 0; |
| for( T obj : this) |
| { |
| size += AMQTypedValue.toTypedValue(obj).getEncodingSize()+1; |
| } |
| return size; |
| } |
| |
| public static <T> FieldArray<T> asFieldArray(Collection<T> collection) |
| { |
| if(collection instanceof FieldArray) |
| { |
| return (FieldArray<T>) collection; |
| } |
| else |
| { |
| validateCollection(collection); |
| return new FieldArray<>(collection); |
| } |
| } |
| |
| private static final Set<Class<?>> SUPPORTED_CLASSES = new HashSet<>(Arrays.asList(Boolean.class, |
| Byte.class, |
| Short.class, |
| Character.class, |
| Integer.class, |
| Long.class, |
| Float.class, |
| Double.class, |
| String.class, |
| FieldTable.class, |
| Date.class, |
| BigDecimal.class, |
| byte[].class)); |
| |
| private static <T> void validateCollection(final Collection<T> collection) |
| { |
| for(T val : collection) |
| { |
| if(!(val == null || SUPPORTED_CLASSES.contains(val.getClass()) || val instanceof Collection || val instanceof Map)) |
| { |
| throw new IllegalArgumentException("Cannot convert an object of type " + val.getClass().getName()); |
| } |
| |
| } |
| } |
| |
| public void writeToBuffer(final ByteBuffer buffer) |
| { |
| buffer.putInt(getEncodingSize()); |
| for( T obj : this) |
| { |
| AMQTypedValue.toTypedValue(obj).writeToBuffer(buffer); |
| } |
| } |
| |
| public static FieldArray<?> readFromBuffer(final ByteBuffer buffer) |
| { |
| ArrayList<Object> result = new ArrayList<>(); |
| int size = buffer.getInt(); |
| ByteBuffer slicedBuffer = ByteBufferUtils.view(buffer, 0, size); |
| buffer.position(buffer.position()+size); |
| while(slicedBuffer.hasRemaining()) |
| { |
| result.add(AMQTypedValue.readFromBuffer(slicedBuffer).getValue()); |
| } |
| return new FieldArray<>(result); |
| } |
| } |