blob: 0be51b06fc6fc85fdd68e1d1fb441a9a6970b730 [file] [log] [blame]
/*
* Copyright 2008 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
#include <string>
#include "Debug.h"
#include "FreeValueMessage.h"
#include "HostChannel.h"
#include "InvokeMessage.h"
#include "InvokeSpecialMessage.h"
#include "ReturnMessage.h"
#include "ServerMethods.h"
#include "scoped_ptr/scoped_ptr.h"
using std::string;
Value ServerMethods::getProperty(HostChannel& channel, SessionHandler* handler, int objectRef,
int dispatchId) {
if (!channel.isConnected()) {
Debug::log(Debug::Debugging) << "Ignoring getProperty after disconnect"
<< Debug::flush;
return Value();
}
Value args[2];
args[0].setInt(objectRef);
args[1].setInt(dispatchId);
if (!InvokeSpecialMessage::send(channel, SPECIAL_GET_PROPERTY, 2, args)) {
Debug::log(Debug::Error) << " failed to send invoke of GetProperty(disp=" << dispatchId
<< ", obj=" << objectRef << ")" << Debug::flush;
return Value();
}
scoped_ptr<ReturnMessage> retMsg(channel.reactToMessagesWhileWaitingForReturn(handler));
if (!retMsg.get()) {
Debug::log(Debug::Error) << "getProperty: get return value failed for GetProperty(disp="
<< dispatchId << ", obj=" << objectRef << ")" << Debug::flush;
return Value();
}
return retMsg->getReturnValue();
}
int ServerMethods::hasMethod(HostChannel& channel, SessionHandler* handler, int classId,
const std::string& name) {
if (name != "toString" && name.find("::") == string::npos) {
// only JSNI-style names and toString are valid
return -1;
}
if (!channel.isConnected()) {
Debug::log(Debug::Debugging) << "Ignoring hasMethod after disconnect"
<< Debug::flush;
return -2;
}
Value arg;
arg.setString(name);
if (!InvokeSpecialMessage::send(channel, SPECIAL_HAS_METHOD, 1, &arg)) {
Debug::log(Debug::Error) << "hasMethod: invoke(hasMethod) failed" << Debug::flush;
return -2;
}
scoped_ptr<ReturnMessage> retMsg(channel.reactToMessagesWhileWaitingForReturn(handler));
if (!retMsg.get()) {
Debug::log(Debug::Error) << "hasMethod: get return value failed" << Debug::flush;
return -2;
}
Value retval = retMsg->getReturnValue();
// TODO(jat): better error handling?
return retval.isInt() ? retval.getInt() : -2;
}
int ServerMethods::hasProperty(HostChannel& channel, SessionHandler* handler, int classId,
const std::string& name) {
if (name != "toString" && name.find("::") == string::npos) {
// only JSNI-style names and toString are valid
return -1;
}
if (!channel.isConnected()) {
Debug::log(Debug::Debugging) << "Ignoring hasProperty after disconnect"
<< Debug::flush;
return -2;
}
Value arg;
arg.setString(name);
if (!InvokeSpecialMessage::send(channel, SPECIAL_HAS_PROPERTY, 1, &arg)) {
Debug::log(Debug::Error) << "hasProperty: invoke(hasProperty) failed" << Debug::flush;
return -2;
}
scoped_ptr<ReturnMessage> retMsg(channel.reactToMessagesWhileWaitingForReturn(handler));
if (!retMsg.get()) {
Debug::log(Debug::Error) << "hasProperty: get return value failed" << Debug::flush;
return -2;
}
Value retval = retMsg->getReturnValue();
// TODO(jat): better error handling?
return retval.isInt() ? retval.getInt() : -2;
}
bool ServerMethods::setProperty(HostChannel& channel, SessionHandler* handler, int objectRef,
int dispatchId, const Value& value) {
if (!channel.isConnected()) {
Debug::log(Debug::Debugging) << "Ignoring setProperty after disconnect"
<< Debug::flush;
return false;
}
// TODO(jat): error handling?
Value args[3];
args[0].setInt(objectRef);
args[1].setInt(dispatchId);
args[2] = value;
if (!InvokeSpecialMessage::send(channel, SPECIAL_SET_PROPERTY, 3, args)) {
Debug::log(Debug::Error) << " failed to send invoke of SetProperty(disp=" << dispatchId
<< ", obj=" << objectRef << ")" << Debug::flush;
return false;
}
scoped_ptr<ReturnMessage> retMsg(channel.reactToMessagesWhileWaitingForReturn(handler));
if (!retMsg.get()) {
Debug::log(Debug::Error) << "setProperty: get return value failed for SetProperty(disp="
<< dispatchId << ", obj=" << objectRef << ")" << Debug::flush;
return false;
}
// TODO: use the returned exception?
return !retMsg.get()->isException();
}
bool ServerMethods::freeJava(HostChannel& channel, SessionHandler* handler, int idCount,
const int* ids) {
// If we are disconnected, assume the server will free all of these anyway.
// This deals with the problem of getting finalizers called after the channel is dropped.
if (!channel.isConnected()) {
Debug::log(Debug::Debugging) << "Ignoring freeJava after disconnect"
<< Debug::flush;
return true;
}
if (!FreeValueMessage::send(channel, idCount, ids)) {
Debug::log(Debug::Error) << " failed to send FreeValues message" << Debug::flush;
return false;
}
return true;
}