package org.limewire.core.impl.inspections;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.channels.Channels;
import java.nio.channels.ReadableByteChannel;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import org.limewire.bittorrent.bencoding.Token;
import org.limewire.io.IOUtils;
import org.limewire.io.InvalidDataException;
import org.limewire.util.BEncoder;
/**
* helper parser class
* todo: consider putting the logic here inside the inspections data/spec objects themselves.
*/
public class InspectionsParser {
/**
* Parse gzipped bencoded byte[] into list of inspections specifications
*
* list
* map0
* "startdelay" -> integer
* "interval" -> integer
* "insp" -> list of inspection point strings
* point1,
* point2, point3, ...
* map1
* "startdelay" -> integer
* ...
*
* @param rawInspectionSpecs byte[] raw data
* @return List<InspectionsSpec> inspection specifications
* @throws IOException if error occurs during parsing
*/
// todo: consider putting all the parsing logic in a class that contains a List<InspectionsSpec>
public List<InspectionsSpec> parseInspectionSpecs(byte[] rawInspectionSpecs) throws IOException,
InvalidDataException {
ByteArrayInputStream bais = new ByteArrayInputStream(rawInspectionSpecs);
GZIPInputStream gzip = new GZIPInputStream(bais);
ReadableByteChannel rbc = Channels.newChannel(gzip);
List<InspectionsSpec> specs = new ArrayList<InspectionsSpec>();
List<?> inspSpecs = (List<?>) Token.parse(rbc, "UTF-8");
for (Object inspSpec : inspSpecs) {
specs.add(new InspectionsSpec(inspSpec));
}
return specs;
}
/**
*
* @param insps inspection results
* @return byte[] bencoded and compressed representation of inspection results
* @throws IOException if error occurs during conversion
*/
// todo: revisit whether the parsing logic even belongs in here, or in InspectionDataContainer
// Same with the List<InspectionsSpec>, consider making an object that contains the List<InspectionsSpec>
public byte[] inspectionResultToByteArray(InspectionDataContainer insps) throws IOException {
Map<String, Object> bencodedMap = insps.asBencodedMap();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
GZIPOutputStream dos = null;
try {
dos = new GZIPOutputStream(baos);
try {
BEncoder.getEncoder(dos, false, true, "UTF-8").encodeDict(bencodedMap);
} catch (Throwable bencoding) {
// a BEInspectable returned invalid object - report the error.
String msg = bencoding.toString();
String ret = "d5:error" + msg.length() + ":" + msg + "e";
dos.write(ret.getBytes("UTF-8"));
}
dos.flush();
} finally {
IOUtils.close(dos);
}
return baos.toByteArray();
}
}