/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package com.juniform; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.msgpack.core.MessagePack; import org.msgpack.core.MessagePacker; import org.msgpack.core.MessageUnpacker; import org.msgpack.value.ArrayValue; import org.msgpack.value.IntegerValue; import org.msgpack.value.MapValue; import org.msgpack.value.Value; import org.msgpack.value.impl.ImmutableDoubleValueImpl; /** * * @author acherkashin */ public class JUniformPackerMessagePack implements IJUniformPacker { private final static MessagePack _msgpack = new MessagePack(); // ---------------------------------------------------------------------- // // PUBLIC // ---------------------------------------------------------------------- // @Override public JUniformObject toUniformObjectFromStream(InputStream stream) { MessageUnpacker unpacker = _msgpack.newUnpacker(stream); return this.toUniformObjectFromUnpacker(unpacker); } public JUniformObject toUniformObjectFromUnpacker(MessageUnpacker unpacker) { if (unpacker == null) { return JUniformObject.OBJECT_NIL; } Value value; try { value = unpacker.unpackValue(); } catch (IOException ex) { return JUniformObject.OBJECT_NIL; } return this.toUniformObjectFromObject(value); } @Override public JUniformObject toUniformObjectFromString(String string) { return this.toUniformObjectFromBytes(string.getBytes()); } @Override public JUniformObject toUniformObjectFromBytes(byte[] bytes) { MessageUnpacker unpacker = _msgpack.newUnpacker(bytes); return this.toUniformObjectFromUnpacker(unpacker); } @Override public JUniformObject toUniformObjectFromObject(Object object) { Object result = _toSimpleObjectFromValue(object); if (result == null) { return JUniformObject.OBJECT_NIL; } return new JUniformObject(result); } private Object _toSimpleObjectFromValue(Object object) { if (object == null || !(object instanceof Value)) { return null; } Value value = (Value)object; if (value.isNilValue()) { return null; } else if (value.isBooleanValue()) { return value.asBooleanValue().getBoolean(); } else if (value.isStringValue()) { return value.asStringValue().toString(); } else if (value.isIntegerValue()) { IntegerValue innerValue = value.asIntegerValue(); if (innerValue.isInLongRange()) { return innerValue.asLong(); } else if (innerValue.isInIntRange()) { return innerValue.asInt(); } else if (innerValue.isInShortRange()) { return innerValue.asShort(); } else if (innerValue.isInByteRange()) { return innerValue.asByte(); } return null; } else if (value.isNumberValue()) { // shame on you, MessagePack if (ImmutableDoubleValueImpl.class.equals(value.getClass())) { ImmutableDoubleValueImpl innerValue = (ImmutableDoubleValueImpl)value; return innerValue.toDouble(); } return value.asNumberValue().toLong(); } else if (value.isArrayValue()) { ArrayList<Object> array = new ArrayList<>(); ArrayValue msgpackArray = value.asArrayValue(); Iterator<Value> it = msgpackArray.iterator(); while(it.hasNext()) { Value inner = it.next(); array.add(this.toUniformObjectFromObject(inner)); } return array; } else if (value.isMapValue()) { Map<Object,Object> map = new HashMap<>(); MapValue msgpackMap = value.asMapValue(); Iterator<Map.Entry<Value,Value>> it = msgpackMap.entrySet().iterator(); while(it.hasNext()) { Map.Entry<Value,Value> entry = it.next(); map.put( this._toSimpleObjectFromValue(entry.getKey()), this.toUniformObjectFromObject(entry.getValue()) ); } return map; } return JUniformObject.OBJECT_NIL; } @Override public Object fromUniformObject(JUniformObject object) { ByteArrayOutputStream out = new ByteArrayOutputStream(); MessagePacker packer = _msgpack.newPacker(out); try { this._writeJUniformObjectToPacker(object, packer); packer.close(); } catch (IOException ex) { return null; } return out.toByteArray(); } @Override public byte[] fromUniformObjectToByteArray(JUniformObject object) { Object result = this.fromUniformObject(object); if (result == null) { return null; } return (byte[])result; } @Override public String fromUniformObjectToString(JUniformObject object) { Object result = this.fromUniformObject(object); if (result == null) { return null; } byte[] bytes = (byte[])result; return new String(bytes); } private void _writeJUniformObjectToPacker(JUniformObject object, MessagePacker packer) throws IOException { if (object == null) { packer.packNil(); } else if (object.isMapValue()) { packer.packMapHeader(object.getPropertiesCount()); Iterator<Map.Entry<Object,JUniformObject>> it = object.entrySet().iterator(); while (it.hasNext()) { Map.Entry<Object,JUniformObject> pair = it.next(); this._writeSimpleObjectToPacker(pair.getKey(), packer); this._writeJUniformObjectToPacker(pair.getValue(), packer); } } else if (object.isArrayValue()) { packer.packArrayHeader(object.getElementsCount()); Iterator<JUniformObject> it = object.iterator(); while(it.hasNext()) { this._writeJUniformObjectToPacker(it.next(), packer); } } else { this._writeSimpleObjectToPacker(object.getValue(), packer); } } private void _writeSimpleObjectToPacker(Object object, MessagePacker packer) throws IOException { if (object == null) { packer.packNil(); } else if (object instanceof Byte) { packer.packByte((Byte)object); } else if (object instanceof Boolean) { packer.packBoolean((Boolean)object); } else if (object instanceof Double) { packer.packDouble((Double)object); } else if (object instanceof Float) { packer.packFloat((Float)object); } else if (object instanceof Integer) { packer.packInt((Integer)object); } else if (object instanceof Long) { packer.packLong((Long)object); } else if (object instanceof Short) { packer.packShort((Short)object); } else if (object instanceof String) { packer.packString((String)object); } else { packer.packNil(); } } }