/* * RUBTClient is a BitTorrent client written at Rutgers University for * instructional use. * Copyright (C) 2008 Robert Moore II * * 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 3 of the License, 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, see <http://www.gnu.org/licenses/>. */ package GivenTools; import java.util.*; import java.nio.*; /** * Contains a number of methods useful for debugging and developing programs * using Bencoding methods.  This class is specifically designed to be used * with <code>edu.rutgers.cs.cs352.bt.util.Bencoder</code> and * <code>Bencoder2</code>. * * @author Robert Moore II * */ public class ToolKit { /** * Prints out Java versions of Bencoding data types. * @param o the Object to print.  It must be one of the following * types: @ */ @SuppressWarnings("unchecked") public static void print(Object o) { if (o instanceof ByteBuffer) printString((ByteBuffer) o, true, 0); else if (o instanceof byte[]) printString((byte[]) o, true, 0); else if (o instanceof Integer) printInteger((Integer) o, 0); else if (o instanceof ArrayList) printList((ArrayList) o, 0); else if (o instanceof HashMap) printMap((HashMap) o, 0); else System.err.println("Error: Unknown type"); } /** * Prints the specified object with the provided depth. The depth simply indicates how much to indent. * @param o the object to print * @param depth the depth of the object within another data type. */ @SuppressWarnings("unchecked") public static void print(Object o, int depth) { if (o instanceof ByteBuffer) printString((ByteBuffer) o, true, depth + 1); else if (o instanceof byte[]) printString((byte[]) o, true, depth + 1); else if (o instanceof Integer) printInteger((Integer) o, depth + 1); else if (o instanceof ArrayList) printList((ArrayList) o, depth + 1); else if (o instanceof HashMap) printMap((HashMap) o, depth + 1); else System.err.println("Error: Unknown type"); } /** * Helper method that prints out a byte string as a series of integer or ASCII * characters. * @param bytes the byte string to print. * @param as_text {@code true} if the byte string should be printed as ASCII characters * @param depth the depth of the object within other objects, used for indenting. */ public static void printString(byte[] bytes, boolean as_text, int depth) { for (int k = 0; k < depth; k++) System.out.print(" "); System.out.print("String: "); for (int i = 0; i < bytes.length; i++) { System.out .print(as_text ? (char) bytes[i] : (int) bytes[i] + " "); } System.out.println(); } /** * Helper method that prints out a {@code ByteBuffer} as a series of integer or ASCII * characters. * @param byte_string the {@code ByteBuffer} to print. * @param as_text {@code true} if the {@code ByteBuffer} should be printed as ASCII characters * @param depth the depth of the object within other objects, used for indenting. */ public static void printString(ByteBuffer byte_string, boolean as_text, int depth) { for (int k = 0; k < depth; k++) System.out.print(" "); System.out.print("String: "); byte[] bytes = byte_string.array(); for (int i = 0; i < bytes.length; i++) { System.out .print(as_text ? (char) bytes[i] : (int) bytes[i] + " "); } System.out.println(); } /** * Helper method that prints out an integer. * @param i the integer to print. * @param depth the depth of the object within other objects, used for indenting. */ public static void printInteger(Integer i, int depth) { for (int k = 0; k < depth; k++) System.out.print(" "); System.out.println("Integer: " + i); } /** * Helper method that prints out a list. * @param list the list to print. * @param depth the depth of the object within other objects, used for indenting. */ @SuppressWarnings("unchecked") public static void printList(AbstractList list, int depth) { final Iterator i = list.iterator(); Object o = null; for (int k = 0; k < depth; k++) System.out.print(" "); System.out.println("List: "); while (i.hasNext() && (o = i.next()) != null) { for (int k = 0; k < depth; k++) System.out.print(" "); System.out.print(" +"); print(o, depth); } } /** * Helper method that prints out a dictionary/map. * @param map the dictionary/map to print. * @param depth the depth of the object within other objects, used for indenting. */ @SuppressWarnings("unchecked") public static void printMap(Map map, int depth) { final Iterator i = map.keySet().iterator(); Object key = null; for (int k = 0; k < depth; k++) System.out.print(" "); System.out.println("Dictionary:"); while (i.hasNext() && (key = i.next()) != null) { for (int k = 0; k < depth; k++) System.out.print(" "); System.out.print("(K) "); print(key, depth); Object val = map.get(key); for (int k = 0; k < depth; k++) System.out.print(" "); System.out.print("(V) "); print(val, depth); } } }