/* * 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.chronicle.hash.serialization.impl; import net.openhft.chronicle.bytes.Bytes; import net.openhft.chronicle.bytes.RandomDataInput; import net.openhft.chronicle.hash.AbstractData; import net.openhft.chronicle.hash.Data; import net.openhft.chronicle.hash.serialization.DataAccess; import net.openhft.chronicle.wire.WireIn; import net.openhft.chronicle.wire.WireOut; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.io.*; import static net.openhft.chronicle.hash.serialization.impl.DefaultElasticBytes.DEFAULT_BYTES_CAPACITY; public class SerializableDataAccess<T extends Serializable> extends AbstractData<T> implements DataAccess<T> { // Cache fields transient Bytes bytes; transient OutputStream out; transient InputStream in; /** State field */ transient T instance; public SerializableDataAccess() { this(DEFAULT_BYTES_CAPACITY); } SerializableDataAccess(long bytesCapacity) { initTransients(bytesCapacity); } void initTransients(long bytesCapacity) { bytes = DefaultElasticBytes.allocateDefaultElasticBytes(bytesCapacity); out = bytes.outputStream(); in = bytes.inputStream(); } @Override public RandomDataInput bytes() { return bytes.bytesStore(); } @Override public long offset() { return 0; } @Override public long size() { return bytes.readRemaining(); } @Override public T get() { return instance; } // TODO reuse using object @Override public T getUsing(@Nullable T using) { try { T result = (T) new ObjectInputStream(in).readObject(); bytes.readPosition(0); return result; } catch (IOException | ClassNotFoundException e) { throw new RuntimeException(e); } } @Override public Data<T> getData(@NotNull T instance) { this.instance = instance; bytes.clear(); try { ObjectOutputStream out = new ObjectOutputStream(this.out); out.writeObject(instance); out.flush(); return this; } catch (IOException e) { throw new RuntimeException(e); } } @Override public void uninit() { instance = null; } @Override public DataAccess<T> copy() { return new SerializableDataAccess<>(bytes.realCapacity()); } @Override public void readMarshallable(@NotNull WireIn wireIn) { // no fields to read initTransients(DEFAULT_BYTES_CAPACITY); } @Override public void writeMarshallable(@NotNull WireOut wireOut) { // no fields to write } }