154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "generate_java.h"
254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "AST.h"
354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include "Type.h"
40aa7fe6876d533610b4b993035030b946cc32e4cAlexey Zaytsev#include <string.h>
554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project#include <stdio.h>
6b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project#include <stdlib.h>
7b798689749c64baba81f02e10cf2157c747d6b46The Android Open Source Project#include <string.h>
854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// =================================================
1054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectclass VariableFactory
1154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
1254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic:
1354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    VariableFactory(const string& base); // base must be short
1454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* Get(Type* type);
1554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* Get(int index);
1654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectprivate:
1754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    vector<Variable*> m_vars;
1854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string m_base;
1954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int m_index;
2054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project};
2154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectVariableFactory::VariableFactory(const string& base)
2354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    :m_base(base),
2454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project     m_index(0)
2554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
2654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
2754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
2854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectVariable*
2954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectVariableFactory::Get(Type* type)
3054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
3154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    char name[100];
3254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    sprintf(name, "%s%d", m_base.c_str(), m_index);
3354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_index++;
3454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* v = new Variable(type, name);
3554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m_vars.push_back(v);
3654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return v;
3754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
3854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
3954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectVariable*
4054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectVariableFactory::Get(int index)
4154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
4254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return m_vars[index];
4354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
4454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
4554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// =================================================
4654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectclass StubClass : public Class
4754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
4854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic:
4954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    StubClass(Type* type, Type* interfaceType);
5054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    virtual ~StubClass();
5154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
5254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* transact_code;
5354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* transact_data;
5454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* transact_reply;
5554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* transact_flags;
5654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    SwitchStatement* transact_switch;
5754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectprivate:
5854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    void make_as_interface(Type* interfaceType);
5954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project};
6054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
6154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectStubClass::StubClass(Type* type, Type* interfaceType)
6254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    :Class()
6354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
6454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->comment = "/** Local-side IPC implementation stub class. */";
6554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->modifiers = PUBLIC | ABSTRACT | STATIC;
6654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->what = Class::CLASS;
6754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->type = type;
6854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->extends = BINDER_NATIVE_TYPE;
6954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->interfaces.push_back(interfaceType);
7054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // descriptor
7254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
7354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            new Variable(STRING_TYPE, "DESCRIPTOR"));
7454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    descriptor->value = "\"" + interfaceType->QualifiedName() + "\"";
7554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(descriptor);
7654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
7754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // ctor
7854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* ctor = new Method;
7954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->modifiers = PUBLIC;
8054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->comment = "/** Construct the stub at attach it to the "
8154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        "interface. */";
8254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->name = "Stub";
8354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->statements = new StatementBlock;
8454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface",
8554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            2, THIS_VALUE, new LiteralExpression("DESCRIPTOR"));
8654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    ctor->statements->Add(attach);
8754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(ctor);
8854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
8954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // asInterface
9054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    make_as_interface(interfaceType);
9154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
9254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // asBinder
9354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* asBinder = new Method;
9454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->modifiers = PUBLIC;
9554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->returnType = IBINDER_TYPE;
9654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->name = "asBinder";
9754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->statements = new StatementBlock;
9854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
9954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(asBinder);
10054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
10154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // onTransact
10254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->transact_code = new Variable(INT_TYPE, "code");
10354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->transact_data = new Variable(PARCEL_TYPE, "data");
10454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->transact_reply = new Variable(PARCEL_TYPE, "reply");
10554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->transact_flags = new Variable(INT_TYPE, "flags");
10654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* onTransact = new Method;
1077ea9d79e302b1d71c62802aa514566c9b7f39f67Xavier Ducrohet        onTransact->modifiers = PUBLIC | OVERRIDE;
10854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->returnType = BOOLEAN_TYPE;
10954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->name = "onTransact";
11054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->parameters.push_back(this->transact_code);
11154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->parameters.push_back(this->transact_data);
11254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->parameters.push_back(this->transact_reply);
11354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->parameters.push_back(this->transact_flags);
11454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->statements = new StatementBlock;
11554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
11654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(onTransact);
11754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->transact_switch = new SwitchStatement(this->transact_code);
11854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
11954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    onTransact->statements->Add(this->transact_switch);
12054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4,
12154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    this->transact_code, this->transact_data,
12254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    this->transact_reply, this->transact_flags);
12354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    onTransact->statements->Add(new ReturnStatement(superCall));
12454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
12554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
12654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectStubClass::~StubClass()
12754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
12854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
12954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectvoid
13154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectStubClass::make_as_interface(Type *interfaceType)
13254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
13354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* obj = new Variable(IBINDER_TYPE, "obj");
13454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
13554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* m = new Method;
13654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->comment = "/**\n * Cast an IBinder object into an ";
137754270601a268cfe0ab679768aa33423feb1f974Adrian Taylor        m->comment += interfaceType->QualifiedName();
13854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->comment += " interface,\n";
13954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->comment += " * generating a proxy if needed.\n */";
14054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->modifiers = PUBLIC | STATIC;
14154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->returnType = interfaceType;
14254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->name = "asInterface";
14354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->parameters.push_back(obj);
14454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        m->statements = new StatementBlock;
14554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
14654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IfStatement* ifstatement = new IfStatement();
14754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
14854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ifstatement->statements = new StatementBlock;
14954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
15054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m->statements->Add(ifstatement);
15154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
15254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
15354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
15454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
15554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IInterfaceType* iinType = new IInterfaceType();
15654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable *iin = new Variable(iinType, "iin");
15754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, iinType);
15854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m->statements->Add(iinVd);
15954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Ensure the instance type of the local object is as expected.
16154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // One scenario where this is needed is if another package (with a
16254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // different class loader) runs in the same process as the service.
16354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
16454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin;
16554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
16654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Comparison* instOfCheck = new Comparison(iin, " instanceof ",
16754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            new LiteralExpression(interfaceType->QualifiedName()));
16854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IfStatement* instOfStatement = new IfStatement();
16954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
17054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        instOfStatement->statements = new StatementBlock;
17154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin)));
17254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m->statements->Add(instOfStatement);
17354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
17454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string proxyType = interfaceType->QualifiedName();
17554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    proxyType += ".Stub.Proxy";
17654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    NewExpression* ne = new NewExpression(NAMES.Find(proxyType));
17754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    ne->arguments.push_back(obj);
17854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    m->statements->Add(new ReturnStatement(ne));
17954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(m);
18154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
18254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
18554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// =================================================
18654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectclass ProxyClass : public Class
18754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
18854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectpublic:
18954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    ProxyClass(Type* type, InterfaceType* interfaceType);
19054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    virtual ~ProxyClass();
19154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* mRemote;
19354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    bool mOneWay;
19454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project};
19554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
19654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType)
19754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    :Class()
19854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
19954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->modifiers = PRIVATE | STATIC;
20054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->what = Class::CLASS;
20154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->type = type;
20254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->interfaces.push_back(interfaceType);
20354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mOneWay = interfaceType->OneWay();
20554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
20654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // IBinder mRemote
20754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    mRemote = new Variable(IBINDER_TYPE, "mRemote");
20854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(new Field(PRIVATE, mRemote));
20954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // Proxy()
21154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* remote = new Variable(IBINDER_TYPE, "remote");
21254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* ctor = new Method;
21354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->name = "Proxy";
21454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->statements = new StatementBlock;
21554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        ctor->parameters.push_back(remote);
21654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    ctor->statements->Add(new Assignment(mRemote, remote));
21754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(ctor);
21854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
21954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // IBinder asBinder()
22054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* asBinder = new Method;
22154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->modifiers = PUBLIC;
22254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->returnType = IBINDER_TYPE;
22354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->name = "asBinder";
22454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        asBinder->statements = new StatementBlock;
22554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    asBinder->statements->Add(new ReturnStatement(mRemote));
22654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    this->elements.push_back(asBinder);
22754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
22854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
22954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source ProjectProxyClass::~ProxyClass()
23054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
23154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
23254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
23354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project// =================================================
23454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic string
23554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgather_comments(extra_text_type* extra)
23654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
23754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string s;
23854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (extra) {
23954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (extra->which == SHORT_COMMENT) {
24054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s += extra->data;
24154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
24254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        else if (extra->which == LONG_COMMENT) {
24354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s += "/*";
24454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s += extra->data;
24554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            s += "*/";
24654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
24754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        extra = extra->next;
24854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
24954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return s;
25054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
25154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
25254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic string
25354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectappend(const char* a, const char* b)
25454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
25554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string s = a;
25654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    s += b;
25754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return s;
25854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
25954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
26054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void
26154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_new_array(Type* t, StatementBlock* addTo, Variable* v,
26254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            Variable* parcel)
26354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
26454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* len = new Variable(INT_TYPE, v->name + "_length");
26554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
26654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    IfStatement* lencheck = new IfStatement();
26754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
26854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lencheck->statements->Add(new Assignment(v, NULL_VALUE));
26954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lencheck->elseif = new IfStatement();
27054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    lencheck->elseif->statements->Add(new Assignment(v,
27154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                new NewArrayExpression(t, len)));
27254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    addTo->Add(lencheck);
27354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
27454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
27554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void
27654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v,
27754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            Variable* parcel, int flags)
27854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
27954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (v->dimension == 0) {
28054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        t->WriteToParcel(addTo, v, parcel, flags);
28154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
28254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (v->dimension == 1) {
28354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        t->WriteArrayToParcel(addTo, v, parcel, flags);
28454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
28554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
28654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
28754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void
28854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
289b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes                            Variable* parcel, Variable** cl)
29054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
29154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (v->dimension == 0) {
292b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes        t->CreateFromParcel(addTo, v, parcel, cl);
29354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
29454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (v->dimension == 1) {
295b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes        t->CreateArrayFromParcel(addTo, v, parcel, cl);
29654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
29754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
29854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
29954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void
30054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
301b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes                            Variable* parcel, Variable** cl)
30254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
30354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (v->dimension == 0) {
304b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes        t->ReadFromParcel(addTo, v, parcel, cl);
30554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
30654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (v->dimension == 1) {
307b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes        t->ReadArrayFromParcel(addTo, v, parcel, cl);
30854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
30954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
31054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
31154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
31254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void
31354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_method(const method_type* method, Class* interface,
31454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    StubClass* stubClass, ProxyClass* proxyClass, int index)
31554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
31654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    arg_type* arg;
31754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int i;
31854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    bool hasOutParams = false;
31954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    const bool oneway = proxyClass->mOneWay || method->oneway;
32154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // == the TRANSACT_ constant =============================================
32354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    string transactCodeName = "TRANSACTION_";
32454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    transactCodeName += method->name.data;
32554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    char transactCodeValue[50];
327754270601a268cfe0ab679768aa33423feb1f974Adrian Taylor    sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
32854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
32954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Field* transactCode = new Field(STATIC | FINAL,
33054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            new Variable(INT_TYPE, transactCodeName));
33154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    transactCode->value = transactCodeValue;
33254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stubClass->elements.push_back(transactCode);
33354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
33454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // == the declaration in the interface ===================================
33554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* decl = new Method;
33654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        decl->comment = gather_comments(method->comments_token->extra);
33754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        decl->modifiers = PUBLIC;
33854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        decl->returnType = NAMES.Search(method->type.type.data);
33954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        decl->returnTypeDimension = method->type.dimension;
34054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        decl->name = method->name.data;
34154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
34254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    arg = method->args;
34354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (arg != NULL) {
34454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        decl->parameters.push_back(new Variable(
34554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            NAMES.Search(arg->type.type.data), arg->name.data,
34654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            arg->type.dimension));
34754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        arg = arg->next;
34854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
34954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
35154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    interface->elements.push_back(decl);
35354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // == the stub method ====================================================
35554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Case* c = new Case(transactCodeName);
35754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
35854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data);
35954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
36054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // interface token validation is the very first thing we do
36154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->statements->Add(new MethodCall(stubClass->transact_data,
36254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            "enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));
36354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
36454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // args
365b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes    Variable* cl = NULL;
36654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    VariableFactory stubArgs("_arg");
36754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    arg = method->args;
36854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (arg != NULL) {
36954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Type* t = NAMES.Search(arg->type.type.data);
37054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Variable* v = stubArgs.Get(t);
37154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        v->dimension = arg->type.dimension;
37254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
37354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->statements->Add(new VariableDeclaration(v));
37454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
37554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (convert_direction(arg->direction.data) & IN_PARAMETER) {
37654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            generate_create_from_parcel(t, c->statements, v,
377b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes                    stubClass->transact_data, &cl);
37854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        } else {
37954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (arg->type.dimension == 0) {
38054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                c->statements->Add(new Assignment(
38154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                                v, new NewExpression(v->type)));
38254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
38354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            else if (arg->type.dimension == 1) {
38454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                generate_new_array(v->type, c->statements, v,
38554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        stubClass->transact_data);
38654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
38754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            else {
38854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
38954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        __LINE__);
39054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
39154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
39254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
39354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        realCall->arguments.push_back(v);
39454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
39554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        arg = arg->next;
39654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
39754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
39854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the real call
39954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* _result = NULL;
40054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (0 == strcmp(method->type.type.data, "void")) {
40154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->statements->Add(realCall);
40254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
40354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!oneway) {
40454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // report that there were no exceptions
40554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            MethodCall* ex = new MethodCall(stubClass->transact_reply,
40654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    "writeNoException", 0);
40754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->statements->Add(ex);
40854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
40954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
41054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        _result = new Variable(decl->returnType, "_result",
41154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                decl->returnTypeDimension);
41254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        c->statements->Add(new VariableDeclaration(_result, realCall));
41354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
41454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (!oneway) {
41554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            // report that there were no exceptions
41654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            MethodCall* ex = new MethodCall(stubClass->transact_reply,
41754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                    "writeNoException", 0);
41854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            c->statements->Add(ex);
41954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
42054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // marshall the return value
42254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        generate_write_to_parcel(decl->returnType, c->statements, _result,
42354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    stubClass->transact_reply,
42454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    Type::PARCELABLE_WRITE_RETURN_VALUE);
42554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
42654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
42754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // out parameters
42854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    i = 0;
42954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    arg = method->args;
43054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (arg != NULL) {
43154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Type* t = NAMES.Search(arg->type.type.data);
43254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Variable* v = stubArgs.Get(i++);
43354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
43454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
43554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            generate_write_to_parcel(t, c->statements, v,
43654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                stubClass->transact_reply,
43754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                Type::PARCELABLE_WRITE_RETURN_VALUE);
43854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            hasOutParams = true;
43954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
44054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
44154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        arg = arg->next;
44254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
44354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
44454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // return true
44554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->statements->Add(new ReturnStatement(TRUE_VALUE));
44654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stubClass->transact_switch->cases.push_back(c);
44754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
44854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // == the proxy method ===================================================
44954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* proxy = new Method;
45054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->comment = gather_comments(method->comments_token->extra);
45154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->modifiers = PUBLIC;
45254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->returnType = NAMES.Search(method->type.type.data);
45354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->returnTypeDimension = method->type.dimension;
45454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->name = method->name.data;
45554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->statements = new StatementBlock;
45654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        arg = method->args;
45754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        while (arg != NULL) {
45854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            proxy->parameters.push_back(new Variable(
45954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            NAMES.Search(arg->type.type.data), arg->name.data,
46054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            arg->type.dimension));
46154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            arg = arg->next;
46254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
46354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
46454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    proxyClass->elements.push_back(proxy);
46554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
46654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the parcels
46754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* _data = new Variable(PARCEL_TYPE, "_data");
46854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    proxy->statements->Add(new VariableDeclaration(_data,
46954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                new MethodCall(PARCEL_TYPE, "obtain")));
47054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Variable* _reply = NULL;
47154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (!oneway) {
47254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        _reply = new Variable(PARCEL_TYPE, "_reply");
47354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->statements->Add(new VariableDeclaration(_reply,
47454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                                    new MethodCall(PARCEL_TYPE, "obtain")));
47554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
47654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
47754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the return value
47854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    _result = NULL;
47954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (0 != strcmp(method->type.type.data, "void")) {
48054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        _result = new Variable(proxy->returnType, "_result",
48154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                method->type.dimension);
48254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->statements->Add(new VariableDeclaration(_result));
48354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
48454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
48554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // try and finally
48654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    TryStatement* tryStatement = new TryStatement();
48754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    proxy->statements->Add(tryStatement);
48854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    FinallyStatement* finallyStatement = new FinallyStatement();
48954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    proxy->statements->Add(finallyStatement);
49054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
49154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the interface identifier token: the DESCRIPTOR constant, marshalled as a string
49254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken",
49354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            1, new LiteralExpression("DESCRIPTOR")));
49454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
49554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the parameters
49654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    arg = method->args;
49754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (arg != NULL) {
49854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Type* t = NAMES.Search(arg->type.type.data);
49954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
50054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        int dir = convert_direction(arg->direction.data);
50154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (dir == OUT_PARAMETER && arg->type.dimension != 0) {
50254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            IfStatement* checklen = new IfStatement();
50354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            checklen->expression = new Comparison(v, "==", NULL_VALUE);
50454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            checklen->statements->Add(new MethodCall(_data, "writeInt", 1,
50554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        new LiteralExpression("-1")));
50654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            checklen->elseif = new IfStatement();
50754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            checklen->elseif->statements->Add(new MethodCall(_data, "writeInt",
50854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                        1, new FieldVariable(v, "length")));
50954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            tryStatement->statements->Add(checklen);
51054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
51154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        else if (dir & IN_PARAMETER) {
51254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            generate_write_to_parcel(t, tryStatement->statements, v, _data, 0);
51354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
51454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        arg = arg->next;
51554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
51654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
51754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the transact call
51854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4,
51954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            new LiteralExpression("Stub." + transactCodeName),
52054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            _data, _reply ? _reply : NULL_VALUE,
52154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                            new LiteralExpression(
522754270601a268cfe0ab679768aa33423feb1f974Adrian Taylor                                oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0"));
52354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    tryStatement->statements->Add(call);
52454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
52554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // throw back exceptions.
52654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (_reply) {
52754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        MethodCall* ex = new MethodCall(_reply, "readException", 0);
52854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        tryStatement->statements->Add(ex);
52954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
53054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
53154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // returning and cleanup
53254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (_reply != NULL) {
53354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (_result != NULL) {
53454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            generate_create_from_parcel(proxy->returnType,
535b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes                    tryStatement->statements, _result, _reply, &cl);
53654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
53754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
53854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        // the out/inout parameters
53954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        arg = method->args;
54054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        while (arg != NULL) {
54154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Type* t = NAMES.Search(arg->type.type.data);
54254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
54354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
54454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                generate_read_from_parcel(t, tryStatement->statements,
545b9eba866b203b28e58f35598023f49b4b58a0635Elliott Hughes                                            v, _reply, &cl);
54654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            }
54754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            arg = arg->next;
54854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
54954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
55154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
55254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
55354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (_result != NULL) {
55554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        proxy->statements->Add(new ReturnStatement(_result));
55654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
55754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
55854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
55954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic void
56054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_interface_descriptors(StubClass* stub, ProxyClass* proxy)
56154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
56254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the interface descriptor transaction handler
56354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Case* c = new Case("INTERFACE_TRANSACTION");
56454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->statements->Add(new MethodCall(stub->transact_reply, "writeString",
56554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            1, new LiteralExpression("DESCRIPTOR")));
56654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    c->statements->Add(new ReturnStatement(TRUE_VALUE));
56754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stub->transact_switch->cases.push_back(c);
56854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
56954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // and the proxy-side method returning the descriptor directly
57054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Method* getDesc = new Method;
57154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    getDesc->modifiers = PUBLIC;
57254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    getDesc->returnType = STRING_TYPE;
57354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    getDesc->returnTypeDimension = 0;
57454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    getDesc->name = "getInterfaceDescriptor";
57554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    getDesc->statements = new StatementBlock;
57654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
57754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    proxy->elements.push_back(getDesc);
57854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
57954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectstatic Class*
58154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_interface_class(const interface_type* iface)
58254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
58354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    InterfaceType* interfaceType = static_cast<InterfaceType*>(
58454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        NAMES.Find(iface->package, iface->name.data));
58554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
58654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the interface class
58754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Class* interface = new Class;
58854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interface->comment = gather_comments(iface->comments_token->extra);
58954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interface->modifiers = PUBLIC;
59054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interface->what = Class::INTERFACE;
59154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interface->type = interfaceType;
59254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interface->interfaces.push_back(IINTERFACE_TYPE);
59354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
59454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the stub inner class
59554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    StubClass* stub = new StubClass(
59654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()),
59754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interfaceType);
59854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    interface->elements.push_back(stub);
59954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // the proxy inner class
60154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    ProxyClass* proxy = new ProxyClass(
60254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        NAMES.Find(iface->package,
60354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                         append(iface->name.data, ".Stub.Proxy").c_str()),
60454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        interfaceType);
60554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    stub->elements.push_back(proxy);
60654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
60754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // stub and proxy support for getInterfaceDescriptor()
60854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    generate_interface_descriptors(stub, proxy);
60954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
61054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    // all the declared methods of the interface
61154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    int index = 0;
61254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    interface_item_type* item = iface->interface_items;
61354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    while (item != NULL) {
61454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (item->item_type == METHOD_TYPE) {
61554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            generate_method((method_type*)item, interface, stub, proxy, index);
61654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
61754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        item = item->next;
61854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        index++;
61954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
62054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return interface;
62254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
62354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
62454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectint
62554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Projectgenerate_java(const string& filename, const string& originalSrc,
62654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project                interface_type* iface)
62754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project{
62854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    Document* document = new Document;
62954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        document->comment = "";
63054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (iface->package) document->package = iface->package;
63154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        document->originalSrc = originalSrc;
63254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        document->classes.push_back(generate_interface_class(iface));
63354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
63454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project//    printf("outputting... filename=%s\n", filename.c_str());
63554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    FILE* to;
63654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    if (filename == "-") {
63754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        to = stdout;
63854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    } else {
63954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project       /* open file in binary mode to ensure that the tool produces the
64054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        * same output on all platforms !!
64154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        */
64254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        to = fopen(filename.c_str(), "wb");
64354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        if (to == NULL) {
64454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            fprintf(stderr, "unable to open %s for write\n", filename.c_str());
64554b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project            return 1;
64654b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project        }
64754b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    }
64854b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
64954b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    document->Write(to);
65054b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
65154b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    fclose(to);
65254b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project    return 0;
65354b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project}
65454b6cfa9a9e5b861a9930af873580d6dc20f773The Android Open Source Project
655