/* * Commons eID Project. * Copyright (C) 2008-2013 FedICT. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License version * 3.0 as published by the Free Software Foundation. * * This software 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, see * http://www.gnu.org/licenses/. */ package be.fedict.commons.eid.consumer.tlv; import java.lang.reflect.Field; import java.nio.ByteBuffer; /** * Byte Array Fields Offset/Length Parser supports extraction of byte array * slices, unsigned 8 and 16-bit values from byte array integers * * @author Frank Marien */ public class ByteArrayParser { private ByteArrayParser() { super(); } /** * Parses the given file using the meta-data annotations within the baClass * parameter. * * @param <T> * @param file * @param baClass * @return */ public static <T> T parse(final byte[] file, final Class<T> baClass) { T t; try { t = parseThrowing(file, baClass); } catch (final Exception ex) { throw new RuntimeException("error parsing file: " + baClass.getName(), ex); } return t; } private static <T> T parseThrowing(final byte[] data, final Class<T> baClass) throws InstantiationException, IllegalAccessException { final Field[] fields = baClass.getDeclaredFields(); final T baObject = baClass.newInstance(); for (Field field : fields) { final ByteArrayField baFieldAnnotation = field .getAnnotation(ByteArrayField.class); if (baFieldAnnotation != null) { final int offset = baFieldAnnotation.offset(); final int length = baFieldAnnotation.length(); if (field.getType().isArray() && field.getType().getComponentType() .equals(byte.class)) { final byte[] byteArray = new byte[length]; System.arraycopy(data, offset, byteArray, 0, length); field.set(baObject, byteArray); } else if (field.getType().equals(int.class)) { final ByteBuffer buff = ByteBuffer.wrap(data); switch (length) { case 1 : field.set(baObject, (int) buff.get(offset) & 0xff); break; case 2 : field.set(baObject, (int) buff.getShort(offset) & 0xffff); break; } } } } return baObject; } }