public void run() { try { // System.out.println(this + "]" + id + " run start"); boolean b = runSupport(); // System.out.println(this + "]" + id + " runSupport Done: ret=" + b); if (returnValueObject != null && returnValueObject.length > 0) { returnValueObject[0] = b; } } catch (Throwable e) { Debug.out(id, e); } finally { // System.out.println(this + "]" + id + " sem=" + sem); if (sem != null) { // System.out.println(this + "]" + id + " sem Release"); sem.release(); } } }
private boolean encodeObject(Object object) throws IOException { if (object instanceof BEncodableObject) { object = ((BEncodableObject) object).toBencodeObject(); } if (object instanceof String || object instanceof Float || object instanceof Double) { String tempString = (object instanceof String) ? (String) object : String.valueOf(object); // usually this is simpler to encode by hand as chars < 0x80 map directly in UTF-8 boolean simple = true; int char_count = tempString.length(); byte[] encoded = new byte[char_count]; for (int i = 0; i < char_count; i++) { char c = tempString.charAt(i); if (c < 0x80) { encoded[i] = (byte) c; } else { simple = false; break; } } if (simple) { writeInt(char_count); writeChar(':'); writeBytes(encoded); } else { ByteBuffer bb = Constants.DEFAULT_CHARSET.encode(tempString); writeInt(bb.limit()); writeChar(':'); writeByteBuffer(bb); } } else if (object instanceof Map) { @SuppressWarnings("unchecked") Map<String, Object> tempMap = (Map<String, Object>) object; SortedMap<String, Object> tempTree = null; // unfortunately there are some occasions where we want to ensure that // the 'key' of the map is not mangled by assuming its UTF-8 encodable. // In particular the response from a tracker scrape request uses the // torrent hash as the KEY. Hence the introduction of the type below // to allow the constructor of the Map to indicate that the keys should // be extracted using a BYTE_ENCODING boolean byte_keys = false; // object instanceof ByteEncodedKeyHashMap; // write the d writeChar('d'); // are we sorted? if (tempMap instanceof TreeMap) { tempTree = (TreeMap<String, Object>) tempMap; } else { tempTree = new TreeMap<String, Object>(tempMap); } Iterator<Map.Entry<String, Object>> it = tempTree.entrySet().iterator(); while (it.hasNext()) { Map.Entry<String, Object> entry = (Map.Entry<String, Object>) it.next(); Object o_key = entry.getKey(); Object value = entry.getValue(); if (value != null) { if (o_key instanceof byte[]) { encodeObject(o_key); if (!encodeObject(value)) encodeObject(""); } else if (o_key instanceof String) { String key = (String) o_key; if (byte_keys) { try { encodeObject(Constants.BYTE_CHARSET.encode(key)); if (!encodeObject(value)) encodeObject(""); } catch (UnsupportedEncodingException e) { throw (new IOException("BEncoder: unsupport encoding: " + e.getMessage())); } } else { // if we put non-ascii chars in as keys we can get horrible expanding // config issues as we cycle through decode/encode cycles with certain // characters encodeObject(key); // Key goes in as UTF-8 if (!encodeObject(value)) encodeObject(""); } } else Debug.out( "Attempt to encode an unsupported map key type: " + object.getClass() + ";value=" + object); } } writeChar('e'); } else if (object instanceof List) { @SuppressWarnings("unchecked") List<Object> tempList = (List<Object>) object; // write out the l writeChar('l'); for (int i = 0; i < tempList.size(); i++) { encodeObject(tempList.get(i)); } writeChar('e'); } else if (object instanceof Long) { Long tempLong = (Long) object; // write out the l writeChar('i'); writeLong(tempLong.longValue()); writeChar('e'); } else if (object instanceof Integer) { Integer tempInteger = (Integer) object; // write out the l writeChar('i'); writeInt(tempInteger.intValue()); writeChar('e'); } else if (object instanceof byte[]) { byte[] tempByteArray = (byte[]) object; writeInt(tempByteArray.length); writeChar(':'); if (url_encode) { writeBytes( URLEncoder.encode( new String(tempByteArray, Constants.BYTE_ENCODING), Constants.BYTE_ENCODING) .getBytes()); } else { writeBytes(tempByteArray); } } else if (object instanceof ByteBuffer) { ByteBuffer bb = (ByteBuffer) object; writeInt(bb.limit()); writeChar(':'); writeByteBuffer(bb); } else if (object == null) { // ideally we'd bork here but I don't want to run the risk of breaking existing stuff so just // log Debug.out("Attempt to encode a null value: sofar=" + getEncodedSoFar()); return false; } else { Debug.out( "Attempt to encode an unsupported entry type: " + object.getClass() + ";value=" + object); return false; } return true; }