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

hu.akarnokd.rxjava2.internal.operators.PublisherArraySource Maven / Gradle / Ivy

/**
 * Copyright 2015 David Karnok and Netflix, Inc.
 * 
 * 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 hu.akarnokd.rxjava2.internal.operators;

import java.util.concurrent.atomic.AtomicLong;

import org.reactivestreams.*;

import hu.akarnokd.rxjava2.internal.subscribers.ConditionalSubscriber;
import hu.akarnokd.rxjava2.internal.subscriptions.SubscriptionHelper;
import hu.akarnokd.rxjava2.internal.util.BackpressureHelper;

public final class PublisherArraySource implements Publisher {
    final T[] array;
    public PublisherArraySource(T[] array) {
        this.array = array;
    }
    public T[] array() {
        return array;
    }
    @Override
    public void subscribe(Subscriber s) {
        if (s instanceof ConditionalSubscriber) {
            ConditionalSubscriber cs = (ConditionalSubscriber) s;
            s.onSubscribe(new ConditionalArraySourceSubscription(array, cs));
        } else {
            s.onSubscribe(new ArraySourceSubscription(array, s));
        }
    }
    
    static final class ArraySourceSubscription extends AtomicLong implements Subscription {
        /** */
        private static final long serialVersionUID = -225561973532207332L;
        
        final T[] array;
        final Subscriber subscriber;
        
        int index;
        volatile boolean cancelled;
        
        public ArraySourceSubscription(T[] array, Subscriber subscriber) {
            this.array = array;
            this.subscriber = subscriber;
        }
        
        @Override
        public void request(long n) {
            if (SubscriptionHelper.validateRequest(n)) {
                return;
            }
            if (BackpressureHelper.add(this, n) == 0L) {
                long r = n;
                final Subscriber s = subscriber;
                for (;;) {
                    int i = index;
                    T[] a = array;
                    int len = a.length;
                    if (i + r >= len) {
                        if (cancelled) {
                            return;
                        }
                        for (int j = i; j < len; j++) {
                            T t = a[j];
                            if (t == null) {
                                s.onError(new NullPointerException("The " + j + "th array element is null"));
                                return;
                            }
                            s.onNext(t);
                            if (cancelled) {
                                return;
                            }
                        }
                        s.onComplete();
                        return;
                    }
                    long e = 0;
                    if (cancelled) {
                        return;
                    }
                    while (r != 0 && i < len) {
                        T t = a[i];
                        if (t == null) {
                            s.onError(new NullPointerException("The " + i + "th array element is null"));
                            return;
                        }
                        s.onNext(t);
                        if (cancelled) {
                            return;
                        }
                        if (++i == len) {
                            s.onComplete();
                            return;
                        }
                        r--;
                        e--;
                    }
                    index = i;
                    r = addAndGet(e);
                    if (r == 0L) {
                        return;
                    }
                }
            }
        }
        @Override
        public void cancel() {
            cancelled = true;
        }
    }
    
    static final class ConditionalArraySourceSubscription extends AtomicLong implements Subscription {
        /** */
        private static final long serialVersionUID = -225561973532207332L;
        
        final T[] array;
        final ConditionalSubscriber subscriber;
        
        int index;
        volatile boolean cancelled;
        
        public ConditionalArraySourceSubscription(T[] array, ConditionalSubscriber subscriber) {
            this.array = array;
            this.subscriber = subscriber;
        }
        
        @Override
        public void request(long n) {
            if (SubscriptionHelper.validateRequest(n)) {
                return;
            }
            if (BackpressureHelper.add(this, n) == 0L) {
                long r = n;
                final ConditionalSubscriber s = subscriber;
                for (;;) {
                    int i = index;
                    T[] a = array;
                    int len = a.length;
                    if (i + r >= len) {
                        if (cancelled) {
                            return;
                        }
                        for (int j = i; j < len; j++) {
                            T t = a[j];
                            if (t == null) {
                                s.onError(new NullPointerException("The " + j + "th array element is null"));
                                return;
                            }
                            s.onNext(t);
                            if (cancelled) {
                                return;
                            }
                        }
                        s.onComplete();
                        return;
                    }
                    long e = 0;
                    if (cancelled) {
                        return;
                    }
                    while (r != 0 && i < len) {
                        boolean b = s.onNextIf(a[i]);
                        if (cancelled) {
                            return;
                        }
                        if (++i == len) {
                            s.onComplete();
                            return;
                        }
                        if (b) {
                            r--;
                            e--;
                        }
                    }
                    index = i;
                    r = addAndGet(e);
                    if (r == 0L) {
                        return;
                    }
                }
            }
        }
        @Override
        public void cancel() {
            cancelled = true;
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy