/*
* Copyright 2015 MiLaboratory.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 com.milaboratory.primitivio;
import com.milaboratory.primitivio.annotations.Serializable;
import java.io.*;
import java.util.*;
public final class Util {
private Util() {
}
static Class<?> findSerializableParent(Class<?> type, boolean direct, boolean withCustomSerializersOnly) {
Class<?> root = null, tmp;
Serializable a = type.getAnnotation(Serializable.class);
if (a != null && (!withCustomSerializersOnly || a.custom().length > 0))
if (direct)
return type;
else
root = type;
Class<?> superclass = type.getSuperclass();
if (superclass != null) {
tmp = findSerializableParent(superclass, direct, withCustomSerializersOnly);
if (tmp != null) {
if (root == null)
root = tmp;
else
throw new RuntimeException("Custom serializers conflict: " + root + " and " + tmp + " through " + type);
}
}
for (Class<?> cInterface : type.getInterfaces()) {
tmp = findSerializableParent(cInterface, direct, withCustomSerializersOnly);
if (tmp != null) {
if (root == null || root == tmp)
root = tmp;
else
throw new RuntimeException("Custom serializers conflict: " + root + " and " + tmp + " through " + type);
}
}
return root;
}
public static void writeList(List<?> list, String fileName) throws IOException {
try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(fileName))) {
writeList(list, stream);
}
}
public static void writeList(List<?> list, File file) throws IOException {
try (BufferedOutputStream stream = new BufferedOutputStream(new FileOutputStream(file))) {
writeList(list, stream);
}
}
public static void writeList(List<?> list, OutputStream output) {
writeList(list, new PrimitivO(output));
}
public static void writeList(List<?> list, PrimitivO output) {
output.writeInt(list.size());
for (Object o : list)
output.writeObject(o);
}
public static <O> List<O> readList(Class<O> type, String fileName) throws IOException {
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream(fileName))) {
return readList(type, stream);
}
}
public static <O> List<O> readList(Class<O> type, File file) throws IOException {
try (BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file))) {
return readList(type, stream);
}
}
public static <O> List<O> readList(Class<O> type, InputStream is) {
return readList(type, new PrimitivI(is));
}
public static <O> List<O> readList(Class<O> type, PrimitivI input) {
int size = input.readInt();
List<O> list = new ArrayList<>(size);
while ((--size) >= 0)
list.add(input.readObject(type));
return list;
}
public static <K, V> void writeMap(Map<K, V> map, PrimitivO output) {
output.writeVarInt(map.size());
for (Map.Entry<K, V> entry : map.entrySet()) {
output.writeObject(entry.getKey());
output.writeObject(entry.getValue());
}
}
public static <K extends Enum<K>, V> EnumMap<K, V> readEnumMap(PrimitivI input, Class<K> keyClass, Class<V> valueClass) {
int size = input.readVarInt();
EnumMap<K, V> map = new EnumMap<>(keyClass);
for (; size > 0; --size) {
K key = input.readObject(keyClass);
V value = input.readObject(valueClass);
map.put(key, value);
}
return map;
}
public static <K, V> Map<K, V> readMap(PrimitivI input, Class<K> keyClass, Class<V> valueClass) {
int size = input.readVarInt();
Map<K, V> map = new HashMap<>(size);
for (; size > 0; --size) {
K key = input.readObject(keyClass);
V value = input.readObject(valueClass);
map.put(key, value);
}
return map;
}
public static long zigZagEncodeLong(long value) {
return (value << 1) ^ (value >> 63);
}
public static long zigZagDecodeLong(long value) {
return (value >>> 1) ^ ((value << 63) >> 63);
}
public static int zigZagEncodeInt(int value) {
return (value << 1) ^ (value >> 31);
}
public static int zigZagDecodeInt(int value) {
return (value >>> 1) ^ ((value << 31) >> 31);
}
}