1fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include "generate_java.h"
2fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include "Type.h"
3fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <string.h>
4fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <stdio.h>
5fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <stdlib.h>
6fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato#include <string.h>
7fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
8fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato// =================================================
9fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratoclass StubClass : public Class
10fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
11fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratopublic:
12fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    StubClass(Type* type, Type* interfaceType);
13fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    virtual ~StubClass();
14fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
15fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* transact_code;
16fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* transact_data;
17fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* transact_reply;
18fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* transact_flags;
19fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    SwitchStatement* transact_switch;
20fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratoprivate:
21fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    void make_as_interface(Type* interfaceType);
22fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato};
23fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
24fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoStubClass::StubClass(Type* type, Type* interfaceType)
25fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    :Class()
26fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
27fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->comment = "/** Local-side IPC implementation stub class. */";
28fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->modifiers = PUBLIC | ABSTRACT | STATIC;
29fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->what = Class::CLASS;
30fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->type = type;
31fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->extends = BINDER_NATIVE_TYPE;
32fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->interfaces.push_back(interfaceType);
33fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
34fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // descriptor
35fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
36fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            new Variable(STRING_TYPE, "DESCRIPTOR"));
37fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    descriptor->value = "\"" + interfaceType->QualifiedName() + "\"";
38fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(descriptor);
39fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
40fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // ctor
41fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* ctor = new Method;
42fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->modifiers = PUBLIC;
43fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->comment = "/** Construct the stub at attach it to the "
44fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                        "interface. */";
45fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->name = "Stub";
46fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->statements = new StatementBlock;
47fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface",
48fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            2, THIS_VALUE, new LiteralExpression("DESCRIPTOR"));
49fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    ctor->statements->Add(attach);
50fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(ctor);
51fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
52fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // asInterface
53fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    make_as_interface(interfaceType);
54fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
55fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // asBinder
56fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* asBinder = new Method;
57b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes        asBinder->modifiers = PUBLIC | OVERRIDE;
58fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        asBinder->returnType = IBINDER_TYPE;
59fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        asBinder->name = "asBinder";
60fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        asBinder->statements = new StatementBlock;
61fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
62fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(asBinder);
63fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
64fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // onTransact
65fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->transact_code = new Variable(INT_TYPE, "code");
66fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->transact_data = new Variable(PARCEL_TYPE, "data");
67fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->transact_reply = new Variable(PARCEL_TYPE, "reply");
68fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->transact_flags = new Variable(INT_TYPE, "flags");
69fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* onTransact = new Method;
70fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->modifiers = PUBLIC | OVERRIDE;
71fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->returnType = BOOLEAN_TYPE;
72fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->name = "onTransact";
73fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->parameters.push_back(this->transact_code);
74fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->parameters.push_back(this->transact_data);
75fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->parameters.push_back(this->transact_reply);
76fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->parameters.push_back(this->transact_flags);
77fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->statements = new StatementBlock;
78fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
79fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(onTransact);
80fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->transact_switch = new SwitchStatement(this->transact_code);
81fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
82fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    onTransact->statements->Add(this->transact_switch);
83fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4,
84fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                    this->transact_code, this->transact_data,
85fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                    this->transact_reply, this->transact_flags);
86fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    onTransact->statements->Add(new ReturnStatement(superCall));
87fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
88fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
89fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoStubClass::~StubClass()
90fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
91fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
92fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
93fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratovoid
94fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoStubClass::make_as_interface(Type *interfaceType)
95fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
96fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* obj = new Variable(IBINDER_TYPE, "obj");
97fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
98fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* m = new Method;
99fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->comment = "/**\n * Cast an IBinder object into an ";
100fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->comment += interfaceType->QualifiedName();
101fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->comment += " interface,\n";
102fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->comment += " * generating a proxy if needed.\n */";
103fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->modifiers = PUBLIC | STATIC;
104fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->returnType = interfaceType;
105fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->name = "asInterface";
106fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->parameters.push_back(obj);
107fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        m->statements = new StatementBlock;
108fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
109fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    IfStatement* ifstatement = new IfStatement();
110fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
111fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ifstatement->statements = new StatementBlock;
112fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
113fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    m->statements->Add(ifstatement);
114fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
115fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
116fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
117fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
118fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    IInterfaceType* iinType = new IInterfaceType();
119fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable *iin = new Variable(iinType, "iin");
120b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes    VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL);
121fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    m->statements->Add(iinVd);
122fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
123fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // Ensure the instance type of the local object is as expected.
124fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // One scenario where this is needed is if another package (with a
125fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // different class loader) runs in the same process as the service.
126fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
127fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin;
128fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
129fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Comparison* instOfCheck = new Comparison(iin, " instanceof ",
130fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            new LiteralExpression(interfaceType->QualifiedName()));
131fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    IfStatement* instOfStatement = new IfStatement();
132fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
133fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        instOfStatement->statements = new StatementBlock;
134fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin)));
135fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    m->statements->Add(instOfStatement);
136fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
137fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    string proxyType = interfaceType->QualifiedName();
138fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    proxyType += ".Stub.Proxy";
139fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    NewExpression* ne = new NewExpression(NAMES.Find(proxyType));
140fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    ne->arguments.push_back(obj);
141fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    m->statements->Add(new ReturnStatement(ne));
142fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
143fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(m);
144fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
145fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
146fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
147fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
148fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato// =================================================
149fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratoclass ProxyClass : public Class
150fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
151fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratopublic:
152fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    ProxyClass(Type* type, InterfaceType* interfaceType);
153fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    virtual ~ProxyClass();
154fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
155fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* mRemote;
156fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    bool mOneWay;
157fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato};
158fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
159fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType)
160fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    :Class()
161fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
162fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->modifiers = PRIVATE | STATIC;
163fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->what = Class::CLASS;
164fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->type = type;
165fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->interfaces.push_back(interfaceType);
166fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
167fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    mOneWay = interfaceType->OneWay();
168fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
169fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // IBinder mRemote
170fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    mRemote = new Variable(IBINDER_TYPE, "mRemote");
171fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(new Field(PRIVATE, mRemote));
172fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
173fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // Proxy()
174fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* remote = new Variable(IBINDER_TYPE, "remote");
175fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* ctor = new Method;
176fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->name = "Proxy";
177fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->statements = new StatementBlock;
178fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        ctor->parameters.push_back(remote);
179fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    ctor->statements->Add(new Assignment(mRemote, remote));
180fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(ctor);
181fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
182fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // IBinder asBinder()
183fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* asBinder = new Method;
184b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes        asBinder->modifiers = PUBLIC | OVERRIDE;
185fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        asBinder->returnType = IBINDER_TYPE;
186fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        asBinder->name = "asBinder";
187fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        asBinder->statements = new StatementBlock;
188fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    asBinder->statements->Add(new ReturnStatement(mRemote));
189fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    this->elements.push_back(asBinder);
190fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
191fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
192fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoProxyClass::~ProxyClass()
193fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
194fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
195fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
196fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato// =================================================
197fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void
198fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_new_array(Type* t, StatementBlock* addTo, Variable* v,
199fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            Variable* parcel)
200fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
201fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* len = new Variable(INT_TYPE, v->name + "_length");
202fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
203fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    IfStatement* lencheck = new IfStatement();
204fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
205fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    lencheck->statements->Add(new Assignment(v, NULL_VALUE));
206fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    lencheck->elseif = new IfStatement();
207fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    lencheck->elseif->statements->Add(new Assignment(v,
208fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                new NewArrayExpression(t, len)));
209fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    addTo->Add(lencheck);
210fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
211fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
212fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void
213fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v,
214fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            Variable* parcel, int flags)
215fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
216fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (v->dimension == 0) {
217fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        t->WriteToParcel(addTo, v, parcel, flags);
218fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
219fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (v->dimension == 1) {
220fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        t->WriteArrayToParcel(addTo, v, parcel, flags);
221fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
222fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
223fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
224fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void
225fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
226fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            Variable* parcel, Variable** cl)
227fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
228fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (v->dimension == 0) {
229fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        t->CreateFromParcel(addTo, v, parcel, cl);
230fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
231fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (v->dimension == 1) {
232fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        t->CreateArrayFromParcel(addTo, v, parcel, cl);
233fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
234fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
235fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
236fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void
237fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
238fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            Variable* parcel, Variable** cl)
239fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
240fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (v->dimension == 0) {
241fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        t->ReadFromParcel(addTo, v, parcel, cl);
242fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
243fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (v->dimension == 1) {
244fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        t->ReadArrayFromParcel(addTo, v, parcel, cl);
245fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
246fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
247fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
248fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
249fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void
250fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_method(const method_type* method, Class* interface,
251fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                    StubClass* stubClass, ProxyClass* proxyClass, int index)
252fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
253fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    arg_type* arg;
254fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    int i;
255fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    bool hasOutParams = false;
256fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
257fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    const bool oneway = proxyClass->mOneWay || method->oneway;
258fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
259fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // == the TRANSACT_ constant =============================================
260fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    string transactCodeName = "TRANSACTION_";
261fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    transactCodeName += method->name.data;
262fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
263fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    char transactCodeValue[50];
264fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
265fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
266fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Field* transactCode = new Field(STATIC | FINAL,
267fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            new Variable(INT_TYPE, transactCodeName));
268fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    transactCode->value = transactCodeValue;
269fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    stubClass->elements.push_back(transactCode);
270fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
271fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // == the declaration in the interface ===================================
272fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* decl = new Method;
273fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        decl->comment = gather_comments(method->comments_token->extra);
274fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        decl->modifiers = PUBLIC;
275fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        decl->returnType = NAMES.Search(method->type.type.data);
276fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        decl->returnTypeDimension = method->type.dimension;
277fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        decl->name = method->name.data;
278fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
279fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    arg = method->args;
280fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    while (arg != NULL) {
281fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        decl->parameters.push_back(new Variable(
282fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            NAMES.Search(arg->type.type.data), arg->name.data,
283fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            arg->type.dimension));
284fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        arg = arg->next;
285fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
286fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
287fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
288fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
289fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    interface->elements.push_back(decl);
290fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
291fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // == the stub method ====================================================
292fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
293fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Case* c = new Case(transactCodeName);
294fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
295fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data);
296fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
297fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // interface token validation is the very first thing we do
298fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    c->statements->Add(new MethodCall(stubClass->transact_data,
299fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            "enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));
300fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
301fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // args
302fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* cl = NULL;
303fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    VariableFactory stubArgs("_arg");
304fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    arg = method->args;
305fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    while (arg != NULL) {
306fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        Type* t = NAMES.Search(arg->type.type.data);
307fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        Variable* v = stubArgs.Get(t);
308fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        v->dimension = arg->type.dimension;
309fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
310fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        c->statements->Add(new VariableDeclaration(v));
311fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
312fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
313fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            generate_create_from_parcel(t, c->statements, v,
314fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                    stubClass->transact_data, &cl);
315fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        } else {
316fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            if (arg->type.dimension == 0) {
317fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                c->statements->Add(new Assignment(v, new NewExpression(v->type)));
318fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            }
319fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            else if (arg->type.dimension == 1) {
320fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                generate_new_array(v->type, c->statements, v,
321fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                        stubClass->transact_data);
322fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            }
323fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            else {
324fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
325fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                        __LINE__);
326fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            }
327fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
328fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
329fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        realCall->arguments.push_back(v);
330fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
331fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        arg = arg->next;
332fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
333fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
334fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the real call
335fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* _result = NULL;
336fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (0 == strcmp(method->type.type.data, "void")) {
337fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        c->statements->Add(realCall);
338fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
339fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (!oneway) {
340fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            // report that there were no exceptions
341fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            MethodCall* ex = new MethodCall(stubClass->transact_reply,
342fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                    "writeNoException", 0);
343fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            c->statements->Add(ex);
344fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
345fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    } else {
346fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        _result = new Variable(decl->returnType, "_result",
347fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                decl->returnTypeDimension);
348fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        c->statements->Add(new VariableDeclaration(_result, realCall));
349fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
350fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (!oneway) {
351fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            // report that there were no exceptions
352fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            MethodCall* ex = new MethodCall(stubClass->transact_reply,
353fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                    "writeNoException", 0);
354fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            c->statements->Add(ex);
355fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
356fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
357fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        // marshall the return value
358fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        generate_write_to_parcel(decl->returnType, c->statements, _result,
359fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                    stubClass->transact_reply,
360fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                    Type::PARCELABLE_WRITE_RETURN_VALUE);
361fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
362fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
363fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // out parameters
364fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    i = 0;
365fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    arg = method->args;
366fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    while (arg != NULL) {
367fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        Type* t = NAMES.Search(arg->type.type.data);
368fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        Variable* v = stubArgs.Get(i++);
369fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
370fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
371fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            generate_write_to_parcel(t, c->statements, v,
372fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                stubClass->transact_reply,
373fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                Type::PARCELABLE_WRITE_RETURN_VALUE);
374fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            hasOutParams = true;
375fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
376fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
377fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        arg = arg->next;
378fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
379fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
380fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // return true
381fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    c->statements->Add(new ReturnStatement(TRUE_VALUE));
382fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    stubClass->transact_switch->cases.push_back(c);
383fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
384fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // == the proxy method ===================================================
385fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* proxy = new Method;
386fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->comment = gather_comments(method->comments_token->extra);
387b327c41e125a3be15a6c6c4dba318fe1b2392605Elliott Hughes        proxy->modifiers = PUBLIC | OVERRIDE;
388fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->returnType = NAMES.Search(method->type.type.data);
389fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->returnTypeDimension = method->type.dimension;
390fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->name = method->name.data;
391fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->statements = new StatementBlock;
392fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        arg = method->args;
393fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        while (arg != NULL) {
394fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            proxy->parameters.push_back(new Variable(
395fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            NAMES.Search(arg->type.type.data), arg->name.data,
396fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            arg->type.dimension));
397fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            arg = arg->next;
398fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
399fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
400fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    proxyClass->elements.push_back(proxy);
401fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
402fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the parcels
403fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* _data = new Variable(PARCEL_TYPE, "_data");
404fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    proxy->statements->Add(new VariableDeclaration(_data,
405fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                new MethodCall(PARCEL_TYPE, "obtain")));
406fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Variable* _reply = NULL;
407fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (!oneway) {
408fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        _reply = new Variable(PARCEL_TYPE, "_reply");
409fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->statements->Add(new VariableDeclaration(_reply,
410fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                    new MethodCall(PARCEL_TYPE, "obtain")));
411fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
412fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
413fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the return value
414fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    _result = NULL;
415fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (0 != strcmp(method->type.type.data, "void")) {
416fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        _result = new Variable(proxy->returnType, "_result",
417fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                method->type.dimension);
418fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->statements->Add(new VariableDeclaration(_result));
419fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
420fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
421fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // try and finally
422fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    TryStatement* tryStatement = new TryStatement();
423fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    proxy->statements->Add(tryStatement);
424fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    FinallyStatement* finallyStatement = new FinallyStatement();
425fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    proxy->statements->Add(finallyStatement);
426fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
427fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the interface identifier token: the DESCRIPTOR constant, marshalled as a string
428fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken",
429fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            1, new LiteralExpression("DESCRIPTOR")));
430fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
431fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the parameters
432fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    arg = method->args;
433fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    while (arg != NULL) {
434fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        Type* t = NAMES.Search(arg->type.type.data);
435fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
436fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        int dir = convert_direction(arg->direction.data);
437fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (dir == OUT_PARAMETER && arg->type.dimension != 0) {
438fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            IfStatement* checklen = new IfStatement();
439fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            checklen->expression = new Comparison(v, "==", NULL_VALUE);
440fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            checklen->statements->Add(new MethodCall(_data, "writeInt", 1,
441fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                        new LiteralExpression("-1")));
442fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            checklen->elseif = new IfStatement();
443fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            checklen->elseif->statements->Add(new MethodCall(_data, "writeInt",
444fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                        1, new FieldVariable(v, "length")));
445fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            tryStatement->statements->Add(checklen);
446fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
447fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        else if (dir & IN_PARAMETER) {
448fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            generate_write_to_parcel(t, tryStatement->statements, v, _data, 0);
449fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
450fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        arg = arg->next;
451fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
452fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
453fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the transact call
454fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4,
455fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            new LiteralExpression("Stub." + transactCodeName),
456fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            _data, _reply ? _reply : NULL_VALUE,
457fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                            new LiteralExpression(
458fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0"));
459fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    tryStatement->statements->Add(call);
460fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
461fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // throw back exceptions.
462fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (_reply) {
463fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        MethodCall* ex = new MethodCall(_reply, "readException", 0);
464fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        tryStatement->statements->Add(ex);
465fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
466fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
467fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // returning and cleanup
468fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (_reply != NULL) {
469fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (_result != NULL) {
470fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            generate_create_from_parcel(proxy->returnType,
471fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                    tryStatement->statements, _result, _reply, &cl);
472fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
473fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
474fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        // the out/inout parameters
475fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        arg = method->args;
476fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        while (arg != NULL) {
477fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            Type* t = NAMES.Search(arg->type.type.data);
478fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
479fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
480fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                generate_read_from_parcel(t, tryStatement->statements,
481fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                                            v, _reply, &cl);
482fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            }
483fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            arg = arg->next;
484fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
485fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
486fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
487fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
488fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
489fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
490fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    if (_result != NULL) {
491fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        proxy->statements->Add(new ReturnStatement(_result));
492fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
493fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
494fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
495fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratostatic void
496fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_interface_descriptors(StubClass* stub, ProxyClass* proxy)
497fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
498fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the interface descriptor transaction handler
499fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Case* c = new Case("INTERFACE_TRANSACTION");
500fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    c->statements->Add(new MethodCall(stub->transact_reply, "writeString",
501fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            1, new LiteralExpression("DESCRIPTOR")));
502fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    c->statements->Add(new ReturnStatement(TRUE_VALUE));
503fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    stub->transact_switch->cases.push_back(c);
504fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
505fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // and the proxy-side method returning the descriptor directly
506fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Method* getDesc = new Method;
507fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    getDesc->modifiers = PUBLIC;
508fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    getDesc->returnType = STRING_TYPE;
509fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    getDesc->returnTypeDimension = 0;
510fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    getDesc->name = "getInterfaceDescriptor";
511fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    getDesc->statements = new StatementBlock;
512fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
513fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    proxy->elements.push_back(getDesc);
514fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
515fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
516fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe OnoratoClass*
517fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onoratogenerate_binder_interface_class(const interface_type* iface)
518fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato{
519fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    InterfaceType* interfaceType = static_cast<InterfaceType*>(
520fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        NAMES.Find(iface->package, iface->name.data));
521fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
522fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the interface class
523fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    Class* interface = new Class;
524fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interface->comment = gather_comments(iface->comments_token->extra);
525fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interface->modifiers = PUBLIC;
526fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interface->what = Class::INTERFACE;
527fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interface->type = interfaceType;
528fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interface->interfaces.push_back(IINTERFACE_TYPE);
529fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
530fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the stub inner class
531fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    StubClass* stub = new StubClass(
532fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()),
533fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interfaceType);
534fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    interface->elements.push_back(stub);
535fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
536fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // the proxy inner class
537fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    ProxyClass* proxy = new ProxyClass(
538fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        NAMES.Find(iface->package,
539fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato                         append(iface->name.data, ".Stub.Proxy").c_str()),
540fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        interfaceType);
541fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    stub->elements.push_back(proxy);
542fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
543fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // stub and proxy support for getInterfaceDescriptor()
544fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    generate_interface_descriptors(stub, proxy);
545fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
546fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    // all the declared methods of the interface
547fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    int index = 0;
548fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    interface_item_type* item = iface->interface_items;
549fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    while (item != NULL) {
550fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        if (item->item_type == METHOD_TYPE) {
551fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato            generate_method((method_type*)item, interface, stub, proxy, index);
552fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        }
553fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        item = item->next;
554fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato        index++;
555fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    }
556fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
557fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato    return interface;
558fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato}
559fdfe2ff8c60c367a4eb7cecb4cbe1d62b41a8c20Joe Onorato
560