ExternalTypeEnumeration.java revision b9cc48a43ed984587c939d02fba5316bf5c0df6e
1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2013 Eric Lafortune (eric@graphics.cornell.edu)
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
16 *
17 * You should have received a copy of the GNU General Public License along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21package proguard.classfile.util;
22
23import proguard.classfile.ClassConstants;
24
25
26/**
27 * An <code>ExternalTypeEnumeration</code> provides an enumeration of all
28 * types listed in a given external descriptor string. The method name can
29 * be retrieved separately.
30 * <p>
31 * A <code>ExternalTypeEnumeration</code> object can be reused for processing
32 * different subsequent descriptors, by means of the <code>setDescriptor</code>
33 * method.
34 *
35 * @author Eric Lafortune
36 */
37public class ExternalTypeEnumeration
38{
39    private String descriptor;
40    private int    index;
41
42
43    public ExternalTypeEnumeration(String descriptor)
44    {
45        setDescriptor(descriptor);
46    }
47
48
49    ExternalTypeEnumeration()
50    {
51    }
52
53
54    void setDescriptor(String descriptor)
55    {
56        this.descriptor = descriptor;
57
58        reset();
59    }
60
61
62    public void reset()
63    {
64        index = descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN) + 1;
65
66        if (index < 1)
67        {
68            throw new IllegalArgumentException("Missing opening parenthesis in descriptor ["+descriptor+"]");
69        }
70    }
71
72
73    public boolean hasMoreTypes()
74    {
75        return index < descriptor.length() - 1;
76    }
77
78
79    public String nextType()
80    {
81        int startIndex = index;
82
83        // Find the next separating comma.
84        index = descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_SEPARATOR,
85                                   startIndex);
86
87        // Otherwise find the closing parenthesis.
88        if (index < 0)
89        {
90            index = descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_CLOSE,
91                                       startIndex);
92            if (index < 0)
93            {
94                throw new IllegalArgumentException("Missing closing parenthesis in descriptor ["+descriptor+"]");
95            }
96        }
97
98        return descriptor.substring(startIndex, index++).trim();
99    }
100
101
102    public String methodName()
103    {
104        return descriptor.substring(0, descriptor.indexOf(ClassConstants.EXTERNAL_METHOD_ARGUMENTS_OPEN)).trim();
105    }
106}
107