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

org.fxmisc.richtext.model.Codec Maven / Gradle / Ivy

There is a newer version: 0.11.3
Show newest version
package org.fxmisc.richtext.model;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Collection;
import java.util.List;
import java.util.Optional;

import javafx.scene.paint.Color;

import org.reactfx.util.Either;

/**
 * Specifies a way to serialize an object to/from a data stream
 *
 * @param  the type of object to serialize
 */
public interface Codec {

    String getName();
    void encode(DataOutputStream os, T t) throws IOException;
    T decode(DataInputStream is) throws IOException;


    static final Codec STRING_CODEC = new Codec() {

        @Override
        public String getName() {
            return "string";
        }

        @Override
        public void encode(DataOutputStream os, String s) throws IOException {
            os.writeUTF(s);
        }

        @Override
        public String decode(DataInputStream is) throws IOException {
            return is.readUTF();
        }
    };

    static final Codec COLOR_CODEC = new Codec() {

        @Override
        public String getName() {
            return "color";
        }

        @Override
        public void encode(DataOutputStream os, Color c)
                throws IOException {
            os.writeDouble(c.getRed());
            os.writeDouble(c.getGreen());
            os.writeDouble(c.getBlue());
            os.writeDouble(c.getOpacity());
        }

        @Override
        public Color decode(DataInputStream is) throws IOException {
            return Color.color(
                    is.readDouble(),
                    is.readDouble(),
                    is.readDouble(),
                    is.readDouble());
        }

    };

    static  Codec> styledSegmentCodec(Codec segCodec, Codec styleCodec) {
        return new Codec>() {
            @Override
            public String getName() {
                return "styled-segment<" + segCodec.getName() + ", " + styleCodec.getName() + ">";
            }

            @Override
            public void encode(DataOutputStream os, StyledSegment styledSegment) throws IOException {
                segCodec.encode(os, styledSegment.getSegment());
                styleCodec.encode(os, styledSegment.getStyle());
            }

            @Override
            public StyledSegment decode(DataInputStream is) throws IOException {
                SEG seg = segCodec.decode(is);
                S style = styleCodec.decode(is);
                return new StyledSegment<>(seg, style);
            }
        };
    }

    public static  Codec> styledTextCodec(Codec styleCodec) {
        return new Codec>() {
            @Override
            public String getName() {
                return "styled-text";
            }

            @Override
            public void encode(DataOutputStream os, StyledSegment styledSeg) throws IOException {
                Codec.STRING_CODEC.encode(os, styledSeg.getSegment());
                styleCodec.encode(os, styledSeg.getStyle());

            }

            @Override
            public StyledSegment decode(DataInputStream is) throws IOException {
                String text = Codec.STRING_CODEC.decode(is);
                S style = styleCodec.decode(is);
                return new StyledSegment<>(text, style);
            }
        };
    }

    static  Codec> listCodec(Codec elemCodec) {
        return SuperCodec.collectionListCodec(elemCodec);
    }

    static  Codec> collectionCodec(Codec elemCodec) {
        return SuperCodec.upCast(SuperCodec.collectionListCodec(elemCodec));
    }

    static  Codec> optionalCodec(Codec elemCodec) {
        return new Codec>() {

            @Override
            public String getName() {
                return "optional<" + elemCodec.getName() + ">";
            }

            @Override
            public void encode(DataOutputStream os, Optional ot) throws IOException {
                if(ot.isPresent()) {
                    os.writeBoolean(true);
                    elemCodec.encode(os, ot.get());
                } else {
                    os.writeBoolean(false);
                }
            }

            @Override
            public Optional decode(DataInputStream is) throws IOException {
                return is.readBoolean()
                        ? Optional.of(elemCodec.decode(is))
                        : Optional.empty();
            }

        };
    }

    static > Codec enumCodec(Class enumType) {
        return new Codec() {

            @Override
            public String getName() {
                return enumType.getSimpleName();
            }

            @Override
            public void encode(DataOutputStream os, E e) throws IOException {
                os.writeInt(e.ordinal());
            }

            @Override
            public E decode(DataInputStream is) throws IOException {
                int ord = is.readInt();
                return enumType.getEnumConstants()[ord];
            }

        };
    }

    static  Codec> eitherCodec(Codec lCodec, Codec rCodec) {
        return new Codec>() {

            @Override
            public String getName() {
                return "either<" + lCodec.getName() + ", " + rCodec.getName() + ">";
            }

            @Override
            public void encode(DataOutputStream os, Either e) throws IOException {
                if(e.isLeft()) {
                    os.writeBoolean(false);
                    lCodec.encode(os, e.getLeft());
                } else {
                    os.writeBoolean(true);
                    rCodec.encode(os, e.getRight());
                }
            }

            @Override
            public Either decode(DataInputStream is) throws IOException {
                boolean isRight = is.readBoolean();
                return isRight
                        ? Either.right(rCodec.decode(is))
                        : Either.left (lCodec.decode(is));
            }
        };
    }
}