All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.chm.converter.protostuff.codec.factory.CollectionCodecFactory Maven / Gradle / Ivy

package com.chm.converter.protostuff.codec.factory;

import com.chm.converter.core.reflect.ConverterTypes;
import com.chm.converter.core.reflect.TypeToken;
import com.chm.converter.core.universal.UniversalFactory;
import com.chm.converter.core.universal.UniversalGenerate;
import com.chm.converter.protostuff.codec.ProtostuffCodec;
import com.chm.converter.protostuff.codec.RuntimeTypeCodec;
import io.protostuff.Input;
import io.protostuff.Output;
import io.protostuff.ProtostuffException;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.Collection;

/**
 * 集合类编解码
 *
 * @author caihongming
 * @version v1.0
 * @date 2021-11-30
 **/
public class CollectionCodecFactory implements UniversalFactory {

    public static final String FIELD_NAME_VALUE = "v";

    @Override
    public ProtostuffCodec create(UniversalGenerate generate, TypeToken typeToken) {
        Class rawTypeOfSrc = typeToken.getRawType();
        if (!Collection.class.isAssignableFrom(rawTypeOfSrc)) {
            return null;
        }
        Type type = typeToken.getType();
        Type elementType = ConverterTypes.getCollectionElementType(type, rawTypeOfSrc);
        ProtostuffCodec elementCodec = new RuntimeTypeCodec(generate, generate.get(elementType), elementType);
        return new CollectionCodec(typeToken, elementCodec);
    }

    public static class CollectionCodec extends ProtostuffCodec> {

        private final ProtostuffCodec elementCodec;

        protected CollectionCodec(TypeToken> typeToken, ProtostuffCodec elementCodec) {
            super(typeToken);
            this.elementCodec = elementCodec;
        }

        @Override
        public String getFieldName(int number) {
            return number == 1 ? FIELD_NAME_VALUE : null;
        }

        @Override
        public int getFieldNumber(String name) {
            return name.length() == 1 && name.charAt(0) == 'v' ? 1 : 0;
        }

        @Override
        public void writeTo(Output output, Collection message) throws IOException {
            for (V value : message) {
                // null values not serialized.
                if (value != null) {
                    output.writeObject(1, value, elementCodec, true);
                }
            }
        }


        @Override
        public Collection mergeFrom(Input input) throws IOException {
            Collection collection = constructor.construct();
            for (int number = input.readFieldNumber(this); ; number = input.readFieldNumber(this)) {
                switch (number) {
                    case 0:
                        return collection;
                    case 1:
                        collection.add(input.mergeObject(null, elementCodec));
                        break;
                    default:
                        throw new ProtostuffException("The collection was incorrectly " +
                                "serialized.");
                }
            }
        }

        @Override
        public CollectionCodec newInstance() {
            return new CollectionCodec<>(this.typeToken, this.elementCodec);
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy