View Javadoc
1   package nom.tam.util.array;
2   
3   /*
4    * #%L
5    * nom.tam FITS library
6    * %%
7    * Copyright (C) 1996 - 2024 nom-tam-fits
8    * %%
9    * This is free and unencumbered software released into the public domain.
10   *
11   * Anyone is free to copy, modify, publish, use, compile, sell, or
12   * distribute this software, either in source code form or as a compiled
13   * binary, for any purpose, commercial or non-commercial, and by any
14   * means.
15   *
16   * In jurisdictions that recognize copyright laws, the author or authors
17   * of this software dedicate any and all copyright interest in the
18   * software to the public domain. We make this dedication for the benefit
19   * of the public at large and to the detriment of our heirs and
20   * successors. We intend this dedication to be an overt act of
21   * relinquishment in perpetuity of all present and future rights to this
22   * software under copyright law.
23   *
24   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
27   * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
28   * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
29   * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30   * OTHER DEALINGS IN THE SOFTWARE.
31   * #L%
32   */
33  
34  import java.lang.reflect.Array;
35  
36  /**
37   * @deprecated (<i>)for internal use</i>) Visibility may be reduced to the
38   *             package level in the future. A multi-dimensional array index.
39   *             Used only by {@link MultiArrayCopier} and
40   *             {@link MultiArrayIterator}.
41   */
42  public class MultiArrayPointer {
43  
44      /** A dummy object to mark the end. */
45      public static final Object END = new Object();
46  
47      private Object array;
48  
49      private int index;
50  
51      private int length;
52  
53      private MultiArrayPointer sub;
54  
55      private MultiArrayPointer backup;
56  
57      /**
58       * Constructs a new pointer for an unspecified multi-dimensional array
59       * object.
60       * 
61       * @deprecated (<i>)for internal use</i>) Visibility may be reduced to
62       *             private.
63       */
64      public MultiArrayPointer() {
65      }
66  
67      /**
68       * Constructs a new pointer for the specified multidimensional array object.
69       * 
70       * @param baseArray
71       *            the multidimensional array to iterate over.
72       */
73      public MultiArrayPointer(Object baseArray) {
74          this();
75          set(baseArray);
76      }
77  
78      private void activateSub(Object element) {
79          if (backup == null) {
80              backup = new MultiArrayPointer();
81          }
82          sub = backup;
83          sub.set(element);
84      }
85  
86      private void deactivateSub() {
87          sub = null;
88      }
89  
90      /**
91       * Returns the next base element in the array
92       * 
93       * @return the next base element in the array.
94       */
95      public Object next() {
96          while (true) {
97              if (sub != null) {
98                  Object subNext = sub.next();
99                  if (subNext != MultiArrayPointer.END) {
100                     return subNext;
101                 }
102                 deactivateSub();
103             }
104             if (index >= length) {
105                 return MultiArrayPointer.END;
106             }
107             Object element = Array.get(array, index++);
108             if ((element == null) || !isSubArray(element)) {
109                 return element;
110             }
111             activateSub(element);
112         }
113     }
114 
115     /**
116      * Resets the pointer such that {@link #next()} will return the first
117      * element again.
118      */
119     public void reset() {
120         index = 0;
121         deactivateSub();
122     }
123 
124     private void set(Object newArray) {
125         array = newArray;
126         length = Array.getLength(array);
127         sub = null;
128         index = 0;
129     }
130 
131     /**
132      * Checks whether entries in a given element are also arrays themselves.
133      * 
134      * @param element
135      *            the element
136      * @return <code>true</code> if the entries in the given element are also
137      *         arrays, otherwise <code>false</code>.
138      * @deprecated (<i>)for internal use</i>) Visibility may be reduced to
139      *             private.
140      */
141     public static boolean isSubArray(Object element) {
142         if (!(element instanceof Object[])) {
143             return false;
144         }
145 
146         for (Object o : (Object[]) element) {
147             if (o != null) {
148                 if (o.getClass().isArray()) {
149                     return true;
150                 }
151             }
152         }
153 
154         return false;
155     }
156 }