SegmentUtils.java

  1. /*
  2.  *  Licensed to the Apache Software Foundation (ASF) under one or more
  3.  *  contributor license agreements.  See the NOTICE file distributed with
  4.  *  this work for additional information regarding copyright ownership.
  5.  *  The ASF licenses this file to You under the Apache License, Version 2.0
  6.  *  (the "License"); you may not use this file except in compliance with
  7.  *  the License.  You may obtain a copy of the License at
  8.  *
  9.  *     http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  *  Unless required by applicable law or agreed to in writing, software
  12.  *  distributed under the License is distributed on an "AS IS" BASIS,
  13.  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  *  See the License for the specific language governing permissions and
  15.  *  limitations under the License.
  16.  */
  17. package org.apache.commons.compress.harmony.unpack200;

  18. /**
  19.  * Utility class for unpack200
  20.  */
  21. public final class SegmentUtils {

  22.     public static int countArgs(final String descriptor) {
  23.         return countArgs(descriptor, 1);
  24.     }

  25.     /**
  26.      * Count the number of arguments in the descriptor. Each long or double counts as widthOfLongsAndDoubles; all other arguments count as 1.
  27.      *
  28.      * @param descriptor             String for which arguments are counted
  29.      * @param widthOfLongsAndDoubles int increment to apply for longs doubles. This is typically 1 when counting arguments alone, or 2 when counting arguments
  30.      *                               for invokeinterface.
  31.      * @return integer count
  32.      */
  33.     protected static int countArgs(final String descriptor, final int widthOfLongsAndDoubles) {
  34.         final int bra = descriptor.indexOf('(');
  35.         final int ket = descriptor.indexOf(')');
  36.         if (bra == -1 || ket == -1 || ket < bra) {
  37.             throw new IllegalArgumentException("No arguments");
  38.         }

  39.         boolean inType = false;
  40.         boolean consumingNextType = false;
  41.         int count = 0;
  42.         for (int i = bra + 1; i < ket; i++) {
  43.             final char charAt = descriptor.charAt(i);
  44.             if (inType && charAt == ';') {
  45.                 inType = false;
  46.                 consumingNextType = false;
  47.             } else if (!inType && charAt == 'L') {
  48.                 inType = true;
  49.                 count++;
  50.             } else if (charAt == '[') {
  51.                 consumingNextType = true;
  52.             } else if (inType) {
  53.                 // NOP
  54.             } else if (consumingNextType) {
  55.                 count++;
  56.                 consumingNextType = false;
  57.             } else if (charAt == 'D' || charAt == 'J') {
  58.                 count += widthOfLongsAndDoubles;
  59.             } else {
  60.                 count++;
  61.             }
  62.         }
  63.         return count;
  64.     }

  65.     public static int countBit16(final int[] flags) {
  66.         int count = 0;
  67.         for (final int flag : flags) {
  68.             if ((flag & 1 << 16) != 0) {
  69.                 count++;
  70.             }
  71.         }
  72.         return count;
  73.     }

  74.     public static int countBit16(final long[] flags) {
  75.         int count = 0;
  76.         for (final long flag : flags) {
  77.             if ((flag & 1 << 16) != 0) {
  78.                 count++;
  79.             }
  80.         }
  81.         return count;
  82.     }

  83.     public static int countBit16(final long[][] flags) {
  84.         int count = 0;
  85.         for (final long[] flag : flags) {
  86.             for (final long element : flag) {
  87.                 if ((element & 1 << 16) != 0) {
  88.                     count++;
  89.                 }
  90.             }
  91.         }
  92.         return count;
  93.     }

  94.     public static int countInvokeInterfaceArgs(final String descriptor) {
  95.         return countArgs(descriptor, 2);
  96.     }

  97.     public static int countMatches(final long[] flags, final IMatcher matcher) {
  98.         int count = 0;
  99.         for (final long flag : flags) {
  100.             if (matcher.matches(flag)) {
  101.                 count++;
  102.             }
  103.         }
  104.         return count;
  105.     }

  106.     public static int countMatches(final long[][] flags, final IMatcher matcher) {
  107.         int count = 0;
  108.         for (final long[] flag : flags) {
  109.             count += countMatches(flag, matcher);
  110.         }
  111.         return count;
  112.     }

  113. }