/** * Copyright (c) 2013, Will Szumski * * This file is part of formicidae. * * formicidae 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 of the License, or * (at your option) any later version. * * formicidae 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 formicidae. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package org.cowboycoders.ant.utils; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.cowboycoders.ant.messages.FatalMessageException; import org.cowboycoders.ant.messages.Constants.DataElement; /** * @author will * */ public class DataElementUtils { private DataElementUtils() { } /** * Sets a DataElement in a payload * @param payload to modify * @param messageElements describe the composition of the payload * @param element to modify * @param value to set {@code element} to * @param offset to messageElements description * @param skip how many identical elements to skip before insertion * @return true, if successful otherwise false */ public static boolean setDataElement( ArrayList<Byte> payload, DataElement [] messageElements, DataElement element, Integer value, int offset, int skip ) { if (!Arrays.asList(messageElements).contains(element)) { throw new FatalMessageException("Arg, element, not in expected list"); } boolean completed = false; List<Byte> insertionBytes = ByteUtils.lsbSplit(value, element.getLength()); completed = insertElementBytes(payload, messageElements, element, insertionBytes, offset,skip); if (!completed) { throw new FatalMessageException("Byte insertion failed"); } return completed; } /** * Inserts data, given as a {@code List} of Bytes, into a payload * @param payload the payload to insert bytes into * @param messageElements description of the composition * @param element element we are targeting * @param bytesToInsert new bytes to insert * @param offset to messageElements description * @param skip how many identical elements to skip before insertion * @return true if successful, otherwise false */ private static boolean insertElementBytes( ArrayList<Byte> payload, DataElement [] messageElements, DataElement element, List<Byte> bytesToInsert, int offset, int skip ) { assert bytesToInsert.size() == element.getLength() : "Number of bytes to insert doesn't match expected element length"; boolean completed = false; int elementCount = 0; int index = offset; for (DataElement e : messageElements) { if (e == element) { if (elementCount == skip) { for (byte b : bytesToInsert) { payload.set(index, b); index++; } completed = true; break; } elementCount++; } index += e.getLength(); } return completed; } /** * Gets the data associated with a given {@code DataElement} * @param payload to get the data from * @param messageElements describes the composition of the payload * @param element to get data for * @param offset in payload to start of messageElements * @param skip in payload to start of messageElements * @return data element */ public static Integer getDataElement( ArrayList<Byte> payload, DataElement [] messageElements, DataElement element, int offset, int skip) { if (!Arrays.asList(messageElements).contains(element)) { throw new FatalMessageException("Arg, element, not in expected list"); } Integer rtn = null; int elementCount = 0; int index = offset; for (DataElement e : messageElements) { if (e == element) { if (elementCount == skip) { rtn = ByteUtils.lsbMerge(payload.subList(index, index += e.getLength())); break; } elementCount++; } index += e.getLength(); } return rtn; } }