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 arguments count as 1. 030 * 031 * @param descriptor String for which arguments are counted 032 * @param widthOfLongsAndDoubles int increment to apply for longs doubles. This is typically 1 when counting arguments alone, or 2 when counting arguments 033 * for invokeinterface. 034 * @return integer count 035 */ 036 protected static int countArgs(final String descriptor, final int widthOfLongsAndDoubles) { 037 final int bra = descriptor.indexOf('('); 038 final int ket = descriptor.indexOf(')'); 039 if (bra == -1 || ket == -1 || ket < bra) { 040 throw new IllegalArgumentException("No arguments"); 041 } 042 043 boolean inType = false; 044 boolean consumingNextType = false; 045 int count = 0; 046 for (int i = bra + 1; i < ket; i++) { 047 final char charAt = descriptor.charAt(i); 048 if (inType && charAt == ';') { 049 inType = false; 050 consumingNextType = false; 051 } else if (!inType && charAt == 'L') { 052 inType = true; 053 count++; 054 } else if (charAt == '[') { 055 consumingNextType = true; 056 } else if (inType) { 057 // NOP 058 } else if (consumingNextType) { 059 count++; 060 consumingNextType = false; 061 } else if (charAt == 'D' || charAt == 'J') { 062 count += widthOfLongsAndDoubles; 063 } else { 064 count++; 065 } 066 } 067 return count; 068 } 069 070 public static int countBit16(final int[] flags) { 071 int count = 0; 072 for (final int flag : flags) { 073 if ((flag & 1 << 16) != 0) { 074 count++; 075 } 076 } 077 return count; 078 } 079 080 public static int countBit16(final long[] flags) { 081 int count = 0; 082 for (final long flag : flags) { 083 if ((flag & 1 << 16) != 0) { 084 count++; 085 } 086 } 087 return count; 088 } 089 090 public static int countBit16(final long[][] flags) { 091 int count = 0; 092 for (final long[] flag : flags) { 093 for (final long element : flag) { 094 if ((element & 1 << 16) != 0) { 095 count++; 096 } 097 } 098 } 099 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}