1/*
2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package java.nio;
27
28import java.util.Comparator;
29import java.util.Spliterator;
30import java.util.function.IntConsumer;
31
32/**
33 * A Spliterator.OfInt for sources that traverse and split elements
34 * maintained in a CharBuffer.
35 *
36 * @implNote
37 * The implementation is based on the code for the Array-based spliterators.
38 */
39class CharBufferSpliterator implements Spliterator.OfInt {
40    private final CharBuffer buffer;
41    private int index;   // current index, modified on advance/split
42    private final int limit;
43
44    CharBufferSpliterator(CharBuffer buffer) {
45        this(buffer, buffer.position(), buffer.limit());
46    }
47
48    CharBufferSpliterator(CharBuffer buffer, int origin, int limit) {
49        assert origin <= limit;
50        this.buffer = buffer;
51        this.index = (origin <= limit) ? origin : limit;
52        this.limit = limit;
53    }
54
55    @Override
56    public OfInt trySplit() {
57        int lo = index, mid = (lo + limit) >>> 1;
58        return (lo >= mid)
59               ? null
60               : new CharBufferSpliterator(buffer, lo, index = mid);
61    }
62
63    @Override
64    public void forEachRemaining(IntConsumer action) {
65        if (action == null)
66            throw new NullPointerException();
67        CharBuffer cb = buffer;
68        int i = index;
69        int hi = limit;
70        index = hi;
71        while (i < hi) {
72            action.accept(cb.getUnchecked(i++));
73        }
74    }
75
76    @Override
77    public boolean tryAdvance(IntConsumer action) {
78        if (action == null)
79            throw new NullPointerException();
80        if (index >= 0 && index < limit) {
81            action.accept(buffer.getUnchecked(index++));
82            return true;
83        }
84        return false;
85    }
86
87    @Override
88    public long estimateSize() {
89        return (long)(limit - index);
90    }
91
92    @Override
93    public int characteristics() {
94        return Buffer.SPLITERATOR_CHARACTERISTICS;
95    }
96}
97