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: */
017: package org.apache.harmony.pack200;
018:
019: // TODO Write doc
020: public final class SegmentUtils {
021:
022: public static int countArgs(String descriptor) {
023: return countArgs(descriptor, 1);
024: }
025:
026: public static int countInvokeInterfaceArgs(String descriptor) {
027: return countArgs(descriptor, 2);
028: }
029:
030: /**
031: * Count the number of arguments in the descriptor. Each
032: * long or double counts as widthOfLongsAndDoubles; all other
033: * arguments count as 1.
034: * @param descriptor String for which arguments are counted
035: * @param widthOfLongsAndDoubles int increment to apply for longs
036: * doubles. This is typically 1 when counting arguments alone,
037: * or 2 when counting arguments for invokeinterface.
038: * @return integer count
039: */
040: protected static int countArgs(String descriptor,
041: int widthOfLongsAndDoubles) {
042: int bra = descriptor.indexOf("(");
043: int ket = descriptor.indexOf(")");
044: if (bra == -1 || ket == -1 || ket < bra)
045: throw new IllegalArgumentException("No arguments");
046:
047: boolean inType = false;
048: boolean consumingNextType = false;
049: int count = 0;
050: for (int i = bra + 1; i < ket; i++) {
051: char charAt = descriptor.charAt(i);
052: if (inType && charAt == ';') {
053: inType = false;
054: consumingNextType = false;
055: } else if (!inType && charAt == 'L') {
056: inType = true;
057: count++;
058: } else if (charAt == '[') {
059: consumingNextType = true;
060: } else if (inType) {
061: // NOP
062: } else {
063: if (consumingNextType) {
064: count++;
065: consumingNextType = false;
066: } else {
067: if (charAt == 'D' || charAt == 'J') {
068: count += widthOfLongsAndDoubles;
069: } else {
070: count++;
071: }
072: }
073: }
074: }
075: return count;
076: }
077:
078: public static int countMatches(long[] flags, IMatcher matcher) {
079: int count = 0;
080: for (int i = 0; i < flags.length; i++) {
081: if (matcher.matches(flags[i]))
082: count++;
083: }
084: return count;
085: }
086:
087: public static int countBit16(int[] flags) {
088: int count = 0;
089: for (int i = 0; i < flags.length; i++) {
090: if ((flags[i] & (1 << 16)) != 0)
091: count++;
092: }
093: return count;
094: }
095:
096: public static int countBit16(long[] flags) {
097: int count = 0;
098: for (int i = 0; i < flags.length; i++) {
099: if ((flags[i] & (1 << 16)) != 0)
100: count++;
101: }
102: return count;
103: }
104:
105: public static int countBit16(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: return count;
114: }
115:
116: public static int countMatches(long[][] flags, IMatcher matcher) {
117: int count = 0;
118: for (int i = 0; i < flags.length; i++) {
119: count += countMatches(flags[i], matcher);
120: }
121: return count;
122: }
123:
124: /**
125: * Answer the index of the first character <= '$'
126: * in the parameter. This is used instead of indexOf('$')
127: * because inner classes may be separated by any character
128: * <= '$' (in other words, Foo#Bar is as valid as Foo$Bar).
129: * If no $ character is found, answer -1.
130: * @param string String to search for $
131: * @return first index of $ character, or -1 if not found
132: */
133: public static int indexOfFirstDollar(String string) {
134: for (int index = 0; index < string.length(); index++) {
135: if (string.charAt(index) <= '$') {
136: return index;
137: }
138: }
139: return -1;
140: }
141:
142: private SegmentUtils() {
143: // Intended to be a helper class
144: }
145:
146: /**
147: * This is a debugging message to aid the developer in writing this
148: * class. If the property 'debug.pack200' is set, this will
149: * generate messages to stderr; otherwise, it will be silent.
150: *
151: * @param message
152: * @deprecated this may be removed from production code
153: */
154: public static void debug(String message) {
155: if (System.getProperty("debug.pack200") != null) {
156: System.err.println(message);
157: }
158: }
159:
160: }
|