1 /*
   2  * Copyright (c) 2005, 2020, 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 
  26 /*
  27  *******************************************************************************
  28  * (C) Copyright IBM Corp. 1996-2005 - All Rights Reserved                     *
  29  *                                                                             *
  30  * The original version of this source code and documentation is copyrighted   *
  31  * and owned by IBM, These materials are provided under terms of a License     *
  32  * Agreement between IBM and Sun. This technology is protected by multiple     *
  33  * US and International patents. This notice and attribution to IBM may not    *
  34  * to removed.                                                                 *
  35  *******************************************************************************
  36  */
  37 
  38 package jdk.internal.icu.impl;
  39 
  40 import jdk.internal.icu.text.Replaceable;
  41 import jdk.internal.icu.text.ReplaceableString;
  42 import jdk.internal.icu.text.UCharacterIterator;
  43 
  44 /**
  45  * DLF docs must define behavior when Replaceable is mutated underneath
  46  * the iterator.
  47  *
  48  * This and ICUCharacterIterator share some code, maybe they should share
  49  * an implementation, or the common state and implementation should be
  50  * moved up into UCharacterIterator.
  51  *
  52  * What are first, last, and getBeginIndex doing here?!?!?!
  53  */
  54 public class ReplaceableUCharacterIterator extends UCharacterIterator {
  55 
  56     // public constructor ------------------------------------------------------
  57 
  58     /**
  59      * Public constructor
  60      * @param str text which the iterator will be based on
  61      */
  62     public ReplaceableUCharacterIterator(String str){
  63         if(str==null){
  64             throw new IllegalArgumentException();
  65         }
  66         this.replaceable  = new ReplaceableString(str);
  67         this.currentIndex = 0;
  68     }
  69 
  70     /**
  71      * Public constructor
  72      * @param buf buffer of text on which the iterator will be based
  73      */
  74     public ReplaceableUCharacterIterator(StringBuffer buf){
  75         if(buf==null){
  76             throw new IllegalArgumentException();
  77         }
  78         this.replaceable  = new ReplaceableString(buf);
  79         this.currentIndex = 0;
  80     }
  81 
  82     // public methods ----------------------------------------------------------
  83 
  84     /**
  85      * Creates a copy of this iterator, does not clone the underlying
  86      * <code>Replaceable</code>object
  87      * @return copy of this iterator
  88      */
  89     public Object clone(){
  90         try {
  91           return super.clone();
  92         } catch (CloneNotSupportedException e) {
  93             return null; // never invoked
  94         }
  95     }
  96 
  97     /**
  98      * Returns the current UTF16 character.
  99      * @return current UTF16 character
 100      */
 101     public int current(){
 102         if (currentIndex < replaceable.length()) {
 103             return replaceable.charAt(currentIndex);
 104         }
 105         return DONE;
 106     }
 107 
 108     /**
 109      * Returns the length of the text
 110      * @return length of the text
 111      */
 112     public int getLength(){
 113         return replaceable.length();
 114     }
 115 
 116     /**
 117      * Gets the current currentIndex in text.
 118      * @return current currentIndex in text.
 119      */
 120     public int getIndex(){
 121         return currentIndex;
 122     }
 123 
 124     /**
 125      * Returns next UTF16 character and increments the iterator's currentIndex by 1.
 126      * If the resulting currentIndex is greater or equal to the text length, the
 127      * currentIndex is reset to the text length and a value of DONECODEPOINT is
 128      * returned.
 129      * @return next UTF16 character in text or DONE if the new currentIndex is off the
 130      *         end of the text range.
 131      */
 132     public int next(){
 133         if (currentIndex < replaceable.length()) {
 134             return replaceable.charAt(currentIndex++);
 135         }
 136         return DONE;
 137     }
 138 
 139 
 140     /**
 141      * Returns previous UTF16 character and decrements the iterator's currentIndex by
 142      * 1.
 143      * If the resulting currentIndex is less than 0, the currentIndex is reset to 0 and a
 144      * value of DONECODEPOINT is returned.
 145      * @return next UTF16 character in text or DONE if the new currentIndex is off the
 146      *         start of the text range.
 147      */
 148     public int previous(){
 149         if (currentIndex > 0) {
 150             return replaceable.charAt(--currentIndex);
 151         }
 152         return DONE;
 153     }
 154 
 155     /**
 156      * Sets the currentIndex to the specified currentIndex in the text and returns that
 157      * single UTF16 character at currentIndex.
 158      * This assumes the text is stored as 16-bit code units.
 159      * @param currentIndex the currentIndex within the text.
 160      * @exception IllegalArgumentException is thrown if an invalid currentIndex is
 161      *            supplied. i.e. currentIndex is out of bounds.
 162      */
 163     public void setIndex(int currentIndex) {
 164         if (currentIndex < 0 || currentIndex > replaceable.length()) {
 165             throw new IllegalArgumentException();
 166         }
 167         this.currentIndex = currentIndex;
 168     }
 169 
 170     public int getText(char[] fillIn, int offset){
 171         int length = replaceable.length();
 172         if(offset < 0 || offset + length > fillIn.length){
 173             throw new IndexOutOfBoundsException(Integer.toString(length));
 174         }
 175         replaceable.getChars(0,length,fillIn,offset);
 176         return length;
 177     }
 178 
 179     // private data members ----------------------------------------------------
 180 
 181     /**
 182      * Replaceable object
 183      */
 184     private Replaceable replaceable;
 185     /**
 186      * Current currentIndex
 187      */
 188     private int currentIndex;
 189 
 190 }