/* This file is part of GNUnet. Copyright (C) 2011, 2012 Christian Grothoff (and other contributing authors) GNUnet is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. GNUnet is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with GNUnet; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.gnunet.construct.parsers; import org.gnunet.construct.Message; import org.gnunet.construct.ReflectUtil; import java.lang.reflect.Array; import java.lang.reflect.Field; import java.nio.ByteBuffer; import java.util.List; public class FixedSizeArrayParser implements Parser { private final Parser elemParser; private final Field targetField; private final int elemNumber; public FixedSizeArrayParser(final int elemNumber, final Parser elemParser, final Field f) { targetField = f; this.elemNumber = elemNumber; this.elemParser = elemParser; } @Override public int getSize(final Message srcObj) { int size = 0; final Object arr = ReflectUtil.justGet(srcObj, targetField); if (arr == null) { throw new RuntimeException("array not initialized"); } for (int i = 0; i < Array.getLength(arr); ++i) { size += elemParser.getSize((Message) Array.get(arr, i)); } return size; } @Override public int parse(ByteBuffer srcBuf, int frameOffset, Message frameObj, final Message dstObj, List frameSizePath) { int size = 0; final Object arr = Array.newInstance(targetField.getType().getComponentType(), elemNumber); ReflectUtil.justSet(dstObj, targetField, arr); for (int i = 0; i < elemNumber; ++i) { @SuppressWarnings("unchecked") Message elemObj = ReflectUtil.justInstantiate((Class)targetField.getType().getComponentType()); Array.set(arr, i, elemObj); size += elemParser.parse(srcBuf, frameOffset - size, frameObj, elemObj, null); } return size; } @Override public int write(final ByteBuffer dstBuf, final Message srcObj) { int size = 0; final Object arr = ReflectUtil.justGet(srcObj, targetField); if (Array.getLength(arr) != elemNumber) { throw new AssertionError("wrong number of elements"); } for (int i = 0; i < Array.getLength(arr); ++i) { size += elemParser.write(dstBuf, (Message) Array.get(arr, i)); } return size; } @Override public void patch(Message m, int frameSize, List frameSizePath, Message frameObj) { final Object arr = ReflectUtil.justGet(m, targetField); for (int i = 0; i < Array.getLength(arr); ++i) { elemParser.patch((Message) Array.get(arr, i), frameSize, null, frameObj); } } @Override public int getStaticSize() { return elemNumber * elemParser.getStaticSize(); } }