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