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

com.github.davidmoten.rx.Bytes Maven / Gradle / Ivy

package com.github.davidmoten.rx;

import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

import com.github.davidmoten.rx.internal.operators.OnSubscribeInputStream;
import com.github.davidmoten.rx.util.ZippedEntry;

import rx.Observable;
import rx.Observable.Transformer;
import rx.Observer;
import rx.functions.Action1;
import rx.functions.Action2;
import rx.functions.Func0;
import rx.functions.Func1;
import rx.observables.SyncOnSubscribe;

public final class Bytes {

    private Bytes() {
        // prevent instantiation
    }

    /**
     * Returns an Observable stream of byte arrays from the given
     * {@link InputStream} between 1 and {@code size} bytes.
     * 
     * @param is
     *            input stream of bytes
     * @param size
     *            max emitted byte array size
     * @return a stream of byte arrays
     */
    public static Observable from(InputStream is, int size) {
        return Observable.create(new OnSubscribeInputStream(is, size));
    }

    public static Observable from(File file) {
        return from(file, 8192);
    }

    public static Observable from(final File file, final int size) {
        Func0 resourceFactory = new Func0() {

            @Override
            public InputStream call() {
                try {
                    return new BufferedInputStream(new FileInputStream(file), size);
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
        };
        Func1> observableFactory = new Func1>() {

            @Override
            public Observable call(InputStream is) {
                return from(is, size);
            }
        };
        return Observable.using(resourceFactory, observableFactory, InputStreamCloseHolder.INSTANCE, true);
    }
    
    private static class InputStreamCloseHolder {
        private static final Action1 INSTANCE = new Action1() {

            @Override
            public void call(InputStream is) {
                try {
                    is.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    /**
     * Returns an Observable stream of byte arrays from the given
     * {@link InputStream} of {@code 8192} bytes. The final byte array may be
     * less than {@code 8192} bytes.
     * 
     * @param is
     *            input stream of bytes
     * @return a stream of byte arrays
     */
    public static Observable from(InputStream is) {
        return from(is, 8192);
    }

    public static Observable unzip(final File file) {
        Func0 resourceFactory = new Func0() {
            @Override
            public ZipInputStream call() {
                try {
                    return new ZipInputStream(new FileInputStream(file));
                } catch (FileNotFoundException e) {
                    throw new RuntimeException(e);
                }
            }
        };
        Func1> observableFactory = ZipHolder.OBSERVABLE_FACTORY;
        Action1 disposeAction = ZipHolder.DISPOSER;
        return Observable.using(resourceFactory, observableFactory, disposeAction);
    }

    private static final class ZipHolder {
        static final Action1 DISPOSER = new Action1() {

            @Override
            public void call(ZipInputStream zis) {
                try {
                    zis.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
        final static Func1> OBSERVABLE_FACTORY = new Func1>() {
            @Override
            public Observable call(ZipInputStream zis) {
                return unzip(zis);
            }
        };
    }

    public static Observable unzip(final InputStream is) {
        return unzip(new ZipInputStream(is));
    }

    public static Observable unzip(final ZipInputStream zis) {
        return Observable.create(new SyncOnSubscribe() {

            @Override
            protected ZipInputStream generateState() {
                return zis;
            }

            @Override
            protected ZipInputStream next(ZipInputStream zis, Observer observer) {
                try {
                    ZipEntry zipEntry = zis.getNextEntry();
                    if (zipEntry != null) {
                        observer.onNext(new ZippedEntry(zipEntry, zis));
                    } else {
                        zis.close();
                        observer.onCompleted();
                    }
                } catch (IOException e) {
                    observer.onError(e);
                }
                return zis;
            }
        });
    }

    public static Transformer collect() {
        return new Transformer() {

            @Override
            public Observable call(Observable source) {
                return source.collect(BosCreatorHolder.INSTANCE, BosCollectorHolder.INSTANCE)
                        .map(BosToArrayHolder.INSTANCE);
            }
        };
    }

    private static final class BosCreatorHolder {

        static final Func0 INSTANCE = new Func0() {

            @Override
            public ByteArrayOutputStream call() {
                return new ByteArrayOutputStream();
            }
        };
    }

    private static final class BosCollectorHolder {

        static final Action2 INSTANCE = new Action2() {

            @Override
            public void call(ByteArrayOutputStream bos, byte[] bytes) {
                try {
                    bos.write(bytes);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        };
    }

    private static final class BosToArrayHolder {
        static final Func1 INSTANCE = new Func1() {
            @Override
            public byte[] call(ByteArrayOutputStream bos) {
                return bos.toByteArray();
            }
        };
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy