/*
* 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.lang.io.serialization.impl;
import net.openhft.lang.io.serialization.BytesMarshallable;
import net.openhft.lang.io.serialization.BytesMarshaller;
import net.openhft.lang.io.serialization.BytesMarshallerFactory;
import net.openhft.lang.io.serialization.CompactBytesMarshaller;
import net.openhft.lang.model.constraints.NotNull;
import java.io.Externalizable;
import java.nio.ByteBuffer;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
import static net.openhft.lang.io.serialization.CompactBytesMarshaller.*;
/**
* @author peter.lawrey
*/
public final class VanillaBytesMarshallerFactory implements BytesMarshallerFactory {
private static final long serialVersionUID = 1L;
private transient Map<Class<?>, BytesMarshaller<?>> marshallerMap;
private transient BytesMarshaller<?>[] compactMarshallerMap;
private void init() {
marshallerMap = new LinkedHashMap<Class<?>, BytesMarshaller<?>>();
compactMarshallerMap = new BytesMarshaller[256];
BytesMarshaller<String> stringMarshaller = new StringMarshaller(16 * 1024);
addMarshaller(String.class, stringMarshaller);
addMarshaller(CharSequence.class, (BytesMarshaller)stringMarshaller);
addMarshaller(Class.class, new ClassMarshaller(Thread.currentThread().getContextClassLoader()));
addMarshaller(Date.class, new DateMarshaller(10191));
addMarshaller(Integer.class, new CompactEnumBytesMarshaller<Integer>(Integer.class, 10191, INT_CODE));
addMarshaller(Long.class, new CompactEnumBytesMarshaller<Long>(Long.class, 10191, LONG_CODE));
addMarshaller(Double.class, new CompactEnumBytesMarshaller<Double>(Double.class, 10191, DOUBLE_CODE));
addMarshaller(ByteBuffer.class, ByteBufferMarshaller.INSTANCE);
}
@NotNull
@SuppressWarnings("unchecked")
@Override
public <E> BytesMarshaller<E> acquireMarshaller(@NotNull Class<E> eClass, boolean create) {
if (marshallerMap == null) {
init();
}
BytesMarshaller em = marshallerMap.get(eClass);
if (em == null) {
if (eClass.isEnum()) {
marshallerMap.put(eClass, em = new EnumBytesMarshaller(eClass, null));
} else if (BytesMarshallable.class.isAssignableFrom(eClass)) {
marshallerMap.put(eClass, em = new BytesMarshallableMarshaller((Class) eClass));
} else if (Externalizable.class.isAssignableFrom(eClass)) {
marshallerMap.put(eClass, em = new ExternalizableMarshaller((Class) eClass));
} else if (Throwable.class.isAssignableFrom(eClass)) {
marshallerMap.put(eClass, em = NoMarshaller.INSTANCE);
} else {
try {
marshallerMap.put(eClass, em = new GenericEnumMarshaller<E>(eClass, 1000));
} catch (Exception e) {
marshallerMap.put(eClass, em = NoMarshaller.INSTANCE);
}
}
}
return em;
}
@Override
@SuppressWarnings("unchecked")
public <E> BytesMarshaller<E> getMarshaller(byte code) {
if (marshallerMap == null) {
init();
}
return (BytesMarshaller<E>) compactMarshallerMap[code & 0xFF];
}
public <E> void addMarshaller(Class<E> eClass, BytesMarshaller<E> marshaller) {
if (marshallerMap == null) {
init();
}
marshallerMap.put(eClass, marshaller);
if (marshaller instanceof CompactBytesMarshaller) {
compactMarshallerMap[((CompactBytesMarshaller) marshaller).code()] = marshaller;
}
}
}