package serializers; import java.io.*; import java.util.ArrayList; import java.util.Collections; import java.util.List; import org.apache.thrift.TDeserializer; import org.apache.thrift.TSerializer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocolFactory; import data.media.MediaTransformer; import serializers.thrift.media.*; public class Thrift { public static void register(TestGroups groups) { groups.media.add(mediaTransformer, new MediaSerializer(ProtocolSpec.DefaultBinary), new SerFeatures( SerFormat.BIN_CROSSLANG, SerGraph.FLAT_TREE, SerClass.CLASSES_KNOWN, "" ) ); groups.media.add(mediaTransformer, new MediaSerializer(ProtocolSpec.CompactBinary), new SerFeatures( SerFormat.BIN_CROSSLANG, SerGraph.FLAT_TREE, SerClass.CLASSES_KNOWN, "" ) ); } // ------------------------------------------------------------ // Serializers public static final class ProtocolSpec { public final TProtocolFactory factory; public final String suffix; public ProtocolSpec(TProtocolFactory factory, String suffix) { this.factory = factory; this.suffix = suffix; } public static final ProtocolSpec DefaultBinary = new ProtocolSpec(new TBinaryProtocol.Factory(), ""); public static final ProtocolSpec CompactBinary = new ProtocolSpec(new TCompactProtocol.Factory(), "-compact"); } public static final class MediaSerializer extends Serializer<MediaContent> { private final ProtocolSpec spec; public MediaSerializer(ProtocolSpec spec) { this.spec = spec; } public MediaContent deserialize(byte[] array) throws Exception { MediaContent content = new MediaContent(); new TDeserializer(spec.factory).deserialize(content, array); return content; } public byte[] serialize(MediaContent content) throws Exception { return new TSerializer(spec.factory).serialize(content); } public String getName() { return "thrift" + spec.suffix; } @Override public final void serializeItems(MediaContent[] items, OutputStream out0) throws Exception { DataOutputStream out = new DataOutputStream(out0); TSerializer ser = new TSerializer(spec.factory); for (MediaContent item : items) { byte[] data = ser.serialize(item); out.writeInt(data.length); out.write(data); } // should we write end marker (length of 0) or not? For now, omit it out.flush(); } @Override public MediaContent[] deserializeItems(InputStream in0, int numberOfItems) throws Exception { DataInputStream in = new DataInputStream(in0); TDeserializer deser = new TDeserializer(spec.factory); MediaContent[] result = new MediaContent[numberOfItems]; for (int i = 0; i < numberOfItems; ++i) { int len = in.readInt(); byte[] data = new byte[len]; in.readFully(data); MediaContent content = new MediaContent(); deser.deserialize(content, data); result[i] = content; } return result; } } // ------------------------------------------------------------ // Transformers public static final MediaTransformer<MediaContent> mediaTransformer = new MediaTransformer<MediaContent>() { @Override public MediaContent[] resultArray(int size) { return new MediaContent[size]; } // ---------------------------------------------------------- // Forward public MediaContent forward(data.media.MediaContent mc) { MediaContent cb = new MediaContent(); cb.setMedia(forwardMedia(mc.media)); for (data.media.Image image : mc.images) { cb.addToImage(forwardImage(image)); } return cb; } private Media forwardMedia(data.media.Media media) { // Media Media mb = new Media(); mb.setUri(media.uri); if (media.title != null) mb.setTitle(media.title); mb.setWidth(media.width); mb.setHeight(media.height); mb.setFormat(media.format); mb.setDuration(media.duration); mb.setSize(media.size); if (media.hasBitrate) mb.setBitrate(media.bitrate); for (String person : media.persons) { mb.addToPerson(person); } mb.setPlayer(forwardPlayer(media.player)); if (media.copyright != null) mb.setCopyright(media.copyright); return mb; } public Player forwardPlayer(data.media.Media.Player p) { switch (p) { case JAVA: return Player.JAVA; case FLASH: return Player.FLASH; default: throw new AssertionError("invalid case: " + p); } } private Image forwardImage(data.media.Image image) { Image ib = new Image(); ib.setUri(image.uri); if (image.title != null) ib.setTitle(image.title); ib.setWidth(image.width); ib.setHeight(image.height); ib.setSize(forwardSize(image.size)); return ib; } public Size forwardSize(data.media.Image.Size s) { switch (s) { case SMALL: return Size.SMALL; case LARGE: return Size.LARGE; default: throw new AssertionError("invalid case: " + s); } } // ---------------------------------------------------------- // Reverse public data.media.MediaContent reverse(MediaContent mc) { List<data.media.Image> images = new ArrayList<data.media.Image>(mc.getImageSize()); for (Image image : mc.getImage()) { images.add(reverseImage(image)); } return new data.media.MediaContent(reverseMedia(mc.getMedia()), images); } private data.media.Media reverseMedia(Media media) { // Media return new data.media.Media( media.getUri(), media.isSetTitle() ? media.getTitle() : null, media.getWidth(), media.getHeight(), media.getFormat(), media.getDuration(), media.getSize(), media.isSetBitrate() ? media.getBitrate() : 0, media.isSetBitrate(), new ArrayList<String>(media.getPerson()), reversePlayer(media.getPlayer()), media.isSetCopyright() ? media.getCopyright() : null ); } public data.media.Media.Player reversePlayer(Player p) { if (p == Player.JAVA) return data.media.Media.Player.JAVA; if (p == Player.FLASH) return data.media.Media.Player.FLASH; throw new AssertionError("invalid case: " + p); } private data.media.Image reverseImage(Image image) { return new data.media.Image( image.getUri(), image.isSetTitle() ? image.getTitle() : null, image.getWidth(), image.getHeight(), reverseSize(image.getSize())); } public data.media.Image.Size reverseSize(Size s) { switch (s) { case SMALL: return data.media.Image.Size.SMALL; case LARGE: return data.media.Image.Size.LARGE; default: throw new AssertionError("invalid case: " + s); } } public data.media.MediaContent shallowReverse(MediaContent mc) { return new data.media.MediaContent(reverseMedia(mc.getMedia()), Collections.<data.media.Image>emptyList()); } }; }