/* * Copyright (C) 2012, 2016 higherfrequencytrading.com * Copyright (C) 2016 Roman Leventov * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package net.openhft.xstream.converters; import com.thoughtworks.xstream.converters.ConversionException; import com.thoughtworks.xstream.converters.Converter; import com.thoughtworks.xstream.converters.MarshallingContext; import com.thoughtworks.xstream.converters.UnmarshallingContext; import com.thoughtworks.xstream.io.HierarchicalStreamReader; import com.thoughtworks.xstream.io.HierarchicalStreamWriter; import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.*; /** * Created by Rob Austin */ public class ByteBufferConverter implements Converter { private final Charset charset = Charset.forName("ISO-8859-1"); private final CharsetDecoder decoder = charset.newDecoder(); @Override public void marshal(Object o, HierarchicalStreamWriter writer, MarshallingContext marshallingContext) { ByteBuffer buffer = (ByteBuffer) o; writer.startNode("position"); marshallingContext.convertAnother(buffer.position()); writer.endNode(); writer.startNode("capacity"); marshallingContext.convertAnother(buffer.capacity()); writer.endNode(); writer.startNode("limit"); marshallingContext.convertAnother(buffer.limit()); writer.endNode(); writer.startNode("isDirect"); marshallingContext.convertAnother(buffer.isDirect()); writer.endNode(); buffer.limit(); buffer.capacity(); int position = buffer.position(); int limit = buffer.limit(); buffer.clear(); writer.startNode("data"); try { CharBuffer charBuffer = decoder.decode(buffer); writer.setValue(charBuffer.toString()); } catch (CharacterCodingException e) { throw new ConversionException("", e); } writer.endNode(); buffer.limit(limit); buffer.position(position); } @Override public Object unmarshal(HierarchicalStreamReader reader, UnmarshallingContext unmarshallingContext) { reader.moveDown(); int position = (Integer) unmarshallingContext.convertAnother(null, int.class); reader.moveUp(); reader.moveDown(); int capacity = (Integer) unmarshallingContext.convertAnother(null, int.class); reader.moveUp(); reader.moveDown(); int limit = (Integer) unmarshallingContext.convertAnother(null, int.class); reader.moveUp(); reader.moveDown(); boolean isDirect = (Boolean) unmarshallingContext.convertAnother(null, boolean.class); reader.moveUp(); ByteBuffer buffer = isDirect ? ByteBuffer.allocateDirect(capacity) : ByteBuffer.allocate(capacity); buffer.clear(); reader.moveDown(); String o = (String) unmarshallingContext.convertAnother(null, String.class); CharBuffer uCharBuffer = CharBuffer.wrap(o); CharsetEncoder encoder = charset.newEncoder(); CoderResult encode = encoder.encode(uCharBuffer, buffer, true); if (encode.isError()) throw new ConversionException(""); buffer.limit(limit); buffer.position(position); reader.moveUp(); buffer.limit(limit); buffer.position(position); return buffer; } @Override public boolean canConvert(Class aClass) { return ByteBuffer.class.isAssignableFrom(aClass); } }