/* * BEValue - Holds different types that a bencoded byte array can represent. * Copyright (C) 2003 Mark J. Wielaard * * This file is part of Snark. * * This program 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 2, or (at your option) any later version. * * This program 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 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. */ package org.klomp.snark.bencode; import java.io.UnsupportedEncodingException; import java.util.List; import java.util.Map; /** * Holds different types that a bencoded byte array can represent. You need to * call the correct get method to get the correct java type object. If the * BEValue wasn't actually of the requested type you will get a * InvalidBEncodingException. * * @author Mark Wielaard (mark@klomp.org) */ public class BEValue { // This is either a byte[], Number, List or Map. private final Object value; public BEValue (byte[] value) { this.value = value; } public BEValue (Number value) { this.value = value; } public BEValue (List value) { this.value = value; } public BEValue (Map value) { this.value = value; } /** * Returns this BEValue as a String. This operation only succeeds when the * BEValue is a byte[], otherwise it will throw a InvalidBEncodingException. * The byte[] will be interpreted as UTF-8 encoded characters. */ public String getString () throws InvalidBEncodingException { try { return new String(getBytes(), "UTF-8"); } catch (ClassCastException cce) { throw new InvalidBEncodingException(cce.toString()); } catch (UnsupportedEncodingException uee) { throw new InternalError(uee.toString()); } } /** * Returns this BEValue as a byte[]. This operation only succeeds when the * BEValue is actually a byte[], otherwise it will throw a * InvalidBEncodingException. */ public byte[] getBytes () throws InvalidBEncodingException { try { return (byte[])value; } catch (ClassCastException cce) { throw new InvalidBEncodingException(cce.toString()); } } /** * Returns this BEValue as a Number. This operation only succeeds when the * BEValue is actually a Number, otherwise it will throw a * InvalidBEncodingException. */ public Number getNumber () throws InvalidBEncodingException { try { return (Number)value; } catch (ClassCastException cce) { throw new InvalidBEncodingException(cce.toString()); } } /** * Returns this BEValue as int. This operation only succeeds when the * BEValue is actually a Number, otherwise it will throw a * InvalidBEncodingException. The returned int is the result of * <code>Number.intValue()</code>. */ public int getInt () throws InvalidBEncodingException { return getNumber().intValue(); } /** * Returns this BEValue as long. This operation only succeeds when the * BEValue is actually a Number, otherwise it will throw a * InvalidBEncodingException. The returned long is the result of * <code>Number.longValue()</code>. */ public long getLong () throws InvalidBEncodingException { return getNumber().longValue(); } /** * Returns this BEValue as a List of BEValues. This operation only succeeds * when the BEValue is actually a List, otherwise it will throw a * InvalidBEncodingException. */ @SuppressWarnings("unchecked") public List<BEValue> getList () throws InvalidBEncodingException { try { return (List<BEValue>)value; } catch (ClassCastException cce) { throw new InvalidBEncodingException(cce.toString()); } } /** * Returns this BEValue as a Map of BEValue keys and BEValue values. This * operation only succeeds when the BEValue is actually a Map, otherwise it * will throw a InvalidBEncodingException. */ public Map getMap () throws InvalidBEncodingException { try { return (Map)value; } catch (ClassCastException cce) { throw new InvalidBEncodingException(cce.toString()); } } @Override public String toString () { String valueString; if (value instanceof byte[]) { byte[] bs = (byte[])value; // XXX - Stupid heuristic... if (bs.length <= 12) { valueString = new String(bs); } else { valueString = "bytes:" + bs.length; } } else { valueString = value.toString(); } return "BEValue[" + valueString + "]"; } }