001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.compress.harmony.unpack200; 018 019/** 020 * Utility class for unpack200 021 */ 022public final class SegmentUtils { 023 024 public static int countArgs(final String descriptor) { 025 return countArgs(descriptor, 1); 026 } 027 028 public static int countInvokeInterfaceArgs(final String descriptor) { 029 return countArgs(descriptor, 2); 030 } 031 032 /** 033 * Count the number of arguments in the descriptor. Each long or double counts as widthOfLongsAndDoubles; all other 034 * arguments count as 1. 035 * 036 * @param descriptor String for which arguments are counted 037 * @param widthOfLongsAndDoubles int increment to apply for longs doubles. This is typically 1 when counting 038 * arguments alone, or 2 when counting arguments for invokeinterface. 039 * @return integer count 040 */ 041 protected static int countArgs(final String descriptor, final int widthOfLongsAndDoubles) { 042 final int bra = descriptor.indexOf('('); 043 final int ket = descriptor.indexOf(')'); 044 if (bra == -1 || ket == -1 || ket < bra) { 045 throw new IllegalArgumentException("No arguments"); 046 } 047 048 boolean inType = false; 049 boolean consumingNextType = false; 050 int count = 0; 051 for (int i = bra + 1; i < ket; i++) { 052 final char charAt = descriptor.charAt(i); 053 if (inType && charAt == ';') { 054 inType = false; 055 consumingNextType = false; 056 } else if (!inType && charAt == 'L') { 057 inType = true; 058 count++; 059 } else if (charAt == '[') { 060 consumingNextType = true; 061 } else if (inType) { 062 // NOP 063 } else if (consumingNextType) { 064 count++; 065 consumingNextType = false; 066 } else if (charAt == 'D' || charAt == 'J') { 067 count += widthOfLongsAndDoubles; 068 } else { 069 count++; 070 } 071 } 072 return count; 073 } 074 075 public static int countMatches(final long[] flags, final IMatcher matcher) { 076 int count = 0; 077 for (int i = 0; i < flags.length; i++) { 078 if (matcher.matches(flags[i])) { 079 count++; 080 } 081 } 082 return count; 083 } 084 085 public static int countBit16(final int[] flags) { 086 int count = 0; 087 for (int i = 0; i < flags.length; i++) { 088 if ((flags[i] & (1 << 16)) != 0) { 089 count++; 090 } 091 } 092 return count; 093 } 094 095 public static int countBit16(final long[] flags) { 096 int count = 0; 097 for (int i = 0; i < flags.length; i++) { 098 if ((flags[i] & (1 << 16)) != 0) { 099 count++; 100 } 101 } 102 return count; 103 } 104 105 public static int countBit16(final long[][] flags) { 106 int count = 0; 107 for (int i = 0; i < flags.length; i++) { 108 for (int j = 0; j < flags[i].length; j++) { 109 if ((flags[i][j] & (1 << 16)) != 0) { 110 count++; 111 } 112 } 113 } 114 return count; 115 } 116 117 public static int countMatches(final long[][] flags, final IMatcher matcher) { 118 int count = 0; 119 for (int i = 0; i < flags.length; i++) { 120 count += countMatches(flags[i], matcher); 121 } 122 return count; 123 } 124 125}