View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one or more
3    *  contributor license agreements.  See the NOTICE file distributed with
4    *  this work for additional information regarding copyright ownership.
5    *  The ASF licenses this file to You under the Apache License, Version 2.0
6    *  (the "License"); you may not use this file except in compliance with
7    *  the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.commons.compress.harmony.unpack200;
18  
19  /**
20   * Utility class for unpack200
21   */
22  public final class SegmentUtils {
23  
24      public static int countArgs(final String descriptor) {
25          return countArgs(descriptor, 1);
26      }
27  
28      /**
29       * Count the number of arguments in the descriptor. Each long or double counts as widthOfLongsAndDoubles; all other arguments count as 1.
30       *
31       * @param descriptor             String for which arguments are counted
32       * @param widthOfLongsAndDoubles int increment to apply for longs doubles. This is typically 1 when counting arguments alone, or 2 when counting arguments
33       *                               for invokeinterface.
34       * @return integer count
35       */
36      protected static int countArgs(final String descriptor, final int widthOfLongsAndDoubles) {
37          final int bra = descriptor.indexOf('(');
38          final int ket = descriptor.indexOf(')');
39          if (bra == -1 || ket == -1 || ket < bra) {
40              throw new IllegalArgumentException("No arguments");
41          }
42  
43          boolean inType = false;
44          boolean consumingNextType = false;
45          int count = 0;
46          for (int i = bra + 1; i < ket; i++) {
47              final char charAt = descriptor.charAt(i);
48              if (inType && charAt == ';') {
49                  inType = false;
50                  consumingNextType = false;
51              } else if (!inType && charAt == 'L') {
52                  inType = true;
53                  count++;
54              } else if (charAt == '[') {
55                  consumingNextType = true;
56              } else if (inType) {
57                  // NOP
58              } else if (consumingNextType) {
59                  count++;
60                  consumingNextType = false;
61              } else if (charAt == 'D' || charAt == 'J') {
62                  count += widthOfLongsAndDoubles;
63              } else {
64                  count++;
65              }
66          }
67          return count;
68      }
69  
70      public static int countBit16(final int[] flags) {
71          int count = 0;
72          for (final int flag : flags) {
73              if ((flag & 1 << 16) != 0) {
74                  count++;
75              }
76          }
77          return count;
78      }
79  
80      public static int countBit16(final long[] flags) {
81          int count = 0;
82          for (final long flag : flags) {
83              if ((flag & 1 << 16) != 0) {
84                  count++;
85              }
86          }
87          return count;
88      }
89  
90      public static int countBit16(final long[][] flags) {
91          int count = 0;
92          for (final long[] flag : flags) {
93              for (final long element : flag) {
94                  if ((element & 1 << 16) != 0) {
95                      count++;
96                  }
97              }
98          }
99          return count;
100     }
101 
102     public static int countInvokeInterfaceArgs(final String descriptor) {
103         return countArgs(descriptor, 2);
104     }
105 
106     public static int countMatches(final long[] flags, final IMatcher matcher) {
107         int count = 0;
108         for (final long flag : flags) {
109             if (matcher.matches(flag)) {
110                 count++;
111             }
112         }
113         return count;
114     }
115 
116     public static int countMatches(final long[][] flags, final IMatcher matcher) {
117         int count = 0;
118         for (final long[] flag : flags) {
119             count += countMatches(flag, matcher);
120         }
121         return count;
122     }
123 
124 }