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 /** 029 * Count the number of arguments in the descriptor. Each long or double counts as widthOfLongsAndDoubles; all other 030 * arguments count as 1. 031 * 032 * @param descriptor String for which arguments are counted 033 * @param widthOfLongsAndDoubles int increment to apply for longs doubles. This is typically 1 when counting 034 * arguments alone, or 2 when counting arguments for invokeinterface. 035 * @return integer count 036 */ 037 protected static int countArgs(final String descriptor, final int widthOfLongsAndDoubles) { 038 final int bra = descriptor.indexOf('('); 039 final int ket = descriptor.indexOf(')'); 040 if (bra == -1 || ket == -1 || ket < bra) { 041 throw new IllegalArgumentException("No arguments"); 042 } 043 044 boolean inType = false; 045 boolean consumingNextType = false; 046 int count = 0; 047 for (int i = bra + 1; i < ket; i++) { 048 final char charAt = descriptor.charAt(i); 049 if (inType && charAt == ';') { 050 inType = false; 051 consumingNextType = false; 052 } else if (!inType && charAt == 'L') { 053 inType = true; 054 count++; 055 } else if (charAt == '[') { 056 consumingNextType = true; 057 } else if (inType) { 058 // NOP 059 } else if (consumingNextType) { 060 count++; 061 consumingNextType = false; 062 } else if (charAt == 'D' || charAt == 'J') { 063 count += widthOfLongsAndDoubles; 064 } else { 065 count++; 066 } 067 } 068 return count; 069 } 070 071 public static int countBit16(final int[] flags) { 072 int count = 0; 073 for (final int flag : flags) { 074 if ((flag & (1 << 16)) != 0) { 075 count++; 076 } 077 } 078 return count; 079 } 080 081 public static int countBit16(final long[] flags) { 082 int count = 0; 083 for (final long flag : flags) { 084 if ((flag & (1 << 16)) != 0) { 085 count++; 086 } 087 } 088 return count; 089 } 090 091 public static int countBit16(final long[][] flags) { 092 int count = 0; 093 for (final long[] flag : flags) { 094 for (final long element : flag) { 095 if ((element & (1 << 16)) != 0) { 096 count++; 097 } 098 } 099 } 100 return count; 101 } 102 103 public static int countInvokeInterfaceArgs(final String descriptor) { 104 return countArgs(descriptor, 2); 105 } 106 107 public static int countMatches(final long[] flags, final IMatcher matcher) { 108 int count = 0; 109 for (final long flag : flags) { 110 if (matcher.matches(flag)) { 111 count++; 112 } 113 } 114 return count; 115 } 116 117 public static int countMatches(final long[][] flags, final IMatcher matcher) { 118 int count = 0; 119 for (final long[] flag : flags) { 120 count += countMatches(flag, matcher); 121 } 122 return count; 123 } 124 125}