Moved to own MsgPack implementation
This commit is contained in:
		@@ -10,6 +10,7 @@ subprojects {
 | 
			
		||||
 | 
			
		||||
    repositories {
 | 
			
		||||
        mavenCentral()
 | 
			
		||||
        maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    test {
 | 
			
		||||
 
 | 
			
		||||
@@ -25,7 +25,7 @@ artifacts {
 | 
			
		||||
 | 
			
		||||
dependencies {
 | 
			
		||||
    compile 'org.slf4j:slf4j-api:1.7.12'
 | 
			
		||||
    compile 'org.msgpack:msgpack-core:0.8.11'
 | 
			
		||||
    compile 'ch.dissem.msgpack:msgpack:development-SNAPSHOT'
 | 
			
		||||
    testCompile 'junit:junit:4.12'
 | 
			
		||||
    testCompile 'org.hamcrest:hamcrest-library:1.3'
 | 
			
		||||
    testCompile 'org.mockito:mockito-core:1.10.19'
 | 
			
		||||
 
 | 
			
		||||
@@ -1,9 +1,9 @@
 | 
			
		||||
package ch.dissem.bitmessage.entity.valueobject;
 | 
			
		||||
 | 
			
		||||
import ch.dissem.bitmessage.exception.ApplicationException;
 | 
			
		||||
import org.msgpack.core.MessagePack;
 | 
			
		||||
import org.msgpack.core.MessagePacker;
 | 
			
		||||
import org.msgpack.core.MessageUnpacker;
 | 
			
		||||
import ch.dissem.msgpack.types.MPMap;
 | 
			
		||||
import ch.dissem.msgpack.types.MPString;
 | 
			
		||||
import ch.dissem.msgpack.types.MPType;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
@@ -39,13 +39,10 @@ public class ExtendedEncoding implements Serializable {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public byte[] zip() {
 | 
			
		||||
        try (ByteArrayOutputStream out = new ByteArrayOutputStream();
 | 
			
		||||
             DeflaterOutputStream zipper = new DeflaterOutputStream(out)) {
 | 
			
		||||
 | 
			
		||||
            MessagePacker packer = MessagePack.newDefaultPacker(zipper);
 | 
			
		||||
            content.pack(packer);
 | 
			
		||||
            packer.close();
 | 
			
		||||
            zipper.close();
 | 
			
		||||
        try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
 | 
			
		||||
            try (DeflaterOutputStream zipper = new DeflaterOutputStream(out)) {
 | 
			
		||||
                content.pack().pack(zipper);
 | 
			
		||||
            }
 | 
			
		||||
            return out.toByteArray();
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            throw new ApplicationException(e);
 | 
			
		||||
@@ -68,12 +65,12 @@ public class ExtendedEncoding implements Serializable {
 | 
			
		||||
    public interface Unpacker<T extends ExtendedType> {
 | 
			
		||||
        String getType();
 | 
			
		||||
 | 
			
		||||
        T unpack(MessageUnpacker unpacker, int size);
 | 
			
		||||
        T unpack(MPMap<MPString, MPType<?>> map);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public interface ExtendedType extends Serializable {
 | 
			
		||||
        String getType();
 | 
			
		||||
 | 
			
		||||
        void pack(MessagePacker packer) throws IOException;
 | 
			
		||||
        MPMap<MPString, MPType<?>> pack() throws IOException;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,8 +3,7 @@ package ch.dissem.bitmessage.entity.valueobject.extended;
 | 
			
		||||
import ch.dissem.bitmessage.entity.Plaintext;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.ExtendedEncoding;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
 | 
			
		||||
import org.msgpack.core.MessagePacker;
 | 
			
		||||
import org.msgpack.core.MessageUnpacker;
 | 
			
		||||
import ch.dissem.msgpack.types.*;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +14,10 @@ import java.net.URLConnection;
 | 
			
		||||
import java.nio.file.Files;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.bitmessage.entity.valueobject.extended.Attachment.Disposition.attachment;
 | 
			
		||||
import static ch.dissem.bitmessage.utils.Strings.str;
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.mp;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extended encoding type 'message'. Properties 'parents' and 'files' not yet supported by PyBitmessage, so they might not work
 | 
			
		||||
 * properly with future PyBitmessage implementations.
 | 
			
		||||
@@ -74,45 +77,33 @@ public class Message implements ExtendedEncoding.ExtendedType {
 | 
			
		||||
        return Objects.hash(subject, body, parents, files);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(MessagePacker packer) throws IOException {
 | 
			
		||||
        int size = 3;
 | 
			
		||||
    @Override
 | 
			
		||||
    public MPMap<MPString, MPType<?>> pack() throws IOException {
 | 
			
		||||
        MPMap<MPString, MPType<?>> result = new MPMap<>();
 | 
			
		||||
        result.put(mp(""), mp(TYPE));
 | 
			
		||||
        result.put(mp("subject"), mp(subject));
 | 
			
		||||
        result.put(mp("body"), mp(body));
 | 
			
		||||
 | 
			
		||||
        if (!files.isEmpty()) {
 | 
			
		||||
            size++;
 | 
			
		||||
        }
 | 
			
		||||
        if (!parents.isEmpty()) {
 | 
			
		||||
            size++;
 | 
			
		||||
        }
 | 
			
		||||
        packer.packMapHeader(size);
 | 
			
		||||
        packer.packString("");
 | 
			
		||||
        packer.packString(TYPE);
 | 
			
		||||
        packer.packString("subject");
 | 
			
		||||
        packer.packString(subject);
 | 
			
		||||
        packer.packString("body");
 | 
			
		||||
        packer.packString(body);
 | 
			
		||||
        if (!files.isEmpty()) {
 | 
			
		||||
            packer.packString("files");
 | 
			
		||||
            packer.packArrayHeader(files.size());
 | 
			
		||||
            MPArray<MPMap<MPString, MPType<?>>> items = new MPArray<>();
 | 
			
		||||
            result.put(mp("files"), items);
 | 
			
		||||
            for (Attachment file : files) {
 | 
			
		||||
                packer.packMapHeader(4);
 | 
			
		||||
                packer.packString("name");
 | 
			
		||||
                packer.packString(file.getName());
 | 
			
		||||
                packer.packString("data");
 | 
			
		||||
                packer.packBinaryHeader(file.getData().length);
 | 
			
		||||
                packer.writePayload(file.getData());
 | 
			
		||||
                packer.packString("type");
 | 
			
		||||
                packer.packString(file.getType());
 | 
			
		||||
                packer.packString("disposition");
 | 
			
		||||
                packer.packString(file.getDisposition().name());
 | 
			
		||||
                MPMap<MPString, MPType<?>> item = new MPMap<>();
 | 
			
		||||
                item.put(mp("name"), mp(file.getName()));
 | 
			
		||||
                item.put(mp("data"), mp(file.getData()));
 | 
			
		||||
                item.put(mp("type"), mp(file.getType()));
 | 
			
		||||
                item.put(mp("disposition"), mp(file.getDisposition().name()));
 | 
			
		||||
                items.add(item);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        if (!parents.isEmpty()) {
 | 
			
		||||
            packer.packString("parents");
 | 
			
		||||
            packer.packArrayHeader(parents.size());
 | 
			
		||||
            MPArray<MPBinary> items = new MPArray<>();
 | 
			
		||||
            result.put(mp("parents"), items);
 | 
			
		||||
            for (InventoryVector parent : parents) {
 | 
			
		||||
                packer.packBinaryHeader(parent.getHash().length);
 | 
			
		||||
                packer.writePayload(parent.getHash());
 | 
			
		||||
                items.add(mp(parent.getHash()));
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Builder {
 | 
			
		||||
@@ -185,86 +176,44 @@ public class Message implements ExtendedEncoding.ExtendedType {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Message unpack(MessageUnpacker unpacker, int size) {
 | 
			
		||||
        public Message unpack(MPMap<MPString, MPType<?>> map) {
 | 
			
		||||
            Message.Builder builder = new Message.Builder();
 | 
			
		||||
            try {
 | 
			
		||||
                for (int i = 0; i < size; i++) {
 | 
			
		||||
                    String key = unpacker.unpackString();
 | 
			
		||||
                    switch (key) {
 | 
			
		||||
                        case "subject":
 | 
			
		||||
                            builder.subject(unpacker.unpackString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "body":
 | 
			
		||||
                            builder.body(unpacker.unpackString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "parents":
 | 
			
		||||
                            builder.parents = unpackParents(unpacker);
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "files":
 | 
			
		||||
                            builder.files = unpackFiles(unpacker);
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            LOG.error("Unexpected data with key: " + key);
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
            builder.subject(str(map.get(mp("subject"))));
 | 
			
		||||
            builder.body(str(map.get(mp("body"))));
 | 
			
		||||
            @SuppressWarnings("unchecked")
 | 
			
		||||
            MPArray<MPBinary> parents = (MPArray<MPBinary>) map.get(mp("parents"));
 | 
			
		||||
            if (parents != null) {
 | 
			
		||||
                for (MPBinary parent : parents) {
 | 
			
		||||
                    builder.addParent(new InventoryVector(parent.getValue()));
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                LOG.error(e.getMessage(), e);
 | 
			
		||||
            }
 | 
			
		||||
            @SuppressWarnings("unchecked")
 | 
			
		||||
            MPArray<MPMap<MPString, MPType<?>>> files = (MPArray<MPMap<MPString, MPType<?>>>) map.get(mp("files"));
 | 
			
		||||
            if (files != null) {
 | 
			
		||||
                for (MPMap<MPString, MPType<?>> item : files) {
 | 
			
		||||
                    Attachment.Builder b = new Attachment.Builder();
 | 
			
		||||
                    b.name(str(item.get(mp("name"))));
 | 
			
		||||
                    b.data(bin(item.get(mp("data"))));
 | 
			
		||||
                    b.type(str(item.get(mp("type"))));
 | 
			
		||||
                    String disposition = str(item.get(mp("disposition")));
 | 
			
		||||
                    if ("inline".equals(disposition)) {
 | 
			
		||||
                        b.inline();
 | 
			
		||||
                    } else if ("attachment".equals(disposition)) {
 | 
			
		||||
                        b.attachment();
 | 
			
		||||
                    }
 | 
			
		||||
                    builder.addFile(b.build());
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return new Message(builder);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static List<InventoryVector> unpackParents(MessageUnpacker unpacker) throws IOException {
 | 
			
		||||
            int size = unpacker.unpackArrayHeader();
 | 
			
		||||
            List<InventoryVector> parents = new ArrayList<>(size);
 | 
			
		||||
            for (int i = 0; i < size; i++) {
 | 
			
		||||
                int binarySize = unpacker.unpackBinaryHeader();
 | 
			
		||||
                parents.add(new InventoryVector(unpacker.readPayload(binarySize)));
 | 
			
		||||
        private byte[] bin(MPType data) {
 | 
			
		||||
            if (data instanceof MPBinary) {
 | 
			
		||||
                return ((MPBinary) data).getValue();
 | 
			
		||||
            } else {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            return parents;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        private static List<Attachment> unpackFiles(MessageUnpacker unpacker) throws IOException {
 | 
			
		||||
            int size = unpacker.unpackArrayHeader();
 | 
			
		||||
            List<Attachment> files = new ArrayList<>(size);
 | 
			
		||||
            for (int i = 0; i < size; i++) {
 | 
			
		||||
                Attachment.Builder attachment = new Attachment.Builder();
 | 
			
		||||
                int mapSize = unpacker.unpackMapHeader();
 | 
			
		||||
                for (int j = 0; j < mapSize; j++) {
 | 
			
		||||
                    String key = unpacker.unpackString();
 | 
			
		||||
                    switch (key) {
 | 
			
		||||
                        case "name":
 | 
			
		||||
                            attachment.name(unpacker.unpackString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "data":
 | 
			
		||||
                            int binarySize = unpacker.unpackBinaryHeader();
 | 
			
		||||
                            attachment.data(unpacker.readPayload(binarySize));
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "type":
 | 
			
		||||
                            attachment.type(unpacker.unpackString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "disposition":
 | 
			
		||||
                            String disposition = unpacker.unpackString();
 | 
			
		||||
                            switch (disposition) {
 | 
			
		||||
                                case "inline":
 | 
			
		||||
                                    attachment.inline();
 | 
			
		||||
                                    break;
 | 
			
		||||
                                case "attachment":
 | 
			
		||||
                                    attachment.attachment();
 | 
			
		||||
                                    break;
 | 
			
		||||
                                default:
 | 
			
		||||
                                    LOG.debug("Unknown disposition: " + disposition);
 | 
			
		||||
                                    break;
 | 
			
		||||
                            }
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            LOG.debug("Unknown file info '" + key + "' with data: " + unpacker.unpackValue());
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
                files.add(attachment.build());
 | 
			
		||||
            }
 | 
			
		||||
            return files;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -3,20 +3,19 @@ package ch.dissem.bitmessage.entity.valueobject.extended;
 | 
			
		||||
import ch.dissem.bitmessage.entity.Plaintext;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.ExtendedEncoding;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.InventoryVector;
 | 
			
		||||
import org.msgpack.core.MessagePacker;
 | 
			
		||||
import org.msgpack.core.MessageUnpacker;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
import ch.dissem.msgpack.types.*;
 | 
			
		||||
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.bitmessage.utils.Strings.str;
 | 
			
		||||
import static ch.dissem.msgpack.types.Utils.mp;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Extended encoding type 'vote'. Specification still outstanding, so this will need some work.
 | 
			
		||||
 */
 | 
			
		||||
public class Vote implements ExtendedEncoding.ExtendedType {
 | 
			
		||||
    private static final long serialVersionUID = -8427038604209964837L;
 | 
			
		||||
    private static final Logger LOG = LoggerFactory.getLogger(Vote.class);
 | 
			
		||||
 | 
			
		||||
    public static final String TYPE = "vote";
 | 
			
		||||
 | 
			
		||||
@@ -55,15 +54,13 @@ public class Vote implements ExtendedEncoding.ExtendedType {
 | 
			
		||||
        return Objects.hash(msgId, vote);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void pack(MessagePacker packer) throws IOException {
 | 
			
		||||
        packer.packMapHeader(3);
 | 
			
		||||
        packer.packString("");
 | 
			
		||||
        packer.packString(TYPE);
 | 
			
		||||
        packer.packString("msgId");
 | 
			
		||||
        packer.packBinaryHeader(msgId.getHash().length);
 | 
			
		||||
        packer.writePayload(msgId.getHash());
 | 
			
		||||
        packer.packString("vote");
 | 
			
		||||
        packer.packString(vote);
 | 
			
		||||
    @Override
 | 
			
		||||
    public MPMap<MPString, MPType<?>> pack() throws IOException {
 | 
			
		||||
        MPMap<MPString, MPType<?>> result = new MPMap<>();
 | 
			
		||||
        result.put(mp(""), mp(TYPE));
 | 
			
		||||
        result.put(mp("msgId"), mp(msgId.getHash()));
 | 
			
		||||
        result.put(mp("vote"), mp(vote));
 | 
			
		||||
        return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static class Builder {
 | 
			
		||||
@@ -104,27 +101,13 @@ public class Vote implements ExtendedEncoding.ExtendedType {
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        @Override
 | 
			
		||||
        public Vote unpack(MessageUnpacker unpacker, int size) {
 | 
			
		||||
        public Vote unpack(MPMap<MPString, MPType<?>> map) {
 | 
			
		||||
            Vote.Builder builder = new Vote.Builder();
 | 
			
		||||
            try {
 | 
			
		||||
                for (int i = 0; i < size; i++) {
 | 
			
		||||
                    String key = unpacker.unpackString();
 | 
			
		||||
                    switch (key) {
 | 
			
		||||
                        case "msgId":
 | 
			
		||||
                            int binarySize = unpacker.unpackBinaryHeader();
 | 
			
		||||
                            builder.msgId(new InventoryVector(unpacker.readPayload(binarySize)));
 | 
			
		||||
                            break;
 | 
			
		||||
                        case "vote":
 | 
			
		||||
                            builder.vote(unpacker.unpackString());
 | 
			
		||||
                            break;
 | 
			
		||||
                        default:
 | 
			
		||||
                            LOG.error("Unexpected data with key: " + key);
 | 
			
		||||
                            break;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            } catch (IOException e) {
 | 
			
		||||
                LOG.error(e.getMessage(), e);
 | 
			
		||||
            MPType<?> msgId = map.get(mp("msgId"));
 | 
			
		||||
            if (msgId instanceof MPBinary) {
 | 
			
		||||
                builder.msgId(new InventoryVector(((MPBinary) msgId).getValue()));
 | 
			
		||||
            }
 | 
			
		||||
            builder.vote(str(map.get(mp("vote"))));
 | 
			
		||||
            return new Vote(builder);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -4,8 +4,10 @@ import ch.dissem.bitmessage.entity.valueobject.ExtendedEncoding;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.extended.Message;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.extended.Vote;
 | 
			
		||||
import ch.dissem.bitmessage.exception.ApplicationException;
 | 
			
		||||
import org.msgpack.core.MessagePack;
 | 
			
		||||
import org.msgpack.core.MessageUnpacker;
 | 
			
		||||
import ch.dissem.msgpack.Reader;
 | 
			
		||||
import ch.dissem.msgpack.types.MPMap;
 | 
			
		||||
import ch.dissem.msgpack.types.MPString;
 | 
			
		||||
import ch.dissem.msgpack.types.MPType;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
@@ -15,6 +17,8 @@ import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.zip.InflaterInputStream;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.bitmessage.utils.Strings.str;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Factory that creates {@link ExtendedEncoding} objects from byte arrays. You can register your own types by adding a
 | 
			
		||||
 * {@link ExtendedEncoding.Unpacker} using {@link #registerFactory(ExtendedEncoding.Unpacker)}.
 | 
			
		||||
@@ -22,7 +26,7 @@ import java.util.zip.InflaterInputStream;
 | 
			
		||||
public class ExtendedEncodingFactory {
 | 
			
		||||
    private static final Logger LOG = LoggerFactory.getLogger(ExtendedEncodingFactory.class);
 | 
			
		||||
    private static final ExtendedEncodingFactory INSTANCE = new ExtendedEncodingFactory();
 | 
			
		||||
    private static final String KEY_MESSAGE_TYPE = "";
 | 
			
		||||
    private static final MPString KEY_MESSAGE_TYPE = new MPString("");
 | 
			
		||||
    private Map<String, ExtendedEncoding.Unpacker<?>> factories = new HashMap<>();
 | 
			
		||||
 | 
			
		||||
    private ExtendedEncodingFactory() {
 | 
			
		||||
@@ -37,17 +41,17 @@ public class ExtendedEncodingFactory {
 | 
			
		||||
 | 
			
		||||
    public ExtendedEncoding unzip(byte[] zippedData) {
 | 
			
		||||
        try (InflaterInputStream unzipper = new InflaterInputStream(new ByteArrayInputStream(zippedData))) {
 | 
			
		||||
            MessageUnpacker unpacker = MessagePack.newDefaultUnpacker(unzipper);
 | 
			
		||||
            int mapSize = unpacker.unpackMapHeader();
 | 
			
		||||
            String key = unpacker.unpackString();
 | 
			
		||||
            if (!KEY_MESSAGE_TYPE.equals(key)) {
 | 
			
		||||
                LOG.error("Unexpected content: " + key);
 | 
			
		||||
            Reader reader = Reader.getInstance();
 | 
			
		||||
            @SuppressWarnings("unchecked")
 | 
			
		||||
            MPMap<MPString, MPType<?>> map = (MPMap<MPString, MPType<?>>) reader.read(unzipper);
 | 
			
		||||
            MPType<?> messageType = map.get(KEY_MESSAGE_TYPE);
 | 
			
		||||
            if (messageType == null) {
 | 
			
		||||
                LOG.error("Missing message type");
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
            String type = unpacker.unpackString();
 | 
			
		||||
            ExtendedEncoding.Unpacker<?> factory = factories.get(type);
 | 
			
		||||
            return new ExtendedEncoding(factory.unpack(unpacker, mapSize - 1));
 | 
			
		||||
        } catch (IOException e) {
 | 
			
		||||
            ExtendedEncoding.Unpacker<?> factory = factories.get(str(messageType));
 | 
			
		||||
            return new ExtendedEncoding(factory.unpack(map));
 | 
			
		||||
        } catch (ClassCastException | IOException e) {
 | 
			
		||||
            throw new ApplicationException(e);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -37,4 +37,8 @@ public class Strings {
 | 
			
		||||
        }
 | 
			
		||||
        return hex;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static String str(Object o) {
 | 
			
		||||
        return o == null ? null : o.toString();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -21,22 +21,26 @@ import ch.dissem.bitmessage.entity.BitmessageAddress;
 | 
			
		||||
import ch.dissem.bitmessage.entity.Plaintext;
 | 
			
		||||
import ch.dissem.bitmessage.entity.payload.Pubkey;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.Label;
 | 
			
		||||
import ch.dissem.bitmessage.entity.valueobject.extended.Message;
 | 
			
		||||
import org.apache.commons.lang3.text.WordUtils;
 | 
			
		||||
import org.slf4j.Logger;
 | 
			
		||||
import org.slf4j.LoggerFactory;
 | 
			
		||||
 | 
			
		||||
import java.net.InetAddress;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
import java.util.regex.Pattern;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
 | 
			
		||||
import static ch.dissem.bitmessage.demo.CommandLine.COMMAND_BACK;
 | 
			
		||||
import static ch.dissem.bitmessage.demo.CommandLine.ERROR_UNKNOWN_COMMAND;
 | 
			
		||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A simple command line Bitmessage application
 | 
			
		||||
 */
 | 
			
		||||
public class Application {
 | 
			
		||||
    private final static Logger LOG = LoggerFactory.getLogger(Application.class);
 | 
			
		||||
    private final static Pattern RESPONSE_PATTERN = Pattern.compile("^RE:.*$", CASE_INSENSITIVE);
 | 
			
		||||
    private final CommandLine commandLine;
 | 
			
		||||
 | 
			
		||||
    private BitmessageContext ctx;
 | 
			
		||||
@@ -342,7 +346,7 @@ public class Application {
 | 
			
		||||
            System.out.println();
 | 
			
		||||
            System.out.println("c) compose message");
 | 
			
		||||
            System.out.println("s) compose broadcast");
 | 
			
		||||
            if (label.getType() == Label.Type.TRASH) {
 | 
			
		||||
            if (label != null && label.getType() == Label.Type.TRASH) {
 | 
			
		||||
                System.out.println("e) empty trash");
 | 
			
		||||
            }
 | 
			
		||||
            System.out.println(COMMAND_BACK);
 | 
			
		||||
@@ -392,7 +396,7 @@ public class Application {
 | 
			
		||||
            command = commandLine.nextCommand();
 | 
			
		||||
            switch (command) {
 | 
			
		||||
                case "r":
 | 
			
		||||
                    compose(message.getTo(), message.getFrom(), "RE: " + message.getSubject());
 | 
			
		||||
                    compose(message.getTo(), message.getFrom(), message);
 | 
			
		||||
                    break;
 | 
			
		||||
                case "d":
 | 
			
		||||
                    ctx.labeler().delete(message);
 | 
			
		||||
@@ -442,14 +446,20 @@ public class Application {
 | 
			
		||||
        return commandLine.selectAddress(addresses, "To:");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void compose(BitmessageAddress from, BitmessageAddress to, String subject) {
 | 
			
		||||
    private void compose(BitmessageAddress from, BitmessageAddress to, Plaintext parent) {
 | 
			
		||||
        boolean broadcast = (to == null);
 | 
			
		||||
        String subject;
 | 
			
		||||
        System.out.println();
 | 
			
		||||
        System.out.println("From:    " + from);
 | 
			
		||||
        if (!broadcast) {
 | 
			
		||||
            System.out.println("To:      " + to);
 | 
			
		||||
        }
 | 
			
		||||
        if (subject != null) {
 | 
			
		||||
        if (parent != null) {
 | 
			
		||||
            if (RESPONSE_PATTERN.matcher(parent.getSubject()).matches()) {
 | 
			
		||||
                subject = parent.getSubject();
 | 
			
		||||
            } else {
 | 
			
		||||
                subject = "RE: " + parent.getSubject();
 | 
			
		||||
            }
 | 
			
		||||
            System.out.println("Subject: " + subject);
 | 
			
		||||
        } else {
 | 
			
		||||
            System.out.print("Subject: ");
 | 
			
		||||
@@ -462,10 +472,20 @@ public class Application {
 | 
			
		||||
            line = commandLine.nextLine();
 | 
			
		||||
            message.append(line).append('\n');
 | 
			
		||||
        } while (line.length() > 0 || !commandLine.yesNo("Send message?"));
 | 
			
		||||
        if (broadcast) {
 | 
			
		||||
            ctx.broadcast(from, subject, message.toString());
 | 
			
		||||
        Plaintext.Type type = broadcast ? Plaintext.Type.BROADCAST : Plaintext.Type.MSG;
 | 
			
		||||
        Plaintext.Builder builder = new Plaintext.Builder(type);
 | 
			
		||||
        builder.from(from);
 | 
			
		||||
        builder.to(to);
 | 
			
		||||
        if (commandLine.yesNo("Use extended encoding?")) {
 | 
			
		||||
            Message.Builder extended = new Message.Builder();
 | 
			
		||||
            extended.subject(subject).body(message.toString());
 | 
			
		||||
            if (parent != null) {
 | 
			
		||||
                extended.addParent(parent);
 | 
			
		||||
            }
 | 
			
		||||
            builder.message(extended.build());
 | 
			
		||||
        } else {
 | 
			
		||||
            ctx.send(from, to, subject, message.toString());
 | 
			
		||||
            builder.message(subject, message.toString());
 | 
			
		||||
        }
 | 
			
		||||
        ctx.send(builder.build());
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user