/* * Copyright 2016 higherfrequencytrading.com * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package net.openhft.chronicle.engine.server.internal; import net.openhft.chronicle.wire.ValueIn; import net.openhft.chronicle.wire.ValueOut; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.Map.Entry; import java.util.function.BiConsumer; import java.util.function.Function; class GenericWireAdapter<K, V> implements WireAdapter<K, V> { private final BiConsumer<ValueOut, K> keyToWire = ValueOut::object; @Nullable private final Function<ValueIn, K> wireToKey; private final BiConsumer<ValueOut, V> valueToWire = ValueOut::object; @NotNull private final Function<ValueIn, V> wireToValue; @NotNull private final Function<ValueIn, Entry<K, V>> wireToEntry; private final BiConsumer<ValueOut, Entry<K, V>> entryToWire = (v, e) -> v.marshallable(w -> w.write(() -> "key").object(e.getKey()) .write(() -> "value").object(e.getValue())); // if its a string builder re-uses it private final ThreadLocal<CharSequence> usingKey = ThreadLocal.withInitial(StringBuilder::new); private final ThreadLocal<CharSequence> usingValue = ThreadLocal.withInitial(StringBuilder::new); @NotNull private final Class<K> kClass; @NotNull private final Class<V> vClass; GenericWireAdapter(@NotNull final Class<K> kClass, @NotNull final Class<V> vClass) { this.kClass = kClass; this.vClass = vClass; wireToKey = (valueIn) -> valueIn.object(kClass); wireToValue = in -> in.object(vClass); wireToEntry = valueIn -> valueIn.applyToMarshallable(x -> { @NotNull final K key = (K) ((kClass == CharSequence.class) ? x.read(() -> "key").object(usingKey.get(), CharSequence.class) : x.read(() -> "key").object(kClass)); @NotNull final V value = (V) ((vClass == CharSequence.class) ? x.read(() -> "value").object(usingValue.get(), CharSequence.class) : x.read(() -> "value").object(vClass)); return new Entry<K, V>() { @Nullable @Override public K getKey() { return key; } @Nullable @Override public V getValue() { return value; } @NotNull @Override public V setValue(V value) { throw new UnsupportedOperationException(); } }; }); } @NotNull public BiConsumer<ValueOut, K> keyToWire() { return keyToWire; } @NotNull public Function<ValueIn, K> wireToKey() { return wireToKey; } @NotNull public BiConsumer<ValueOut, V> valueToWire() { return valueToWire; } @NotNull public Function<ValueIn, V> wireToValue() { return wireToValue; } @NotNull public BiConsumer<ValueOut, Entry<K, V>> entryToWire() { return entryToWire; } @NotNull public Function<ValueIn, Entry<K, V>> wireToEntry() { return wireToEntry; } @NotNull @Override public String toString() { return "GenericWireAdapter{" + "kClass=" + kClass + ", vClass=" + vClass + '}'; } }