code: /*
   * Copyright (c) 2016-2020 chronicle.software
   */
  
  package net.openhft.chronicle.hash.serialization.impl;
  
  import net.openhft.chronicle.bytes.Bytes;
  import net.openhft.chronicle.bytes.CommonMarshallable;
  import net.openhft.chronicle.bytes.ReadBytesMarshallable;
  import net.openhft.chronicle.bytes.WriteBytesMarshallable;
  import net.openhft.chronicle.wire.ReadMarshallable;
  import net.openhft.chronicle.wire.Wire;
  import net.openhft.chronicle.wire.Wires;
  import net.openhft.chronicle.wire.WriteMarshallable;
  import org.jetbrains.annotations.NotNull;
  import org.jetbrains.annotations.Nullable;
  
  /**
   * A marshaller that is aware of {@link CommonMarshallable#usesSelfDescribingMessage()}
   *
   * @param <V> value class
   */
  public class CommonMarshallableReaderWriter<V extends CommonMarshallable>
          extends CachingCreatingMarshaller<V> {
  
      public CommonMarshallableReaderWriter(Class<V> vClass) {
          super(vClass);
      }
  
      @NotNull
      @Override
      public V read(Bytes in, long size, @Nullable V using) {
          if (using == null)
              using = createInstance();
          if (using.usesSelfDescribingMessage()) {
              ((ReadMarshallable) using).readMarshallable(Wires.binaryWireForRead(in, in.readPosition(), size));
          } else {
              ((ReadBytesMarshallable) using).readMarshallable(in);
          }
          return using;
      }
  
      @Override
      protected void writeToWire(Wire wire, @NotNull V toWrite) {
          if (toWrite.usesSelfDescribingMessage()) {
              ((WriteMarshallable) toWrite).writeMarshallable(wire);
          } else {
              ((WriteBytesMarshallable) toWrite).writeMarshallable(wire.bytes());
          }
      }
  }
  