Compare commits
1 Commits
tags/arele
...
tags/Last1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
973a54719f |
5
mozilla/js/src/liveconnect/MANIFEST
Normal file
5
mozilla/js/src/liveconnect/MANIFEST
Normal file
@@ -0,0 +1,5 @@
|
||||
# This is a list of local files which get copied to the mozilla:dist directory
|
||||
#
|
||||
|
||||
jsjava.h
|
||||
nsILiveconnect.h
|
||||
89
mozilla/js/src/liveconnect/Makefile
Normal file
89
mozilla/js/src/liveconnect/Makefile
Normal file
@@ -0,0 +1,89 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
|
||||
|
||||
DEPTH = ../../..
|
||||
|
||||
include $(DEPTH)/config/config.mk
|
||||
|
||||
ifdef NSJVM
|
||||
DIRS = classes
|
||||
endif
|
||||
|
||||
MODULE = java
|
||||
LIBRARY_NAME = jsj
|
||||
|
||||
REQUIRES = java js applet nspr img util layer xpcom
|
||||
|
||||
CSRCS = jsj.c \
|
||||
jsj_JSObject.c \
|
||||
jsj_JavaArray.c \
|
||||
jsj_JavaClass.c \
|
||||
jsj_JavaMember.c \
|
||||
jsj_JavaObject.c \
|
||||
jsj_JavaPackage.c \
|
||||
jsj_array.c \
|
||||
jsj_class.c \
|
||||
jsj_convert.c \
|
||||
jsj_field.c \
|
||||
jsj_hash.c \
|
||||
jsj_method.c \
|
||||
jsj_utils.c \
|
||||
nsCLiveconnect.c \
|
||||
nsCLiveconnectFactory.c
|
||||
|
||||
|
||||
LLIBS=$(LIBNSPR) $(DIST)/lib/js$(MOZ_BITS)$(VERSION_NUMBER).lib \
|
||||
$(DIST)/lib/xpcom32.lib
|
||||
|
||||
|
||||
ifdef NSJVM
|
||||
JNI_GEN = netscape.javascript.JSObject netscape.javascript.JSException
|
||||
endif
|
||||
|
||||
EXPORTS = jsjava.h \
|
||||
$(JNI_GEN_DIR)/netscape_javascript_JSObject.h \
|
||||
$(JNI_GEN_DIR)/netscape_javascript_JSException.h \
|
||||
nsILiveconnect.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
######################################################################
|
||||
|
||||
# Generate jsj_nodl.c (so that you can check it in)
|
||||
# These make rules only works on IRIX...sigh
|
||||
|
||||
ifeq ($(OS_ARCH),IRIX)
|
||||
jsj_nodl.c: $(OBJDIR)/stubs.o Makefile $(DEPTH)/config/nodl.pl
|
||||
rm -f $@
|
||||
$(PERL) $(DEPTH)/config/nodl.pl "jsj_nodl_tab" \
|
||||
`nm -Bn $(OBJDIR)/stubs.o | egrep Java_.*_stub | awk '{print $$3;}'` > $@
|
||||
endif
|
||||
|
||||
ifdef JAVA_OR_OJI
|
||||
$(OBJDIR)/stubs.o: \
|
||||
$(JNI_GEN_DIR)/netscape_javascript_JSObject.c \
|
||||
$(JNI_GEN_DIR)/netscape_javascript_JSException.c \
|
||||
$(NULL)
|
||||
else
|
||||
$(OBJDIR)/stubs.o:
|
||||
endif
|
||||
|
||||
90
mozilla/js/src/liveconnect/Makefile.in
Normal file
90
mozilla/js/src/liveconnect/Makefile.in
Normal file
@@ -0,0 +1,90 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
|
||||
|
||||
DEPTH = ../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
ifdef NSJVM
|
||||
DIRS = classes
|
||||
endif
|
||||
|
||||
|
||||
MODULE = java
|
||||
LIBRARY_NAME = jsj
|
||||
|
||||
REQUIRES = java js applet nspr img util layer xpcom caps oji plugin
|
||||
|
||||
CSRCS = jsj.c \
|
||||
jsj_JSObject.c \
|
||||
jsj_JavaArray.c \
|
||||
jsj_JavaClass.c \
|
||||
jsj_JavaMember.c \
|
||||
jsj_JavaObject.c \
|
||||
jsj_JavaPackage.c \
|
||||
jsj_array.c \
|
||||
jsj_class.c \
|
||||
jsj_convert.c \
|
||||
jsj_field.c \
|
||||
jsj_hash.c \
|
||||
jsj_method.c \
|
||||
jsj_utils.c
|
||||
nsCLiveconnect.c \
|
||||
nsCLiveconnectFactory.c
|
||||
|
||||
|
||||
ifdef NSJVM
|
||||
JNI_GEN = netscape.javascript.JSObject netscape.javascript.JSException
|
||||
endif
|
||||
|
||||
EXPORTS = $(srcdir)/jsjava.h \
|
||||
$(srcdir)/$(JNI_GEN_DIR)/netscape_javascript_JSObject.h \
|
||||
$(srcdir)/$(JNI_GEN_DIR)/netscape_javascript_JSException.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
######################################################################
|
||||
|
||||
# Generate jsj_nodl.c (so that you can check it in)
|
||||
# These make rules only works on IRIX...sigh
|
||||
|
||||
ifeq ($(OS_ARCH),IRIX)
|
||||
jsj_nodl.c: $(OBJDIR)/stubs.o Makefile $(topsrcdir)/config/nodl.pl
|
||||
rm -f $@
|
||||
$(PERL) $(topsrcdir)/config/nodl.pl "jsj_nodl_tab" \
|
||||
`nm -Bn $(OBJDIR)/stubs.o | egrep Java_.*_stub | awk '{print $$3;}'` > $@
|
||||
endif
|
||||
|
||||
ifdef JAVA_OR_OJI
|
||||
$(OBJDIR)/stubs.o: \
|
||||
$(JRI_GEN_DIR)/netscape_javascript_JSObject.c \
|
||||
$(JRI_GEN_DIR)/netscape_javascript_JSException.c \
|
||||
$(NULL)
|
||||
else
|
||||
$(OBJDIR)/stubs.o:
|
||||
endif
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include "jni.h"
|
||||
|
||||
/* Header for class netscape_javascript_JSException */
|
||||
|
||||
#ifndef _Included_netscape_javascript_JSException
|
||||
#define _Included_netscape_javascript_JSException
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
102
mozilla/js/src/liveconnect/_jni/netscape_javascript_JSObject.h
Normal file
102
mozilla/js/src/liveconnect/_jni/netscape_javascript_JSObject.h
Normal file
@@ -0,0 +1,102 @@
|
||||
/* DO NOT EDIT THIS FILE - it is machine generated */
|
||||
#include "jni.h"
|
||||
|
||||
/* Header for class netscape_javascript_JSObject */
|
||||
|
||||
#ifndef _Included_netscape_javascript_JSObject
|
||||
#define _Included_netscape_javascript_JSObject
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: initClass
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_initClass
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getMember
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getMember
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getSlot
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getSlot
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: setMember
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setMember
|
||||
(JNIEnv *, jobject, jstring, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: setSlot
|
||||
* Signature: (ILjava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setSlot
|
||||
(JNIEnv *, jobject, jint, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: removeMember
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_removeMember
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: call
|
||||
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call
|
||||
(JNIEnv *, jobject, jstring, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: eval
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_eval
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: toString
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_netscape_javascript_JSObject_toString
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getWindow
|
||||
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: finalize
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
65
mozilla/js/src/liveconnect/classes/Makefile
Normal file
65
mozilla/js/src/liveconnect/classes/Makefile
Normal file
@@ -0,0 +1,65 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
|
||||
|
||||
DEPTH = ../../../..
|
||||
|
||||
MODULE = java
|
||||
|
||||
#
|
||||
# the idea is that the install phase for those modules will
|
||||
# make their own signed jar files
|
||||
# there are some exceptions here that we deal with
|
||||
# stuff in modules and in ns/js/jsj
|
||||
#
|
||||
JMODS = netscape/javascript netscape/javascript/adapters
|
||||
|
||||
#
|
||||
# JDIRS is dependant on JAVA_DESTPATH in config/rules.m[a]k.
|
||||
# Be sure to touch that directory if you add a new directory to
|
||||
# JDIRS, or else it will not build. FIXME
|
||||
#
|
||||
JDIRS = $(JMODS)
|
||||
|
||||
JAR_JSJ = jsj10.jar
|
||||
JAR_JSJ_CLASSES = $(JMODS)
|
||||
|
||||
#
|
||||
# jars to build at install time
|
||||
#
|
||||
JARS = $(JAR_JSJ)
|
||||
|
||||
include $(DEPTH)/config/rules.mk
|
||||
|
||||
JAVA_SOURCEPATH = $(DEPTH)/js/src/liveconnect/classes
|
||||
|
||||
doc::
|
||||
$(JAVADOC) -d $(DIST)/doc netscape.javascript
|
||||
|
||||
natives_list:: FORCE
|
||||
rm -rf $@
|
||||
find . -name "*.class" -print | sed 's@\./\(.*\)\.class$$@\1@' | \
|
||||
sed 's@/@.@g' | xargs $(JVH) -natives | sort > $@
|
||||
|
||||
check_natives:: natives_list
|
||||
rm -f found_natives
|
||||
nm -B ../$(OBJDIR)/*.o \
|
||||
| egrep "Java.*_stub" | awk '{ print $$3; }' | sort > found_natives
|
||||
diff found_natives natives_list
|
||||
|
||||
FORCE:
|
||||
70
mozilla/js/src/liveconnect/classes/Makefile.in
Normal file
70
mozilla/js/src/liveconnect/classes/Makefile.in
Normal file
@@ -0,0 +1,70 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = java
|
||||
|
||||
#
|
||||
# the idea is that the install phase for those modules will
|
||||
# make their own signed jar files
|
||||
# there are some exceptions here that we deal with
|
||||
# stuff in modules and in ns/js/jsj
|
||||
#
|
||||
JMODS = netscape/javascript netscape/javascript/adapters
|
||||
|
||||
#
|
||||
# JDIRS is dependant on JAVA_DESTPATH in config/rules.m[a]k.
|
||||
# Be sure to touch that directory if you add a new directory to
|
||||
# JDIRS, or else it will not build. FIXME
|
||||
#
|
||||
JDIRS = $(JMODS)
|
||||
|
||||
JAR_JSJ = jsj10.jar
|
||||
JAR_JSJ_CLASSES = $(JMODS)
|
||||
|
||||
#
|
||||
# jars to build at install time
|
||||
#
|
||||
JARS = $(JAR_JSJ)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
JAVA_SOURCEPATH = $(topsrcdir)/js/src/liveconnect/classes
|
||||
|
||||
doc::
|
||||
$(JAVADOC) -d $(DIST)/doc netscape.javascript
|
||||
|
||||
natives_list:: FORCE
|
||||
rm -rf $@
|
||||
find . -name "*.class" -print | sed 's@\./\(.*\)\.class$$@\1@' | \
|
||||
sed 's@/@.@g' | xargs $(JVH) -natives | sort > $@
|
||||
|
||||
check_natives:: natives_list
|
||||
rm -f found_natives
|
||||
nm -B ../$(OBJDIR)/*.o \
|
||||
| egrep "Java.*_stub" | awk '{ print $$3; }' | sort > found_natives
|
||||
diff found_natives natives_list
|
||||
|
||||
FORCE:
|
||||
78
mozilla/js/src/liveconnect/classes/makefile.win
Normal file
78
mozilla/js/src/liveconnect/classes/makefile.win
Normal file
@@ -0,0 +1,78 @@
|
||||
#!gmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
#
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Makefile to build the JavaScript-Java tree
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
DEPTH = ..\..\..\..
|
||||
|
||||
JAVA_SOURCEPATH=$(DEPTH)\js\src\liveconnect\classes
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define the files necessary to build the target (ie. OBJS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
JMOZ = \
|
||||
netscape/javascript \
|
||||
$(NULL)
|
||||
|
||||
|
||||
all::
|
||||
|
||||
MODULE=java
|
||||
JMODS=netscape/javascript
|
||||
!ifdef JAVA_OR_NSJVM
|
||||
JDIRS=$(JMODS)
|
||||
JAR_JSJ_CLASSES=$(JMODS)
|
||||
JAR_NAME = jsj10.jar
|
||||
!endif
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
!ifdef JAVA_OR_NSJVM
|
||||
install::
|
||||
cd $(JAVA_DESTPATH)
|
||||
@echo +++ building/updating $(JAR_NAME)
|
||||
-for %i in ($(JAR_JSJ_CLASSES:/=\)) do @$(ZIP_PROG) $(ZIP_FLAGS) $(JAR_NAME) %i\*.class
|
||||
cd $(MAKEDIR)
|
||||
|
||||
!ifdef REGENERATE
|
||||
install::
|
||||
cd $(JAVA_DESTPATH)
|
||||
@echo +++ updating $(DEPTH)\nav-java\stubs\classes\$(JAR_NAME) for checkin
|
||||
-for %i in ($(JAR_JSJ_CLASSES:/=\)) do @$(ZIP_PROG) $(ZIP_FLAGS) ..\..\nav-java\stubs\classes\$(JAR_NAME) %i\*.class
|
||||
cd $(MAKEDIR)
|
||||
!endif
|
||||
!endif
|
||||
|
||||
javadoc:
|
||||
-mkdir $(XPDIST)\javadoc 2> NUL
|
||||
echo $(JAVADOC) -sourcepath . -d $(XPDIST)\javadoc $(JDIRS:/=.)
|
||||
$(JAVADOC) -sourcepath . -d $(XPDIST)\javadoc $(JDIRS:/=.)
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
/* Insert copyright and license here 19** */
|
||||
|
||||
package netscape.javascript;
|
||||
|
||||
/**
|
||||
* JSException is an exception which is thrown when JavaScript code
|
||||
* returns an error.
|
||||
*/
|
||||
|
||||
public
|
||||
class JSException extends Exception {
|
||||
String filename;
|
||||
int lineno;
|
||||
String source;
|
||||
int tokenIndex;
|
||||
|
||||
/**
|
||||
* Constructs a JSException without a detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
*/
|
||||
public JSException() {
|
||||
super();
|
||||
filename = "unknown";
|
||||
lineno = 0;
|
||||
source = "";
|
||||
tokenIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JSException with a detail message.
|
||||
* A detail message is a String that describes this particular exception.
|
||||
* @param s the detail message
|
||||
*/
|
||||
public JSException(String s) {
|
||||
super(s);
|
||||
filename = "unknown";
|
||||
lineno = 0;
|
||||
source = "";
|
||||
tokenIndex = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a JSException with a detail message and all the
|
||||
* other info that usually comes with a JavaScript error.
|
||||
* @param s the detail message
|
||||
*/
|
||||
public JSException(String s, String filename, int lineno,
|
||||
String source, int tokenIndex) {
|
||||
super(s);
|
||||
this.filename = filename;
|
||||
this.lineno = lineno;
|
||||
this.source = source;
|
||||
this.tokenIndex = tokenIndex;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
|
||||
/* Insert copyright and license here 19** */
|
||||
|
||||
/* more doc todo:
|
||||
* threads
|
||||
* gc
|
||||
*
|
||||
*
|
||||
*/
|
||||
|
||||
package netscape.javascript;
|
||||
|
||||
import java.applet.Applet;
|
||||
|
||||
/**
|
||||
* JSObject allows Java to manipulate objects that are
|
||||
* defined in JavaScript.
|
||||
* Values passed from Java to JavaScript are converted as
|
||||
* follows:<ul>
|
||||
* <li>JSObject is converted to the original JavaScript object
|
||||
* <li>Any other Java object is converted to a JavaScript wrapper,
|
||||
* which can be used to access methods and fields of the java object.
|
||||
* Converting this wrapper to a string will call the toString method
|
||||
* on the original object, converting to a number will call the
|
||||
* floatValue method if possible and fail otherwise. Converting
|
||||
* to a boolean will try to call the booleanValue method in the
|
||||
* same way.
|
||||
* <li>Java arrays are wrapped with a JavaScript object that understands
|
||||
* array.length and array[index]
|
||||
* <li>A Java boolean is converted to a JavaScript boolean
|
||||
* <li>Java byte, char, short, int, long, float, and double are converted
|
||||
* to JavaScript numbers
|
||||
* </ul>
|
||||
* Values passed from JavaScript to Java are converted as follows:<ul>
|
||||
* <li>objects which are wrappers around java objects are unwrapped
|
||||
* <li>other objects are wrapped with a JSObject
|
||||
* <li>strings, numbers and booleans are converted to String, Float,
|
||||
* and Boolean objects respectively
|
||||
* </ul>
|
||||
* This means that all JavaScript values show up as some kind
|
||||
* of java.lang.Object in Java. In order to make much use of them,
|
||||
* you will have to cast them to the appropriate subclass of Object,
|
||||
* e.g. <code>(String) window.getMember("name");</code> or
|
||||
* <code>(JSObject) window.getMember("document");</code>.
|
||||
*/
|
||||
public final class JSObject {
|
||||
/* the internal object data */
|
||||
private int internal;
|
||||
|
||||
/**
|
||||
* initialize
|
||||
*/
|
||||
private static native void initClass();
|
||||
static {
|
||||
// On MRJ, this property won't exist, because the library is preloaded.
|
||||
String liveConnectLibrary = System.getProperty("netscape.jsj.dll", null);
|
||||
if (liveConnectLibrary != null) {
|
||||
System.loadLibrary(liveConnectLibrary);
|
||||
initClass();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* it is illegal to construct a JSObject manually
|
||||
*/
|
||||
private JSObject(int jsobj_addr) {
|
||||
internal = jsobj_addr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a named member of a JavaScript object.
|
||||
* Equivalent to "this.<i>name</i>" in JavaScript.
|
||||
*/
|
||||
public native Object getMember(String name);
|
||||
|
||||
/**
|
||||
* Retrieves an indexed member of a JavaScript object.
|
||||
* Equivalent to "this[<i>index</i>]" in JavaScript.
|
||||
*/
|
||||
// public Object getMember(int index) { return getSlot(index); }
|
||||
public native Object getSlot(int index);
|
||||
|
||||
/**
|
||||
* Sets a named member of a JavaScript object.
|
||||
* Equivalent to "this.<i>name</i> = <i>value</i>" in JavaScript.
|
||||
*/
|
||||
public native void setMember(String name, Object value);
|
||||
|
||||
/**
|
||||
* Sets an indexed member of a JavaScript object.
|
||||
* Equivalent to "this[<i>index</i>] = <i>value</i>" in JavaScript.
|
||||
*/
|
||||
// public void setMember(int index, Object value) {
|
||||
// setSlot(index, value);
|
||||
// }
|
||||
public native void setSlot(int index, Object value);
|
||||
|
||||
/**
|
||||
* Removes a named member of a JavaScript object.
|
||||
*/
|
||||
public native void removeMember(String name);
|
||||
|
||||
/**
|
||||
* Calls a JavaScript method.
|
||||
* Equivalent to "this.<i>methodName</i>(<i>args</i>[0], <i>args</i>[1], ...)" in JavaScript.
|
||||
*/
|
||||
public native Object call(String methodName, Object args[]);
|
||||
|
||||
/**
|
||||
* Evaluates a JavaScript expression. The expression is a string
|
||||
* of JavaScript source code which will be evaluated in the context
|
||||
* given by "this".
|
||||
*/
|
||||
public native Object eval(String s);
|
||||
|
||||
/**
|
||||
* Converts a JSObject to a String.
|
||||
*/
|
||||
public native String toString();
|
||||
|
||||
// should use some sort of identifier rather than String
|
||||
// is "property" the right word?
|
||||
// native String[] listProperties();
|
||||
|
||||
|
||||
/**
|
||||
* get a JSObject for the window containing the given applet
|
||||
*/
|
||||
public static native JSObject getWindow(Applet applet);
|
||||
|
||||
/**
|
||||
* Finalization decrements the reference count on the corresponding
|
||||
* JavaScript object.
|
||||
*/
|
||||
protected native void finalize();
|
||||
|
||||
/**
|
||||
* Override java.lang.Object.equals() because identity is not preserved
|
||||
* with instances of JSObject.
|
||||
*/
|
||||
public boolean equals(Object obj) {
|
||||
JSObject jsobj;
|
||||
|
||||
if (!(obj instanceof JSObject))
|
||||
return false;
|
||||
jsobj = (JSObject)obj;
|
||||
return (internal == jsobj.internal);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/* ** */
|
||||
/**
|
||||
* The JSProxy interface allows applets and plugins to
|
||||
* share javascript contexts.
|
||||
*/
|
||||
|
||||
package netscape.javascript;
|
||||
import java.applet.Applet;
|
||||
|
||||
public interface JSProxy {
|
||||
Object getMember(JSObject jso, String name);
|
||||
Object getSlot(JSObject jso, int index);
|
||||
void setMember(JSObject jso, String name, Object value);
|
||||
void setSlot(JSObject jso, int index, Object value);
|
||||
void removeMember(JSObject jso, String name);
|
||||
Object call(JSObject jso, String methodName, Object args[]);
|
||||
Object eval(JSObject jso, String s);
|
||||
String toString(JSObject jso);
|
||||
JSObject getWindow(Applet applet);
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
package netscape.javascript;
|
||||
|
||||
/**
|
||||
* Runs a JavaScript object with a run() method in a separate thread.
|
||||
*/
|
||||
public class JSRunnable implements Runnable {
|
||||
private JSObject runnable;
|
||||
|
||||
public JSRunnable(JSObject runnable) {
|
||||
this.runnable = runnable;
|
||||
synchronized(this) {
|
||||
new Thread(this).start();
|
||||
try {
|
||||
this.wait();
|
||||
} catch (InterruptedException ie) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
try {
|
||||
runnable.call("run", null);
|
||||
synchronized(this) {
|
||||
notifyAll();
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
System.err.println(t);
|
||||
t.printStackTrace(System.err);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/* ** */
|
||||
|
||||
package netscape.javascript;
|
||||
import java.io.*;
|
||||
|
||||
public class JSUtil {
|
||||
|
||||
/* Return the stack trace of an exception or error as a String */
|
||||
public static String getStackTrace(Throwable t) {
|
||||
ByteArrayOutputStream captureStream;
|
||||
PrintStream p;
|
||||
|
||||
captureStream = new ByteArrayOutputStream();
|
||||
p = new PrintStream(captureStream);
|
||||
|
||||
t.printStackTrace(p);
|
||||
p.flush();
|
||||
|
||||
return captureStream.toString();
|
||||
}
|
||||
}
|
||||
876
mozilla/js/src/liveconnect/jsj.c
Normal file
876
mozilla/js/src/liveconnect/jsj.c
Normal file
@@ -0,0 +1,876 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the top-level initialization code and the implementation of the
|
||||
* public API.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jsjava.h" /* LiveConnect external API */
|
||||
|
||||
/*
|
||||
* At certain times during initialization, there may be no JavaScript context
|
||||
* available to direct error reports to, in which case the error messages
|
||||
* are sent to this function. The caller is responsible for free'ing
|
||||
* the js_error_msg argument.
|
||||
*/
|
||||
static void
|
||||
report_java_initialization_error(JNIEnv *jEnv, const char *js_error_msg)
|
||||
{
|
||||
const char *error_msg, *java_error_msg;
|
||||
|
||||
java_error_msg = NULL;
|
||||
#if 0 /* This can never work here, because jsj_GetJavaErrorMessage relies on
|
||||
jlThrowable_toString which is set up by the initialization that calls
|
||||
this function. */
|
||||
if (jEnv) {
|
||||
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
}
|
||||
#endif
|
||||
if (java_error_msg) {
|
||||
error_msg = PR_smprintf("initialization error: %s (%s)\n",
|
||||
js_error_msg, java_error_msg);
|
||||
free((void*)java_error_msg);
|
||||
} else {
|
||||
error_msg = PR_smprintf("initialization error: %s\n",
|
||||
js_error_msg);
|
||||
}
|
||||
|
||||
jsj_LogError(error_msg);
|
||||
}
|
||||
|
||||
/*
|
||||
* Opaque JVM handles to Java classes and methods required for Java reflection.
|
||||
* These are computed and cached during initialization.
|
||||
*/
|
||||
|
||||
jclass jlObject; /* java.lang.Object */
|
||||
jclass jlrMethod; /* java.lang.reflect.Method */
|
||||
jclass jlrField; /* java.lang.reflect.Field */
|
||||
jclass jlVoid; /* java.lang.Void */
|
||||
jclass jlrConstructor; /* java.lang.reflect.Constructor */
|
||||
jclass jlThrowable; /* java.lang.Throwable */
|
||||
jclass jlSystem; /* java.lang.System */
|
||||
jclass jlClass; /* java.lang.Class */
|
||||
jclass jlBoolean; /* java.lang.Boolean */
|
||||
jclass jlDouble; /* java.lang.Double */
|
||||
jclass jlString; /* java.lang.String */
|
||||
jclass njJSObject; /* netscape.javascript.JSObject */
|
||||
jclass njJSException; /* netscape.javascript.JSException */
|
||||
jclass njJSUtil; /* netscape.javascript.JSUtil */
|
||||
|
||||
jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */
|
||||
jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */
|
||||
jmethodID jlClass_getFields; /* java.lang.Class.getFields() */
|
||||
jmethodID jlClass_getName; /* java.lang.Class.getName() */
|
||||
jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */
|
||||
jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */
|
||||
jmethodID jlClass_isArray; /* java.lang.Class.isArray() */
|
||||
|
||||
jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */
|
||||
jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */
|
||||
jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */
|
||||
jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */
|
||||
|
||||
jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
|
||||
jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */
|
||||
|
||||
jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
|
||||
jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
|
||||
jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
|
||||
|
||||
jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
|
||||
jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
|
||||
jmethodID jlDouble_Double; /* java.lang.Double constructor */
|
||||
jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */
|
||||
|
||||
jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */
|
||||
jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
|
||||
|
||||
jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */
|
||||
|
||||
jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
|
||||
|
||||
jmethodID njJSException_JSException; /* netscape.javascript.JSexception constructor */
|
||||
jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
|
||||
jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
|
||||
jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
|
||||
jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
|
||||
jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
|
||||
jfieldID njJSException_source; /* netscape.javascript.JSException.source */
|
||||
jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
|
||||
|
||||
/* Obtain a reference to a Java class */
|
||||
#define LOAD_CLASS(qualified_name, class) \
|
||||
{ \
|
||||
jclass _##class = (*jEnv)->FindClass(jEnv, #qualified_name); \
|
||||
if (_##class == 0) { \
|
||||
(*jEnv)->ExceptionClear(jEnv); \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't load class " #qualified_name); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
class = (*jEnv)->NewGlobalRef(jEnv, _##class); \
|
||||
}
|
||||
|
||||
/* Obtain a methodID reference to a Java method or constructor */
|
||||
#define _LOAD_METHOD(qualified_class, method, mvar, signature, class, is_static)\
|
||||
if (is_static) { \
|
||||
class##_##mvar = \
|
||||
(*jEnv)->GetStaticMethodID(jEnv, class, #method, signature); \
|
||||
} else { \
|
||||
class##_##mvar = \
|
||||
(*jEnv)->GetMethodID(jEnv, class, #method, signature); \
|
||||
} \
|
||||
if (class##_##mvar == 0) { \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't get mid for " #qualified_class "." #method "()"); \
|
||||
return JS_FALSE; \
|
||||
}
|
||||
|
||||
/* Obtain a methodID reference to a Java instance method */
|
||||
#define LOAD_METHOD(qualified_class, method, signature, class) \
|
||||
_LOAD_METHOD(qualified_class, method, method, signature, class, JS_FALSE)
|
||||
|
||||
/* Obtain a methodID reference to a Java static method */
|
||||
#define LOAD_STATIC_METHOD(qualified_class, method, signature, class) \
|
||||
_LOAD_METHOD(qualified_class, method, method, signature, class, JS_TRUE)
|
||||
|
||||
/* Obtain a methodID reference to a Java constructor */
|
||||
#define LOAD_CONSTRUCTOR(qualified_class, method, signature, class) \
|
||||
_LOAD_METHOD(qualified_class,<init>, method, signature, class, JS_FALSE)
|
||||
|
||||
/* Obtain a fieldID reference to a Java instance or static field */
|
||||
#define _LOAD_FIELDID(qualified_class, field, signature, class, is_static) \
|
||||
if (is_static) { \
|
||||
class##_##field = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
|
||||
} else { \
|
||||
class##_##field = (*jEnv)->GetFieldID(jEnv, class, #field, signature);\
|
||||
} \
|
||||
if (class##_##field == 0) { \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't get fid for " #qualified_class "." #field); \
|
||||
return JS_FALSE; \
|
||||
}
|
||||
|
||||
/* Obtain a fieldID reference to a Java instance field */
|
||||
#define LOAD_FIELDID(qualified_class, field, signature, class) \
|
||||
_LOAD_FIELDID(qualified_class, field, signature, class, JS_FALSE)
|
||||
|
||||
/* Obtain the value of a static field in a Java class */
|
||||
#define LOAD_FIELD_VAL(qualified_class, field, signature, class, type) \
|
||||
{ \
|
||||
jfieldID field_id; \
|
||||
field_id = (*jEnv)->GetStaticFieldID(jEnv, class, #field, signature);\
|
||||
if (field_id == 0) { \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't get fid for " #qualified_class "." #field); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
class##_##field = \
|
||||
(*jEnv)->GetStatic##type##Field(jEnv, class, field_id); \
|
||||
if (class##_##field == 0) { \
|
||||
report_java_initialization_error(jEnv, \
|
||||
"Can't read static field " #qualified_class "." #field); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Obtain the value of a static field in a Java class, which is known to
|
||||
contain an object value. */
|
||||
#define LOAD_FIELD_OBJ(qualified_class, field, signature, class) \
|
||||
LOAD_FIELD_VAL(qualified_class, field, signature, class, Object); \
|
||||
class##_##field = (*jEnv)->NewGlobalRef(jEnv, class##_##field);
|
||||
|
||||
/*
|
||||
* Load the Java classes, and the method and field descriptors required for Java reflection.
|
||||
* Returns JS_TRUE on success, JS_FALSE on failure.
|
||||
*/
|
||||
static JSBool
|
||||
init_java_VM_reflection(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
|
||||
{
|
||||
/* Load Java system classes and method, including java.lang.reflect classes */
|
||||
LOAD_CLASS(java/lang/Object, jlObject);
|
||||
LOAD_CLASS(java/lang/Class, jlClass);
|
||||
LOAD_CLASS(java/lang/reflect/Method, jlrMethod);
|
||||
LOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
|
||||
LOAD_CLASS(java/lang/reflect/Field, jlrField);
|
||||
LOAD_CLASS(java/lang/Throwable, jlThrowable);
|
||||
LOAD_CLASS(java/lang/System, jlSystem);
|
||||
LOAD_CLASS(java/lang/Boolean, jlBoolean);
|
||||
LOAD_CLASS(java/lang/Double, jlDouble);
|
||||
LOAD_CLASS(java/lang/String, jlString);
|
||||
LOAD_CLASS(java/lang/Void, jlVoid);
|
||||
|
||||
LOAD_METHOD(java.lang.Class, getMethods, "()[Ljava/lang/reflect/Method;",jlClass);
|
||||
LOAD_METHOD(java.lang.Class, getConstructors, "()[Ljava/lang/reflect/Constructor;",jlClass);
|
||||
LOAD_METHOD(java.lang.Class, getFields, "()[Ljava/lang/reflect/Field;", jlClass);
|
||||
LOAD_METHOD(java.lang.Class, getName, "()Ljava/lang/String;", jlClass);
|
||||
LOAD_METHOD(java.lang.Class, isArray, "()Z", jlClass);
|
||||
LOAD_METHOD(java.lang.Class, getComponentType, "()Ljava/lang/Class;", jlClass);
|
||||
LOAD_METHOD(java.lang.Class, getModifiers, "()I", jlClass);
|
||||
|
||||
LOAD_METHOD(java.lang.reflect.Method, getName, "()Ljava/lang/String;", jlrMethod);
|
||||
LOAD_METHOD(java.lang.reflect.Method, getParameterTypes, "()[Ljava/lang/Class;", jlrMethod);
|
||||
LOAD_METHOD(java.lang.reflect.Method, getReturnType, "()Ljava/lang/Class;", jlrMethod);
|
||||
LOAD_METHOD(java.lang.reflect.Method, getModifiers, "()I", jlrMethod);
|
||||
|
||||
LOAD_METHOD(java.lang.reflect.Constructor, getParameterTypes, "()[Ljava/lang/Class;", jlrConstructor);
|
||||
LOAD_METHOD(java.lang.reflect.Constructor, getModifiers, "()I", jlrConstructor);
|
||||
|
||||
LOAD_METHOD(java.lang.reflect.Field, getName, "()Ljava/lang/String;", jlrField);
|
||||
LOAD_METHOD(java.lang.reflect.Field, getType, "()Ljava/lang/Class;", jlrField);
|
||||
LOAD_METHOD(java.lang.reflect.Field, getModifiers, "()I", jlrField);
|
||||
|
||||
LOAD_METHOD(java.lang.Throwable, toString, "()Ljava/lang/String;", jlThrowable);
|
||||
LOAD_METHOD(java.lang.Throwable, getMessage, "()Ljava/lang/String;", jlThrowable);
|
||||
|
||||
LOAD_METHOD(java.lang.Double, doubleValue, "()D", jlDouble);
|
||||
|
||||
LOAD_METHOD(java.lang.Boolean, booleanValue, "()Z", jlBoolean);
|
||||
|
||||
LOAD_STATIC_METHOD(java.lang.System, identityHashCode, "(Ljava/lang/Object;)I", jlSystem);
|
||||
|
||||
LOAD_CONSTRUCTOR(java.lang.Boolean, Boolean, "(Z)V", jlBoolean);
|
||||
LOAD_CONSTRUCTOR(java.lang.Double, Double, "(D)V", jlDouble);
|
||||
|
||||
LOAD_FIELD_OBJ(java.lang.Void, TYPE, "Ljava/lang/Class;", jlVoid);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#if XP_MAC
|
||||
|
||||
/**
|
||||
* Workaround for the fact that MRJ loads a different instance of the shared library.
|
||||
*/
|
||||
|
||||
#include "netscape_javascript_JSObject.h"
|
||||
|
||||
static JSObject_RegisterNativeMethods(JNIEnv* jEnv)
|
||||
{
|
||||
// Manually load the required native methods.
|
||||
static JNINativeMethod nativeMethods[] = {
|
||||
"initClass", "()V", (void*)&Java_netscape_javascript_JSObject_initClass,
|
||||
"getMember", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getMember,
|
||||
"getSlot", "(I)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_getSlot,
|
||||
"setMember", "(Ljava/lang/String;Ljava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setMember,
|
||||
"setSlot", "(ILjava/lang/Object;)V", (void*)&Java_netscape_javascript_JSObject_setSlot,
|
||||
"removeMember", "(Ljava/lang/String;)V", (void*)&Java_netscape_javascript_JSObject_removeMember,
|
||||
"call", "(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_call,
|
||||
"eval", "(Ljava/lang/String;)Ljava/lang/Object;", (void*)&Java_netscape_javascript_JSObject_eval,
|
||||
|
||||
"toString", "()Ljava/lang/String;", (void*)&Java_netscape_javascript_JSObject_toString,
|
||||
"getWindow", "(Ljava/applet/Applet;)Lnetscape/javascript/JSObject;", (void*)&Java_netscape_javascript_JSObject_getWindow,
|
||||
"finalize", "()V", (void*)&Java_netscape_javascript_JSObject_finalize,
|
||||
/* "equals", "(Ljava/lang/Object;)Z", (void*)&Java_netscape_javascript_JSObject_equals */
|
||||
};
|
||||
(*jEnv)->RegisterNatives(jEnv, njJSObject, nativeMethods, sizeof(nativeMethods) / sizeof(JNINativeMethod));
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
report_java_initialization_error(jEnv, "Couldn't initialize JSObject native methods.");
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
}
|
||||
/* call the initClass method, since we nailed the static initializer for testing. */
|
||||
Java_netscape_javascript_JSObject_initClass(jEnv, njJSObject);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* Load Netscape-specific Java extension classes, methods, and fields */
|
||||
static JSBool
|
||||
init_netscape_java_classes(JSJavaVM *jsjava_vm, JNIEnv *jEnv)
|
||||
{
|
||||
LOAD_CLASS(netscape/javascript/JSObject, njJSObject);
|
||||
LOAD_CLASS(netscape/javascript/JSException, njJSException);
|
||||
LOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
|
||||
|
||||
#if XP_MAC
|
||||
JSObject_RegisterNativeMethods(jEnv);
|
||||
#endif
|
||||
|
||||
LOAD_CONSTRUCTOR(netscape.javascript.JSObject,
|
||||
JSObject, "(I)V", njJSObject);
|
||||
LOAD_CONSTRUCTOR(netscape.javascript.JSException,
|
||||
JSException, "(Ljava/lang/String;Ljava/lang/String;ILjava/lang/String;I)V",
|
||||
njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSObject,
|
||||
internal, "I", njJSObject);
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
lineno, "I", njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
tokenIndex, "I", njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
source, "Ljava/lang/String;", njJSException);
|
||||
LOAD_FIELDID(netscape.javascript.JSException,
|
||||
filename, "Ljava/lang/String;", njJSException);
|
||||
|
||||
LOAD_STATIC_METHOD(netscape.javascript.JSUtil,
|
||||
getStackTrace, "(Ljava/lang/Throwable;)Ljava/lang/String;",
|
||||
njJSUtil);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSJavaVM *jsjava_vm_list = NULL;
|
||||
|
||||
/*
|
||||
* Called once per Java VM, this function initializes the classes, fields, and
|
||||
* methods required for Java reflection. If java_vm is NULL, a new Java VM is
|
||||
* created, using the provided classpath in addition to any default classpath.
|
||||
* The classpath argument is ignored, however, if java_vm_arg is non-NULL.
|
||||
*/
|
||||
JSJavaVM *
|
||||
JSJ_ConnectToJavaVM(SystemJavaVM *java_vm_arg, void* initargs)
|
||||
{
|
||||
SystemJavaVM* java_vm;
|
||||
JSJavaVM *jsjava_vm;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
PR_ASSERT(JSJ_callbacks);
|
||||
PR_ASSERT(JSJ_callbacks->attach_current_thread);
|
||||
PR_ASSERT(JSJ_callbacks->detach_current_thread);
|
||||
PR_ASSERT(JSJ_callbacks->get_java_vm);
|
||||
|
||||
jsjava_vm = (JSJavaVM*)malloc(sizeof(JSJavaVM));
|
||||
if (!jsjava_vm)
|
||||
return NULL;
|
||||
memset(jsjava_vm, 0, sizeof(JSJavaVM));
|
||||
|
||||
java_vm = java_vm_arg;
|
||||
|
||||
/* If a Java VM was passed in, try to attach to it on the current thread. */
|
||||
if (java_vm) {
|
||||
jEnv = JSJ_callbacks->attach_current_thread(java_vm);
|
||||
if (jEnv == NULL) {
|
||||
jsj_LogError("Failed to attach to Java VM thread\n");
|
||||
free(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else {
|
||||
PRBool ok;
|
||||
PR_ASSERT(JSJ_callbacks->create_java_vm);
|
||||
PR_ASSERT(JSJ_callbacks->destroy_java_vm);
|
||||
|
||||
ok = JSJ_callbacks->create_java_vm(&java_vm, &jEnv, initargs);
|
||||
if (!ok || java_vm == NULL) {
|
||||
jsj_LogError("Failed to create Java VM\n");
|
||||
free(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Remember that we created the VM so that we know to destroy it later */
|
||||
jsjava_vm->jsj_created_java_vm = JS_TRUE;
|
||||
}
|
||||
|
||||
jsjava_vm->java_vm = java_vm;
|
||||
jsjava_vm->main_thread_env = jEnv;
|
||||
|
||||
/* Load the Java classes, and the method and field descriptors required for
|
||||
Java reflection. */
|
||||
if (!init_java_VM_reflection(jsjava_vm, jEnv)) {
|
||||
JSJ_DisconnectFromJavaVM(jsjava_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* JVM initialization for netscape.javascript.JSObject is performed
|
||||
* independently of the other classes that are initialized in
|
||||
* init_java_VM_reflection, because we allow it to fail. In the case
|
||||
* of failure, LiveConnect is still operative, but only when calling
|
||||
* from JS to Java and not vice-versa.
|
||||
*/
|
||||
init_netscape_java_classes(jsjava_vm, jEnv);
|
||||
|
||||
/* Put this VM on the list of all created VMs */
|
||||
jsjava_vm->next = jsjava_vm_list;
|
||||
jsjava_vm_list = jsjava_vm;
|
||||
|
||||
return jsjava_vm;
|
||||
}
|
||||
|
||||
JSJCallbacks *JSJ_callbacks = NULL;
|
||||
|
||||
/* Called once to set up callbacks for all instances of LiveConnect */
|
||||
void
|
||||
JSJ_Init(JSJCallbacks *callbacks)
|
||||
{
|
||||
PR_ASSERT(callbacks);
|
||||
JSJ_callbacks = callbacks;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize the provided JSContext by setting up the JS classes necessary for
|
||||
* reflection and by defining JavaPackage objects for the default Java packages
|
||||
* as properties of global_obj. Additional packages may be pre-defined by
|
||||
* setting the predefined_packages argument. (Pre-defining a Java package at
|
||||
* initialization time is not necessary, but it will make package lookup faster
|
||||
* and, more importantly, will avoid unnecessary network accesses if classes
|
||||
* are being loaded over the network.)
|
||||
*/
|
||||
JSBool
|
||||
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
|
||||
JavaPackageDef *predefined_packages)
|
||||
{
|
||||
/* Initialize the JavaScript classes used for reflection */
|
||||
if (!jsj_init_JavaObject(cx, global_obj))
|
||||
return JS_FALSE;
|
||||
|
||||
/* if (!jsj_init_JavaMember(cx, global_obj))
|
||||
return JS_FALSE; */
|
||||
|
||||
if (!jsj_init_JavaPackage(cx, global_obj, predefined_packages))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!jsj_init_JavaClass(cx, global_obj))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!jsj_init_JavaArray(cx, global_obj))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!jsj_init_JavaMember(cx, global_obj))
|
||||
return JS_FALSE;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Eliminate a reference to a Java class */
|
||||
#define UNLOAD_CLASS(qualified_name, class) \
|
||||
if (class) { \
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, class); \
|
||||
class = NULL; \
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine severs the connection to a Java VM, freeing all related resources.
|
||||
* It shouldn't be called until the global scope has been cleared in all related
|
||||
* JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
|
||||
* GC is performed. Otherwise, accessed to free'ed memory could result.
|
||||
*/
|
||||
void
|
||||
JSJ_DisconnectFromJavaVM(JSJavaVM *jsjava_vm)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
SystemJavaVM *java_vm;
|
||||
JSJavaVM *j, **jp;
|
||||
|
||||
java_vm = jsjava_vm->java_vm;
|
||||
jEnv = jsjava_vm->main_thread_env;
|
||||
|
||||
/* Drop all references to Java objects and classes */
|
||||
jsj_DiscardJavaObjReflections(jEnv);
|
||||
jsj_DiscardJavaClassReflections(jEnv);
|
||||
|
||||
if (jsjava_vm->jsj_created_java_vm) {
|
||||
(void)JSJ_callbacks->destroy_java_vm(java_vm, jEnv);
|
||||
} else {
|
||||
UNLOAD_CLASS(java/lang/Object, jlObject);
|
||||
UNLOAD_CLASS(java/lang/Class, jlClass);
|
||||
UNLOAD_CLASS(java/lang/reflect/Method, jlrMethod);
|
||||
UNLOAD_CLASS(java/lang/reflect/Constructor, jlrConstructor);
|
||||
UNLOAD_CLASS(java/lang/reflect/Field, jlrField);
|
||||
UNLOAD_CLASS(java/lang/Throwable, jlThrowable);
|
||||
UNLOAD_CLASS(java/lang/System, jlSystem);
|
||||
UNLOAD_CLASS(java/lang/Boolean, jlBoolean);
|
||||
UNLOAD_CLASS(java/lang/Double, jlDouble);
|
||||
UNLOAD_CLASS(java/lang/String, jlString);
|
||||
UNLOAD_CLASS(java/lang/Void, jlVoid);
|
||||
UNLOAD_CLASS(netscape/javascript/JSObject, njJSObject);
|
||||
UNLOAD_CLASS(netscape/javascript/JSException, njJSException);
|
||||
UNLOAD_CLASS(netscape/javascript/JSUtil, njJSUtil);
|
||||
}
|
||||
|
||||
|
||||
/* Remove this VM from the list of all JSJavaVM objects. */
|
||||
for (jp = &jsjava_vm_list; (j = *jp) != NULL; jp = &j->next) {
|
||||
if (j == jsjava_vm) {
|
||||
*jp = jsjava_vm->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
PR_ASSERT(j);
|
||||
|
||||
free(jsjava_vm);
|
||||
}
|
||||
|
||||
static JSJavaThreadState *thread_list = NULL;
|
||||
|
||||
static JSJavaThreadState *
|
||||
new_jsjava_thread_state(JSJavaVM *jsjava_vm, const char *thread_name, JNIEnv *jEnv)
|
||||
{
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
jsj_env = (JSJavaThreadState *)malloc(sizeof(JSJavaThreadState));
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
memset(jsj_env, 0, sizeof(JSJavaThreadState));
|
||||
|
||||
jsj_env->jEnv = jEnv;
|
||||
jsj_env->jsjava_vm = jsjava_vm;
|
||||
if (thread_name)
|
||||
jsj_env->name = strdup(thread_name);
|
||||
|
||||
/* THREADSAFETY - need to protect against races */
|
||||
jsj_env->next = thread_list;
|
||||
thread_list = jsj_env;
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
static JSJavaThreadState *
|
||||
find_jsjava_thread(JNIEnv *jEnv)
|
||||
{
|
||||
JSJavaThreadState *e, **p, *jsj_env;
|
||||
jsj_env = NULL;
|
||||
|
||||
/* THREADSAFETY - need to protect against races in manipulating the thread list */
|
||||
|
||||
/* Search for the thread state among the list of all created
|
||||
LiveConnect threads */
|
||||
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
|
||||
if (e->jEnv == jEnv) {
|
||||
jsj_env = e;
|
||||
*p = jsj_env->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Move a found thread to head of list for faster search next time. */
|
||||
if (jsj_env)
|
||||
thread_list = jsj_env;
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJavaThreadState *)
|
||||
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *name, JNIEnv **java_envp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
SystemJavaVM *java_vm;
|
||||
JSJavaThreadState *jsj_env;
|
||||
|
||||
/* Try to attach a Java thread to the current native thread */
|
||||
java_vm = jsjava_vm->java_vm;
|
||||
jEnv = JSJ_callbacks->attach_current_thread(java_vm);
|
||||
if (jEnv == NULL)
|
||||
return NULL;
|
||||
|
||||
/* If we found an existing thread state, just return it. */
|
||||
jsj_env = find_jsjava_thread(jEnv);
|
||||
if (jsj_env)
|
||||
return jsj_env;
|
||||
|
||||
/* Create a new wrapper around the thread/VM state */
|
||||
jsj_env = new_jsjava_thread_state(jsjava_vm, name, jEnv);
|
||||
|
||||
if (java_envp)
|
||||
*java_envp = jEnv;
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
static JSJavaVM *
|
||||
map_java_vm_to_jsjava_vm(SystemJavaVM *java_vm)
|
||||
{
|
||||
JSJavaVM *v;
|
||||
for (v = jsjava_vm_list; v; v = v->next) {
|
||||
if (v->java_vm == java_vm)
|
||||
return v;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Unfortunately, there's no standard means to associate any private data with
|
||||
* a JNI thread environment, so we need to use the Java environment pointer as
|
||||
* the key in a lookup table that maps it to a JSJavaThreadState structure,
|
||||
* where we store all our per-thread private data. If no existing thread state
|
||||
* is found, a new one is created.
|
||||
*
|
||||
* If an error occurs, returns NULL and sets the errp argument to an error
|
||||
* message, which the caller is responsible for free'ing.
|
||||
*/
|
||||
JSJavaThreadState *
|
||||
jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp)
|
||||
{
|
||||
JSJavaThreadState *jsj_env;
|
||||
SystemJavaVM *java_vm;
|
||||
JSJavaVM *jsjava_vm;
|
||||
|
||||
/* If we found an existing thread state, just return it. */
|
||||
jsj_env = find_jsjava_thread(jEnv);
|
||||
if (jsj_env)
|
||||
return jsj_env;
|
||||
|
||||
/* No one set up a LiveConnect thread state for a given Java thread.
|
||||
Invoke the callback to create one on-the-fly. */
|
||||
|
||||
/* First, figure out which Java VM is calling us */
|
||||
java_vm = JSJ_callbacks->get_java_vm(jEnv);
|
||||
if (jsjava_vm == NULL)
|
||||
return NULL;
|
||||
|
||||
/* Get our private JavaVM data */
|
||||
jsjava_vm = map_java_vm_to_jsjava_vm(java_vm);
|
||||
if (!jsjava_vm) {
|
||||
*errp = PR_smprintf("Total weirdness: No JSJavaVM wrapper ever created "
|
||||
"for JavaVM 0x%08x", java_vm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
jsj_env = new_jsjava_thread_state(jsjava_vm, NULL, jEnv);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is used to specify a particular JSContext as *the* JavaScript
|
||||
* execution environment to be used when LiveConnect is accessed from the given
|
||||
* Java thread, i.e. by using one of the methods of netscape.javascript.JSObject.
|
||||
* (There can only be one such JS context for a given Java thread. To
|
||||
* multiplex JSContexts among a single thread, this function must be called
|
||||
* before Java is invoked on that thread.) The return value is the previous
|
||||
* context associated with the given Java thread.
|
||||
*/
|
||||
PR_IMPLEMENT(JSContext *)
|
||||
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env)
|
||||
{
|
||||
JSContext *old_context;
|
||||
old_context = jsj_env->cx;
|
||||
jsj_env->cx = cx;
|
||||
return old_context;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env)
|
||||
{
|
||||
SystemJavaVM *java_vm;
|
||||
JNIEnv* jEnv;
|
||||
JSJavaThreadState *e, **p;
|
||||
|
||||
/* Disassociate the current native thread from its corresponding Java thread */
|
||||
java_vm = jsj_env->jsjava_vm->java_vm;
|
||||
jEnv = jsj_env->jEnv;
|
||||
if (!JSJ_callbacks->detach_current_thread(java_vm, jEnv))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Destroy the LiveConnect execution environment passed in */
|
||||
jsj_ClearPendingJSErrors(jsj_env);
|
||||
|
||||
/* THREADSAFETY - need to protect against races */
|
||||
for (p = &thread_list; (e = *p) != NULL; p = &(e->next)) {
|
||||
if (e == jsj_env) {
|
||||
*p = jsj_env->next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
free(jsj_env);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool
|
||||
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, vp);
|
||||
}
|
||||
|
||||
/*===========================================================================*/
|
||||
|
||||
#ifndef MOZILLA_CLIENT
|
||||
|
||||
/* The convenience functions below present a complete, but simplified
|
||||
LiveConnect API which is designed to handle the special case of a single
|
||||
Java-VM, single-threaded operation, and use of only one JSContext. */
|
||||
|
||||
/* We can get away with global variables in our single-threaded,
|
||||
single-JSContext case. */
|
||||
static JSJavaVM * the_jsj_vm = NULL;
|
||||
static JSContext * the_cx = NULL;
|
||||
static JSJavaThreadState * the_jsj_thread = NULL;
|
||||
static JSObject * the_global_js_obj = NULL;
|
||||
|
||||
/* Trivial implementation of callback function */
|
||||
static JSJavaThreadState *
|
||||
default_map_js_context_to_jsj_thread(JSContext *cx, char **errp)
|
||||
{
|
||||
return the_jsj_thread;
|
||||
}
|
||||
|
||||
/* Trivial implementation of callback function */
|
||||
static JSContext *
|
||||
default_map_jsj_thread_to_js_context(JSJavaThreadState *jsj_env, JNIEnv *jEnv, char **errp)
|
||||
{
|
||||
return the_cx;
|
||||
}
|
||||
|
||||
/* Trivial implementation of callback function */
|
||||
static JSObject *
|
||||
default_map_java_object_to_js_object(JNIEnv *jEnv, jobject hint, char **errp)
|
||||
{
|
||||
return the_global_js_obj;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
default_create_java_vm(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs)
|
||||
{
|
||||
jint err;
|
||||
const char* user_classpath = (const char*)initargs;
|
||||
|
||||
/* No Java VM supplied, so create our own */
|
||||
JDK1_1InitArgs vm_args;
|
||||
|
||||
/* Magic constant indicates JRE version 1.1 */
|
||||
vm_args.version = 0x00010001;
|
||||
JNI_GetDefaultJavaVMInitArgs(&vm_args);
|
||||
|
||||
/* Prepend the classpath argument to the default JVM classpath */
|
||||
if (user_classpath) {
|
||||
#ifdef XP_UNIX
|
||||
const char *full_classpath = PR_smprintf("%s:%s", user_classpath, vm_args.classpath);
|
||||
#else
|
||||
const char *full_classpath = PR_smprintf("%s;%s", user_classpath, vm_args.classpath);
|
||||
#endif
|
||||
if (!full_classpath) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
vm_args.classpath = (char*)full_classpath;
|
||||
}
|
||||
|
||||
err = JNI_CreateJavaVM((JavaVM**)jvm, initialEnv, &vm_args);
|
||||
return err == 0;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
default_destroy_java_vm(SystemJavaVM* jvm, JNIEnv* initialEnv)
|
||||
{
|
||||
JavaVM* java_vm = (JavaVM*)jvm;
|
||||
jint err = (*java_vm)->DestroyJavaVM(java_vm);
|
||||
return err == 0;
|
||||
}
|
||||
|
||||
static JNIEnv* PR_CALLBACK
|
||||
default_attach_current_thread(SystemJavaVM* jvm)
|
||||
{
|
||||
JavaVM* java_vm = (JavaVM*)jvm;
|
||||
JNIEnv* env = NULL;
|
||||
jint err = (*java_vm)->AttachCurrentThread(java_vm, &env, NULL);
|
||||
return env;
|
||||
}
|
||||
|
||||
static PRBool PR_CALLBACK
|
||||
default_detach_current_thread(SystemJavaVM* jvm, JNIEnv* env)
|
||||
{
|
||||
JavaVM* java_vm = (JavaVM*)jvm;
|
||||
/* assert that env is the JNIEnv of the current thread */
|
||||
jint err = (*java_vm)->DetachCurrentThread(java_vm);
|
||||
return err == 0;
|
||||
}
|
||||
|
||||
static SystemJavaVM* PR_CALLBACK
|
||||
default_get_java_vm(JNIEnv* env)
|
||||
{
|
||||
JavaVM* java_vm = NULL;
|
||||
jint err = (*env)->GetJavaVM(env, &java_vm);
|
||||
return (SystemJavaVM*)java_vm;
|
||||
}
|
||||
|
||||
/* Trivial implementations of callback functions */
|
||||
JSJCallbacks jsj_default_callbacks = {
|
||||
default_map_jsj_thread_to_js_context,
|
||||
default_map_js_context_to_jsj_thread,
|
||||
default_map_java_object_to_js_object,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
default_create_java_vm,
|
||||
default_destroy_java_vm,
|
||||
default_attach_current_thread,
|
||||
default_detach_current_thread,
|
||||
default_get_java_vm
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize the provided JSContext by setting up the JS classes necessary for
|
||||
* reflection and by defining JavaPackage objects for the default Java packages
|
||||
* as properties of global_obj. If java_vm is NULL, a new Java VM is
|
||||
* created, using the provided classpath in addition to any default classpath.
|
||||
* The classpath argument is ignored, however, if java_vm is non-NULL.
|
||||
*/
|
||||
JSBool
|
||||
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj, SystemJavaVM *java_vm, const char *classpath)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
||||
PR_ASSERT(!the_jsj_vm);
|
||||
the_jsj_vm = JSJ_ConnectToJavaVM(java_vm, (void*)classpath);
|
||||
if (!the_jsj_vm)
|
||||
return JS_FALSE;
|
||||
|
||||
JSJ_Init(&jsj_default_callbacks);
|
||||
|
||||
if (!JSJ_InitJSContext(cx, global_obj, NULL))
|
||||
goto error;
|
||||
the_cx = cx;
|
||||
the_global_js_obj = global_obj;
|
||||
|
||||
the_jsj_thread = JSJ_AttachCurrentThreadToJava(the_jsj_vm, "main thread", &jEnv);
|
||||
if (!the_jsj_thread)
|
||||
goto error;
|
||||
JSJ_SetDefaultJSContextForJavaThread(cx, the_jsj_thread);
|
||||
return JS_TRUE;
|
||||
|
||||
error:
|
||||
JSJ_SimpleShutdown();
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up all LiveConnect resources. Destroy the Java VM if it was
|
||||
* created by LiveConnect.
|
||||
*/
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_SimpleShutdown()
|
||||
{
|
||||
PR_ASSERT(the_jsj_vm);
|
||||
JSJ_DisconnectFromJavaVM(the_jsj_vm);
|
||||
the_jsj_vm = NULL;
|
||||
the_cx = NULL;
|
||||
the_global_js_obj = NULL;
|
||||
the_jsj_thread = NULL;
|
||||
}
|
||||
|
||||
#endif /* MOZILLA_CLIENT */
|
||||
76
mozilla/js/src/liveconnect/jsj1640.rc
Normal file
76
mozilla/js/src/liveconnect/jsj1640.rc
Normal file
@@ -0,0 +1,76 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
// Version stamp for this .DLL
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#include <ver.h>
|
||||
|
||||
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
|
||||
FILEVERSION 4 // major, minor, release (alpha 1), build #
|
||||
|
||||
PRODUCTVERSION 4
|
||||
|
||||
FILEFLAGSMASK 0
|
||||
|
||||
FILEFLAGS 0 // final version
|
||||
|
||||
FILEOS VOS_DOS_WINDOWS16
|
||||
|
||||
FILETYPE VFT_DLL
|
||||
|
||||
FILESUBTYPE 0 // not used
|
||||
|
||||
BEGIN
|
||||
|
||||
BLOCK "StringFileInfo"
|
||||
|
||||
BEGIN
|
||||
|
||||
BLOCK "040904E4" // Lang=US English, CharSet=Windows Multilingual
|
||||
|
||||
BEGIN
|
||||
|
||||
VALUE "CompanyName", "Netscape Communications Corporation\0"
|
||||
|
||||
VALUE "FileDescription", "Netscape 16-bit JavaScript-Java Module\0"
|
||||
|
||||
VALUE "FileVersion", "4.0\0"
|
||||
|
||||
VALUE "InternalName", "JSJ1640\0"
|
||||
|
||||
VALUE "LegalCopyright", "Copyright Netscape Communications. 1994-96\0"
|
||||
|
||||
VALUE "LegalTrademarks", "Netscape, Mozilla\0"
|
||||
|
||||
VALUE "OriginalFilename","JSJ1640.DLL\0"
|
||||
|
||||
VALUE "ProductName", "NETSCAPE\0"
|
||||
|
||||
VALUE "ProductVersion", "4.0\0"
|
||||
|
||||
END
|
||||
|
||||
END
|
||||
|
||||
END
|
||||
|
||||
1243
mozilla/js/src/liveconnect/jsj_JSObject.c
Normal file
1243
mozilla/js/src/liveconnect/jsj_JSObject.c
Normal file
File diff suppressed because it is too large
Load Diff
403
mozilla/js/src/liveconnect/jsj_JavaArray.c
Normal file
403
mozilla/js/src/liveconnect/jsj_JavaArray.c
Normal file
@@ -0,0 +1,403 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the definition of the JavaScript JavaArray class.
|
||||
* Instances of JavaArray are used to reflect Java arrays.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
/* Shorthands for ASCII (7-bit) decimal and hex conversion. */
|
||||
#define JS7_ISDEC(c) (((c) >= '0') && ((c) <= '9'))
|
||||
#define JS7_UNDEC(c) ((c) - '0')
|
||||
|
||||
/*
|
||||
* Convert any jsval v to an integer jsval if ToString(v)
|
||||
* contains a base-10 integer that fits into 31 bits.
|
||||
* Otherwise return v.
|
||||
*/
|
||||
static jsval
|
||||
try_convert_to_jsint(JSContext *cx, jsval idval)
|
||||
{
|
||||
const jschar *cp;
|
||||
JSString *jsstr;
|
||||
|
||||
jsstr = JS_ValueToString(cx, idval);
|
||||
if (!jsstr)
|
||||
return idval;
|
||||
|
||||
cp = JS_GetStringChars(jsstr);
|
||||
if (JS7_ISDEC(*cp)) {
|
||||
jsuint index = JS7_UNDEC(*cp++);
|
||||
jsuint oldIndex = 0;
|
||||
jsuint c = 0;
|
||||
if (index != 0) {
|
||||
while (JS7_ISDEC(*cp)) {
|
||||
oldIndex = index;
|
||||
c = JS7_UNDEC(*cp);
|
||||
index = 10*index + c;
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
if (*cp == 0 &&
|
||||
(oldIndex < (JSVAL_INT_MAX / 10) ||
|
||||
(oldIndex == (JSVAL_INT_MAX / 10) && c < (JSVAL_INT_MAX % 10)))) {
|
||||
return INT_TO_JSVAL(index);
|
||||
}
|
||||
}
|
||||
return idval;
|
||||
}
|
||||
|
||||
|
||||
static JSBool
|
||||
access_java_array_element(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JSObject *obj,
|
||||
jsid id,
|
||||
jsval *vp,
|
||||
JSBool do_assignment)
|
||||
{
|
||||
jsval idval;
|
||||
jarray java_array;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
jsize array_length, index;
|
||||
JavaSignature *array_component_signature;
|
||||
|
||||
/* printf("In JavaArray_getProperty\n"); */
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper) {
|
||||
const char *property_name;
|
||||
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
|
||||
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
|
||||
if (!strcmp(property_name, "constructor")) {
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
JS_ReportError(cx, "illegal operation on JavaArray prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
java_array = java_wrapper->java_obj;
|
||||
|
||||
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_ARRAY);
|
||||
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
|
||||
if (!JSVAL_IS_INT(idval))
|
||||
idval = try_convert_to_jsint(cx, idval);
|
||||
|
||||
if (!JSVAL_IS_INT(idval)) {
|
||||
/*
|
||||
* Usually, properties of JavaArray objects are indexed by integers, but
|
||||
* Java arrays also inherit all the methods of java.lang.Object, so a
|
||||
* string-valued property is also possible.
|
||||
*/
|
||||
if (JSVAL_IS_STRING(idval)) {
|
||||
const char *member_name;
|
||||
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
|
||||
if (do_assignment) {
|
||||
JSVersion version = JS_GetVersion(cx);
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
|
||||
JS_ReportError(cx, "Attempt to write to invalid Java array "
|
||||
"element \"%s\"", member_name);
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
} else {
|
||||
if (!strcmp(member_name, "length")) {
|
||||
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
|
||||
if (array_length < 0)
|
||||
return JS_FALSE;
|
||||
if (vp)
|
||||
*vp = INT_TO_JSVAL(array_length);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Check to see if we're reflecting a Java array method */
|
||||
return JavaObject_getPropertyById(cx, obj, id, vp);
|
||||
}
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "invalid Java array index expression");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
index = JSVAL_TO_INT(idval);
|
||||
|
||||
#if 0
|
||||
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_array);
|
||||
if (array_length < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
/* Just let Java throw an exception instead of checking array bounds here */
|
||||
if (index < 0 || index >= array_length) {
|
||||
JS_ReportError(cx, "Java array index %d out of range", index);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
array_component_signature = class_descriptor->array_component_signature;
|
||||
|
||||
if (!vp)
|
||||
return JS_TRUE;
|
||||
|
||||
if (do_assignment) {
|
||||
return jsj_SetJavaArrayElement(cx, jEnv, java_array, index,
|
||||
array_component_signature, *vp);
|
||||
} else {
|
||||
return jsj_GetJavaArrayElement(cx, jEnv, java_array, index,
|
||||
array_component_signature, vp);
|
||||
}
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JavaArray_getPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
return access_java_array_element(cx, jEnv, obj, id, vp, JS_FALSE);
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JavaArray_setPropertyById(JSContext *cx, JSObject *obj, jsval id, jsval *vp)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
return access_java_array_element(cx, jEnv, obj, id, vp, JS_TRUE);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
, const char *file, uintN line
|
||||
#endif
|
||||
)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
return access_java_array_element(cx, jEnv, obj, id, NULL, JS_FALSE);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
JS_ReportError(cx, "Cannot define a new property in a JavaArray");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_getAttributes(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSProperty *prop, uintN *attrsp)
|
||||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_setAttributes(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSProperty *prop, uintN *attrsp)
|
||||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Silently ignore all setAttribute attempts */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
JSVersion version = JS_GetVersion(cx);
|
||||
|
||||
*vp = JSVAL_FALSE;
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
JS_ReportError(cx, "Properties of JavaArray objects may not be deleted");
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
/* Attempts to delete permanent properties are silently ignored
|
||||
by ECMAScript. */
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
/* printf("In JavaArray_defaultValue()\n"); */
|
||||
return JavaObject_convert(cx, obj, JSTYPE_STRING, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JNIEnv *jEnv;
|
||||
jsize array_length, index;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
/* Check for prototype object */
|
||||
if (!java_wrapper) {
|
||||
*statep = JSVAL_NULL;
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(0);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
array_length = jsj_GetJavaArrayLength(cx, jEnv, java_wrapper->java_obj);
|
||||
if (array_length < 0)
|
||||
return JS_FALSE;
|
||||
|
||||
switch(enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
*statep = INT_TO_JSVAL(0);
|
||||
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(array_length);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
index = JSVAL_TO_INT(*statep);
|
||||
if (index < array_length) {
|
||||
JS_ValueToId(cx, INT_TO_JSVAL(index), idp);
|
||||
index++;
|
||||
*statep = INT_TO_JSVAL(index);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Fall through ... */
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaArray_checkAccess(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSAccessMode mode, jsval *vp, uintN *attrsp)
|
||||
{
|
||||
switch (mode) {
|
||||
case JSACC_WATCH:
|
||||
JS_ReportError(cx, "Cannot place watchpoints on JavaArray object properties");
|
||||
return JS_FALSE;
|
||||
|
||||
case JSACC_IMPORT:
|
||||
JS_ReportError(cx, "Cannot export a JavaArray object's properties");
|
||||
return JS_FALSE;
|
||||
|
||||
default:
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
JSObjectOps JavaArray_ops = {
|
||||
/* Mandatory non-null function pointer members. */
|
||||
NULL, /* newObjectMap */
|
||||
NULL, /* destroyObjectMap */
|
||||
JavaArray_lookupProperty,
|
||||
JavaArray_defineProperty,
|
||||
JavaArray_getPropertyById, /* getProperty */
|
||||
JavaArray_setPropertyById, /* setProperty */
|
||||
JavaArray_getAttributes,
|
||||
JavaArray_setAttributes,
|
||||
JavaArray_deleteProperty,
|
||||
JavaArray_defaultValue,
|
||||
JavaArray_newEnumerate,
|
||||
JavaArray_checkAccess,
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
NULL, /* thisObject */
|
||||
NULL, /* dropProperty */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL /* hasInstance */
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
JavaArray_getObjectOps(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
return &JavaArray_ops;
|
||||
}
|
||||
|
||||
JSClass JavaArray_class = {
|
||||
"JavaArray", JSCLASS_HAS_PRIVATE,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JavaObject_convert, JavaObject_finalize,
|
||||
JavaArray_getObjectOps,
|
||||
};
|
||||
|
||||
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
|
||||
/* Initialize the JS JavaArray class */
|
||||
JSBool
|
||||
jsj_init_JavaArray(JSContext *cx, JSObject *global_obj)
|
||||
{
|
||||
JavaArray_ops.newObjectMap = js_ObjectOps.newObjectMap;
|
||||
JavaArray_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
|
||||
|
||||
if (!JS_InitClass(cx, global_obj,
|
||||
0, &JavaArray_class, 0, 0,
|
||||
0, 0, 0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
586
mozilla/js/src/liveconnect/jsj_JavaClass.c
Normal file
586
mozilla/js/src/liveconnect/jsj_JavaClass.c
Normal file
@@ -0,0 +1,586 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the native code implementation of JS's JavaClass class.
|
||||
*
|
||||
* A JavaClass is JavaScript's representation of a Java class.
|
||||
* Its parent JS object is always a JavaPackage object. A JavaClass is not an
|
||||
* exact reflection of Java's corresponding java.lang.Class object. Rather,
|
||||
* the properties of a JavaClass are the static methods and properties of the
|
||||
* corresponding Java class.
|
||||
*
|
||||
* Note that there is no runtime equivalent to the JavaClass class in Java.
|
||||
* (Although there are instances of java.lang.String and there are static
|
||||
* methods of java.lang.String that can be invoked, there's no such thing as
|
||||
* a first-class object that can be referenced simply as "java.lang.String".)
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
static JSBool
|
||||
JavaClass_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
char *name;
|
||||
JSString *str;
|
||||
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor)
|
||||
return JS_FALSE;
|
||||
|
||||
switch(type) {
|
||||
|
||||
|
||||
case JSTYPE_STRING:
|
||||
/* Convert '/' to '.' so that it looks like Java language syntax. */
|
||||
if (!class_descriptor->name)
|
||||
break;
|
||||
name = PR_smprintf("[JavaClass %s]", class_descriptor->name);
|
||||
if (!name) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
str = JS_NewString(cx, name, strlen(name));
|
||||
if (!str) {
|
||||
free(name);
|
||||
/* It's not necessary to call JS_ReportOutOfMemory(), as
|
||||
JS_NewString() will do so on failure. */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*vp = STRING_TO_JSVAL(str);
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
lookup_static_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
||||
JavaClassDescriptor **class_descriptorp,
|
||||
jsid id, JavaMemberDescriptor **memberp)
|
||||
{
|
||||
jsval idval;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
const char *member_name;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor) {
|
||||
*class_descriptorp = NULL;
|
||||
*memberp = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (class_descriptorp)
|
||||
*class_descriptorp = class_descriptor;
|
||||
|
||||
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (!member_descriptor) {
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
if (!JSVAL_IS_STRING(idval)) {
|
||||
JS_ReportError(cx, "invalid JavaClass property expression. "
|
||||
"(methods and fields of a JavaClass object can only be identified by their name)");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
|
||||
/* Why do we have to do this ? */
|
||||
if (!strcmp(member_name, "prototype")) {
|
||||
*memberp = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "Java class %s has no public static field or method named \"%s\"",
|
||||
class_descriptor->name, member_name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
if (memberp)
|
||||
*memberp = member_descriptor;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JavaClass_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jsval idval;
|
||||
jclass java_class;
|
||||
const char *member_name;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* printf("In JavaClass_getProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
|
||||
return JS_FALSE;
|
||||
if (!member_descriptor) {
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
|
||||
if (member_descriptor->field) {
|
||||
if (!member_descriptor->methods) {
|
||||
return jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, vp);
|
||||
} else {
|
||||
PR_ASSERT(0);
|
||||
}
|
||||
} else {
|
||||
JSFunction *function;
|
||||
|
||||
/* TODO - eliminate JSFUN_BOUND_METHOD */
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
function = JS_NewFunction(cx, jsj_JavaStaticMethodWrapper, 0,
|
||||
JSFUN_BOUND_METHOD, obj, member_name);
|
||||
if (!function)
|
||||
return JS_FALSE;
|
||||
|
||||
*vp = OBJECT_TO_JSVAL(JS_GetFunctionObject(function));
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JavaClass_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jclass java_class;
|
||||
const char *member_name;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
jsval idval;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* printf("In JavaClass_setProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_static_member_by_id(cx, jEnv, obj, &class_descriptor, id, &member_descriptor))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Check for the case where there is a method with the given name, but no field
|
||||
with that name */
|
||||
if (!member_descriptor->field)
|
||||
goto no_such_field;
|
||||
|
||||
/* Silently fail if field value is final (immutable), as required by ECMA spec */
|
||||
if (member_descriptor->field->modifiers & ACC_FINAL)
|
||||
return JS_TRUE;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_class, *vp);
|
||||
|
||||
no_such_field:
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
JS_ReportError(cx, "No static field named \"%s\" in Java class %s",
|
||||
member_name, class_descriptor->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the private native data associated with the JavaPackage object.
|
||||
*/
|
||||
PR_STATIC_CALLBACK(void)
|
||||
JavaClass_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
|
||||
JavaClassDescriptor *class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor)
|
||||
return;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
/* printf("Finalizing %s\n", class_descriptor->name); */
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
|
||||
}
|
||||
|
||||
|
||||
static JSBool
|
||||
JavaClass_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
, const char *file, uintN line
|
||||
#endif
|
||||
)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSErrorReporter old_reporter;
|
||||
|
||||
/* printf("In JavaClass_lookupProperty()\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
old_reporter = JS_SetErrorReporter(cx, NULL);
|
||||
if (lookup_static_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {
|
||||
*objp = obj;
|
||||
*propp = (JSProperty*)1;
|
||||
} else {
|
||||
*objp = NULL;
|
||||
*propp = NULL;
|
||||
}
|
||||
|
||||
JS_SetErrorReporter(cx, old_reporter);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
JS_ReportError(cx, "Cannot define a new property in a JavaClass");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_getAttributes(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSProperty *prop, uintN *attrsp)
|
||||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_setAttributes(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSProperty *prop, uintN *attrsp)
|
||||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Silently ignore all setAttribute attempts */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
JSVersion version = JS_GetVersion(cx);
|
||||
|
||||
*vp = JSVAL_FALSE;
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
JS_ReportError(cx, "Properties of JavaClass objects may not be deleted");
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
/* Attempts to delete permanent properties are silently ignored
|
||||
by ECMAScript. */
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
/* printf("In JavaClass_defaultValue()\n"); */
|
||||
return JavaClass_convert(cx, obj, JSTYPE_STRING, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
|
||||
/* Check for prototype JavaClass object */
|
||||
if (!class_descriptor) {
|
||||
*statep = JSVAL_NULL;
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(0);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
switch(enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor);
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
member_descriptor = JSVAL_TO_PRIVATE(*statep);
|
||||
if (member_descriptor) {
|
||||
*idp = member_descriptor->id;
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
|
||||
return JS_TRUE;
|
||||
}
|
||||
/* Fall through ... */
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaClass_checkAccess(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSAccessMode mode, jsval *vp, uintN *attrsp)
|
||||
{
|
||||
switch (mode) {
|
||||
case JSACC_WATCH:
|
||||
JS_ReportError(cx, "Cannot place watchpoints on JavaClass object properties");
|
||||
return JS_FALSE;
|
||||
|
||||
case JSACC_IMPORT:
|
||||
JS_ReportError(cx, "Cannot export a JavaClass object's properties");
|
||||
return JS_FALSE;
|
||||
|
||||
default:
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Implement the JavaScript instanceof operator for JavaClass objects by using
|
||||
* the equivalent Java instanceof operation.
|
||||
*/
|
||||
static JSBool
|
||||
JavaClass_hasInstance(JSContext *cx, JSObject *obj, jsval candidate_jsval,
|
||||
JSBool *has_instancep)
|
||||
{
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JSClass *js_class;
|
||||
JSBool has_instance;
|
||||
JSObject *candidate_obj;
|
||||
jclass java_class;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
has_instance = JS_FALSE;
|
||||
class_descriptor = JS_GetPrivate(cx, obj);
|
||||
if (!class_descriptor) {
|
||||
JS_ReportError(cx, "illegal operation on JavaClass prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make sure that the thing to the left of the instanceof operator is a
|
||||
* Java object.
|
||||
*/
|
||||
if (!JSVAL_IS_OBJECT(candidate_jsval))
|
||||
goto done;
|
||||
candidate_obj = JSVAL_TO_OBJECT(candidate_jsval);
|
||||
js_class = JS_GetClass(candidate_obj);
|
||||
if ((js_class != &JavaObject_class) && (js_class != &JavaArray_class))
|
||||
goto done;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
java_wrapper = JS_GetPrivate(cx, candidate_obj);
|
||||
if (!java_wrapper) {
|
||||
JS_ReportError(cx, "illegal operation on prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
java_obj = java_wrapper->java_obj;
|
||||
/* Get JNI pointer */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
has_instance = (*jEnv)->IsInstanceOf(jEnv, java_obj, java_class);
|
||||
|
||||
done:
|
||||
*has_instancep = has_instance;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSObjectOps JavaClass_ops = {
|
||||
/* Mandatory non-null function pointer members. */
|
||||
NULL, /* newObjectMap */
|
||||
NULL, /* destroyObjectMap */
|
||||
JavaClass_lookupProperty,
|
||||
JavaClass_defineProperty,
|
||||
JavaClass_getPropertyById, /* getProperty */
|
||||
JavaClass_setPropertyById, /* setProperty */
|
||||
JavaClass_getAttributes,
|
||||
JavaClass_setAttributes,
|
||||
JavaClass_deleteProperty,
|
||||
JavaClass_defaultValue,
|
||||
JavaClass_newEnumerate,
|
||||
JavaClass_checkAccess,
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
NULL, /* thisObject */
|
||||
NULL, /* dropProperty */
|
||||
jsj_JavaConstructorWrapper, /* call */
|
||||
jsj_JavaConstructorWrapper, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
JavaClass_hasInstance, /* hasInstance */
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
JavaClass_getObjectOps(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
return &JavaClass_ops;
|
||||
}
|
||||
|
||||
JSClass JavaClass_class = {
|
||||
"JavaClass", JSCLASS_HAS_PRIVATE,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JavaClass_convert, JavaClass_finalize,
|
||||
JavaClass_getObjectOps,
|
||||
};
|
||||
|
||||
static JSObject *
|
||||
jsj_new_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
JSObject *JavaClass_obj;
|
||||
|
||||
JavaClass_obj = JS_NewObject(cx, &JavaClass_class, 0, parent_obj);
|
||||
if (!JavaClass_obj)
|
||||
return NULL;
|
||||
|
||||
JS_SetPrivate(cx, JavaClass_obj, (void *)class_descriptor);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* printf("JavaClass \'%s\' created\n", class_descriptor->name); */
|
||||
#endif
|
||||
|
||||
return JavaClass_obj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject* parent_obj,
|
||||
const char *simple_class_name,
|
||||
jclass java_class)
|
||||
{
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JSObject *JavaClass_obj;
|
||||
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
|
||||
if (!class_descriptor)
|
||||
return NULL;
|
||||
|
||||
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, parent_obj, class_descriptor);
|
||||
if (!JavaClass_obj)
|
||||
return NULL;
|
||||
|
||||
if (!JS_DefineProperty(cx, parent_obj, simple_class_name,
|
||||
OBJECT_TO_JSVAL(JavaClass_obj), 0, 0,
|
||||
JSPROP_PERMANENT|JSPROP_READONLY|JSPROP_ENUMERATE))
|
||||
return NULL;
|
||||
return JavaClass_obj;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The getClass() native JS method is defined as a property of the global
|
||||
* object. Given a JavaObject it returns the corresponding JavaClass. This
|
||||
* is useful for accessing static methods and fields.
|
||||
*
|
||||
* js> getClass(new java.lang.String("foo"))
|
||||
* [JavaClass java.lang.String]
|
||||
*/
|
||||
static JSBool
|
||||
getClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
JSObject *obj_arg, *JavaClass_obj;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (argc != 1 ||
|
||||
!JSVAL_IS_OBJECT(argv[0]) ||
|
||||
!(obj_arg = JSVAL_TO_OBJECT(argv[0])) ||
|
||||
(!JS_InstanceOf(cx, obj_arg, &JavaObject_class, 0) &&
|
||||
!JS_InstanceOf(cx, obj_arg, &JavaArray_class, 0))) {
|
||||
JS_ReportError(cx, "getClass expects a Java object argument");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj_arg);
|
||||
if (!java_wrapper) {
|
||||
JS_ReportError(cx, "getClass called on prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
|
||||
JavaClass_obj = jsj_new_JavaClass(cx, jEnv, NULL, class_descriptor);
|
||||
if (!JavaClass_obj)
|
||||
return JS_FALSE;
|
||||
*rval = OBJECT_TO_JSVAL(JavaClass_obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
JSBool
|
||||
jsj_init_JavaClass(JSContext *cx, JSObject *global_obj)
|
||||
{
|
||||
JavaClass_ops.newObjectMap = js_ObjectOps.newObjectMap;
|
||||
JavaClass_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
|
||||
|
||||
/* Define JavaClass class */
|
||||
if (!JS_InitClass(cx, global_obj, 0, &JavaClass_class, 0, 0, 0, 0, 0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!JS_DefineFunction(cx, global_obj, "getClass", getClass, 0,
|
||||
JSPROP_READONLY))
|
||||
return JS_FALSE;
|
||||
|
||||
return jsj_InitJavaClassReflectionsTable();
|
||||
}
|
||||
|
||||
134
mozilla/js/src/liveconnect/jsj_JavaMember.c
Normal file
134
mozilla/js/src/liveconnect/jsj_JavaMember.c
Normal file
@@ -0,0 +1,134 @@
|
||||
/* -*- Mode: C; tab-width: 8 -*-
|
||||
* Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the native code implementation of JS's JavaMember class.
|
||||
* JavaMember's are a strange beast required only to handle the special case
|
||||
* of a public field and a public method that appear in the same class and
|
||||
* have the same name. When such a field/method is used in Java, the compiler
|
||||
* can statically determine from context whether the field or the method is
|
||||
* being referenced, but that is not possible with JavaScript. For example:
|
||||
*
|
||||
* ambiguousVal = javaObj.fieldOrMethod; // ambiguousVal is a JavaMember object
|
||||
* a = ambiguousVal(); // ambiguousVal used as a method value
|
||||
* b = ambiguousVal + 4; // ambiguousVal used as a field value
|
||||
*
|
||||
* A JavaMember instance carries both the captured value of the Java field and
|
||||
* the method value until the context that the value is to be used in is known,
|
||||
* at which point conversion forces the use of one or the other.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
/* Private, native portion of a JavaMember */
|
||||
typedef struct JavaMethodOrFieldValue {
|
||||
jsval method_val;
|
||||
jsval field_val;
|
||||
} JavaMethodOrFieldValue;
|
||||
|
||||
JSObject *
|
||||
jsj_CreateJavaMember(JSContext *cx, jsval method_val, jsval field_val)
|
||||
{
|
||||
JavaMethodOrFieldValue *member_val;
|
||||
JSObject *JavaMember_obj;
|
||||
|
||||
member_val = (JavaMethodOrFieldValue *)JS_malloc(cx, sizeof(*member_val));
|
||||
if (!member_val)
|
||||
return NULL;
|
||||
|
||||
JavaMember_obj = JS_NewObject(cx, &JavaMember_class, 0, 0);
|
||||
if (!JavaMember_obj) {
|
||||
JS_free(cx, member_val);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JS_SetPrivate(cx, JavaMember_obj, (void *)member_val);
|
||||
member_val->method_val = method_val;
|
||||
JS_AddRoot(cx, &member_val->method_val);
|
||||
member_val->field_val = field_val;
|
||||
if (JSVAL_IS_GCTHING(field_val))
|
||||
JS_AddRoot(cx, &member_val->field_val);
|
||||
|
||||
return JavaMember_obj;
|
||||
}
|
||||
|
||||
static void
|
||||
JavaMember_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JavaMethodOrFieldValue *member_val;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
member_val = JS_GetPrivate(cx, obj);
|
||||
if (!member_val)
|
||||
return;
|
||||
JS_RemoveRoot(cx, &member_val->method_val);
|
||||
if (JSVAL_IS_GCTHING(member_val->method_val))
|
||||
JS_RemoveRoot(cx, &member_val->method_val);
|
||||
JS_free(cx, member_val);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaMember_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
JavaMethodOrFieldValue *member_val;
|
||||
|
||||
member_val = JS_GetPrivate(cx, obj);
|
||||
if (!member_val) {
|
||||
if (type == JSTYPE_OBJECT) {
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case JSTYPE_VOID:
|
||||
case JSTYPE_STRING:
|
||||
case JSTYPE_NUMBER:
|
||||
case JSTYPE_BOOLEAN:
|
||||
case JSTYPE_OBJECT:
|
||||
*vp = member_val->field_val;
|
||||
return JS_TRUE;
|
||||
|
||||
case JSTYPE_FUNCTION:
|
||||
*vp = member_val->method_val;
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
JSClass JavaMember_class = {
|
||||
"JavaMember", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JS_PropertyStub,
|
||||
JS_EnumerateStub, JS_ResolveStub,
|
||||
JavaMember_convert, JavaMember_finalize
|
||||
};
|
||||
|
||||
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
JSBool
|
||||
jsj_init_JavaMember(JSContext *cx, JSObject *global_obj)
|
||||
{
|
||||
if (!JS_InitClass(cx, global_obj,
|
||||
0, &JavaMember_class, 0, 0,
|
||||
0, 0,
|
||||
0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
686
mozilla/js/src/liveconnect/jsj_JavaObject.c
Normal file
686
mozilla/js/src/liveconnect/jsj_JavaObject.c
Normal file
@@ -0,0 +1,686 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the native code implementation of JS's JavaObject class.
|
||||
*
|
||||
* An instance of JavaObject is the JavaScript reflection of a Java object.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jsj_hash.h" /* Hash table with Java object as key */
|
||||
|
||||
|
||||
/*
|
||||
* This is a hash table that maps from Java objects to JS objects.
|
||||
* It is used to ensure that the same JS object is obtained when a Java
|
||||
* object is reflected more than once, so that JS object equality tests
|
||||
* work in the expected manner, i.e. the "==" and "===" operators.
|
||||
*
|
||||
* The table entry keys are Java objects (of type jobject) and the entry values
|
||||
* are JSObject pointers. Because the jobject type is an opaque handle and
|
||||
* not necessarily a pointer, the hashing and key comparison functions must
|
||||
* invoke the appropriate JVM functions.
|
||||
*
|
||||
* When the corresponding JS object instance is finalized, the entry is
|
||||
* removed from the table, and a Java GC root for the Java object is removed.
|
||||
*/
|
||||
static JSJHashTable *java_obj_reflections = NULL;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
static PRMonitor *java_obj_reflections_monitor = NULL;
|
||||
#endif
|
||||
|
||||
static JSBool
|
||||
init_java_obj_reflections_table()
|
||||
{
|
||||
java_obj_reflections =
|
||||
JSJ_NewHashTable(512, jsj_HashJavaObject, jsj_JavaObjectComparator,
|
||||
NULL, NULL, NULL);
|
||||
if (!java_obj_reflections)
|
||||
return JS_FALSE;
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
java_obj_reflections_monitor = PR_NewNamedMonitor("java_obj_reflections");
|
||||
if (!java_obj_reflections_monitor) {
|
||||
PR_HashTableDestroy(java_obj_reflections);
|
||||
return JS_FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
jsj_WrapJavaObject(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
jobject java_obj,
|
||||
jclass java_class)
|
||||
{
|
||||
JSJHashNumber hash_code;
|
||||
JSClass *js_class;
|
||||
JSObject *js_wrapper_obj;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JSJHashEntry *he, **hep;
|
||||
|
||||
js_wrapper_obj = NULL;
|
||||
|
||||
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_EnterMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
hep = JSJ_HashTableRawLookup(java_obj_reflections,
|
||||
hash_code, java_obj, (void*)jEnv);
|
||||
he = *hep;
|
||||
if (he) {
|
||||
js_wrapper_obj = (JSObject *)he->value;
|
||||
if (js_wrapper_obj)
|
||||
goto done;
|
||||
}
|
||||
|
||||
/* No existing reflection found. Construct a new one */
|
||||
class_descriptor = jsj_GetJavaClassDescriptor(cx, jEnv, java_class);
|
||||
if (!class_descriptor)
|
||||
goto done;
|
||||
if (class_descriptor->type == JAVA_SIGNATURE_ARRAY) {
|
||||
js_class = &JavaArray_class;
|
||||
} else {
|
||||
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS);
|
||||
js_class = &JavaObject_class;
|
||||
}
|
||||
|
||||
/* Create new JS object to reflect Java object */
|
||||
js_wrapper_obj = JS_NewObject(cx, js_class, NULL, NULL);
|
||||
if (!js_wrapper_obj)
|
||||
goto done;
|
||||
|
||||
/* Create private, native portion of JavaObject */
|
||||
java_wrapper =
|
||||
(JavaObjectWrapper *)JS_malloc(cx, sizeof(JavaObjectWrapper));
|
||||
if (!java_wrapper) {
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor);
|
||||
goto done;
|
||||
}
|
||||
JS_SetPrivate(cx, js_wrapper_obj, java_wrapper);
|
||||
java_wrapper->class_descriptor = class_descriptor;
|
||||
|
||||
java_obj = (*jEnv)->NewGlobalRef(jEnv, java_obj);
|
||||
java_wrapper->java_obj = java_obj;
|
||||
if (!java_obj)
|
||||
goto out_of_memory;
|
||||
|
||||
/* Add the JavaObject to the hash table */
|
||||
he = JSJ_HashTableRawAdd(java_obj_reflections, hep, hash_code,
|
||||
java_obj, js_wrapper_obj, (void*)jEnv);
|
||||
if (!he) {
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
|
||||
goto out_of_memory;
|
||||
}
|
||||
|
||||
done:
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
return js_wrapper_obj;
|
||||
|
||||
out_of_memory:
|
||||
/* No need to free js_wrapper_obj, as it will be finalized by GC. */
|
||||
JS_ReportOutOfMemory(cx);
|
||||
js_wrapper_obj = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_java_obj_reflection_from_hashtable(jobject java_obj, JNIEnv *jEnv)
|
||||
{
|
||||
JSJHashNumber hash_code;
|
||||
JSJHashEntry *he, **hep;
|
||||
|
||||
hash_code = jsj_HashJavaObject((void*)java_obj, (void*)jEnv);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_EnterMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
|
||||
hep = JSJ_HashTableRawLookup(java_obj_reflections, hash_code,
|
||||
java_obj, (void*)jEnv);
|
||||
he = *hep;
|
||||
|
||||
PR_ASSERT(he);
|
||||
if (he)
|
||||
JSJ_HashTableRawRemove(java_obj_reflections, hep, he, (void*)jEnv);
|
||||
|
||||
#ifdef JS_THREADSAFE
|
||||
PR_ExitMonitor(java_obj_reflections_monitor);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
JavaObject_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper)
|
||||
return;
|
||||
java_obj = java_wrapper->java_obj;
|
||||
|
||||
if (java_obj) {
|
||||
remove_java_obj_reflection_from_hashtable(java_obj, jEnv);
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
|
||||
}
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, java_wrapper->class_descriptor);
|
||||
JS_free(cx, java_wrapper);
|
||||
}
|
||||
|
||||
/* Trivial helper for jsj_DiscardJavaObjReflections(), below */
|
||||
static PRIntn
|
||||
enumerate_remove_java_obj(JSJHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
JNIEnv *jEnv = (JNIEnv*)arg;
|
||||
jobject java_obj;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JSObject *java_wrapper_obj;
|
||||
|
||||
java_wrapper_obj = (JSObject *)he->value;
|
||||
java_wrapper = JS_GetPrivate(NULL, java_wrapper_obj);
|
||||
java_obj = java_wrapper->java_obj;
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_obj);
|
||||
java_wrapper->java_obj = NULL;
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
/* This shutdown routine discards all JNI references to Java objects
|
||||
that have been reflected into JS, even if there are still references
|
||||
to them from JS. */
|
||||
void
|
||||
jsj_DiscardJavaObjReflections(JNIEnv *jEnv)
|
||||
{
|
||||
if (java_obj_reflections) {
|
||||
JSJ_HashTableEnumerateEntries(java_obj_reflections,
|
||||
enumerate_remove_java_obj,
|
||||
(void*)jEnv);
|
||||
JSJ_HashTableDestroy(java_obj_reflections);
|
||||
java_obj_reflections = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
PR_CALLBACK JSBool
|
||||
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper) {
|
||||
if (type == JSTYPE_OBJECT) {
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
|
||||
switch (type) {
|
||||
case JSTYPE_OBJECT:
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSTYPE_FUNCTION:
|
||||
JS_ReportError(cx, "can't convert Java object to function");
|
||||
return JS_FALSE;
|
||||
|
||||
case JSTYPE_VOID:
|
||||
case JSTYPE_STRING:
|
||||
/* Either extract a C-string from the java.lang.String object
|
||||
or call the Java toString() method */
|
||||
return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
case JSTYPE_NUMBER:
|
||||
/* Call Java doubleValue() method, if applicable */
|
||||
return jsj_ConvertJavaObjectToJSNumber(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
case JSTYPE_BOOLEAN:
|
||||
/* Call booleanValue() method, if applicable */
|
||||
return jsj_ConvertJavaObjectToJSBoolean(cx, jEnv, class_descriptor, java_obj, vp);
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
lookup_member_by_id(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
||||
JavaObjectWrapper **java_wrapperp,
|
||||
jsid id,
|
||||
JavaMemberDescriptor **member_descriptorp)
|
||||
{
|
||||
jsval idval;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
const char *member_name, *property_name;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
if (!java_wrapper) {
|
||||
if (JS_IdToValue(cx, id, &idval) && JSVAL_IS_STRING(idval) &&
|
||||
(property_name = JS_GetStringBytes(JSVAL_TO_STRING(idval))) != NULL) {
|
||||
if (!strcmp(property_name, "constructor")) {
|
||||
*java_wrapperp = NULL;
|
||||
*member_descriptorp = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
JS_ReportError(cx, "illegal operation on JavaObject prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
PR_ASSERT(class_descriptor->type == JAVA_SIGNATURE_CLASS ||
|
||||
class_descriptor->type == JAVA_SIGNATURE_ARRAY);
|
||||
|
||||
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (!member_descriptor) {
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
if (!JSVAL_IS_STRING(idval)) {
|
||||
JS_ReportError(cx, "invalid JavaObject property expression. "
|
||||
"(methods and field properties of a JavaObject object can only be strings)");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
|
||||
JS_ReportError(cx, "Java class %s has no public instance field or "
|
||||
"method named \"%s\"",
|
||||
class_descriptor->name, member_name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Success. Handle the multiple return values */
|
||||
if (java_wrapperp)
|
||||
*java_wrapperp = java_wrapper;
|
||||
if (member_descriptorp)
|
||||
*member_descriptorp = member_descriptor;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_CALLBACK JSBool
|
||||
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jobject java_obj;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JNIEnv *jEnv;
|
||||
JSObject *funobj;
|
||||
jsval field_val, method_val;
|
||||
JSBool success;
|
||||
|
||||
/* printf("In JavaObject_getProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Handle access to "constructor" property of prototype object with
|
||||
silent failure. */
|
||||
if (!member_descriptor) {
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
field_val = method_val = JSVAL_VOID;
|
||||
|
||||
/* If a field member, get the value of the field */
|
||||
if (member_descriptor->field) {
|
||||
success = jsj_GetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, &field_val);
|
||||
if (!success)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* If a method member, build a wrapper around the Java method */
|
||||
if (member_descriptor->methods) {
|
||||
/* Create a function object with this JavaObject as its parent, so that
|
||||
JSFUN_BOUND_METHOD binds it as the default 'this' for the function. */
|
||||
funobj = JS_CloneFunctionObject(cx, member_descriptor->invoke_func_obj, obj);
|
||||
if (!funobj)
|
||||
return JS_FALSE;
|
||||
method_val = OBJECT_TO_JSVAL(funobj);
|
||||
}
|
||||
|
||||
#if TEST_JAVAMEMBER
|
||||
/* Always create a JavaMember object, even though it's inefficient */
|
||||
obj = jsj_CreateJavaMember(cx, method_val, field_val);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
#else /* !TEST_JAVAMEMBER */
|
||||
|
||||
if (member_descriptor->field) {
|
||||
if (!member_descriptor->methods) {
|
||||
/* Return value of Java field */
|
||||
*vp = field_val;
|
||||
} else {
|
||||
/* Handle special case of access to a property that could refer
|
||||
to either a Java field or a method that share the same name.
|
||||
In Java, such ambiguity is not possible because the compiler
|
||||
can statically determine which is being accessed. */
|
||||
obj = jsj_CreateJavaMember(cx, method_val, field_val);
|
||||
if (!obj)
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
|
||||
} else {
|
||||
/* Return wrapper around Java method */
|
||||
*vp = method_val;
|
||||
}
|
||||
|
||||
#endif /* !TEST_JAVAMEMBER */
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
PR_STATIC_CALLBACK(JSBool)
|
||||
JavaObject_setPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
jobject java_obj;
|
||||
const char *member_name;
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
jsval idval;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
/* printf("In JavaObject_setProperty\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
if (!lookup_member_by_id(cx, jEnv, obj, &java_wrapper, id, &member_descriptor))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Check for the case where there is a method with the give name, but no field
|
||||
with that name */
|
||||
if (!member_descriptor->field)
|
||||
goto no_such_field;
|
||||
|
||||
/* Silently fail if field value is final (immutable), as required by ECMA spec */
|
||||
if (member_descriptor->field->modifiers & ACC_FINAL)
|
||||
return JS_TRUE;
|
||||
|
||||
java_obj = java_wrapper->java_obj;
|
||||
return jsj_SetJavaFieldValue(cx, jEnv, member_descriptor->field, java_obj, *vp);
|
||||
|
||||
no_such_field:
|
||||
JS_IdToValue(cx, id, &idval);
|
||||
member_name = JS_GetStringBytes(JSVAL_TO_STRING(idval));
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
JS_ReportError(cx, "No instance field named \"%s\" in Java class %s",
|
||||
member_name, class_descriptor->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_lookupProperty(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSObject **objp, JSProperty **propp
|
||||
#if defined JS_THREADSAFE && defined DEBUG
|
||||
, const char *file, uintN line
|
||||
#endif
|
||||
)
|
||||
{
|
||||
JNIEnv *jEnv;
|
||||
JSErrorReporter old_reporter;
|
||||
|
||||
/* printf("In JavaObject_lookupProperty()\n"); */
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
old_reporter = JS_SetErrorReporter(cx, NULL);
|
||||
if (lookup_member_by_id(cx, jEnv, obj, NULL, id, NULL)) {
|
||||
*objp = obj;
|
||||
*propp = (JSProperty*)1;
|
||||
} else {
|
||||
*objp = NULL;
|
||||
*propp = NULL;
|
||||
}
|
||||
|
||||
JS_SetErrorReporter(cx, old_reporter);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_defineProperty(JSContext *cx, JSObject *obj, jsid id, jsval value,
|
||||
JSPropertyOp getter, JSPropertyOp setter,
|
||||
uintN attrs, JSProperty **propp)
|
||||
{
|
||||
JS_ReportError(cx, "Cannot define a new property in a JavaObject");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_getAttributes(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSProperty *prop, uintN *attrsp)
|
||||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
*attrsp = JSPROP_PERMANENT|JSPROP_ENUMERATE;
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_setAttributes(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSProperty *prop, uintN *attrsp)
|
||||
{
|
||||
/* We don't maintain JS property attributes for Java class members */
|
||||
if (*attrsp != (JSPROP_PERMANENT|JSPROP_ENUMERATE)) {
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Silently ignore all setAttribute attempts */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_deleteProperty(JSContext *cx, JSObject *obj, jsid id, jsval *vp)
|
||||
{
|
||||
JSVersion version = JS_GetVersion(cx);
|
||||
|
||||
*vp = JSVAL_FALSE;
|
||||
|
||||
if (!JSVERSION_IS_ECMA(version)) {
|
||||
JS_ReportError(cx, "Properties of JavaObject objects may not be deleted");
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
/* Attempts to delete permanent properties are silently ignored
|
||||
by ECMAScript. */
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_defaultValue(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
/* printf("In JavaObject_defaultValue()\n"); */
|
||||
return JavaObject_convert(cx, obj, type, vp);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_newEnumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
|
||||
jsval *statep, jsid *idp)
|
||||
{
|
||||
JavaObjectWrapper *java_wrapper;
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
java_wrapper = JS_GetPrivate(cx, obj);
|
||||
/* Check for prototype object */
|
||||
if (!java_wrapper) {
|
||||
*statep = JSVAL_NULL;
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(0);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
class_descriptor = java_wrapper->class_descriptor;
|
||||
|
||||
switch(enum_op) {
|
||||
case JSENUMERATE_INIT:
|
||||
|
||||
/* Get the Java per-thread environment pointer for this JSContext */
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor);
|
||||
if (idp)
|
||||
*idp = INT_TO_JSVAL(class_descriptor->num_instance_members);
|
||||
return JS_TRUE;
|
||||
|
||||
case JSENUMERATE_NEXT:
|
||||
member_descriptor = JSVAL_TO_PRIVATE(*statep);
|
||||
if (member_descriptor) {
|
||||
*idp = member_descriptor->id;
|
||||
*statep = PRIVATE_TO_JSVAL(member_descriptor->next);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Fall through ... */
|
||||
|
||||
case JSENUMERATE_DESTROY:
|
||||
*statep = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaObject_checkAccess(JSContext *cx, JSObject *obj, jsid id,
|
||||
JSAccessMode mode, jsval *vp, uintN *attrsp)
|
||||
{
|
||||
switch (mode) {
|
||||
case JSACC_WATCH:
|
||||
JS_ReportError(cx, "Cannot place watchpoints on JavaObject object properties");
|
||||
return JS_FALSE;
|
||||
|
||||
case JSACC_IMPORT:
|
||||
JS_ReportError(cx, "Cannot export a JavaObject object's properties");
|
||||
return JS_FALSE;
|
||||
|
||||
default:
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
JSObjectOps JavaObject_ops = {
|
||||
/* Mandatory non-null function pointer members. */
|
||||
NULL, /* newObjectMap */
|
||||
NULL, /* destroyObjectMap */
|
||||
JavaObject_lookupProperty,
|
||||
JavaObject_defineProperty,
|
||||
JavaObject_getPropertyById, /* getProperty */
|
||||
JavaObject_setPropertyById, /* setProperty */
|
||||
JavaObject_getAttributes,
|
||||
JavaObject_setAttributes,
|
||||
JavaObject_deleteProperty,
|
||||
JavaObject_defaultValue,
|
||||
JavaObject_newEnumerate,
|
||||
JavaObject_checkAccess,
|
||||
|
||||
/* Optionally non-null members start here. */
|
||||
NULL, /* thisObject */
|
||||
NULL, /* dropProperty */
|
||||
NULL, /* call */
|
||||
NULL, /* construct */
|
||||
NULL, /* xdrObject */
|
||||
NULL, /* hasInstance */
|
||||
};
|
||||
|
||||
static JSObjectOps *
|
||||
JavaObject_getObjectOps(JSContext *cx, JSClass *clazz)
|
||||
{
|
||||
return &JavaObject_ops;
|
||||
}
|
||||
|
||||
JSClass JavaObject_class = {
|
||||
"JavaObject", JSCLASS_HAS_PRIVATE,
|
||||
NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, JavaObject_convert, JavaObject_finalize,
|
||||
JavaObject_getObjectOps,
|
||||
};
|
||||
|
||||
extern PR_IMPORT_DATA(JSObjectOps) js_ObjectOps;
|
||||
|
||||
|
||||
JSBool
|
||||
jsj_init_JavaObject(JSContext *cx, JSObject *global_obj)
|
||||
{
|
||||
JavaObject_ops.newObjectMap = js_ObjectOps.newObjectMap;
|
||||
JavaObject_ops.destroyObjectMap = js_ObjectOps.destroyObjectMap;
|
||||
|
||||
if (!JS_InitClass(cx, global_obj,
|
||||
0, &JavaObject_class, 0, 0,
|
||||
0, 0,
|
||||
0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
return init_java_obj_reflections_table();
|
||||
}
|
||||
500
mozilla/js/src/liveconnect/jsj_JavaPackage.c
Normal file
500
mozilla/js/src/liveconnect/jsj_JavaPackage.c
Normal file
@@ -0,0 +1,500 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the native code implementation of the JavaPackage class.
|
||||
*
|
||||
* A JavaPackage is JavaScript's representation of a Java package. The
|
||||
* JavaPackage object contains only a string, which is the path to the package,
|
||||
* e.g. "java/lang". The JS properties of a JavaPackage are either nested packages
|
||||
* or a JavaClass object, which represents the path to a Java class.
|
||||
*
|
||||
* Note that there is no equivalent to a JavaPackage object in Java. Example:
|
||||
* Although there are instances of java.lang.String and there are static methods
|
||||
* of java.lang.String that can be invoked, there's no such thing as a java.lang
|
||||
* object in Java that exists at run time.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jsjava.h"
|
||||
|
||||
|
||||
JSClass JavaPackage_class; /* Forward declaration */
|
||||
|
||||
/*
|
||||
* The native part of a JavaPackage object. It gets stored in the object's
|
||||
* private slot.
|
||||
*/
|
||||
typedef struct {
|
||||
const char * path; /* e.g. "java/lang" or NULL if top level package */
|
||||
int flags; /* e.g. PKG_SYSTEM, PKG_CLASS */
|
||||
} JavaPackage_Private;
|
||||
|
||||
static JSObject *
|
||||
define_JavaPackage(JSContext *cx, JSObject *parent_obj,
|
||||
const char *obj_name, const char *path, int flags)
|
||||
{
|
||||
JSObject *package_obj;
|
||||
JavaPackage_Private *package;
|
||||
|
||||
package_obj = JS_DefineObject(cx, parent_obj, obj_name, &JavaPackage_class, 0,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY);
|
||||
if (!package_obj)
|
||||
return NULL;
|
||||
|
||||
/* Attach private, native data to the JS object */
|
||||
package = (JavaPackage_Private *)JS_malloc(cx, sizeof(JavaPackage_Private));
|
||||
JS_SetPrivate(cx, package_obj, (void *)package);
|
||||
if (path)
|
||||
package->path = JS_strdup(cx, path);
|
||||
else
|
||||
package->path = "";
|
||||
|
||||
package->flags = flags;
|
||||
|
||||
/* Check for OOM */
|
||||
if (!package->path) {
|
||||
JS_DeleteProperty(cx, parent_obj, obj_name);
|
||||
JS_free(cx, package);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return package_obj;
|
||||
}
|
||||
|
||||
/* JavaPackage uses standard JS getProperty */
|
||||
|
||||
/*
|
||||
* Don't allow user-defined properties to be set on Java package objects, e.g.
|
||||
* it is illegal to write "java.lang.myProperty = 4". We probably could relax
|
||||
* this restriction, but it's potentially confusing and not clearly useful.
|
||||
*/
|
||||
static JSBool
|
||||
JavaPackage_setProperty(JSContext *cx, JSObject *obj, jsval slot, jsval *vp)
|
||||
{
|
||||
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
|
||||
if (!package) {
|
||||
JS_ReportError(cx, "illegal attempt to add property to "
|
||||
"JavaPackage prototype object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
JS_ReportError(cx, "You may not add properties to a JavaPackage object");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool quiet_resolve_failure;
|
||||
|
||||
/*
|
||||
* Resolve a component name to be either the name of a class or a package.
|
||||
*/
|
||||
static JSBool
|
||||
JavaPackage_resolve(JSContext *cx, JSObject *obj, jsval id)
|
||||
{
|
||||
JavaPackage_Private *package;
|
||||
JSBool ok = JS_TRUE;
|
||||
jclass jclazz;
|
||||
char *subPath, *newPath;
|
||||
const char *path;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
package = (JavaPackage_Private *)JS_GetPrivate(cx, obj);
|
||||
if (!package)
|
||||
return JS_TRUE;
|
||||
|
||||
if (!JSVAL_IS_STRING(id))
|
||||
return JS_TRUE;
|
||||
subPath = JS_GetStringBytes(JSVAL_TO_STRING(id));
|
||||
|
||||
/*
|
||||
* There will be an attempt to invoke the toString() method when producing
|
||||
* the string representation of a JavaPackage. When this occurs, avoid
|
||||
* creating a bogus toString package. (This means that no one can ever
|
||||
* create a package with the simple name "toString", but we'll live with
|
||||
* that limitation.)
|
||||
*/
|
||||
if (!strcmp(subPath, "toString"))
|
||||
return JS_FALSE;
|
||||
|
||||
path = package->path;
|
||||
newPath = PR_smprintf("%s%s%s", path, (path[0] ? "/" : ""), subPath);
|
||||
if (!newPath) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
jsj_MapJSContextToJSJThread(cx, &jEnv);
|
||||
if (!jEnv)
|
||||
return JS_FALSE;
|
||||
|
||||
/*
|
||||
Unfortunately, Java provides no way to find out whether a particular
|
||||
name is a package or not. The only way to tell is to try to load the
|
||||
name as a class file and, if that fails, assume it's a package. This
|
||||
makes things work as expected for the most part, but it has three
|
||||
noticeable problems that keep coming up:
|
||||
|
||||
- You can refer to a package like java.lang.i.buried.paul without
|
||||
generating a complaint. Of course, you'll never be able to refer to
|
||||
any classes through it.
|
||||
|
||||
- An annoying consequence of the above is that misspelling a class name
|
||||
results in a cryptic error about packages.
|
||||
|
||||
- In a browser context, i.e. where applets are involved, figuring out
|
||||
whether something is a class may require looking for it over the net
|
||||
using the current classloader. This means that the first time you
|
||||
refer to java.lang.System in a js context, there will be an attempt
|
||||
to search for [[DOCBASE]]/java.class on the server.
|
||||
|
||||
A solution is to explicitly tell jsjava the names of all the (local)
|
||||
packages on the CLASSPATH. (Not implemented yet.)
|
||||
|
||||
*/
|
||||
jclazz = (*jEnv)->FindClass(jEnv, newPath);
|
||||
if (jclazz) {
|
||||
JSObject *newClass;
|
||||
|
||||
newClass = jsj_define_JavaClass(cx, jEnv, obj, subPath, jclazz);
|
||||
if (!newClass) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
} else {
|
||||
|
||||
/* We assume that any failed attempt to load a class is because it
|
||||
doesn't exist. If we wanted to do a better job, we would check
|
||||
the exception type and make sure that it's NoClassDefFoundError */
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
|
||||
/* beard: this has to be done here, so built-in classes will be defined. */
|
||||
/* Painful hack for pre_define_java_packages() */
|
||||
if (quiet_resolve_failure) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*
|
||||
* If there's no class of the given name, then we must be referring to
|
||||
* a package. However, don't allow bogus sub-packages of pre-defined
|
||||
* system packages to be created.
|
||||
*/
|
||||
if (JS_InstanceOf(cx, obj, &JavaPackage_class, NULL)) {
|
||||
JavaPackage_Private *package;
|
||||
|
||||
package = JS_GetPrivate(cx, obj);
|
||||
if (package->flags & PKG_SYSTEM) {
|
||||
char *msg, *cp;
|
||||
|
||||
msg = PR_smprintf("No Java system package with name \"%s\" was identified "
|
||||
"and no Java class with that name exists either",
|
||||
newPath);
|
||||
|
||||
/* Check for OOM */
|
||||
if (msg) {
|
||||
/* Convert package of form "java/lang" to "java.lang" */
|
||||
for (cp = msg; *cp != '\0'; cp++)
|
||||
if (*cp == '/')
|
||||
*cp = '.';
|
||||
JS_ReportError(cx, msg);
|
||||
free((char*)msg);
|
||||
}
|
||||
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (!define_JavaPackage(cx, obj, subPath, newPath, 0)) {
|
||||
ok = JS_FALSE;
|
||||
goto out;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
/* printf("JavaPackage \'%s\' created\n", newPath); */
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
out:
|
||||
free(newPath);
|
||||
return ok;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaPackage_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp)
|
||||
{
|
||||
JSString *str;
|
||||
char *name, *cp;
|
||||
|
||||
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
|
||||
if (!package) {
|
||||
fprintf(stderr, "JavaPackage_resolve: no private data!\n");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
|
||||
/* Pretty-printing of JavaPackage */
|
||||
case JSTYPE_VOID: /* Default value */
|
||||
case JSTYPE_NUMBER:
|
||||
case JSTYPE_STRING:
|
||||
/* Convert '/' to '.' so that it looks like Java language syntax. */
|
||||
if (!package->path)
|
||||
break;
|
||||
name = PR_smprintf("[JavaPackage %s]", package->path);
|
||||
if (!name) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return JS_FALSE;
|
||||
}
|
||||
for (cp = name; *cp != '\0'; cp++)
|
||||
if (*cp == '/')
|
||||
*cp = '.';
|
||||
str = JS_NewString(cx, name, strlen(name));
|
||||
if (!str) {
|
||||
free(name);
|
||||
/* It's not necessary to call JS_ReportOutOfMemory(), as
|
||||
JS_NewString() will do so on failure. */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
*vp = STRING_TO_JSVAL(str);
|
||||
break;
|
||||
|
||||
case JSTYPE_OBJECT:
|
||||
*vp = OBJECT_TO_JSVAL(obj);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free the private native data associated with the JavaPackage object.
|
||||
*/
|
||||
static void
|
||||
JavaPackage_finalize(JSContext *cx, JSObject *obj)
|
||||
{
|
||||
JavaPackage_Private *package = JS_GetPrivate(cx, obj);
|
||||
if (!package)
|
||||
return;
|
||||
|
||||
if (package->path)
|
||||
JS_free(cx, (char *)package->path);
|
||||
JS_free(cx, package);
|
||||
}
|
||||
|
||||
/*
|
||||
* The definition of the JavaPackage class
|
||||
*/
|
||||
JSClass JavaPackage_class = {
|
||||
"JavaPackage", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, JS_PropertyStub, JavaPackage_setProperty,
|
||||
JS_EnumerateStub, JavaPackage_resolve,
|
||||
JavaPackage_convert, JavaPackage_finalize
|
||||
};
|
||||
|
||||
JavaPackageDef
|
||||
standard_java_packages[] = {
|
||||
{"java", NULL, PKG_USER},
|
||||
{"java.applet", NULL, PKG_USER},
|
||||
{"java.awt", NULL, PKG_USER},
|
||||
{"java.awt.datatransfer",
|
||||
NULL, PKG_SYSTEM},
|
||||
{"java.awt.event", NULL, PKG_SYSTEM},
|
||||
{"java.awt.image", NULL, PKG_SYSTEM},
|
||||
{"java.awt.peer", NULL, PKG_SYSTEM},
|
||||
{"java.beans", NULL, PKG_USER},
|
||||
{"java.io", NULL, PKG_SYSTEM},
|
||||
{"java.lang", NULL, PKG_USER},
|
||||
{"java.lang.reflect", NULL, PKG_SYSTEM},
|
||||
{"java.math", NULL, PKG_SYSTEM},
|
||||
{"java.net", NULL, PKG_USER},
|
||||
{"java.rmi", NULL, PKG_USER},
|
||||
{"java.rmi.dgc", NULL, PKG_USER},
|
||||
{"java.rmi.user", NULL, PKG_USER},
|
||||
{"java.rmi.registry", NULL, PKG_USER},
|
||||
{"java.rmi.server", NULL, PKG_USER},
|
||||
{"java.security", NULL, PKG_USER},
|
||||
{"java.security.acl", NULL, PKG_SYSTEM},
|
||||
{"java.security.interfaces",
|
||||
NULL, PKG_SYSTEM},
|
||||
{"java.sql", NULL, PKG_USER},
|
||||
{"java.text", NULL, PKG_USER},
|
||||
{"java.text.resources", NULL, PKG_SYSTEM},
|
||||
{"java.util", NULL, PKG_USER},
|
||||
{"java.util.zip", NULL, PKG_SYSTEM},
|
||||
|
||||
{"netscape", NULL, PKG_USER},
|
||||
{"netscape.applet", NULL, PKG_SYSTEM},
|
||||
{"netscape.application",NULL, PKG_SYSTEM},
|
||||
{"netscape.debug", NULL, PKG_SYSTEM},
|
||||
{"netscape.javascript", NULL, PKG_SYSTEM},
|
||||
{"netscape.ldap", NULL, PKG_SYSTEM},
|
||||
{"netscape.misc", NULL, PKG_SYSTEM},
|
||||
{"netscape.net", NULL, PKG_SYSTEM},
|
||||
{"netscape.plugin", NULL, PKG_SYSTEM},
|
||||
{"netscape.util", NULL, PKG_SYSTEM},
|
||||
{"netscape.secfile", NULL, PKG_SYSTEM},
|
||||
{"netscape.security", NULL, PKG_SYSTEM},
|
||||
{"netscape.WAI", NULL, PKG_SYSTEM},
|
||||
|
||||
{"sun", NULL, PKG_USER},
|
||||
{"Packages", "", PKG_USER},
|
||||
|
||||
{NULL, NULL, 0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Pre-define a hierarchy of JavaPackage objects.
|
||||
* Pre-defining a Java package at initialization time is not necessary, but
|
||||
* it will make package lookup faster and, more importantly, will avoid
|
||||
* unnecessary network accesses if classes are being loaded over the network.
|
||||
*/
|
||||
static JSBool
|
||||
pre_define_java_packages(JSContext *cx, JSObject *global_obj,
|
||||
JavaPackageDef *predefined_packages)
|
||||
{
|
||||
JSBool package_exists;
|
||||
JSObject *parent_obj;
|
||||
JavaPackageDef *package_def;
|
||||
char *simple_name, *cp, *package_name, *path;
|
||||
int flags;
|
||||
|
||||
if (!predefined_packages)
|
||||
return JS_TRUE;
|
||||
|
||||
/* Iterate over all pre-defined Java packages */
|
||||
for (package_def = predefined_packages; package_def->name; package_def++) {
|
||||
package_name = path = NULL;
|
||||
|
||||
parent_obj = global_obj;
|
||||
package_name = strdup(package_def->name);
|
||||
if (!package_name)
|
||||
goto out_of_memory;
|
||||
|
||||
/* Walk the chain of JavaPackage objects to get to the parent of the
|
||||
rightmost sub-package in the fully-qualified package name. */
|
||||
for (simple_name = strtok(package_name, "."); 1; simple_name = strtok(NULL, ".")) {
|
||||
jsval v;
|
||||
|
||||
if (!simple_name) {
|
||||
JS_ReportError(cx, "Package %s defined twice ?", package_name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Check to see if the sub-package already exists */
|
||||
quiet_resolve_failure = JS_TRUE;
|
||||
package_exists = JS_LookupProperty(cx, parent_obj, simple_name, &v) && JSVAL_IS_OBJECT(v);
|
||||
quiet_resolve_failure = JS_FALSE;
|
||||
|
||||
if (package_exists) {
|
||||
parent_obj = JSVAL_TO_OBJECT(v);
|
||||
continue;
|
||||
} else {
|
||||
/* New package objects should only be created at the terminal
|
||||
sub-package in a fully-qualified package-name */
|
||||
if (strtok(NULL, ".")) {
|
||||
JS_ReportError(cx, "Illegal predefined package definition for %s",
|
||||
package_def->name);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (package_def->path) {
|
||||
path = strdup(package_def->path);
|
||||
if (!path)
|
||||
goto out_of_memory;
|
||||
} else {
|
||||
|
||||
/*
|
||||
* The default path is specified, so create it from the
|
||||
* fully-qualified package name.
|
||||
*/
|
||||
path = strdup(package_def->name);
|
||||
if (!path)
|
||||
goto out_of_memory;
|
||||
/* Transform package name, e.g. "java.lang" ==> "java/lang" */
|
||||
for (cp = path; *cp != '\0'; cp++) {
|
||||
if (*cp == '.')
|
||||
*cp = '/';
|
||||
}
|
||||
}
|
||||
flags = package_def->flags;
|
||||
parent_obj = define_JavaPackage(cx, parent_obj, simple_name, path, flags);
|
||||
if (!parent_obj)
|
||||
goto error;
|
||||
|
||||
free(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
free(package_name);
|
||||
}
|
||||
return JS_TRUE;
|
||||
|
||||
out_of_memory:
|
||||
JS_ReportOutOfMemory(cx);
|
||||
|
||||
error:
|
||||
JS_FREE_IF(cx, package_name);
|
||||
JS_FREE_IF(cx, path);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
JavaPackage_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
jsval *rval)
|
||||
{
|
||||
if (!JS_InstanceOf(cx, obj, &JavaPackage_class, argv))
|
||||
return JS_FALSE;
|
||||
return JavaPackage_convert(cx, obj, JSTYPE_STRING, rval);
|
||||
}
|
||||
|
||||
static JSFunctionSpec JavaPackage_methods[] = {
|
||||
{"toString", JavaPackage_toString, 0},
|
||||
{0}
|
||||
};
|
||||
|
||||
/*
|
||||
* One-time initialization for the JavaPackage class. (This is not
|
||||
* run once per thread, rather it's run once for a given JSContext.)
|
||||
*/
|
||||
JSBool
|
||||
jsj_init_JavaPackage(JSContext *cx, JSObject *global_obj,
|
||||
JavaPackageDef *additional_predefined_packages) {
|
||||
|
||||
/* Define JavaPackage class */
|
||||
if (!JS_InitClass(cx, global_obj, 0, &JavaPackage_class,
|
||||
0, 0, 0, JavaPackage_methods, 0, 0))
|
||||
return JS_FALSE;
|
||||
|
||||
/* Add top-level packages, e.g. : java, netscape, sun */
|
||||
if (!pre_define_java_packages(cx, global_obj, standard_java_packages))
|
||||
return JS_FALSE;
|
||||
if (!pre_define_java_packages(cx, global_obj, additional_predefined_packages))
|
||||
return JS_FALSE;
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
180
mozilla/js/src/liveconnect/jsj_array.c
Normal file
180
mozilla/js/src/liveconnect/jsj_array.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the code for reading and writing elements of a Java array.
|
||||
*/
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
/*
|
||||
* Read the Java value at a given index into a Java array and convert it
|
||||
* to a JS value. The array_component_signature describes the type of
|
||||
* the resulting Java value, which can be a primitive type or an object type.
|
||||
* More specifically it can be an array type in the case of multidimensional
|
||||
* arrays.
|
||||
*/
|
||||
JSBool
|
||||
jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index,
|
||||
JavaSignature *array_component_signature,
|
||||
jsval *vp)
|
||||
{
|
||||
jvalue java_value;
|
||||
JavaSignatureChar component_type;
|
||||
|
||||
#define GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
|
||||
(*jEnv)->Get##Type##ArrayRegion(jEnv, java_array, index, 1, \
|
||||
&java_value.member); \
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
|
||||
jsj_ReportJavaError(cx, jEnv, "Error reading element of " \
|
||||
"Java primitive array"); \
|
||||
return JS_FALSE; \
|
||||
}
|
||||
|
||||
component_type = array_component_signature->type;
|
||||
switch(component_type) {
|
||||
case JAVA_SIGNATURE_BYTE:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CHAR:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_SHORT:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_INT:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_LONG:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_FLOAT:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_DOUBLE:
|
||||
GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
java_value.l = (*jEnv)->GetObjectArrayElement(jEnv, java_array, index);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_ReportJavaError(cx, jEnv, "Error reading Java object array");
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
#undef GET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return jsj_ConvertJavaValueToJSValue(cx, jEnv, array_component_signature, &java_value, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array, jsize index,
|
||||
JavaSignature *array_component_signature,
|
||||
jsval js_val)
|
||||
{
|
||||
int dummy_cost;
|
||||
jvalue java_value;
|
||||
JavaSignatureChar component_type;
|
||||
JSBool is_local_ref;
|
||||
|
||||
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, array_component_signature,
|
||||
&dummy_cost, &java_value, &is_local_ref))
|
||||
return JS_FALSE;
|
||||
|
||||
#define SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Type,member) \
|
||||
(*jEnv)->Set##Type##ArrayRegion(jEnv, java_array, index, 1, \
|
||||
&java_value.member); \
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
|
||||
jsj_ReportJavaError(cx, jEnv, "Error assigning to element of " \
|
||||
"Java primitive array"); \
|
||||
return JS_FALSE; \
|
||||
}
|
||||
|
||||
component_type = array_component_signature->type;
|
||||
switch(component_type) {
|
||||
case JAVA_SIGNATURE_BYTE:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Byte,b);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CHAR:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Char,c);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_SHORT:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Short,s);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_INT:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Int,i);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Boolean,z);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_LONG:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Long,j);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_FLOAT:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Float,f);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_DOUBLE:
|
||||
SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
(*jEnv)->SetObjectArrayElement(jEnv, java_array, index, java_value.l);
|
||||
if (is_local_ref) \
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_ReportJavaError(cx, jEnv, "Error assigning to Java object array");
|
||||
return JS_FALSE;
|
||||
}
|
||||
break;
|
||||
|
||||
#undef SET_ELEMENT_FROM_PRIMITIVE_JAVA_ARRAY
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
605
mozilla/js/src/liveconnect/jsj_class.c
Normal file
605
mozilla/js/src/liveconnect/jsj_class.c
Normal file
@@ -0,0 +1,605 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the code that constructs and manipulates JavaClassDescriptor
|
||||
* structs, which are the native wrappers for Java classes.
|
||||
* JavaClassDescriptors are used to describe the signatures of methods and
|
||||
* fields. There is a JavaClassDescriptor associated with the reflection of
|
||||
* each Java Object.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jsj_hash.h" /* Hash tables */
|
||||
|
||||
/* A one-to-one mapping between all referenced java.lang.Class objects and
|
||||
their corresponding JavaClassDescriptor objects */
|
||||
static JSJHashTable *java_class_reflections;
|
||||
|
||||
/*
|
||||
* Given a JVM handle to a java.lang.Class object, malloc a C-string
|
||||
* containing the UTF8 encoding of the fully qualified name of the class.
|
||||
* It's the caller's responsibility to free the returned string.
|
||||
*
|
||||
* If an error occurs, NULL is returned and the error reporter called.
|
||||
*/
|
||||
const char *
|
||||
jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
||||
{
|
||||
jstring java_class_name_jstr;
|
||||
const char *java_class_name;
|
||||
|
||||
/* Get java.lang.String object containing class name */
|
||||
java_class_name_jstr =
|
||||
(*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getName);
|
||||
|
||||
|
||||
if (!java_class_name_jstr)
|
||||
goto error;
|
||||
|
||||
/* Convert to UTF8 encoding and copy */
|
||||
java_class_name = jsj_DupJavaStringUTF(cx, jEnv, java_class_name_jstr);
|
||||
if (!java_class_name)
|
||||
return NULL;
|
||||
|
||||
return java_class_name;
|
||||
|
||||
error:
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Can't get Java class name using"
|
||||
"java.lang.Class.getName()");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert in-place a string of the form "java.lang.String" into "java/lang/String".
|
||||
* Though the former style is conventionally used by Java programmers, the latter is
|
||||
* what the JNI functions require.
|
||||
*/
|
||||
void
|
||||
jsj_MakeJNIClassname(char * class_name)
|
||||
{
|
||||
char * c;
|
||||
for (c = class_name; *c; c++)
|
||||
if (*c == '.')
|
||||
*c = '/';
|
||||
}
|
||||
|
||||
/*
|
||||
* Classify an instance of java.lang.Class as either one of the primitive
|
||||
* types, e.g. int, char, etc., as an array type or as a non-array object type
|
||||
* (subclass of java.lang.Object) by returning the appropriate enum member.
|
||||
*
|
||||
*/
|
||||
static JavaSignatureChar
|
||||
get_signature_type(JSContext *cx, JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
JavaSignatureChar type;
|
||||
const char *java_class_name;
|
||||
|
||||
/* Get UTF8 encoding of class name */
|
||||
java_class_name = class_descriptor->name;
|
||||
PR_ASSERT(java_class_name);
|
||||
if (!java_class_name)
|
||||
return JAVA_SIGNATURE_UNKNOWN;
|
||||
|
||||
if (!strcmp(java_class_name, "byte"))
|
||||
type = JAVA_SIGNATURE_BYTE;
|
||||
else if (!strcmp(java_class_name, "char"))
|
||||
type = JAVA_SIGNATURE_CHAR;
|
||||
else if (!strcmp(java_class_name, "float"))
|
||||
type = JAVA_SIGNATURE_FLOAT;
|
||||
else if (!strcmp(java_class_name, "double"))
|
||||
type = JAVA_SIGNATURE_DOUBLE;
|
||||
else if (!strcmp(java_class_name, "int"))
|
||||
type = JAVA_SIGNATURE_INT;
|
||||
else if (!strcmp(java_class_name, "long"))
|
||||
type = JAVA_SIGNATURE_LONG;
|
||||
else if (!strcmp(java_class_name, "short"))
|
||||
type = JAVA_SIGNATURE_SHORT;
|
||||
else if (!strcmp(java_class_name, "boolean"))
|
||||
type = JAVA_SIGNATURE_BOOLEAN;
|
||||
else if (!strcmp(java_class_name, "void"))
|
||||
type = JAVA_SIGNATURE_VOID;
|
||||
else
|
||||
/* Well, I guess it's a Java class, then. */
|
||||
type = JAVA_SIGNATURE_CLASS;
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
is_java_array_class(JNIEnv *jEnv, jclass java_class)
|
||||
{
|
||||
return (*jEnv)->CallBooleanMethod(jEnv, java_class, jlClass_isArray);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return the class of a Java array's component type. This is not the same
|
||||
* as the array's element type. For example, the component type of an array
|
||||
* of type SomeType[][][] is SomeType[][], but its element type is SomeType.
|
||||
*
|
||||
* If an error occurs, NULL is returned and an error reported.
|
||||
*/
|
||||
static jclass
|
||||
get_java_array_component_class(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
||||
{
|
||||
jclass result;
|
||||
result = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getComponentType);
|
||||
if (!result) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Can't get Java array component class using "
|
||||
"java.lang.Class.getComponentType()");
|
||||
return NULL;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given a Java class, fill in the signature structure that describes the class.
|
||||
* If an error occurs, JS_FALSE is returned and the error reporter called.
|
||||
*/
|
||||
static JSBool
|
||||
compute_java_class_signature(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature)
|
||||
{
|
||||
jclass java_class = signature->java_class;
|
||||
|
||||
if (is_java_array_class(jEnv, java_class)) {
|
||||
jclass component_class;
|
||||
|
||||
signature->type = JAVA_SIGNATURE_ARRAY;
|
||||
|
||||
component_class = get_java_array_component_class(cx, jEnv, java_class);
|
||||
if (!component_class)
|
||||
return JS_FALSE;
|
||||
|
||||
signature->array_component_signature =
|
||||
jsj_GetJavaClassDescriptor(cx, jEnv, component_class);
|
||||
if (!signature->array_component_signature)
|
||||
return JS_FALSE;
|
||||
} else {
|
||||
signature->type = get_signature_type(cx, signature);
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a JavaSignature object into a string format as used by
|
||||
* the JNI functions, e.g. java.lang.Object ==> "Ljava/lang/Object;"
|
||||
* The caller is responsible for freeing the resulting string.
|
||||
*
|
||||
* If an error is encountered, NULL is returned and an error reported.
|
||||
*/
|
||||
const char *
|
||||
jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature)
|
||||
{
|
||||
char *sig;
|
||||
|
||||
if (signature->type == JAVA_SIGNATURE_CLASS) {
|
||||
/* A non-array object class */
|
||||
sig = PR_smprintf("L%s;", signature->name);
|
||||
if (sig)
|
||||
jsj_MakeJNIClassname(sig);
|
||||
|
||||
} else if (signature->type == JAVA_SIGNATURE_ARRAY) {
|
||||
/* An array class */
|
||||
const char *component_signature_string;
|
||||
|
||||
component_signature_string =
|
||||
jsj_ConvertJavaSignatureToString(cx, signature->array_component_signature);
|
||||
if (!component_signature_string)
|
||||
return NULL;
|
||||
sig = PR_smprintf("[%s", component_signature_string);
|
||||
JS_free(cx, (char*)component_signature_string);
|
||||
|
||||
} else {
|
||||
/* A primitive class */
|
||||
sig = PR_smprintf("%c", (char)signature->type);
|
||||
}
|
||||
|
||||
if (!sig) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a JavaSignature object into a human-readable string format as seen
|
||||
* in Java source files, e.g. "byte", or "int[][]" or "java.lang.String".
|
||||
* The caller is responsible for freeing the resulting string.
|
||||
*
|
||||
* If an error is encountered, NULL is returned and an error reported.
|
||||
*/
|
||||
const char *
|
||||
jsj_ConvertJavaSignatureToHRString(JSContext *cx,
|
||||
JavaSignature *signature)
|
||||
{
|
||||
char *sig;
|
||||
JavaSignature *acs;
|
||||
|
||||
if (signature->type == JAVA_SIGNATURE_ARRAY) {
|
||||
/* An array class */
|
||||
const char *component_signature_string;
|
||||
acs = signature->array_component_signature;
|
||||
component_signature_string =
|
||||
jsj_ConvertJavaSignatureToHRString(cx, acs);
|
||||
if (!component_signature_string)
|
||||
return NULL;
|
||||
sig = PR_smprintf("%s[]", component_signature_string);
|
||||
JS_free(cx, (char*)component_signature_string);
|
||||
|
||||
} else {
|
||||
/* A primitive class or a non-array object class */
|
||||
sig = JS_strdup(cx, signature->name);
|
||||
}
|
||||
|
||||
if (!sig) {
|
||||
JS_ReportOutOfMemory(cx);
|
||||
return NULL;
|
||||
}
|
||||
return sig;
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_java_member_descriptor(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor)
|
||||
{
|
||||
JavaMethodSpec *method, *next_method;
|
||||
if (member_descriptor->field)
|
||||
jsj_DestroyFieldSpec(cx, jEnv, member_descriptor->field);
|
||||
|
||||
method = member_descriptor->methods;
|
||||
while (method) {
|
||||
next_method = method->next;
|
||||
jsj_DestroyMethodSpec(cx, jEnv, method);
|
||||
method = next_method;
|
||||
}
|
||||
|
||||
if (member_descriptor->invoke_func_obj)
|
||||
JS_RemoveRoot(cx, &member_descriptor->invoke_func_obj);
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_class_member_descriptors(JSContext *cx, JNIEnv *jEnv, JavaMemberDescriptor *member_descriptor)
|
||||
{
|
||||
JavaMemberDescriptor *next_member;
|
||||
|
||||
while (member_descriptor) {
|
||||
next_member = member_descriptor->next;
|
||||
destroy_java_member_descriptor(cx, jEnv, member_descriptor);
|
||||
member_descriptor = next_member;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
destroy_class_descriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
JS_FREE_IF(cx, (char *)class_descriptor->name);
|
||||
if (class_descriptor->java_class) {
|
||||
JSJ_HashTableRemove(java_class_reflections,
|
||||
class_descriptor->java_class, (void*)jEnv);
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, class_descriptor->java_class);
|
||||
}
|
||||
|
||||
if (class_descriptor->array_component_signature)
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, class_descriptor->array_component_signature);
|
||||
|
||||
destroy_class_member_descriptors(cx, jEnv, class_descriptor->instance_members);
|
||||
destroy_class_member_descriptors(cx, jEnv, class_descriptor->static_members);
|
||||
destroy_class_member_descriptors(cx, jEnv, class_descriptor->constructors);
|
||||
JS_free(cx, class_descriptor);
|
||||
}
|
||||
|
||||
static JavaClassDescriptor *
|
||||
new_class_descriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
||||
{
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
class_descriptor = (JavaClassDescriptor *)JS_malloc(cx, sizeof(JavaClassDescriptor));
|
||||
if (!class_descriptor)
|
||||
return NULL;
|
||||
memset(class_descriptor, 0, sizeof(JavaClassDescriptor));
|
||||
|
||||
class_descriptor->name = jsj_GetJavaClassName(cx, jEnv, java_class);
|
||||
if (!class_descriptor->name)
|
||||
goto error;
|
||||
|
||||
java_class = (*jEnv)->NewGlobalRef(jEnv, java_class);
|
||||
if (!java_class) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Unable to reference Java class");
|
||||
goto error;
|
||||
}
|
||||
class_descriptor->java_class = java_class;
|
||||
|
||||
if (!compute_java_class_signature(cx, jEnv, class_descriptor))
|
||||
goto error;
|
||||
|
||||
class_descriptor->modifiers =
|
||||
(*jEnv)->CallIntMethod(jEnv, java_class, jlClass_getModifiers);
|
||||
class_descriptor->ref_count = 1;
|
||||
|
||||
if (!JSJ_HashTableAdd(java_class_reflections, java_class, class_descriptor,
|
||||
(void*)jEnv))
|
||||
goto error;
|
||||
|
||||
return class_descriptor;
|
||||
|
||||
error:
|
||||
destroy_class_descriptor(cx, jEnv, class_descriptor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Trivial helper for jsj_DiscardJavaClassReflections(), below */
|
||||
static PRIntn
|
||||
enumerate_remove_java_class(JSJHashEntry *he, PRIntn i, void *arg)
|
||||
{
|
||||
JNIEnv *jEnv = (JNIEnv*)arg;
|
||||
jclass java_class;
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
|
||||
class_descriptor = (JavaClassDescriptor*)he->value;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
(*jEnv)->DeleteGlobalRef(jEnv, java_class);
|
||||
class_descriptor->java_class = NULL;
|
||||
|
||||
return HT_ENUMERATE_REMOVE;
|
||||
}
|
||||
|
||||
/* This shutdown routine discards all JNI references to Java objects
|
||||
that have been reflected into JS, even if there are still references
|
||||
to them from JS. */
|
||||
void
|
||||
jsj_DiscardJavaClassReflections(JNIEnv *jEnv)
|
||||
{
|
||||
if (java_class_reflections) {
|
||||
JSJ_HashTableEnumerateEntries(java_class_reflections,
|
||||
enumerate_remove_java_class,
|
||||
(void*)jEnv);
|
||||
JSJ_HashTableDestroy(java_class_reflections);
|
||||
java_class_reflections = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern JavaClassDescriptor *
|
||||
jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class)
|
||||
{
|
||||
JavaClassDescriptor *class_descriptor;
|
||||
class_descriptor = JSJ_HashTableLookup(java_class_reflections,
|
||||
(const void *)java_class,
|
||||
(void*)jEnv);
|
||||
if (!class_descriptor)
|
||||
return new_class_descriptor(cx, jEnv, java_class);
|
||||
|
||||
PR_ASSERT(class_descriptor->ref_count > 0);
|
||||
class_descriptor->ref_count++;
|
||||
return class_descriptor;
|
||||
}
|
||||
|
||||
void
|
||||
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (!--class_descriptor->ref_count)
|
||||
destroy_class_descriptor(cx, jEnv, class_descriptor);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
reflect_java_methods_and_fields(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
JSBool reflect_statics_only)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
|
||||
if (reflect_statics_only)
|
||||
class_descriptor->static_members_reflected = JS_TRUE;
|
||||
else
|
||||
class_descriptor->instance_members_reflected = JS_TRUE;
|
||||
|
||||
if (!jsj_ReflectJavaMethods(cx, jEnv, class_descriptor, reflect_statics_only))
|
||||
return JS_FALSE;
|
||||
if (!jsj_ReflectJavaFields(cx, jEnv, class_descriptor, reflect_statics_only))
|
||||
return JS_FALSE;
|
||||
|
||||
if (reflect_statics_only) {
|
||||
member_descriptor = class_descriptor->static_members;
|
||||
while (member_descriptor) {
|
||||
class_descriptor->num_static_members++;
|
||||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
} else {
|
||||
member_descriptor = class_descriptor->instance_members;
|
||||
while (member_descriptor) {
|
||||
class_descriptor->num_instance_members++;
|
||||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_GetClassStaticMembers(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (!class_descriptor->static_members_reflected)
|
||||
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
|
||||
return class_descriptor->static_members;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_GetClassInstanceMembers(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (!class_descriptor->instance_members_reflected)
|
||||
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_FALSE);
|
||||
return class_descriptor->instance_members;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jsid id)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
|
||||
member_descriptor = jsj_GetClassStaticMembers(cx, jEnv, class_descriptor);
|
||||
while (member_descriptor) {
|
||||
if (id == member_descriptor->id)
|
||||
return member_descriptor;
|
||||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_GetJavaStaticMemberDescriptor(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jstring member_name_jstr)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
jsid id;
|
||||
|
||||
if (!JavaStringToId(cx, jEnv, member_name_jstr, &id))
|
||||
return NULL;
|
||||
|
||||
member_descriptor = jsj_LookupJavaStaticMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (member_descriptor)
|
||||
return member_descriptor;
|
||||
|
||||
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
|
||||
if (!member_descriptor)
|
||||
return NULL;
|
||||
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
|
||||
|
||||
member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr);
|
||||
if (!member_descriptor->name) {
|
||||
JS_free(cx, member_descriptor);
|
||||
return NULL;
|
||||
}
|
||||
member_descriptor->id = id;
|
||||
|
||||
member_descriptor->next = class_descriptor->static_members;
|
||||
class_descriptor->static_members = member_descriptor;
|
||||
|
||||
return member_descriptor;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_GetJavaClassConstructors(JSContext *cx,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
|
||||
if (class_descriptor->constructors)
|
||||
return class_descriptor->constructors;
|
||||
|
||||
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
|
||||
if (!member_descriptor)
|
||||
return NULL;
|
||||
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
|
||||
|
||||
member_descriptor->name = JS_strdup(cx, "<init>");
|
||||
if (!member_descriptor->name) {
|
||||
JS_free(cx, member_descriptor);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
class_descriptor->constructors = member_descriptor;
|
||||
|
||||
return member_descriptor;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor)
|
||||
{
|
||||
if (!class_descriptor->static_members_reflected)
|
||||
reflect_java_methods_and_fields(cx, jEnv, class_descriptor, JS_TRUE);
|
||||
return class_descriptor->constructors;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jsid id)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
|
||||
member_descriptor = jsj_GetClassInstanceMembers(cx, jEnv, class_descriptor);
|
||||
while (member_descriptor) {
|
||||
if (id == member_descriptor->id)
|
||||
return member_descriptor;
|
||||
member_descriptor = member_descriptor->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
JavaMemberDescriptor *
|
||||
jsj_GetJavaMemberDescriptor(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jstring member_name_jstr)
|
||||
{
|
||||
JavaMemberDescriptor *member_descriptor;
|
||||
jsid id;
|
||||
|
||||
if (!JavaStringToId(cx, jEnv, member_name_jstr, &id))
|
||||
return NULL;
|
||||
|
||||
member_descriptor = jsj_LookupJavaMemberDescriptorById(cx, jEnv, class_descriptor, id);
|
||||
if (member_descriptor)
|
||||
return member_descriptor;
|
||||
|
||||
member_descriptor = JS_malloc(cx, sizeof(JavaMemberDescriptor));
|
||||
if (!member_descriptor)
|
||||
return NULL;
|
||||
memset(member_descriptor, 0, sizeof(JavaMemberDescriptor));
|
||||
|
||||
member_descriptor->name = jsj_DupJavaStringUTF(cx, jEnv, member_name_jstr);
|
||||
if (!member_descriptor->name) {
|
||||
JS_free(cx, member_descriptor);
|
||||
return NULL;
|
||||
}
|
||||
member_descriptor->id = id;
|
||||
|
||||
member_descriptor->next = class_descriptor->instance_members;
|
||||
class_descriptor->instance_members = member_descriptor;
|
||||
|
||||
return member_descriptor;
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsj_InitJavaClassReflectionsTable()
|
||||
{
|
||||
java_class_reflections =
|
||||
JSJ_NewHashTable(64, jsj_HashJavaObject, jsj_JavaObjectComparator,
|
||||
NULL, NULL, NULL);
|
||||
|
||||
if (!java_class_reflections)
|
||||
return JS_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
806
mozilla/js/src/liveconnect/jsj_convert.c
Normal file
806
mozilla/js/src/liveconnect/jsj_convert.c
Normal file
@@ -0,0 +1,806 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* Below is the code that converts between Java and JavaScript values of all
|
||||
* types.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
/* Floating-point double utilities, stolen from jsnum.h */
|
||||
#ifdef IS_LITTLE_ENDIAN
|
||||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[1])
|
||||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[0])
|
||||
#else
|
||||
#define JSDOUBLE_HI32(x) (((uint32 *)&(x))[0])
|
||||
#define JSDOUBLE_LO32(x) (((uint32 *)&(x))[1])
|
||||
#endif
|
||||
#define JSDOUBLE_HI32_SIGNBIT 0x80000000
|
||||
#define JSDOUBLE_HI32_EXPMASK 0x7ff00000
|
||||
#define JSDOUBLE_HI32_MANTMASK 0x000fffff
|
||||
|
||||
#define JSDOUBLE_IS_NaN(x) \
|
||||
((JSDOUBLE_HI32(x) & JSDOUBLE_HI32_EXPMASK) == JSDOUBLE_HI32_EXPMASK && \
|
||||
(JSDOUBLE_LO32(x) || (JSDOUBLE_HI32(x) & JSDOUBLE_HI32_MANTMASK)))
|
||||
|
||||
#define JSDOUBLE_IS_INFINITE(x) \
|
||||
((JSDOUBLE_HI32(x) & ~JSDOUBLE_HI32_SIGNBIT) == JSDOUBLE_HI32_EXPMASK && \
|
||||
!JSDOUBLE_LO32(x))
|
||||
|
||||
static JSBool
|
||||
convert_js_obj_to_JSObject_wrapper(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj,
|
||||
JavaSignature *signature,
|
||||
int *cost, jobject *java_value)
|
||||
{
|
||||
if (!njJSObject) {
|
||||
if (java_value)
|
||||
JS_ReportError(cx, "Couldn't convert JavaScript object to an "
|
||||
"instance of netscape.javascript.JSObject "
|
||||
"because that class could not be loaded.");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
if (!(*jEnv)->IsAssignableFrom(jEnv, njJSObject, signature->java_class))
|
||||
return JS_FALSE;
|
||||
|
||||
if (!java_value)
|
||||
return JS_TRUE;
|
||||
|
||||
*java_value = jsj_WrapJSObject(cx, jEnv, js_obj);
|
||||
|
||||
return (*java_value != NULL);
|
||||
}
|
||||
|
||||
jstring
|
||||
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str)
|
||||
{
|
||||
jstring result;
|
||||
result = (*jEnv)->NewString(jEnv, JS_GetStringChars(js_str),
|
||||
JS_GetStringLength(js_str));
|
||||
if (!result) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance "
|
||||
"of java.lang.String");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a JS value to an instance of java.lang.Object or one of its subclasses,
|
||||
* performing any necessary type coercion. If non-trivial coercion is required,
|
||||
* the cost value is incremented. If the java_value pass-by-reference argument
|
||||
* is non-NULL, the resulting Java value is stored there.
|
||||
*
|
||||
* Returns JS_TRUE if the conversion is possible, JS_FALSE otherwise
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
|
||||
int *cost, jobject *java_value, JSBool *is_local_refp)
|
||||
{
|
||||
JSString *jsstr;
|
||||
jclass target_java_class;
|
||||
|
||||
PR_ASSERT(signature->type == JAVA_SIGNATURE_CLASS ||
|
||||
signature->type == JAVA_SIGNATURE_ARRAY);
|
||||
|
||||
/* Initialize to default case, in which no new Java object is
|
||||
synthesized to perform the conversion and, therefore, no JNI local
|
||||
references are being held. */
|
||||
*is_local_refp = JS_FALSE;
|
||||
|
||||
/* Get the Java type of the target value */
|
||||
target_java_class = signature->java_class;
|
||||
|
||||
if (JSVAL_IS_OBJECT(v)) {
|
||||
JSObject *js_obj = JSVAL_TO_OBJECT(v);
|
||||
|
||||
/* JS null is always assignable to a Java object */
|
||||
if (!js_obj) {
|
||||
if (java_value)
|
||||
*java_value = NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
if (JS_InstanceOf(cx, js_obj, &JavaObject_class, 0) ||
|
||||
JS_InstanceOf(cx, js_obj, &JavaArray_class, 0)) {
|
||||
|
||||
/* The source value is a Java object wrapped inside a JavaScript
|
||||
object. Unwrap the JS object and return the original Java
|
||||
object if it's class makes it assignment-compatible with the
|
||||
target class using Java's assignability rules. */
|
||||
JavaObjectWrapper *java_wrapper = JS_GetPrivate(cx, js_obj);
|
||||
jobject java_obj = java_wrapper->java_obj;
|
||||
|
||||
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, target_java_class)) {
|
||||
if (java_value)
|
||||
*java_value = java_obj;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
/* Don't allow wrapped Java objects to be converted to strings */
|
||||
goto conversion_error;
|
||||
#else
|
||||
/* Fall through, to attempt conversion to a Java string */
|
||||
#endif
|
||||
|
||||
} else if (JS_InstanceOf(cx, js_obj, &JavaClass_class, 0)) {
|
||||
/* We're dealing with the reflection of a Java class */
|
||||
JavaClassDescriptor *java_class_descriptor = JS_GetPrivate(cx, js_obj);
|
||||
|
||||
/* Check if target type is java.lang.Class class */
|
||||
if ((*jEnv)->IsAssignableFrom(jEnv, jlClass, target_java_class)) {
|
||||
if (java_value)
|
||||
*java_value = java_class_descriptor->java_class;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Check if target type is netscape.javascript.JSObject wrapper class */
|
||||
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
|
||||
if (*java_value)
|
||||
*is_local_refp = JS_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Fall through, to attempt conversion to a Java string */
|
||||
|
||||
} else if (JS_InstanceOf(cx, js_obj, &JavaMember_class, 0)) {
|
||||
|
||||
if (!JS_ConvertValue(cx, v, JSTYPE_OBJECT, &v))
|
||||
return JS_FALSE;
|
||||
return jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
|
||||
java_value, is_local_refp);
|
||||
|
||||
} else {
|
||||
/* Otherwise, see if the target type is the netscape.javascript.JSObject
|
||||
wrapper class or one of its subclasses, in which case a
|
||||
reference is passed to the original JS object by wrapping it
|
||||
inside an instance of netscape.javascript.JSObject */
|
||||
if (convert_js_obj_to_JSObject_wrapper(cx, jEnv, js_obj, signature, cost, java_value)) {
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Fall through, to attempt conversion to a Java string */
|
||||
}
|
||||
|
||||
} else if (JSVAL_IS_NUMBER(v)) {
|
||||
/* JS numbers, integral or not, can be converted to instances of java.lang.Double */
|
||||
if ((*jEnv)->IsAssignableFrom(jEnv, jlDouble, target_java_class)) {
|
||||
if (java_value) {
|
||||
jsdouble d;
|
||||
if (!JS_ValueToNumber(cx, v, &d))
|
||||
goto conversion_error;
|
||||
*java_value = (*jEnv)->NewObject(jEnv, jlDouble, jlDouble_Double, d);
|
||||
if (*java_value) {
|
||||
*is_local_refp = JS_TRUE;
|
||||
} else {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Couldn't construct instance of java.lang.Double");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
(*cost)++;
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
/* Fall through, to attempt conversion to a java.lang.String ... */
|
||||
|
||||
} else if (JSVAL_IS_BOOLEAN(v)) {
|
||||
/* JS boolean values can be converted to instances of java.lang.Boolean */
|
||||
if ((*jEnv)->IsAssignableFrom(jEnv, jlBoolean, target_java_class)) {
|
||||
if (java_value) {
|
||||
JSBool b;
|
||||
if (!JS_ValueToBoolean(cx, v, &b))
|
||||
goto conversion_error;
|
||||
*java_value =
|
||||
(*jEnv)->NewObject(jEnv, jlBoolean, jlBoolean_Boolean, b);
|
||||
if (*java_value) {
|
||||
*is_local_refp = JS_TRUE;
|
||||
} else {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't construct instance "
|
||||
"of java.lang.Boolean");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
(*cost)++;
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
/* Fall through, to attempt conversion to a java.lang.String ... */
|
||||
}
|
||||
|
||||
/* If no other conversion is possible, see if the target type is java.lang.String */
|
||||
if ((*jEnv)->IsAssignableFrom(jEnv, jlString, target_java_class)) {
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
JSBool is_string = JSVAL_IS_STRING(v);
|
||||
#endif
|
||||
|
||||
/* Convert to JS string, if necessary, and then to a Java Unicode string */
|
||||
jsstr = JS_ValueToString(cx, v);
|
||||
if (jsstr) {
|
||||
if (java_value) {
|
||||
*java_value = jsj_ConvertJSStringToJavaString(cx, jEnv, jsstr);
|
||||
if (*java_value) {
|
||||
*is_local_refp = JS_TRUE;
|
||||
} else {
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
#ifdef LIVECONNECT_IMPROVEMENTS
|
||||
if (!is_string)
|
||||
(*cost)++;
|
||||
#endif
|
||||
return JS_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
conversion_error:
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Valid ranges for Java numeric types */
|
||||
#define jbyte_MAX_VALUE 127.0
|
||||
#define jbyte_MIN_VALUE -128.0
|
||||
#define jchar_MAX_VALUE 65535.0
|
||||
#define jchar_MIN_VALUE 0.0
|
||||
#define jshort_MAX_VALUE 32767.0
|
||||
#define jshort_MIN_VALUE -32768.0
|
||||
#define jint_MAX_VALUE 2147483647.0
|
||||
#define jint_MIN_VALUE -2147483648.0
|
||||
#define jlong_MAX_VALUE 9223372036854775807.0
|
||||
#define jlong_MIN_VALUE -9223372036854775808.0
|
||||
|
||||
/* Utility macro for jsj_ConvertJSValueToJavaValue(), below */
|
||||
#define JSVAL_TO_INTEGRAL_JVALUE(type_name, member_name, member_type, jsval, java_value) \
|
||||
if (!JSVAL_IS_NUMBER(v)) { \
|
||||
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v)) \
|
||||
goto conversion_error; \
|
||||
(*cost)++; \
|
||||
} \
|
||||
{ \
|
||||
member_type member_name; \
|
||||
\
|
||||
if (JSVAL_IS_INT(v)) { \
|
||||
jsint ival = JSVAL_TO_INT(v); \
|
||||
member_name = (member_type) ival; \
|
||||
\
|
||||
/* Check to see if the jsval's magnitude is too large to be \
|
||||
representable in the target java type */ \
|
||||
if (member_name != ival) \
|
||||
goto numeric_conversion_error; \
|
||||
} else { \
|
||||
jdouble dval = *JSVAL_TO_DOUBLE(v); \
|
||||
\
|
||||
/* NaN becomes zero when converted to integral value */ \
|
||||
if (JSDOUBLE_IS_NaN(dval)) \
|
||||
member_name = 0; \
|
||||
\
|
||||
/* Unrepresentably large numbers, including infinities, */ \
|
||||
/* cause an error. */ \
|
||||
else if ((dval > member_type ## _MAX_VALUE) || \
|
||||
(dval < member_type ## _MIN_VALUE)) { \
|
||||
goto numeric_conversion_error; \
|
||||
} else \
|
||||
member_name = (member_type) dval; \
|
||||
\
|
||||
/* Don't allow a non-integral number to be converted \
|
||||
to an integral type */ \
|
||||
/* Actually, we have to allow this for LC1 compatibility */ \
|
||||
/* if ((jdouble)member_name != dval) \
|
||||
(*cost)++; */ \
|
||||
} \
|
||||
if (java_value) \
|
||||
java_value->member_name = member_name; \
|
||||
}
|
||||
|
||||
#if XP_MAC
|
||||
|
||||
/* on MRJ jlong is typedef'd to wide, which is a struct. */
|
||||
#include <Math64.h>
|
||||
|
||||
static jsint jlong_to_jsint(jlong lvalue)
|
||||
{
|
||||
SInt64 val = WideToSInt64(lvalue);
|
||||
return S32Set(val);
|
||||
}
|
||||
|
||||
static jlong jsint_to_jlong(jsint ivalue)
|
||||
{
|
||||
SInt64 val = S64Set(ivalue);
|
||||
wide wval =SInt64ToWide(val);
|
||||
return *(jlong*)&wval;
|
||||
}
|
||||
|
||||
static jdouble jlong_to_jdouble(jlong lvalue)
|
||||
{
|
||||
SInt64 val = WideToSInt64(lvalue);
|
||||
return SInt64ToLongDouble(val);
|
||||
}
|
||||
|
||||
static jlong jdouble_to_jlong(jdouble dvalue)
|
||||
{
|
||||
SInt64 val = LongDoubleToSInt64(dvalue);
|
||||
wide wval = SInt64ToWide(val);
|
||||
return *(jlong*)&wval;
|
||||
}
|
||||
|
||||
/* Mac utility macro for jsj_ConvertJSValueToJavaValue(), below */
|
||||
#define JSVAL_TO_JLONG_JVALUE(member_name, member_type, jsvalue, java_value) \
|
||||
if (!JSVAL_IS_NUMBER(jsvalue)) { \
|
||||
if (!JS_ConvertValue(cx, jsvalue, JSTYPE_NUMBER, &jsvalue)) \
|
||||
goto conversion_error; \
|
||||
(*cost)++; \
|
||||
} \
|
||||
{ \
|
||||
member_type member_name; \
|
||||
\
|
||||
if (JSVAL_IS_INT(jsvalue)) { \
|
||||
jsint ival = JSVAL_TO_INT(jsvalue); \
|
||||
member_name = jsint_to_jlong(ival); \
|
||||
\
|
||||
} else { \
|
||||
jdouble dval = *JSVAL_TO_DOUBLE(jsvalue); \
|
||||
\
|
||||
/* NaN becomes zero when converted to integral value */ \
|
||||
if (JSDOUBLE_IS_NaN(dval)) \
|
||||
member_name = jsint_to_jlong(0); \
|
||||
\
|
||||
/* Unrepresentably large numbers, including infinities, */ \
|
||||
/* cause an error. */ \
|
||||
else if ((dval > member_type ## _MAX_VALUE) || \
|
||||
(dval < member_type ## _MIN_VALUE)) { \
|
||||
goto numeric_conversion_error; \
|
||||
} else \
|
||||
member_name = jdouble_to_jlong(dval); \
|
||||
\
|
||||
/* Don't allow a non-integral number to be converted \
|
||||
to an integral type */ \
|
||||
/* Actually, we have to allow this for LC1 compatibility */ \
|
||||
/*if (jlong_to_jdouble(member_name) != dval) \
|
||||
(*cost)++;*/ \
|
||||
} \
|
||||
if (java_value) \
|
||||
java_value->member_name = member_name; \
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
#define jlong_to_jdouble(lvalue) ((jdouble) lvalue)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Convert a JS value to a Java value of the given type signature. The cost
|
||||
* variable is incremented if coercion is required, e.g. the source value is
|
||||
* a string, but the target type is a boolean.
|
||||
*
|
||||
* Returns JS_FALSE if no conversion is possible, either because the jsval has
|
||||
* a type that is wholly incompatible with the Java value, or because a scalar
|
||||
* jsval can't be represented in a variable of the target type without loss of
|
||||
* precision, e.g. the source value is "4.2" but the destination type is byte.
|
||||
* If conversion is not possible and java_value is non-NULL, the JS error
|
||||
* reporter is called with an appropriate message.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v,
|
||||
JavaSignature *signature,
|
||||
int *cost, jvalue *java_value, JSBool *is_local_refp)
|
||||
{
|
||||
JavaSignatureChar type;
|
||||
JSBool success = JS_FALSE;
|
||||
|
||||
/* Initialize to default case, in which no new Java object is
|
||||
synthesized to perform the conversion and, therefore, no JNI local
|
||||
references are being held. */
|
||||
*is_local_refp = JS_FALSE;
|
||||
|
||||
type = signature->type;
|
||||
switch (type) {
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
if (!JSVAL_IS_BOOLEAN(v)) {
|
||||
if (!JS_ConvertValue(cx, v, JSTYPE_BOOLEAN, &v))
|
||||
goto conversion_error;
|
||||
(*cost)++;
|
||||
}
|
||||
if (java_value)
|
||||
java_value->z = (jboolean)(JSVAL_TO_BOOLEAN(v) == JS_TRUE);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_SHORT:
|
||||
JSVAL_TO_INTEGRAL_JVALUE(short, s, jshort, v, java_value);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_BYTE:
|
||||
JSVAL_TO_INTEGRAL_JVALUE(byte, b, jbyte, v, java_value);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CHAR:
|
||||
/* A one-character string can be converted into a character */
|
||||
if (JSVAL_IS_STRING(v) && (JS_GetStringLength(JSVAL_TO_STRING(v)) == 1)) {
|
||||
v = INT_TO_JSVAL(*JS_GetStringChars(JSVAL_TO_STRING(v)));
|
||||
}
|
||||
JSVAL_TO_INTEGRAL_JVALUE(char, c, jchar, v, java_value);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_INT:
|
||||
JSVAL_TO_INTEGRAL_JVALUE(int, i, jint, v, java_value);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_LONG:
|
||||
#if XP_MAC
|
||||
JSVAL_TO_JLONG_JVALUE(j, jlong, v, java_value);
|
||||
#else
|
||||
JSVAL_TO_INTEGRAL_JVALUE(long, j, jlong, v, java_value);
|
||||
#endif
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_FLOAT:
|
||||
if (!JSVAL_IS_NUMBER(v)) {
|
||||
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
|
||||
goto conversion_error;
|
||||
(*cost)++;
|
||||
}
|
||||
if (java_value) {
|
||||
if (JSVAL_IS_INT(v))
|
||||
java_value->f = (jfloat) JSVAL_TO_INT(v);
|
||||
else
|
||||
java_value->f = (jfloat) *JSVAL_TO_DOUBLE(v);
|
||||
}
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_DOUBLE:
|
||||
if (!JSVAL_IS_NUMBER(v)) {
|
||||
if (!JS_ConvertValue(cx, v, JSTYPE_NUMBER, &v))
|
||||
goto conversion_error;
|
||||
(*cost)++;
|
||||
}
|
||||
if (java_value) {
|
||||
if (JSVAL_IS_INT(v))
|
||||
java_value->d = (jdouble) JSVAL_TO_INT(v);
|
||||
else
|
||||
java_value->d = (jdouble) *JSVAL_TO_DOUBLE(v);
|
||||
}
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, v, signature, cost,
|
||||
&java_value->l, is_local_refp))
|
||||
goto conversion_error;
|
||||
break;
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
return JS_TRUE;
|
||||
|
||||
numeric_conversion_error:
|
||||
success = JS_TRUE;
|
||||
/* Fall through ... */
|
||||
|
||||
conversion_error:
|
||||
|
||||
if (java_value) {
|
||||
const char *jsval_string;
|
||||
JSString *jsstr;
|
||||
|
||||
jsval_string = NULL;
|
||||
jsstr = JS_ValueToString(cx, v);
|
||||
if (jsstr)
|
||||
jsval_string = JS_GetStringBytes(jsstr);
|
||||
if (!jsval_string)
|
||||
jsval_string = "";
|
||||
|
||||
JS_ReportError(cx, "Unable to convert JavaScript value %s to "
|
||||
"Java value of type %s",
|
||||
jsval_string, signature->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/*
|
||||
* A utility routine to create a JavaScript Unicode string from a
|
||||
* java.lang.String (Unicode) string.
|
||||
*/
|
||||
JSString *
|
||||
jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str)
|
||||
{
|
||||
JSString *js_str;
|
||||
jboolean is_copy;
|
||||
const jchar *ucs2_str;
|
||||
jchar *copy_ucs2_str;
|
||||
jsize ucs2_str_len, num_bytes;
|
||||
|
||||
ucs2_str_len = (*jEnv)->GetStringLength(jEnv, java_str);
|
||||
ucs2_str = (*jEnv)->GetStringChars(jEnv, java_str, &is_copy);
|
||||
if (!ucs2_str) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Unable to extract native Unicode from Java string");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
js_str = NULL;
|
||||
|
||||
/* The string data passed into JS_NewUCString() is
|
||||
not copied, so make a copy of the Unicode character vector. */
|
||||
num_bytes = ucs2_str_len * sizeof(jchar);
|
||||
copy_ucs2_str = (jchar*)JS_malloc(cx, num_bytes);
|
||||
if (!copy_ucs2_str)
|
||||
goto done;
|
||||
memcpy(copy_ucs2_str, ucs2_str, num_bytes);
|
||||
|
||||
js_str = JS_NewUCString(cx, (jschar*)copy_ucs2_str, ucs2_str_len);
|
||||
|
||||
done:
|
||||
(*jEnv)->ReleaseStringChars(jEnv, java_str, ucs2_str);
|
||||
return js_str;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to obtain a JS string representation of a Java object.
|
||||
* The java_obj argument must be of type java.lang.Object or a subclass.
|
||||
* If java_obj is a Java string, it's value is simply extracted and
|
||||
* copied into a JS string. Otherwise, the toString() method is called
|
||||
* on java_obj.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJavaObjectToJSString(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jobject java_obj, jsval *vp)
|
||||
{
|
||||
JSString *js_str;
|
||||
jstring java_str;
|
||||
jmethodID toString;
|
||||
|
||||
/* Create a Java string, unless java_obj is already a java.lang.String */
|
||||
if ((*jEnv)->IsInstanceOf(jEnv, java_obj, jlString)) {
|
||||
java_str = java_obj;
|
||||
} else {
|
||||
jclass java_class;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
toString = (*jEnv)->GetMethodID(jEnv, java_class, "toString",
|
||||
"()Ljava/lang/String;");
|
||||
if (!toString) {
|
||||
/* All Java objects have a toString method */
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "No toString() method for class %s!",
|
||||
class_descriptor->name);
|
||||
return JS_FALSE;
|
||||
}
|
||||
java_str = (*jEnv)->CallObjectMethod(jEnv, java_obj, toString);
|
||||
if (!java_str) {
|
||||
jsj_ReportJavaError(cx, jEnv, "toString() method failed");
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* Extract Unicode from java.lang.String instance and convert to JS string */
|
||||
js_str = jsj_ConvertJavaStringToJSString(cx, jEnv, java_str);
|
||||
if (!js_str)
|
||||
return JS_FALSE;
|
||||
|
||||
*vp = STRING_TO_JSVAL(js_str);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a Java object to a number by attempting to call the
|
||||
* doubleValue() method on a Java object to get a double result.
|
||||
* This usually only works on instances of java.lang.Double, but the code
|
||||
* is generalized to work with any Java object that supports this method.
|
||||
*
|
||||
* Returns JS_TRUE if the call was successful.
|
||||
* Returns JS_FALSE if conversion is not possible or an error occurs.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jobject java_obj, jsval *vp)
|
||||
{
|
||||
jdouble d;
|
||||
jmethodID doubleValue;
|
||||
jclass java_class;
|
||||
|
||||
java_class = class_descriptor->java_class;
|
||||
doubleValue = (*jEnv)->GetMethodID(jEnv, java_class, "doubleValue", "()D");
|
||||
if (!doubleValue) {
|
||||
/* There is no doubleValue() method for the object. Try toString()
|
||||
instead and the JS engine will attempt to convert the result to
|
||||
a number. */
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
return jsj_ConvertJavaObjectToJSString(cx, jEnv, class_descriptor,
|
||||
java_obj, vp);
|
||||
}
|
||||
|
||||
d = (*jEnv)->CallDoubleMethod(jEnv, java_obj, doubleValue);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "doubleValue() method failed");
|
||||
return JS_FALSE;
|
||||
}
|
||||
return JS_NewDoubleValue(cx, d, vp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a Java object to a boolean by attempting to call the
|
||||
* booleanValue() method on a Java object to get a boolean result.
|
||||
* This usually only works on instances of java.lang.Boolean, but the code
|
||||
* is generalized to work with any Java object that supports this method.
|
||||
*
|
||||
* Returns JS_TRUE if the call was successful.
|
||||
* Returns JS_FALSE if conversion is not possible or an error occurs.
|
||||
*/
|
||||
extern JSBool
|
||||
jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jobject java_obj, jsval *vp)
|
||||
{
|
||||
jboolean b;
|
||||
jmethodID booleanValue;
|
||||
jclass java_class;
|
||||
|
||||
/* Null converts to false. */
|
||||
if (!java_obj) {
|
||||
*vp = JSVAL_FALSE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
java_class = class_descriptor->java_class;
|
||||
booleanValue = (*jEnv)->GetMethodID(jEnv, java_obj, "booleanValue", "()Z");
|
||||
|
||||
/* Non-null Java object does not have a booleanValue() method, so
|
||||
it converts to true. */
|
||||
if (!booleanValue) {
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
*vp = JSVAL_TRUE;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
b = (*jEnv)->CallBooleanMethod(jEnv, java_obj, booleanValue);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "booleanValue() method failed");
|
||||
return JS_FALSE;
|
||||
}
|
||||
*vp = BOOLEAN_TO_JSVAL(b);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reflect a Java object into a JS value. The source object, java_obj, must
|
||||
* be of type java.lang.Object or a subclass and may, therefore, be an array.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
|
||||
jobject java_obj, jsval *vp)
|
||||
{
|
||||
jclass java_class;
|
||||
JSObject *js_obj;
|
||||
|
||||
/* A null in Java-land is also null in JS */
|
||||
if (!java_obj) {
|
||||
*vp = JSVAL_NULL;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
java_class = (*jEnv)->GetObjectClass(jEnv, java_obj);
|
||||
|
||||
/*
|
||||
* If it's an instance of netscape.javascript.JSObject, i.e. a wrapper
|
||||
* around a JS object that has been passed into the Java world, unwrap
|
||||
* it to obtain the original JS object.
|
||||
*/
|
||||
if (njJSObject && (*jEnv)->IsInstanceOf(jEnv, java_obj, njJSObject)) {
|
||||
#ifdef PRESERVE_JSOBJECT_IDENTITY
|
||||
js_obj = (JSObject *)((*jEnv)->GetIntField(jEnv, java_obj, njJSObject_internal));
|
||||
#else
|
||||
js_obj = jsj_UnwrapJSObjectWrapper(jEnv, java_obj);
|
||||
#endif
|
||||
PR_ASSERT(js_obj);
|
||||
if (!js_obj)
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(js_obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Instances of java.lang.String are wrapped so we can call methods on
|
||||
* them, but they convert to a JS string if used in a string context.
|
||||
*/
|
||||
/* TODO - let's get rid of this annoying "feature" */
|
||||
|
||||
/* otherwise, wrap it inside a JavaObject */
|
||||
js_obj = jsj_WrapJavaObject(cx, jEnv, java_obj, java_class);
|
||||
if (!js_obj)
|
||||
return JS_FALSE;
|
||||
*vp = OBJECT_TO_JSVAL(js_obj);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a Java value (primitive or object) to a JS value.
|
||||
*
|
||||
* This is usually an infallible operation, but JS_FALSE is returned
|
||||
* on an out-of-memory condition and the error reporter is called.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaSignature *signature,
|
||||
jvalue *java_value,
|
||||
jsval *vp)
|
||||
{
|
||||
int32 ival32;
|
||||
|
||||
switch (signature->type) {
|
||||
case JAVA_SIGNATURE_VOID:
|
||||
*vp = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
|
||||
case JAVA_SIGNATURE_BYTE:
|
||||
*vp = INT_TO_JSVAL((jsint)java_value->b);
|
||||
return JS_TRUE;
|
||||
|
||||
case JAVA_SIGNATURE_CHAR:
|
||||
*vp = INT_TO_JSVAL((jsint)java_value->c);
|
||||
return JS_TRUE;
|
||||
|
||||
case JAVA_SIGNATURE_SHORT:
|
||||
*vp = INT_TO_JSVAL((jsint)java_value->s);
|
||||
return JS_TRUE;
|
||||
|
||||
case JAVA_SIGNATURE_INT:
|
||||
ival32 = java_value->i;
|
||||
if (INT_FITS_IN_JSVAL(ival32)) {
|
||||
*vp = INT_TO_JSVAL((jsint) ival32);
|
||||
return JS_TRUE;
|
||||
} else {
|
||||
return JS_NewDoubleValue(cx, ival32, vp);
|
||||
}
|
||||
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
*vp = BOOLEAN_TO_JSVAL((JSBool) java_value->z);
|
||||
return JS_TRUE;
|
||||
|
||||
case JAVA_SIGNATURE_LONG:
|
||||
return JS_NewDoubleValue(cx, jlong_to_jdouble(java_value->j), vp);
|
||||
|
||||
case JAVA_SIGNATURE_FLOAT:
|
||||
return JS_NewDoubleValue(cx, java_value->f, vp);
|
||||
|
||||
case JAVA_SIGNATURE_DOUBLE:
|
||||
return JS_NewDoubleValue(cx, java_value->d, vp);
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
return jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_value->l, vp);
|
||||
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
return JS_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
383
mozilla/js/src/liveconnect/jsj_field.c
Normal file
383
mozilla/js/src/liveconnect/jsj_field.c
Normal file
@@ -0,0 +1,383 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the code used to reflect Java fields as properties of
|
||||
* JavaObject objects and the code to access those fields.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
|
||||
/*
|
||||
* Add a single field, described by java_field, to the JavaMemberDescriptor
|
||||
* named by field_name within the given JavaClassDescriptor.
|
||||
*
|
||||
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
|
||||
*/
|
||||
static JSBool
|
||||
add_java_field_to_class_descriptor(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jstring field_name_jstr,
|
||||
jobject java_field, /* a java.lang.reflect.Field */
|
||||
jint modifiers)
|
||||
{
|
||||
jclass fieldType;
|
||||
jfieldID fieldID;
|
||||
jclass java_class;
|
||||
|
||||
JSBool is_static_field;
|
||||
JavaMemberDescriptor *member_descriptor = NULL;
|
||||
const char *sig_cstr = NULL;
|
||||
const char *field_name = NULL;
|
||||
JavaSignature *signature = NULL;
|
||||
JavaFieldSpec *field_spec = NULL;
|
||||
|
||||
is_static_field = modifiers & ACC_STATIC;
|
||||
if (is_static_field) {
|
||||
member_descriptor = jsj_GetJavaStaticMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
|
||||
} else {
|
||||
member_descriptor = jsj_GetJavaMemberDescriptor(cx, jEnv, class_descriptor, field_name_jstr);
|
||||
}
|
||||
if (!member_descriptor)
|
||||
goto error;
|
||||
|
||||
field_spec = (JavaFieldSpec*)JS_malloc(cx, sizeof(JavaFieldSpec));
|
||||
if (!field_spec)
|
||||
goto error;
|
||||
|
||||
field_spec->modifiers = modifiers;
|
||||
|
||||
/* Get the Java class corresponding to the type of the field */
|
||||
fieldType = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getType);
|
||||
if (!fieldType) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Unable to determine type of field using"
|
||||
" java.lang.reflect.Field.getType()");
|
||||
goto error;
|
||||
}
|
||||
|
||||
signature = jsj_GetJavaClassDescriptor(cx, jEnv, fieldType);
|
||||
if (!signature)
|
||||
goto error;
|
||||
field_spec->signature = signature;
|
||||
|
||||
field_name = jsj_DupJavaStringUTF(cx, jEnv, field_name_jstr);
|
||||
if (!field_name)
|
||||
goto error;
|
||||
field_spec->name = field_name;
|
||||
|
||||
/* Compute the JNI-style (string-based) signature of the field type */
|
||||
sig_cstr = jsj_ConvertJavaSignatureToString(cx, signature);
|
||||
if (!sig_cstr)
|
||||
goto error;
|
||||
|
||||
/* Compute the JNI fieldID and cache it for quick field access */
|
||||
java_class = class_descriptor->java_class;
|
||||
if (is_static_field)
|
||||
fieldID = (*jEnv)->GetStaticFieldID(jEnv, java_class, field_name, sig_cstr);
|
||||
else
|
||||
fieldID = (*jEnv)->GetFieldID(jEnv, java_class, field_name, sig_cstr);
|
||||
if (!fieldID) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Can't get Java field ID for class %s, field %s (sig=%s)",
|
||||
class_descriptor->name, field_name, sig_cstr);
|
||||
goto error;
|
||||
}
|
||||
field_spec->fieldID = fieldID;
|
||||
|
||||
JS_free(cx, (char*)sig_cstr);
|
||||
|
||||
member_descriptor->field = field_spec;
|
||||
|
||||
/* Success */
|
||||
return JS_TRUE;
|
||||
|
||||
error:
|
||||
if (field_spec) {
|
||||
JS_FREE_IF(cx, (char*)field_spec->name);
|
||||
JS_free(cx, field_spec);
|
||||
}
|
||||
JS_FREE_IF(cx, (char*)sig_cstr);
|
||||
if (signature)
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, signature);
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Free up a JavaFieldSpec and all its resources.
|
||||
*/
|
||||
void
|
||||
jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field)
|
||||
{
|
||||
JS_FREE_IF(cx, (char*)field->name);
|
||||
jsj_ReleaseJavaClassDescriptor(cx, jEnv, field->signature);
|
||||
JS_free(cx, field);
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a JavaMemberDescriptor to the collection of members in class_descriptor
|
||||
* for every public field of the identified Java class. (A separate collection
|
||||
* is kept in class_descriptor for static and instance members.)
|
||||
* If reflect_only_static_fields is set, instance fields are not reflected. If
|
||||
* it isn't set, only instance fields are reflected and static fields are not
|
||||
* reflected.
|
||||
*
|
||||
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
|
||||
*/
|
||||
JSBool
|
||||
jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor,
|
||||
JSBool reflect_only_static_fields)
|
||||
{
|
||||
int i;
|
||||
JSBool ok;
|
||||
jint modifiers;
|
||||
jobject java_field;
|
||||
jstring field_name_jstr;
|
||||
jarray joFieldArray;
|
||||
jsize num_fields;
|
||||
jclass java_class;
|
||||
|
||||
/* Get a java array of java.lang.reflect.Field objects, by calling
|
||||
java.lang.Class.getFields(). */
|
||||
java_class = class_descriptor->java_class;
|
||||
joFieldArray = (*jEnv)->CallObjectMethod(jEnv, java_class, jlClass_getFields);
|
||||
if (!joFieldArray) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Can't determine Java object's fields "
|
||||
"using java.lang.Class.getFields()");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Iterate over the class fields */
|
||||
num_fields = (*jEnv)->GetArrayLength(jEnv, joFieldArray);
|
||||
for (i = 0; i < num_fields; i++) {
|
||||
|
||||
/* Get the i'th reflected field */
|
||||
java_field = (*jEnv)->GetObjectArrayElement(jEnv, joFieldArray, i);
|
||||
if (!java_field) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Can't access a Field[] array");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Get the field modifiers, e.g. static, public, private, etc. */
|
||||
modifiers = (*jEnv)->CallIntMethod(jEnv, java_field, jlrField_getModifiers);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Can't access a Field's modifiers using"
|
||||
"java.lang.reflect.Field.getModifiers()");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Don't allow access to private or protected Java fields. */
|
||||
if (!(modifiers & ACC_PUBLIC))
|
||||
continue;
|
||||
|
||||
/* Reflect all instance fields or all static fields, but not both */
|
||||
if (reflect_only_static_fields != ((modifiers & ACC_STATIC) != 0))
|
||||
continue;
|
||||
|
||||
/* Determine the unqualified name of the field */
|
||||
field_name_jstr = (*jEnv)->CallObjectMethod(jEnv, java_field, jlrField_getName);
|
||||
if (!field_name_jstr) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv,
|
||||
"Can't obtain a Field's name"
|
||||
"java.lang.reflect.Field.getName()");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Add a JavaFieldSpec object to the JavaClassDescriptor */
|
||||
ok = add_java_field_to_class_descriptor(cx, jEnv, class_descriptor, field_name_jstr,
|
||||
java_field, modifiers);
|
||||
if (!ok)
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
/* Success */
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the value of a Java field and return it as a JavaScript value.
|
||||
* If the field is static, then java_obj is a Java class, otherwise
|
||||
* it's a Java instance object.
|
||||
*
|
||||
* Returns JS_TRUE on success. Otherwise, returns JS_FALSE and reports an error.
|
||||
*/
|
||||
JSBool
|
||||
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
||||
jobject java_obj, jsval *vp)
|
||||
{
|
||||
JSBool is_static_field;
|
||||
jvalue java_value;
|
||||
JavaSignature *signature;
|
||||
JavaSignatureChar field_type;
|
||||
jfieldID fieldID = field_spec->fieldID;
|
||||
|
||||
is_static_field = field_spec->modifiers & ACC_STATIC;
|
||||
|
||||
#define GET_JAVA_FIELD(Type,member) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (is_static_field) \
|
||||
java_value.member = \
|
||||
(*jEnv)->GetStatic##Type##Field(jEnv, java_obj, fieldID); \
|
||||
else \
|
||||
java_value.member = \
|
||||
(*jEnv)->Get##Type##Field(jEnv, java_obj, fieldID); \
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Error reading Java field"); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
signature = field_spec->signature;
|
||||
field_type = signature->type;
|
||||
switch(field_type) {
|
||||
case JAVA_SIGNATURE_BYTE:
|
||||
GET_JAVA_FIELD(Byte,b);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CHAR:
|
||||
GET_JAVA_FIELD(Char,c);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_SHORT:
|
||||
GET_JAVA_FIELD(Short,s);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_INT:
|
||||
GET_JAVA_FIELD(Int,i);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
GET_JAVA_FIELD(Boolean,z);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_LONG:
|
||||
GET_JAVA_FIELD(Long,j);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_FLOAT:
|
||||
GET_JAVA_FIELD(Float,f);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_DOUBLE:
|
||||
GET_JAVA_FIELD(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
GET_JAVA_FIELD(Object,l);
|
||||
break;
|
||||
|
||||
#undef GET_JAVA_FIELD
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return jsj_ConvertJavaValueToJSValue(cx, jEnv, signature, &java_value, vp);
|
||||
}
|
||||
|
||||
JSBool
|
||||
jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
||||
jclass java_obj, jsval js_val)
|
||||
{
|
||||
JSBool is_static_field, is_local_ref;
|
||||
int dummy_cost;
|
||||
jvalue java_value;
|
||||
JavaSignature *signature;
|
||||
JavaSignatureChar field_type;
|
||||
jfieldID fieldID = field_spec->fieldID;
|
||||
|
||||
is_static_field = field_spec->modifiers & ACC_STATIC;
|
||||
|
||||
#define SET_JAVA_FIELD(Type,member) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (is_static_field) { \
|
||||
(*jEnv)->SetStatic##Type##Field(jEnv, java_obj, fieldID, \
|
||||
java_value.member); \
|
||||
} else { \
|
||||
(*jEnv)->Set##Type##Field(jEnv, java_obj, fieldID,java_value.member);\
|
||||
} \
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) { \
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Error assigning to Java field"); \
|
||||
return JS_FALSE; \
|
||||
} \
|
||||
PR_END_MACRO
|
||||
|
||||
signature = field_spec->signature;
|
||||
if (!jsj_ConvertJSValueToJavaValue(cx, jEnv, js_val, signature, &dummy_cost,
|
||||
&java_value, &is_local_ref))
|
||||
return JS_FALSE;
|
||||
|
||||
field_type = signature->type;
|
||||
switch(field_type) {
|
||||
case JAVA_SIGNATURE_BYTE:
|
||||
SET_JAVA_FIELD(Byte,b);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CHAR:
|
||||
SET_JAVA_FIELD(Char,c);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_SHORT:
|
||||
SET_JAVA_FIELD(Short,s);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_INT:
|
||||
SET_JAVA_FIELD(Int,i);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_BOOLEAN:
|
||||
SET_JAVA_FIELD(Boolean,z);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_LONG:
|
||||
SET_JAVA_FIELD(Long,j);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_FLOAT:
|
||||
SET_JAVA_FIELD(Float,f);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_DOUBLE:
|
||||
SET_JAVA_FIELD(Double,d);
|
||||
break;
|
||||
|
||||
case JAVA_SIGNATURE_CLASS:
|
||||
case JAVA_SIGNATURE_ARRAY:
|
||||
SET_JAVA_FIELD(Object,l);
|
||||
if (is_local_ref)
|
||||
(*jEnv)->DeleteLocalRef(jEnv, java_value.l);
|
||||
break;
|
||||
|
||||
#undef SET_JAVA_FIELD
|
||||
default:
|
||||
PR_ASSERT(0); /* Unknown java type signature */
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
487
mozilla/js/src/liveconnect/jsj_hash.c
Normal file
487
mozilla/js/src/liveconnect/jsj_hash.c
Normal file
@@ -0,0 +1,487 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a copy of the NSPR hash-table library, but it has been slightly
|
||||
* modified to allow an additional argument to be passed into the hash
|
||||
* key-comparision function. This is used to maintain thread-safety by
|
||||
* passing in a JNIEnv pointer to the key-comparison function rather
|
||||
* than storing it in a global. All types,function names, etc. have
|
||||
* been renamed from their original NSPR names to protect the innocent.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_hash.h"
|
||||
#include "prtypes.h"
|
||||
#ifdef NSPR20
|
||||
# include "prlog.h"
|
||||
# include "prbit.h"
|
||||
#else
|
||||
# include "prassert.h"
|
||||
#endif
|
||||
|
||||
/* Compute the number of buckets in ht */
|
||||
#define NBUCKETS(ht) (1 << (JSJ_HASH_BITS - (ht)->shift))
|
||||
|
||||
/* The smallest table has 16 buckets */
|
||||
#define MINBUCKETSLOG2 4
|
||||
#define MINBUCKETS (1 << MINBUCKETSLOG2)
|
||||
|
||||
/* Compute the maximum entries given n buckets that we will tolerate, ~90% */
|
||||
#define OVERLOADED(n) ((n) - ((n) >> 3))
|
||||
|
||||
/* Compute the number of entries below which we shrink the table by half */
|
||||
#define UNDERLOADED(n) (((n) > MINBUCKETS) ? ((n) >> 2) : 0)
|
||||
|
||||
/*
|
||||
** Stubs for default hash allocator ops.
|
||||
*/
|
||||
static void *
|
||||
DefaultAllocTable(void *pool, size_t size)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
#pragma unused (pool)
|
||||
#endif
|
||||
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void
|
||||
DefaultFreeTable(void *pool, void *item)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
#pragma unused (pool)
|
||||
#endif
|
||||
|
||||
free(item);
|
||||
}
|
||||
|
||||
static JSJHashEntry *
|
||||
DefaultAllocEntry(void *pool, const void *key)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
#pragma unused (pool,key)
|
||||
#endif
|
||||
|
||||
return malloc(sizeof(JSJHashEntry));
|
||||
}
|
||||
|
||||
static void
|
||||
DefaultFreeEntry(void *pool, JSJHashEntry *he, PRUintn flag)
|
||||
{
|
||||
#if defined(XP_MAC)
|
||||
#pragma unused (pool)
|
||||
#endif
|
||||
|
||||
if (flag == HT_FREE_ENTRY)
|
||||
free(he);
|
||||
}
|
||||
|
||||
static JSJHashAllocOps defaultHashAllocOps = {
|
||||
DefaultAllocTable, DefaultFreeTable,
|
||||
DefaultAllocEntry, DefaultFreeEntry
|
||||
};
|
||||
|
||||
PR_IMPLEMENT(JSJHashTable *)
|
||||
JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
|
||||
JSJHashComparator keyCompare, JSJHashComparator valueCompare,
|
||||
JSJHashAllocOps *allocOps, void *allocPriv)
|
||||
{
|
||||
JSJHashTable *ht;
|
||||
PRUint32 nb;
|
||||
|
||||
if (n <= MINBUCKETS) {
|
||||
n = MINBUCKETSLOG2;
|
||||
} else {
|
||||
n = PR_CeilingLog2(n);
|
||||
if ((PRInt32)n < 0)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!allocOps) allocOps = &defaultHashAllocOps;
|
||||
|
||||
ht = (*allocOps->allocTable)(allocPriv, sizeof *ht);
|
||||
if (!ht)
|
||||
return 0;
|
||||
memset(ht, 0, sizeof *ht);
|
||||
ht->shift = JSJ_HASH_BITS - n;
|
||||
n = 1 << n;
|
||||
#if defined(XP_PC) && !defined(_WIN32)
|
||||
if (n > 16000) {
|
||||
(*allocOps->freeTable)(allocPriv, ht);
|
||||
return 0;
|
||||
}
|
||||
#endif /* WIN16 */
|
||||
nb = n * sizeof(JSJHashEntry *);
|
||||
ht->buckets = (*allocOps->allocTable)(allocPriv, nb);
|
||||
if (!ht->buckets) {
|
||||
(*allocOps->freeTable)(allocPriv, ht);
|
||||
return 0;
|
||||
}
|
||||
memset(ht->buckets, 0, nb);
|
||||
|
||||
ht->keyHash = keyHash;
|
||||
ht->keyCompare = keyCompare;
|
||||
ht->valueCompare = valueCompare;
|
||||
ht->allocOps = allocOps;
|
||||
ht->allocPriv = allocPriv;
|
||||
return ht;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_HashTableDestroy(JSJHashTable *ht)
|
||||
{
|
||||
PRUint32 i, n;
|
||||
JSJHashEntry *he, *next;
|
||||
JSJHashAllocOps *allocOps = ht->allocOps;
|
||||
void *allocPriv = ht->allocPriv;
|
||||
|
||||
n = NBUCKETS(ht);
|
||||
for (i = 0; i < n; i++) {
|
||||
for (he = ht->buckets[i]; he; he = next) {
|
||||
next = he->next;
|
||||
(*allocOps->freeEntry)(allocPriv, he, HT_FREE_ENTRY);
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
memset(ht->buckets, 0xDB, n * sizeof ht->buckets[0]);
|
||||
#endif
|
||||
(*allocOps->freeTable)(allocPriv, ht->buckets);
|
||||
#ifdef DEBUG
|
||||
memset(ht, 0xDB, sizeof *ht);
|
||||
#endif
|
||||
(*allocOps->freeTable)(allocPriv, ht);
|
||||
}
|
||||
|
||||
/*
|
||||
** Multiplicative hash, from Knuth 6.4.
|
||||
*/
|
||||
#define GOLDEN_RATIO 0x9E3779B9U
|
||||
|
||||
PR_IMPLEMENT(JSJHashEntry **)
|
||||
JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg)
|
||||
{
|
||||
JSJHashEntry *he, **hep, **hep0;
|
||||
JSJHashNumber h;
|
||||
|
||||
#ifdef HASHMETER
|
||||
ht->nlookups++;
|
||||
#endif
|
||||
h = keyHash * GOLDEN_RATIO;
|
||||
h >>= ht->shift;
|
||||
hep = hep0 = &ht->buckets[h];
|
||||
while ((he = *hep) != 0) {
|
||||
if (he->keyHash == keyHash && (*ht->keyCompare)(key, he->key, arg)) {
|
||||
/* Move to front of chain if not already there */
|
||||
if (hep != hep0) {
|
||||
*hep = he->next;
|
||||
he->next = *hep0;
|
||||
*hep0 = he;
|
||||
}
|
||||
return hep0;
|
||||
}
|
||||
hep = &he->next;
|
||||
#ifdef HASHMETER
|
||||
ht->nsteps++;
|
||||
#endif
|
||||
}
|
||||
return hep;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJHashEntry *)
|
||||
JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep,
|
||||
JSJHashNumber keyHash, const void *key, void *value,
|
||||
void *arg)
|
||||
{
|
||||
PRUint32 i, n;
|
||||
JSJHashEntry *he, *next, **oldbuckets;
|
||||
PRUint32 nb;
|
||||
|
||||
/* Grow the table if it is overloaded */
|
||||
n = NBUCKETS(ht);
|
||||
if (ht->nentries >= OVERLOADED(n)) {
|
||||
#ifdef HASHMETER
|
||||
ht->ngrows++;
|
||||
#endif
|
||||
ht->shift--;
|
||||
oldbuckets = ht->buckets;
|
||||
#if defined(XP_PC) && !defined(_WIN32)
|
||||
if (2 * n > 16000)
|
||||
return 0;
|
||||
#endif /* WIN16 */
|
||||
nb = 2 * n * sizeof(JSJHashEntry *);
|
||||
ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb);
|
||||
if (!ht->buckets) {
|
||||
ht->buckets = oldbuckets;
|
||||
return 0;
|
||||
}
|
||||
memset(ht->buckets, 0, nb);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
for (he = oldbuckets[i]; he; he = next) {
|
||||
next = he->next;
|
||||
hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg);
|
||||
PR_ASSERT(*hep == 0);
|
||||
he->next = 0;
|
||||
*hep = he;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
|
||||
#endif
|
||||
(*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
|
||||
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
|
||||
}
|
||||
|
||||
/* Make a new key value entry */
|
||||
he = (*ht->allocOps->allocEntry)(ht->allocPriv, key);
|
||||
if (!he)
|
||||
return 0;
|
||||
he->keyHash = keyHash;
|
||||
he->key = key;
|
||||
he->value = value;
|
||||
he->next = *hep;
|
||||
*hep = he;
|
||||
ht->nentries++;
|
||||
return he;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJHashEntry *)
|
||||
JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg)
|
||||
{
|
||||
JSJHashNumber keyHash;
|
||||
JSJHashEntry *he, **hep;
|
||||
|
||||
keyHash = (*ht->keyHash)(key, arg);
|
||||
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
|
||||
if ((he = *hep) != 0) {
|
||||
/* Hit; see if values match */
|
||||
if ((*ht->valueCompare)(he->value, value, arg)) {
|
||||
/* key,value pair is already present in table */
|
||||
return he;
|
||||
}
|
||||
if (he->value)
|
||||
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_VALUE);
|
||||
he->value = value;
|
||||
return he;
|
||||
}
|
||||
return JSJ_HashTableRawAdd(ht, hep, keyHash, key, value, arg);
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg)
|
||||
{
|
||||
PRUint32 i, n;
|
||||
JSJHashEntry *next, **oldbuckets;
|
||||
PRUint32 nb;
|
||||
|
||||
*hep = he->next;
|
||||
(*ht->allocOps->freeEntry)(ht->allocPriv, he, HT_FREE_ENTRY);
|
||||
|
||||
/* Shrink table if it's underloaded */
|
||||
n = NBUCKETS(ht);
|
||||
if (--ht->nentries < UNDERLOADED(n)) {
|
||||
#ifdef HASHMETER
|
||||
ht->nshrinks++;
|
||||
#endif
|
||||
ht->shift++;
|
||||
oldbuckets = ht->buckets;
|
||||
nb = n * sizeof(JSJHashEntry*) / 2;
|
||||
ht->buckets = (*ht->allocOps->allocTable)(ht->allocPriv, nb);
|
||||
if (!ht->buckets) {
|
||||
ht->buckets = oldbuckets;
|
||||
return;
|
||||
}
|
||||
memset(ht->buckets, 0, nb);
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
for (he = oldbuckets[i]; he; he = next) {
|
||||
next = he->next;
|
||||
hep = JSJ_HashTableRawLookup(ht, he->keyHash, he->key, arg);
|
||||
PR_ASSERT(*hep == 0);
|
||||
he->next = 0;
|
||||
*hep = he;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG
|
||||
memset(oldbuckets, 0xDB, n * sizeof oldbuckets[0]);
|
||||
#endif
|
||||
(*ht->allocOps->freeTable)(ht->allocPriv, oldbuckets);
|
||||
}
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(PRBool)
|
||||
JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg)
|
||||
{
|
||||
JSJHashNumber keyHash;
|
||||
JSJHashEntry *he, **hep;
|
||||
|
||||
keyHash = (*ht->keyHash)(key, arg);
|
||||
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
|
||||
if ((he = *hep) == 0)
|
||||
return PR_FALSE;
|
||||
|
||||
/* Hit; remove element */
|
||||
JSJ_HashTableRawRemove(ht, hep, he, arg);
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(void *)
|
||||
JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg)
|
||||
{
|
||||
JSJHashNumber keyHash;
|
||||
JSJHashEntry *he, **hep;
|
||||
|
||||
keyHash = (*ht->keyHash)(key, arg);
|
||||
hep = JSJ_HashTableRawLookup(ht, keyHash, key, arg);
|
||||
if ((he = *hep) != 0) {
|
||||
return he->value;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
** Iterate over the entries in the hash table calling func for each
|
||||
** entry found. Stop if "f" says to (return value & PR_ENUMERATE_STOP).
|
||||
** Return a count of the number of elements scanned.
|
||||
*/
|
||||
PR_IMPLEMENT(int)
|
||||
JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg)
|
||||
{
|
||||
JSJHashEntry *he, **hep;
|
||||
PRUint32 i, nbuckets;
|
||||
int rv, n = 0;
|
||||
JSJHashEntry *todo = 0;
|
||||
|
||||
nbuckets = NBUCKETS(ht);
|
||||
for (i = 0; i < nbuckets; i++) {
|
||||
hep = &ht->buckets[i];
|
||||
while ((he = *hep) != 0) {
|
||||
rv = (*f)(he, n, arg);
|
||||
n++;
|
||||
if (rv & (HT_ENUMERATE_REMOVE | HT_ENUMERATE_UNHASH)) {
|
||||
*hep = he->next;
|
||||
if (rv & HT_ENUMERATE_REMOVE) {
|
||||
he->next = todo;
|
||||
todo = he;
|
||||
}
|
||||
} else {
|
||||
hep = &he->next;
|
||||
}
|
||||
if (rv & HT_ENUMERATE_STOP) {
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
hep = &todo;
|
||||
while ((he = *hep) != 0) {
|
||||
JSJ_HashTableRawRemove(ht, hep, he, arg);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
#ifdef HASHMETER
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_HashTableDumpMeter(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
|
||||
{
|
||||
double mean, variance;
|
||||
PRUint32 nchains, nbuckets;
|
||||
PRUint32 i, n, maxChain, maxChainLen;
|
||||
JSJHashEntry *he;
|
||||
|
||||
variance = 0;
|
||||
nchains = 0;
|
||||
maxChainLen = 0;
|
||||
nbuckets = NBUCKETS(ht);
|
||||
for (i = 0; i < nbuckets; i++) {
|
||||
he = ht->buckets[i];
|
||||
if (!he)
|
||||
continue;
|
||||
nchains++;
|
||||
for (n = 0; he; he = he->next)
|
||||
n++;
|
||||
variance += n * n;
|
||||
if (n > maxChainLen) {
|
||||
maxChainLen = n;
|
||||
maxChain = i;
|
||||
}
|
||||
}
|
||||
mean = (double)ht->nentries / nchains;
|
||||
variance = fabs(variance / nchains - mean * mean);
|
||||
|
||||
fprintf(fp, "\nHash table statistics:\n");
|
||||
fprintf(fp, " number of lookups: %u\n", ht->nlookups);
|
||||
fprintf(fp, " number of entries: %u\n", ht->nentries);
|
||||
fprintf(fp, " number of grows: %u\n", ht->ngrows);
|
||||
fprintf(fp, " number of shrinks: %u\n", ht->nshrinks);
|
||||
fprintf(fp, " mean steps per hash: %g\n", (double)ht->nsteps
|
||||
/ ht->nlookups);
|
||||
fprintf(fp, "mean hash chain length: %g\n", mean);
|
||||
fprintf(fp, " standard deviation: %g\n", sqrt(variance));
|
||||
fprintf(fp, " max hash chain length: %u\n", maxChainLen);
|
||||
fprintf(fp, " max hash chain: [%u]\n", maxChain);
|
||||
|
||||
for (he = ht->buckets[maxChain], i = 0; he; he = he->next, i++)
|
||||
if ((*dump)(he, i, fp) != HT_ENUMERATE_NEXT)
|
||||
break;
|
||||
}
|
||||
#endif /* HASHMETER */
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp)
|
||||
{
|
||||
int count;
|
||||
|
||||
count = JSJ_HashTableEnumerateEntries(ht, dump, fp);
|
||||
#ifdef HASHMETER
|
||||
JSJ_HashTableDumpMeter(ht, dump, fp);
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(JSJHashNumber)
|
||||
JSJ_HashString(const void *key)
|
||||
{
|
||||
JSJHashNumber h;
|
||||
const unsigned char *s;
|
||||
|
||||
h = 0;
|
||||
for (s = key; *s; s++)
|
||||
h = (h >> 28) ^ (h << 4) ^ *s;
|
||||
return h;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
JSJ_CompareStrings(const void *v1, const void *v2)
|
||||
{
|
||||
return strcmp(v1, v2) == 0;
|
||||
}
|
||||
|
||||
PR_IMPLEMENT(int)
|
||||
JSJ_CompareValues(const void *v1, const void *v2)
|
||||
{
|
||||
return v1 == v2;
|
||||
}
|
||||
141
mozilla/js/src/liveconnect/jsj_hash.h
Normal file
141
mozilla/js/src/liveconnect/jsj_hash.h
Normal file
@@ -0,0 +1,141 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is a copy of the NSPR hash-table library, but it has been slightly
|
||||
* modified to allow an additional argument to be passed into the hash
|
||||
* key-comparision function. This is used to maintain thread-safety by
|
||||
* passing in a JNIEnv pointer to the key-comparison function rather
|
||||
* than storing it in a global. All types,function names, etc. have
|
||||
* been renamed from their original NSPR names to protect the innocent.
|
||||
*/
|
||||
|
||||
#ifndef jsj_hash_h___
|
||||
#define jsj_hash_h___
|
||||
/*
|
||||
* API to portable hash table code.
|
||||
*/
|
||||
#include <stddef.h>
|
||||
#include <stdio.h>
|
||||
#include "prtypes.h"
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
typedef struct JSJHashEntry JSJHashEntry;
|
||||
typedef struct JSJHashTable JSJHashTable;
|
||||
typedef PRUint32 JSJHashNumber;
|
||||
#define JSJ_HASH_BITS 32
|
||||
typedef JSJHashNumber (*JSJHashFunction)(const void *key, void *arg);
|
||||
typedef PRIntn (*JSJHashComparator)(const void *v1, const void *v2, void *arg);
|
||||
typedef PRIntn (*JSJHashEnumerator)(JSJHashEntry *he, PRIntn i, void *arg);
|
||||
|
||||
/* Flag bits in JSJHashEnumerator's return value */
|
||||
#define HT_ENUMERATE_NEXT 0 /* continue enumerating entries */
|
||||
#define HT_ENUMERATE_STOP 1 /* stop enumerating entries */
|
||||
#define HT_ENUMERATE_REMOVE 2 /* remove and free the current entry */
|
||||
#define HT_ENUMERATE_UNHASH 4 /* just unhash the current entry */
|
||||
|
||||
typedef struct JSJHashAllocOps {
|
||||
void * (*allocTable)(void *pool, size_t size);
|
||||
void (*freeTable)(void *pool, void *item);
|
||||
JSJHashEntry * (*allocEntry)(void *pool, const void *key);
|
||||
void (*freeEntry)(void *pool, JSJHashEntry *he, PRUintn flag);
|
||||
} JSJHashAllocOps;
|
||||
|
||||
#define HT_FREE_VALUE 0 /* just free the entry's value */
|
||||
#define HT_FREE_ENTRY 1 /* free value and entire entry */
|
||||
|
||||
struct JSJHashEntry {
|
||||
JSJHashEntry *next; /* hash chain linkage */
|
||||
JSJHashNumber keyHash; /* key hash function result */
|
||||
const void *key; /* ptr to opaque key */
|
||||
void *value; /* ptr to opaque value */
|
||||
};
|
||||
|
||||
struct JSJHashTable {
|
||||
JSJHashEntry **buckets; /* vector of hash buckets */
|
||||
PRUint32 nentries; /* number of entries in table */
|
||||
PRUint32 shift; /* multiplicative hash shift */
|
||||
JSJHashFunction keyHash; /* key hash function */
|
||||
JSJHashComparator keyCompare; /* key comparison function */
|
||||
JSJHashComparator valueCompare; /* value comparison function */
|
||||
JSJHashAllocOps *allocOps; /* allocation operations */
|
||||
void *allocPriv; /* allocation private data */
|
||||
#ifdef HASHMETER
|
||||
PRUint32 nlookups; /* total number of lookups */
|
||||
PRUint32 nsteps; /* number of hash chains traversed */
|
||||
PRUint32 ngrows; /* number of table expansions */
|
||||
PRUint32 nshrinks; /* number of table contractions */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* Create a new hash table.
|
||||
* If allocOps is null, use default allocator ops built on top of malloc().
|
||||
*/
|
||||
PR_EXTERN(JSJHashTable *)
|
||||
JSJ_NewHashTable(PRUint32 n, JSJHashFunction keyHash,
|
||||
JSJHashComparator keyCompare, JSJHashComparator valueCompare,
|
||||
JSJHashAllocOps *allocOps, void *allocPriv);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JSJ_HashTableDestroy(JSJHashTable *ht);
|
||||
|
||||
/* Low level access methods */
|
||||
PR_EXTERN(JSJHashEntry **)
|
||||
JSJ_HashTableRawLookup(JSJHashTable *ht, JSJHashNumber keyHash, const void *key, void *arg);
|
||||
|
||||
PR_EXTERN(JSJHashEntry *)
|
||||
JSJ_HashTableRawAdd(JSJHashTable *ht, JSJHashEntry **hep, JSJHashNumber keyHash,
|
||||
const void *key, void *value, void *arg);
|
||||
|
||||
PR_EXTERN(void)
|
||||
JSJ_HashTableRawRemove(JSJHashTable *ht, JSJHashEntry **hep, JSJHashEntry *he, void *arg);
|
||||
|
||||
/* Higher level access methods */
|
||||
PR_EXTERN(JSJHashEntry *)
|
||||
JSJ_HashTableAdd(JSJHashTable *ht, const void *key, void *value, void *arg);
|
||||
|
||||
PR_EXTERN(PRBool)
|
||||
JSJ_HashTableRemove(JSJHashTable *ht, const void *key, void *arg);
|
||||
|
||||
PR_EXTERN(PRIntn)
|
||||
JSJ_HashTableEnumerateEntries(JSJHashTable *ht, JSJHashEnumerator f, void *arg);
|
||||
|
||||
PR_EXTERN(void *)
|
||||
JSJ_HashTableLookup(JSJHashTable *ht, const void *key, void *arg);
|
||||
|
||||
PR_EXTERN(PRIntn)
|
||||
JSJ_HashTableDump(JSJHashTable *ht, JSJHashEnumerator dump, FILE *fp);
|
||||
|
||||
/* General-purpose C string hash function. */
|
||||
PR_EXTERN(JSJHashNumber)
|
||||
JSJ_HashString(const void *key);
|
||||
|
||||
/* Compare strings using strcmp(), return true if equal. */
|
||||
PR_EXTERN(int)
|
||||
JSJ_CompareStrings(const void *v1, const void *v2);
|
||||
|
||||
/* Stub function just returns v1 == v2 */
|
||||
PR_EXTERN(PRIntn)
|
||||
JSJ_CompareValues(const void *v1, const void *v2);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#endif /* jsj_hash_h___ */
|
||||
1164
mozilla/js/src/liveconnect/jsj_method.c
Normal file
1164
mozilla/js/src/liveconnect/jsj_method.c
Normal file
File diff suppressed because it is too large
Load Diff
0
mozilla/js/src/liveconnect/jsj_nodl.c
Normal file
0
mozilla/js/src/liveconnect/jsj_nodl.c
Normal file
552
mozilla/js/src/liveconnect/jsj_private.h
Normal file
552
mozilla/js/src/liveconnect/jsj_private.h
Normal file
@@ -0,0 +1,552 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* Declarations of private (internal) functions/data/types for
|
||||
* JavaScript <==> Java communication.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _JSJAVA_PVT_H
|
||||
#define _JSJAVA_PVT_H
|
||||
|
||||
#include "prtypes.h"
|
||||
|
||||
/* NSPR1 compatibility definitions */
|
||||
#ifdef NSPR20
|
||||
# include "prprf.h"
|
||||
# include "prlog.h"
|
||||
# include "plhash.h" /* NSPR hash-tables */
|
||||
#else
|
||||
# include "prprintf.h"
|
||||
# include "prassert.h"
|
||||
# include "prhash.h" /* NSPR hash-tables */
|
||||
# define PRHashNumber prhashcode
|
||||
#endif
|
||||
|
||||
#ifdef XP_MAC
|
||||
# include "prosdep.h"
|
||||
#endif
|
||||
|
||||
#include "jsj_hash.h" /* Hash tables */
|
||||
#include "jni.h" /* Java Native Interface */
|
||||
#include "jsapi.h" /* JavaScript engine API */
|
||||
#include "jsjava.h" /* LiveConnect public API */
|
||||
|
||||
|
||||
/*************************** Type Declarations ******************************/
|
||||
|
||||
/* Forward type declarations */
|
||||
typedef struct JavaMemberDescriptor JavaMemberDescriptor;
|
||||
typedef struct JavaMethodSpec JavaMethodSpec;
|
||||
typedef struct JavaClassDescriptor JavaClassDescriptor;
|
||||
typedef struct JavaClassDescriptor JavaSignature;
|
||||
typedef struct CapturedJSError CapturedJSError;
|
||||
typedef struct JavaMemberVal JavaMemberVal;
|
||||
|
||||
/*
|
||||
* This enum uses the same character encoding used by the JDK to encode
|
||||
* Java type signatures, but the enum is easier to debug/compile with.
|
||||
*/
|
||||
typedef enum {
|
||||
JAVA_SIGNATURE_ARRAY = '[',
|
||||
JAVA_SIGNATURE_BYTE = 'B',
|
||||
JAVA_SIGNATURE_CHAR = 'C',
|
||||
JAVA_SIGNATURE_CLASS = 'L',
|
||||
JAVA_SIGNATURE_FLOAT = 'F',
|
||||
JAVA_SIGNATURE_DOUBLE = 'D',
|
||||
JAVA_SIGNATURE_INT = 'I',
|
||||
JAVA_SIGNATURE_LONG = 'J',
|
||||
JAVA_SIGNATURE_SHORT = 'S',
|
||||
JAVA_SIGNATURE_VOID = 'V',
|
||||
JAVA_SIGNATURE_BOOLEAN = 'Z',
|
||||
JAVA_SIGNATURE_UNKNOWN = 0
|
||||
} JavaSignatureChar;
|
||||
|
||||
/* The signature of a Java method consists of the signatures of all its
|
||||
arguments and its return type signature. */
|
||||
typedef struct JavaMethodSignature {
|
||||
jsize num_args; /* Length of arg_signatures array */
|
||||
JavaSignature ** arg_signatures; /* Array of argument signatures */
|
||||
JavaSignature * return_val_signature; /* Return type signature */
|
||||
} JavaMethodSignature;
|
||||
|
||||
/* A descriptor for the reflection of a single Java field */
|
||||
typedef struct JavaFieldSpec {
|
||||
jfieldID fieldID; /* JVM opaque access handle for field */
|
||||
JavaSignature * signature; /* Java type of field */
|
||||
int modifiers; /* Bitfield indicating field qualifiers */
|
||||
const char * name; /* UTF8; TODO - Should support Unicode field names */
|
||||
} JavaFieldSpec;
|
||||
|
||||
/* A descriptor for the reflection of a single Java method.
|
||||
Each overloaded method has a separate corresponding JavaMethodSpec. */
|
||||
struct JavaMethodSpec {
|
||||
jmethodID methodID; /* JVM opaque access handle for method */
|
||||
JavaMethodSignature signature;
|
||||
const char * name; /* UTF8; TODO - Should support Unicode method names */
|
||||
JavaMethodSpec * next; /* next method in chain of overloaded methods */
|
||||
};
|
||||
|
||||
/*
|
||||
* A descriptor for the reflection of a single member of a Java object.
|
||||
* This can represent one or more Java methods and/or a single field.
|
||||
* (When there is more than one method attached to a single JavaMemberDescriptor
|
||||
* they are overloaded methods sharing the same simple name.) This same
|
||||
* descriptor type is used for both static or instance members.
|
||||
*/
|
||||
struct JavaMemberDescriptor {
|
||||
const char * name; /* simple name of field and/or method */
|
||||
jsid id; /* hashed name for quick JS property lookup */
|
||||
JavaFieldSpec * field; /* field with the given name, if any */
|
||||
JavaMethodSpec * methods; /* Overloaded methods which share the same name, if any */
|
||||
JavaMemberDescriptor * next; /* next descriptor in same defining class */
|
||||
JSObject * invoke_func_obj; /* If non-null, JSFunction obj to invoke method */
|
||||
};
|
||||
|
||||
/* This is the native portion of a reflected Java class */
|
||||
struct JavaClassDescriptor {
|
||||
const char * name; /* Name of class, e.g. "java/lang/Byte" */
|
||||
JavaSignatureChar type; /* class category: primitive type, object, array */
|
||||
jclass java_class; /* Opaque JVM handle to corresponding java.lang.Class */
|
||||
int num_instance_members;
|
||||
int num_static_members;
|
||||
JSBool instance_members_reflected;
|
||||
JavaMemberDescriptor * instance_members;
|
||||
JSBool static_members_reflected;
|
||||
JavaMemberDescriptor * static_members;
|
||||
JavaMemberDescriptor * constructors;
|
||||
int modifiers; /* Class declaration qualifiers,
|
||||
e.g. abstract, private */
|
||||
int ref_count; /* # of references to this struct */
|
||||
JavaSignature * array_component_signature; /* Only non-NULL for array classes */
|
||||
};
|
||||
|
||||
/* This is the native portion of a reflected Java method or field */
|
||||
struct JavaMemberVal {
|
||||
jsval field_val; /* Captured value of Java field */
|
||||
jsval invoke_method_func_val; /* JSFunction wrapper around Java method invoker */
|
||||
JavaMemberDescriptor * descriptor;
|
||||
JavaMemberVal * next;
|
||||
};
|
||||
|
||||
/* This is the native portion of a reflected Java object */
|
||||
typedef struct JavaObjectWrapper {
|
||||
jobject java_obj; /* Opaque JVM ref to Java object */
|
||||
JavaClassDescriptor * class_descriptor; /* Java class info */
|
||||
} JavaObjectWrapper;
|
||||
|
||||
/* These are definitions of the Java class/method/field modifier bits.
|
||||
These really shouldn't be hard-coded here. Rather,
|
||||
they should be read from java.lang.reflect.Modifier */
|
||||
#define ACC_PUBLIC 0x0001 /* visible to everyone */
|
||||
#define ACC_STATIC 0x0008 /* instance variable is static */
|
||||
#define ACC_FINAL 0x0010 /* no further subclassing,overriding */
|
||||
#define ACC_INTERFACE 0x0200 /* class is an interface */
|
||||
#define ACC_ABSTRACT 0x0400 /* no definition provided */
|
||||
|
||||
/* A JSJavaVM structure must be created for each Java VM that is accessed
|
||||
via LiveConnect */
|
||||
struct JSJavaVM {
|
||||
/* TODO - all LiveConnect global variables should be migrated into this
|
||||
structure in order to allow more than one LiveConnect-enabled
|
||||
Java VM to exist within the same process. */
|
||||
SystemJavaVM * java_vm;
|
||||
JNIEnv * main_thread_env; /* Main-thread Java environment */
|
||||
JSBool jsj_created_java_vm;
|
||||
int num_attached_threads;
|
||||
JSJavaVM * next; /* next VM among all created VMs */
|
||||
};
|
||||
|
||||
/* Per-thread state that encapsulates the connection to the Java VM */
|
||||
struct JSJavaThreadState {
|
||||
const char * name; /* Thread name, for debugging */
|
||||
JSJavaVM * jsjava_vm; /* All per-JVM state */
|
||||
JNIEnv * jEnv; /* Per-thread opaque handle to Java VM */
|
||||
CapturedJSError * pending_js_errors; /* JS errors to be thrown as Java exceptions */
|
||||
JSContext * cx; /* current JS context for thread */
|
||||
JSJavaThreadState * next; /* next thread state among all created threads */
|
||||
};
|
||||
|
||||
struct JavaToJSSavedState {
|
||||
JSErrorReporter error_reporter;
|
||||
JSJavaThreadState* java_jsj_env;
|
||||
};
|
||||
typedef struct JavaToJSSavedState JavaToJSSavedState;
|
||||
|
||||
|
||||
|
||||
/******************************** Globals ***********************************/
|
||||
|
||||
extern JSJCallbacks *JSJ_callbacks;
|
||||
|
||||
/* JavaScript classes that reflect Java objects */
|
||||
extern JSClass JavaObject_class;
|
||||
extern JSClass JavaArray_class;
|
||||
extern JSClass JavaClass_class;
|
||||
extern JSClass JavaMember_class;
|
||||
|
||||
/*
|
||||
* Opaque JVM handles to Java classes, methods and objects required for
|
||||
* Java reflection. These are computed and cached during initialization.
|
||||
* TODO: These should be moved inside the JSJavaVM struct
|
||||
*/
|
||||
extern jclass jlObject; /* java.lang.Object */
|
||||
extern jclass jlrConstructor; /* java.lang.reflect.Constructor */
|
||||
extern jclass jlThrowable; /* java.lang.Throwable */
|
||||
extern jclass jlSystem; /* java.lang.System */
|
||||
extern jclass jlClass; /* java.lang.Class */
|
||||
extern jclass jlBoolean; /* java.lang.Boolean */
|
||||
extern jclass jlDouble; /* java.lang.Double */
|
||||
extern jclass jlString; /* java.lang.String */
|
||||
extern jclass njJSObject; /* netscape.javascript.JSObject */
|
||||
extern jclass njJSException; /* netscape.javascript.JSException */
|
||||
extern jclass njJSUtil; /* netscape.javascript.JSUtil */
|
||||
|
||||
extern jmethodID jlClass_getMethods; /* java.lang.Class.getMethods() */
|
||||
extern jmethodID jlClass_getConstructors; /* java.lang.Class.getConstructors() */
|
||||
extern jmethodID jlClass_getFields; /* java.lang.Class.getFields() */
|
||||
extern jmethodID jlClass_getName; /* java.lang.Class.getName() */
|
||||
extern jmethodID jlClass_getComponentType; /* java.lang.Class.getComponentType() */
|
||||
extern jmethodID jlClass_getModifiers; /* java.lang.Class.getModifiers() */
|
||||
extern jmethodID jlClass_isArray; /* java.lang.Class.isArray() */
|
||||
|
||||
extern jmethodID jlrMethod_getName; /* java.lang.reflect.Method.getName() */
|
||||
extern jmethodID jlrMethod_getParameterTypes; /* java.lang.reflect.Method.getParameterTypes() */
|
||||
extern jmethodID jlrMethod_getReturnType; /* java.lang.reflect.Method.getReturnType() */
|
||||
extern jmethodID jlrMethod_getModifiers; /* java.lang.reflect.Method.getModifiers() */
|
||||
|
||||
extern jmethodID jlrConstructor_getParameterTypes; /* java.lang.reflect.Constructor.getParameterTypes() */
|
||||
extern jmethodID jlrConstructor_getModifiers; /* java.lang.reflect.Constructor.getModifiers() */
|
||||
|
||||
extern jmethodID jlrField_getName; /* java.lang.reflect.Field.getName() */
|
||||
extern jmethodID jlrField_getType; /* java.lang.reflect.Field.getType() */
|
||||
extern jmethodID jlrField_getModifiers; /* java.lang.reflect.Field.getModifiers() */
|
||||
|
||||
extern jmethodID jlThrowable_getMessage; /* java.lang.Throwable.getMessage() */
|
||||
extern jmethodID jlThrowable_toString; /* java.lang.Throwable.toString() */
|
||||
|
||||
extern jmethodID jlBoolean_Boolean; /* java.lang.Boolean constructor */
|
||||
extern jmethodID jlBoolean_booleanValue; /* java.lang.Boolean.booleanValue() */
|
||||
extern jmethodID jlDouble_Double; /* java.lang.Double constructor */
|
||||
extern jmethodID jlDouble_doubleValue; /* java.lang.Double.doubleValue() */
|
||||
|
||||
extern jmethodID jlSystem_identityHashCode; /* java.lang.System.identityHashCode() */
|
||||
|
||||
extern jobject jlVoid_TYPE; /* java.lang.Void.TYPE value */
|
||||
|
||||
extern jmethodID njJSException_JSException; /* netscape.javascipt.JSexception constructor */
|
||||
extern jmethodID njJSObject_JSObject; /* netscape.javascript.JSObject constructor */
|
||||
extern jmethodID njJSUtil_getStackTrace; /* netscape.javascript.JSUtil.getStackTrace() */
|
||||
extern jfieldID njJSObject_internal; /* netscape.javascript.JSObject.internal */
|
||||
extern jfieldID njJSException_lineno; /* netscape.javascript.JSException.lineno */
|
||||
extern jfieldID njJSException_tokenIndex; /* netscape.javascript.JSException.tokenIndex */
|
||||
extern jfieldID njJSException_source; /* netscape.javascript.JSException.source */
|
||||
extern jfieldID njJSException_filename; /* netscape.javascript.JSException.filename */
|
||||
|
||||
|
||||
/**************** Java <==> JS conversions and Java types *******************/
|
||||
extern JSBool
|
||||
jsj_ComputeJavaClassSignature(JSContext *cx,
|
||||
JavaSignature *signature,
|
||||
jclass java_class);
|
||||
|
||||
extern const char *
|
||||
jsj_ConvertJavaSignatureToString(JSContext *cx, JavaSignature *signature);
|
||||
extern const char *
|
||||
jsj_ConvertJavaSignatureToHRString(JSContext *cx,
|
||||
JavaSignature *signature);
|
||||
extern JavaMethodSignature *
|
||||
jsj_InitJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, jobject method,
|
||||
JavaMethodSignature *method_signature);
|
||||
|
||||
extern const char *
|
||||
jsj_ConvertJavaMethodSignatureToString(JSContext *cx,
|
||||
JavaMethodSignature *method_signature);
|
||||
extern const char *
|
||||
jsj_ConvertJavaMethodSignatureToHRString(JSContext *cx,
|
||||
const char *method_name,
|
||||
JavaMethodSignature *method_signature);
|
||||
extern void
|
||||
jsj_PurgeJavaMethodSignature(JSContext *cx, JNIEnv *jEnv, JavaMethodSignature *signature);
|
||||
|
||||
extern JSBool
|
||||
jsj_ConvertJSValueToJavaValue(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
|
||||
int *cost, jvalue *java_value, JSBool *is_local_refp);
|
||||
extern JSBool
|
||||
jsj_ConvertJSValueToJavaObject(JSContext *cx, JNIEnv *jEnv, jsval v, JavaSignature *signature,
|
||||
int *cost, jobject *java_value, JSBool *is_local_refp);
|
||||
extern jstring
|
||||
jsj_ConvertJSStringToJavaString(JSContext *cx, JNIEnv *jEnv, JSString *js_str);
|
||||
|
||||
extern JSBool
|
||||
jsj_ConvertJavaValueToJSValue(JSContext *cx, JNIEnv *jEnv, JavaSignature *signature,
|
||||
jvalue *java_value, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_ConvertJavaObjectToJSValue(JSContext *cx, JNIEnv *jEnv,
|
||||
jobject java_obj, jsval *vp);
|
||||
|
||||
extern JSString *
|
||||
jsj_ConvertJavaStringToJSString(JSContext *cx, JNIEnv *jEnv, jstring java_str);
|
||||
|
||||
extern JSBool
|
||||
jsj_ConvertJavaObjectToJSString(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jobject java_obj, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_ConvertJavaObjectToJSNumber(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jobject java_obj, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_ConvertJavaObjectToJSBoolean(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jobject java_obj, jsval *vp);
|
||||
extern JSJavaThreadState *
|
||||
jsj_enter_js(JNIEnv *jEnv, jobject java_wrapper_obj,
|
||||
JSContext **cxp, JSObject **js_objp, JavaToJSSavedState* saved_state);
|
||||
extern JSBool
|
||||
jsj_exit_js(JSContext *cx, JSJavaThreadState *jsj_env, JavaToJSSavedState* original_state);
|
||||
|
||||
extern JavaClassDescriptor *
|
||||
jsj_get_jlObject_descriptor(JSContext *cx, JNIEnv *jEnv);
|
||||
|
||||
extern JSBool
|
||||
jsj_remove_js_obj_reflection_from_hashtable(JSContext *cx, JSObject *js_obj);
|
||||
|
||||
extern JSBool
|
||||
jsj_init_js_obj_reflections_table();
|
||||
|
||||
/************************ Java package reflection **************************/
|
||||
extern JSBool
|
||||
jsj_init_JavaPackage(JSContext *, JSObject *,
|
||||
JavaPackageDef *predefined_packages);
|
||||
|
||||
/************************* Java class reflection ***************************/
|
||||
extern JSBool
|
||||
jsj_init_JavaClass(JSContext *cx, JSObject *global_obj);
|
||||
|
||||
extern void
|
||||
jsj_DiscardJavaClassReflections(JNIEnv *jEnv);
|
||||
|
||||
extern const char *
|
||||
jsj_GetJavaClassName(JSContext *cx, JNIEnv *jEnv, jclass java_class);
|
||||
|
||||
extern JavaClassDescriptor *
|
||||
jsj_GetJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, jclass java_class);
|
||||
|
||||
extern void
|
||||
jsj_ReleaseJavaClassDescriptor(JSContext *cx, JNIEnv *jEnv, JavaClassDescriptor *class_descriptor);
|
||||
|
||||
extern JSObject *
|
||||
jsj_define_JavaClass(JSContext *cx, JNIEnv *jEnv, JSObject *obj,
|
||||
const char *unqualified_class_name,
|
||||
jclass jclazz);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_GetJavaMemberDescriptor(JSContext *cx,
|
||||
JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jstring member_name);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_LookupJavaMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jsid id);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_LookupJavaStaticMemberDescriptorById(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jsid id);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_GetJavaStaticMemberDescriptor(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
jstring member_name);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_GetJavaClassConstructors(JSContext *cx,
|
||||
JavaClassDescriptor *class_descriptor);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_LookupJavaClassConstructors(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_GetClassInstanceMembers(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor);
|
||||
|
||||
extern JavaMemberDescriptor *
|
||||
jsj_GetClassStaticMembers(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor);
|
||||
|
||||
extern JSBool
|
||||
jsj_InitJavaClassReflectionsTable();
|
||||
|
||||
/************************* Java field reflection ***************************/
|
||||
|
||||
extern JSBool
|
||||
jsj_GetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
||||
jobject java_obj, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_SetJavaFieldValue(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field_spec,
|
||||
jobject java_obj, jsval js_val);
|
||||
extern JSBool
|
||||
jsj_ReflectJavaFields(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
JSBool reflect_only_static_fields);
|
||||
extern void
|
||||
jsj_DestroyFieldSpec(JSContext *cx, JNIEnv *jEnv, JavaFieldSpec *field);
|
||||
|
||||
/************************* Java method reflection ***************************/
|
||||
extern JSBool
|
||||
jsj_JavaInstanceMethodWrapper(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_JavaStaticMethodWrapper(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_JavaConstructorWrapper(JSContext *cx, JSObject *obj,
|
||||
uintN argc, jsval *argv, jsval *vp);
|
||||
extern JSBool
|
||||
jsj_ReflectJavaMethods(JSContext *cx, JNIEnv *jEnv,
|
||||
JavaClassDescriptor *class_descriptor,
|
||||
JSBool reflect_only_static_methods);
|
||||
extern void
|
||||
jsj_DestroyMethodSpec(JSContext *cx, JNIEnv *jEnv, JavaMethodSpec *method_spec);
|
||||
|
||||
/************************* Java member reflection ***************************/
|
||||
extern JSBool
|
||||
jsj_init_JavaMember(JSContext *, JSObject *);
|
||||
|
||||
extern JSBool
|
||||
jsj_ReflectJavaMethodsAndFields(JSContext *cx, JavaClassDescriptor *class_descriptor,
|
||||
JSBool reflect_only_statics);
|
||||
|
||||
extern JSObject *
|
||||
jsj_CreateJavaMember(JSContext *cx, jsval method_val, jsval field_val);
|
||||
|
||||
/************************* Java object reflection **************************/
|
||||
extern JSBool
|
||||
jsj_init_JavaObject(JSContext *, JSObject *);
|
||||
|
||||
extern JSObject *
|
||||
jsj_WrapJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_obj, jclass java_class);
|
||||
|
||||
extern void
|
||||
jsj_DiscardJavaObjReflections(JNIEnv *jEnv);
|
||||
|
||||
extern JSBool
|
||||
JavaObject_convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp);
|
||||
|
||||
extern void
|
||||
JavaObject_finalize(JSContext *cx, JSObject *obj);
|
||||
|
||||
extern JSBool
|
||||
JavaObject_resolve(JSContext *cx, JSObject *obj, jsval id);
|
||||
|
||||
extern JSBool
|
||||
JavaObject_getProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp);
|
||||
|
||||
extern JSBool
|
||||
JavaObject_getPropertyById(JSContext *cx, JSObject *obj, jsid id, jsval *vp);
|
||||
|
||||
/************************* Java array reflection ***************************/
|
||||
extern JSBool
|
||||
jsj_init_JavaArray(JSContext *cx, JSObject *global_obj);
|
||||
|
||||
extern JSBool
|
||||
jsj_GetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array,
|
||||
jsize index, JavaSignature *array_component_signature,
|
||||
jsval *vp);
|
||||
|
||||
extern JSBool
|
||||
jsj_SetJavaArrayElement(JSContext *cx, JNIEnv *jEnv, jarray java_array,
|
||||
jsize index, JavaSignature *array_component_signature,
|
||||
jsval js_val);
|
||||
|
||||
/********************* JavaScript object reflection ************************/
|
||||
extern jobject
|
||||
jsj_WrapJSObject(JSContext *cx, JNIEnv *jEnv, JSObject *js_obj);
|
||||
|
||||
extern JSObject *
|
||||
jsj_UnwrapJSObjectWrapper(JNIEnv *jEnv, jobject java_wrapper_obj);
|
||||
|
||||
extern void
|
||||
jsj_ClearPendingJSErrors(JSJavaThreadState *jsj_env);
|
||||
|
||||
extern JSBool
|
||||
jsj_ReportUncaughtJSException(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception);
|
||||
|
||||
/**************************** Utilities ************************************/
|
||||
extern void
|
||||
jsj_ReportJavaError(JSContext *cx, JNIEnv *env, const char *format, ...);
|
||||
|
||||
extern void
|
||||
jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...);
|
||||
|
||||
extern const char *
|
||||
jsj_GetJavaErrorMessage(JNIEnv *env);
|
||||
|
||||
extern void
|
||||
jsj_LogError(const char *error_msg);
|
||||
|
||||
PR_CALLBACK JSJHashNumber
|
||||
jsj_HashJavaObject(const void *key, void* env);
|
||||
|
||||
PR_CALLBACK intN
|
||||
jsj_JavaObjectComparator(const void *v1, const void *v2, void *arg);
|
||||
|
||||
extern JSJavaThreadState *
|
||||
jsj_MapJavaThreadToJSJavaThreadState(JNIEnv *jEnv, char **errp);
|
||||
|
||||
extern void
|
||||
jsj_MakeJNIClassname(char *jClassName);
|
||||
|
||||
extern const char *
|
||||
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object);
|
||||
|
||||
extern jsize
|
||||
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array);
|
||||
|
||||
extern JSBool
|
||||
JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp);
|
||||
|
||||
extern const char *
|
||||
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr);
|
||||
|
||||
JSJavaThreadState *
|
||||
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp);
|
||||
|
||||
JSJavaThreadState *
|
||||
jsj_SetJavaJSJEnv(JSJavaThreadState* java_jsj_env);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define DEBUG_LOG(args) printf args
|
||||
#endif
|
||||
|
||||
#define JS_FREE_IF(cx, x) \
|
||||
PR_BEGIN_MACRO \
|
||||
if (x) \
|
||||
JS_free(cx, x); \
|
||||
PR_END_MACRO
|
||||
|
||||
#endif /* _JSJAVA_PVT_H */
|
||||
361
mozilla/js/src/liveconnect/jsj_utils.c
Normal file
361
mozilla/js/src/liveconnect/jsj_utils.c
Normal file
@@ -0,0 +1,361 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains low-level utility code.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "jsj_private.h" /* LiveConnect internals */
|
||||
#include "jsjava.h" /* External LiveConnect API */
|
||||
|
||||
|
||||
/*
|
||||
* This is a hash-table utility routine that computes the hash code of a Java
|
||||
* object by calling java.lang.System.identityHashCode()
|
||||
*/
|
||||
PR_CALLBACK JSJHashNumber
|
||||
jsj_HashJavaObject(const void *key, void* env)
|
||||
{
|
||||
PRHashNumber hash_code;
|
||||
jobject java_obj;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
java_obj = (jobject)key;
|
||||
jEnv = (JNIEnv*) env;
|
||||
hash_code = (*jEnv)->CallStaticIntMethod(jEnv, jlSystem,
|
||||
jlSystem_identityHashCode, java_obj);
|
||||
PR_ASSERT(!(*jEnv)->ExceptionOccurred(jEnv));
|
||||
return hash_code;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a hash-table utility routine for comparing two Java objects.
|
||||
* It's not possible to use the == operator to directly compare two jobject's,
|
||||
* since they're opaque references and aren't guaranteed to be simple pointers
|
||||
* or handles (though they may be in some JVM implementations). Instead,
|
||||
* use the JNI routine for comparing the two objects.
|
||||
*/
|
||||
PR_CALLBACK intN
|
||||
jsj_JavaObjectComparator(const void *v1, const void *v2, void *arg)
|
||||
{
|
||||
jobject java_obj1, java_obj2;
|
||||
JNIEnv *jEnv;
|
||||
|
||||
jEnv = (JNIEnv*)arg;
|
||||
java_obj1 = (jobject)v1;
|
||||
java_obj2 = (jobject)v2;
|
||||
|
||||
if (java_obj1 == java_obj2)
|
||||
return 1;
|
||||
return (*jEnv)->IsSameObject(jEnv, java_obj1, java_obj2);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a UTF8, null-terminated encoding of a Java string. The string must
|
||||
* be free'ed by the caller.
|
||||
*
|
||||
* If an error occurs, returns NULL and calls the JS error reporter.
|
||||
*/
|
||||
const char *
|
||||
jsj_DupJavaStringUTF(JSContext *cx, JNIEnv *jEnv, jstring jstr)
|
||||
{
|
||||
const char *str, *retval;
|
||||
|
||||
str = (*jEnv)->GetStringUTFChars(jEnv, jstr, 0);
|
||||
if (!str) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Can't get UTF8 characters from "
|
||||
"Java string");
|
||||
return NULL;
|
||||
}
|
||||
retval = JS_strdup(cx, str);
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, jstr, str);
|
||||
return retval;
|
||||
}
|
||||
|
||||
JSBool
|
||||
JavaStringToId(JSContext *cx, JNIEnv *jEnv, jstring jstr, jsid *idp)
|
||||
{
|
||||
const jschar *ucs2;
|
||||
JSString *jsstr;
|
||||
jsize ucs2_len;
|
||||
jsval val;
|
||||
|
||||
ucs2 = (*jEnv)->GetStringChars(jEnv, jstr, 0);
|
||||
if (!ucs2) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain Unicode characters"
|
||||
"from Java string");
|
||||
return JS_FALSE;
|
||||
}
|
||||
|
||||
ucs2_len = (*jEnv)->GetStringLength(jEnv, jstr);
|
||||
jsstr = JS_InternUCStringN(cx, ucs2, ucs2_len);
|
||||
(*jEnv)->ReleaseStringChars(jEnv, jstr, ucs2);
|
||||
if (!jsstr)
|
||||
return JS_FALSE;
|
||||
|
||||
val = STRING_TO_JSVAL(jsstr);
|
||||
JS_ValueToId(cx, STRING_TO_JSVAL(jsstr), idp);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
/* Not used ?
|
||||
const char *
|
||||
jsj_ClassNameOfJavaObject(JSContext *cx, JNIEnv *jEnv, jobject java_object)
|
||||
{
|
||||
jobject java_class;
|
||||
|
||||
java_class = (*jEnv)->GetObjectClass(jEnv, java_object);
|
||||
|
||||
if (!java_class) {
|
||||
PR_ASSERT(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return jsj_GetJavaClassName(cx, jEnv, java_class);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Return, as a C string, the error message associated with a Java exception
|
||||
* that occurred as a result of a JNI call, preceded by the class name of
|
||||
* the exception. As a special case, if the class of the exception is
|
||||
* netscape.javascript.JSException, the exception class name is omitted.
|
||||
*
|
||||
* NULL is returned if no Java exception is pending. The caller is
|
||||
* responsible for free'ing the returned string. On exit, the Java exception
|
||||
* is *not* cleared.
|
||||
*/
|
||||
const char *
|
||||
jsj_GetJavaErrorMessage(JNIEnv *jEnv)
|
||||
{
|
||||
const char *java_error_msg;
|
||||
char *error_msg = NULL;
|
||||
jthrowable exception;
|
||||
jstring java_exception_jstring;
|
||||
|
||||
exception = (*jEnv)->ExceptionOccurred(jEnv);
|
||||
if (exception && jlThrowable_toString) {
|
||||
java_exception_jstring =
|
||||
(*jEnv)->CallObjectMethod(jEnv, exception, jlThrowable_toString);
|
||||
java_error_msg = (*jEnv)->GetStringUTFChars(jEnv, java_exception_jstring, NULL);
|
||||
error_msg = strdup((char*)java_error_msg);
|
||||
(*jEnv)->ReleaseStringUTFChars(jEnv, java_exception_jstring, java_error_msg);
|
||||
|
||||
#ifdef DEBUG
|
||||
/* (*jEnv)->ExceptionDescribe(jEnv); */
|
||||
#endif
|
||||
}
|
||||
return error_msg;
|
||||
}
|
||||
|
||||
/*
|
||||
* Return, as a C string, the JVM stack trace associated with a Java
|
||||
* exception, as would be printed by java.lang.Throwable.printStackTrace().
|
||||
* The caller is responsible for free'ing the returned string.
|
||||
*
|
||||
* Returns NULL if an error occurs.
|
||||
*/
|
||||
static const char *
|
||||
get_java_stack_trace(JSContext *cx, JNIEnv *jEnv, jthrowable java_exception)
|
||||
{
|
||||
const char *backtrace;
|
||||
jstring backtrace_jstr;
|
||||
|
||||
backtrace = NULL;
|
||||
if (java_exception && njJSUtil_getStackTrace) {
|
||||
backtrace_jstr = (*jEnv)->CallStaticObjectMethod(jEnv, njJSUtil,
|
||||
njJSUtil_getStackTrace,
|
||||
java_exception);
|
||||
if (!backtrace_jstr) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Unable to get exception stack trace");
|
||||
return NULL;
|
||||
}
|
||||
backtrace = jsj_DupJavaStringUTF(cx, jEnv, backtrace_jstr);
|
||||
}
|
||||
return backtrace;
|
||||
}
|
||||
|
||||
/* Full Java backtrace when Java exceptions reported to JavaScript */
|
||||
#define REPORT_JAVA_EXCEPTION_STACK_TRACE
|
||||
|
||||
/*
|
||||
* This is a wrapper around JS_ReportError(), useful when an error condition
|
||||
* is the result of a JVM failure or exception condition. It appends the
|
||||
* message associated with the pending Java exception to the passed in
|
||||
* printf-style format string and arguments.
|
||||
*/
|
||||
static void
|
||||
vreport_java_error(JSContext *cx, JNIEnv *jEnv, const char *format, va_list ap)
|
||||
{
|
||||
char *error_msg, *js_error_msg;
|
||||
const char *java_stack_trace;
|
||||
const char *java_error_msg;
|
||||
jthrowable java_exception;
|
||||
|
||||
java_error_msg = NULL;
|
||||
java_exception = (*jEnv)->ExceptionOccurred(jEnv);
|
||||
if (java_exception && njJSException &&
|
||||
(*jEnv)->IsInstanceOf(jEnv, java_exception, njJSException)) {
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
jsj_ReportUncaughtJSException(cx, jEnv, java_exception);
|
||||
return;
|
||||
}
|
||||
|
||||
js_error_msg = PR_vsmprintf(format, ap);
|
||||
|
||||
if (!js_error_msg) {
|
||||
PR_ASSERT(0); /* Out-of-memory */
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef REPORT_JAVA_EXCEPTION_STACK_TRACE
|
||||
|
||||
java_stack_trace = get_java_stack_trace(cx, jEnv, java_exception);
|
||||
if (java_stack_trace) {
|
||||
error_msg = PR_smprintf("%s\n%s", js_error_msg, java_stack_trace);
|
||||
free((char*)java_stack_trace);
|
||||
if (!error_msg) {
|
||||
PR_ASSERT(0); /* Out-of-memory */
|
||||
return;
|
||||
}
|
||||
} else
|
||||
|
||||
#endif
|
||||
{
|
||||
java_error_msg = jsj_GetJavaErrorMessage(jEnv);
|
||||
if (java_error_msg) {
|
||||
error_msg = PR_smprintf("%s (%s)\n", js_error_msg, java_error_msg);
|
||||
free((char*)java_error_msg);
|
||||
free(js_error_msg);
|
||||
} else {
|
||||
error_msg = js_error_msg;
|
||||
}
|
||||
}
|
||||
|
||||
JS_ReportError(cx, error_msg);
|
||||
|
||||
/* Important: the Java exception must not be cleared until the reporter
|
||||
has been called, because the capture_js_error_reports_for_java(),
|
||||
called from JS_ReportError(), needs to read the exception from the JVM */
|
||||
(*jEnv)->ExceptionClear(jEnv);
|
||||
free(error_msg);
|
||||
}
|
||||
|
||||
void
|
||||
jsj_ReportJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, format);
|
||||
vreport_java_error(cx, env, format, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Same as jsj_ReportJavaError, except "internal error: " is prepended
|
||||
* to message.
|
||||
*/
|
||||
void
|
||||
jsj_UnexpectedJavaError(JSContext *cx, JNIEnv *env, const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
const char *format2;
|
||||
|
||||
va_start(ap, format);
|
||||
format2 = PR_smprintf("internal error: %s", format);
|
||||
if (format2) {
|
||||
vreport_java_error(cx, env, format2, ap);
|
||||
free((void*)format2);
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* Most LiveConnect errors are signaled by calling JS_ReportError(),
|
||||
* but in some circumstances, the target JSContext for such errors
|
||||
* is not determinable, e.g. during initialization. In such cases
|
||||
* any error messages are routed to this function.
|
||||
*/
|
||||
void
|
||||
jsj_LogError(const char *error_msg)
|
||||
{
|
||||
if (JSJ_callbacks && JSJ_callbacks->error_print)
|
||||
JSJ_callbacks->error_print(error_msg);
|
||||
else
|
||||
fputs(error_msg, stderr);
|
||||
}
|
||||
|
||||
jsize
|
||||
jsj_GetJavaArrayLength(JSContext *cx, JNIEnv *jEnv, jarray java_array)
|
||||
{
|
||||
jsize array_length = (*jEnv)->GetArrayLength(jEnv, java_array);
|
||||
if ((*jEnv)->ExceptionOccurred(jEnv)) {
|
||||
jsj_UnexpectedJavaError(cx, jEnv, "Couldn't obtain array length");
|
||||
return -1;
|
||||
}
|
||||
return array_length;
|
||||
}
|
||||
|
||||
static JSJavaThreadState *the_java_jsj_env = NULL;
|
||||
|
||||
JSJavaThreadState *
|
||||
jsj_MapJSContextToJSJThread(JSContext *cx, JNIEnv **envp)
|
||||
{
|
||||
JSJavaThreadState *jsj_env;
|
||||
char *err_msg;
|
||||
|
||||
*envp = NULL;
|
||||
err_msg = NULL;
|
||||
|
||||
jsj_env = the_java_jsj_env;
|
||||
if (jsj_env == NULL)
|
||||
jsj_env = JSJ_callbacks->map_js_context_to_jsj_thread(cx, &err_msg);
|
||||
if (!jsj_env) {
|
||||
if (err_msg) {
|
||||
JS_ReportError(cx, err_msg);
|
||||
free(err_msg);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (envp)
|
||||
*envp = jsj_env->jEnv;
|
||||
return jsj_env;
|
||||
}
|
||||
|
||||
/**
|
||||
* Since only one Java thread is allowed to enter JavaScript, this function is
|
||||
* used to enforce the use of that thread's state. The static global the_java_jsj_env
|
||||
* overrides using JSJ_callbacks->map_js_context_to_jsj_thread, which maps
|
||||
* native threads to JSJavaThreadStates. This isn't appropriate when Java calls
|
||||
* JavaScript, as there can be a many to one mapping from Java threads to native
|
||||
* threads.
|
||||
*/
|
||||
JSJavaThreadState *
|
||||
jsj_SetJavaJSJEnv(JSJavaThreadState* java_jsj_env)
|
||||
{
|
||||
JSJavaThreadState *old_jsj_env = the_java_jsj_env;
|
||||
the_java_jsj_env = java_jsj_env;
|
||||
return old_jsj_env;
|
||||
}
|
||||
264
mozilla/js/src/liveconnect/jsjava.h
Normal file
264
mozilla/js/src/liveconnect/jsjava.h
Normal file
@@ -0,0 +1,264 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS"
|
||||
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||||
* the License for the specific language governing rights and limitations
|
||||
* under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||||
* Netscape Communications Corporation. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* Publicly exported functions for JavaScript <==> Java communication.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _JSJAVA_H
|
||||
#define _JSJAVA_H
|
||||
|
||||
#ifndef prtypes_h___
|
||||
#include "prtypes.h"
|
||||
#endif
|
||||
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
#include "jni.h" /* Java Native Interface */
|
||||
#include "jsapi.h" /* JavaScript engine API */
|
||||
|
||||
/*
|
||||
* A JSJavaVM structure is a wrapper around a JavaVM which incorporates
|
||||
* additional LiveConnect state.
|
||||
*/
|
||||
typedef struct JSJavaVM JSJavaVM;
|
||||
|
||||
/* LiveConnect and Java state, one per thread */
|
||||
typedef struct JSJavaThreadState JSJavaThreadState;
|
||||
|
||||
/*
|
||||
* An opaque type that represents the connection to the Java VM. In stand-alone
|
||||
* Java environments, this may be a JNI JavaVM object; in the browser environment
|
||||
* it is a reference to a JVM plugin. A set of callbacks in the JSJCallbacks
|
||||
* struct allow it to be manipulated.
|
||||
*/
|
||||
typedef struct SystemJavaVM SystemJavaVM;
|
||||
|
||||
/*
|
||||
* This callback table provides hooks to external functions that implement
|
||||
* functionality specific to the embedding. For example, these callbacks are
|
||||
* necessary in multi-threaded environments or to implement a security
|
||||
* policy.
|
||||
*/
|
||||
typedef struct JSJCallbacks {
|
||||
|
||||
/* This callback is invoked when there is no JavaScript execution
|
||||
environment (JSContext) associated with the current Java thread and
|
||||
a call is made from Java into JavaScript. (A JSContext is associated
|
||||
with a Java thread by calling the JSJ_SetJSContextForJavaThread()
|
||||
function.) This callback is only invoked when Java spontaneously calls
|
||||
into JavaScript, i.e. it is not called when JS calls into Java which
|
||||
calls back into JS.
|
||||
|
||||
This callback can be used to create a JSContext lazily, or obtain
|
||||
one from a pool of available JSContexts. The implementation of this
|
||||
callback can call JSJ_SetJSContextForJavaThread() to avoid any further
|
||||
callbacks of this type for this Java thread. */
|
||||
JSContext * (*map_jsj_thread_to_js_context)(JSJavaThreadState *jsj_env,
|
||||
JNIEnv *jEnv,
|
||||
char **errp);
|
||||
|
||||
/* This callback is invoked whenever a call is made into Java from
|
||||
JavaScript. It's responsible for mapping from a JavaScript execution
|
||||
environment (JSContext) to a Java thread. (A JavaContext can only
|
||||
be associated with one Java thread at a time.) */
|
||||
JSJavaThreadState * (*map_js_context_to_jsj_thread)(JSContext *cx,
|
||||
char **errp);
|
||||
|
||||
/* This callback implements netscape.javascript.JSObject.getWindow(),
|
||||
a method named for its behavior in the browser environment, where it
|
||||
returns the JS "Window" object corresponding to the HTML window that an
|
||||
applet is embedded within. More generally, it's a way for Java to get
|
||||
hold of a JS object that has not been explicitly passed to it. */
|
||||
JSObject * (*map_java_object_to_js_object)(JNIEnv *jEnv, void *pJavaObject,
|
||||
char **errp);
|
||||
|
||||
/* An interim callback function until the LiveConnect security story is
|
||||
straightened out. This function pointer can be set to NULL. */
|
||||
JSPrincipals * (*get_JSPrincipals_from_java_caller)(JNIEnv *jEnv, JSContext *pJSContext);
|
||||
|
||||
/* The following two callbacks sandwich any JS evaluation performed
|
||||
from Java. They may be used to implement concurrency constraints, e.g.
|
||||
by suspending the current thread until some condition is met. In the
|
||||
browser embedding, these are used to maintain the run-to-completion
|
||||
semantics of JavaScript. It is acceptable for either function pointer
|
||||
to be NULL. */
|
||||
JSBool (*enter_js_from_java)(JNIEnv *jEnv, char **errp);
|
||||
void (*exit_js)(JNIEnv *jEnv);
|
||||
|
||||
/* Most LiveConnect errors are signaled by calling JS_ReportError(), but in
|
||||
some circumstances, the target JSContext for such errors is not
|
||||
determinable, e.g. during initialization. In such cases any error
|
||||
messages are routed to this function. If the function pointer is set to
|
||||
NULL, error messages are sent to stderr. */
|
||||
void (*error_print)(const char *error_msg);
|
||||
|
||||
/* This enables liveconnect to ask the VM for a java wrapper so that VM gets a chance to
|
||||
store a mapping between a jsobject and java wrapper. So the unwrapping can be done on the
|
||||
VM side before calling nsILiveconnect apis. This saves on a round trip request. */
|
||||
jobject (*get_java_wrapper)(JNIEnv *jEnv, jint jsobject);
|
||||
|
||||
/* The following set of methods abstract over the JavaVM object. */
|
||||
PRBool (*create_java_vm)(SystemJavaVM* *jvm, JNIEnv* *initialEnv, void* initargs);
|
||||
PRBool (*destroy_java_vm)(SystemJavaVM* jvm, JNIEnv* initialEnv);
|
||||
JNIEnv* (*attach_current_thread)(SystemJavaVM* jvm);
|
||||
PRBool (*detach_current_thread)(SystemJavaVM* jvm, JNIEnv* env);
|
||||
SystemJavaVM* (*get_java_vm)(JNIEnv* env);
|
||||
|
||||
/* Reserved for future use */
|
||||
void * reserved[10];
|
||||
} JSJCallbacks;
|
||||
|
||||
/*===========================================================================*/
|
||||
|
||||
/* A flag that denotes that a Java package has no sub-packages other than those
|
||||
explicitly pre-defined at the time of initialization. An access
|
||||
to a simple name within such a package, therefore, must either correspond to
|
||||
one of these explicitly pre-defined sub-packages or to a class within this
|
||||
package. It is reasonable for LiveConnect to signal an error if a simple
|
||||
name does not comply with these criteria. */
|
||||
#define PKG_SYSTEM 1
|
||||
|
||||
/* A flag that denotes that a Java package which might contain sub-packages
|
||||
that are not pre-defined at initialization time, because the sub-packages
|
||||
may not be the same in all installations. Therefore, an access to a simple
|
||||
name within such a a package which does not correspond to either a
|
||||
pre-defined sub-package or to a class, must be assummed to refer to an
|
||||
unknown sub-package. This behavior may cause bogus JavaPackage objects to be
|
||||
created if a package name is misspelled, e.g. sun.oi.net. */
|
||||
#define PKG_USER 2
|
||||
|
||||
/* A Java package defined at initialization time. */
|
||||
typedef struct JavaPackageDef {
|
||||
const char * name; /* e.g. "java.lang" */
|
||||
const char * path; /* e.g. "java/lang", or NULL for default */
|
||||
int flags; /* PKG_USER, PKG_SYSTEM, etc. */
|
||||
} JavaPackageDef;
|
||||
|
||||
/*===========================================================================*/
|
||||
|
||||
/* The following two convenience functions present a complete, but simplified
|
||||
LiveConnect API which is designed to handle the special case of a single
|
||||
Java-VM, with single-threaded operation, and the use of only one JSContext.
|
||||
The full API is in the section below. */
|
||||
|
||||
/* Initialize the provided JSContext by setting up the JS classes necessary for
|
||||
reflection and by defining JavaPackage objects for the default Java packages
|
||||
as properties of global_obj. If java_vm is NULL, a new Java VM is
|
||||
created, using the provided classpath in addition to any default classpath.
|
||||
The classpath argument is ignored, however, if java_vm is non-NULL. */
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JSJ_SimpleInit(JSContext *cx, JSObject *global_obj,
|
||||
SystemJavaVM *java_vm, const char *classpath);
|
||||
|
||||
/* Free up all resources. Destroy the Java VM if it was created by LiveConnect */
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_SimpleShutdown();
|
||||
|
||||
/*===========================================================================*/
|
||||
|
||||
/* The "full" LiveConnect API, required when more than one thread, Java VM, or
|
||||
JSContext is involved. Initialization pseudocode might go roughly like
|
||||
this:
|
||||
|
||||
JSJ_Init() // Setup callbacks
|
||||
for each JavaVM {
|
||||
JSJ_ConnectToJavaVM(...)
|
||||
}
|
||||
for each JSContext {
|
||||
JSJ_InitJSContext(...)
|
||||
}
|
||||
for each JS evaluation {
|
||||
run JavaScript code in the JSContext;
|
||||
}
|
||||
*/
|
||||
|
||||
/* Called once for all instances of LiveConnect to set up callbacks */
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_Init(JSJCallbacks *callbacks);
|
||||
|
||||
/* Called once per Java VM, this function initializes the classes, fields, and
|
||||
methods required for Java reflection. If java_vm is NULL, a new Java VM is
|
||||
created according to the create_java_vm callback in the JSJCallbacks,
|
||||
using the provided classpath in addition to any default initargs.
|
||||
The initargs argument is ignored, however, if java_vm is non-NULL. */
|
||||
PR_IMPLEMENT(JSJavaVM *)
|
||||
JSJ_ConnectToJavaVM(SystemJavaVM *java_vm, void* initargs);
|
||||
|
||||
/* Initialize the provided JSContext by setting up the JS classes necessary for
|
||||
reflection and by defining JavaPackage objects for the default Java packages
|
||||
as properties of global_obj. Additional packages may be pre-defined by
|
||||
setting the predefined_packages argument. (Pre-defining a Java package at
|
||||
initialization time is not necessary, but it will make package lookup faster
|
||||
and, more importantly, will avoid unnecessary network accesses if classes
|
||||
are being loaded over the network.) */
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JSJ_InitJSContext(JSContext *cx, JSObject *global_obj,
|
||||
JavaPackageDef *predefined_packages);
|
||||
|
||||
/* This function returns a structure that encapsulates the Java and JavaScript
|
||||
execution environment for the current native thread. It is intended to
|
||||
be called from the embedder's implementation of JSJCallback's
|
||||
map_js_context_to_jsj_thread() function. The thread_name argument is only
|
||||
used for debugging purposes and can be set to NULL. The Java JNI
|
||||
environment associated with this thread is returned through the java_envp
|
||||
argument if java_envp is non-NULL. */
|
||||
PR_IMPLEMENT(JSJavaThreadState *)
|
||||
JSJ_AttachCurrentThreadToJava(JSJavaVM *jsjava_vm, const char *thread_name,
|
||||
JNIEnv **java_envp);
|
||||
|
||||
/* Destructor routine for per-thread JSJavaThreadState structure */
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JSJ_DetachCurrentThreadFromJava(JSJavaThreadState *jsj_env);
|
||||
|
||||
/* This function is used to specify a particular JSContext as *the* JavaScript
|
||||
execution environment to be used when LiveConnect is accessed from the given
|
||||
Java thread, i.e. when one of the methods of netscape.javascript.JSObject
|
||||
has been called. There can only be one such JS context for any given Java
|
||||
thread at a time. (To multiplex JSContexts among a single thread, this
|
||||
function could be called before Java is invoked on that thread.) The return
|
||||
value is the previous JSContext associated with the given Java thread.
|
||||
|
||||
If this function has not been called for a thread and a crossing is made
|
||||
into JavaScript from Java, the map_jsj_thread_to_js_context() callback will
|
||||
be invoked to determine the JSContext for the thread. The purpose of the
|
||||
function is to improve performance by avoiding the expense of the callback.
|
||||
*/
|
||||
PR_IMPLEMENT(JSContext *)
|
||||
JSJ_SetDefaultJSContextForJavaThread(JSContext *cx, JSJavaThreadState *jsj_env);
|
||||
|
||||
/* This routine severs the connection to a Java VM, freeing all related resources.
|
||||
It shouldn't be called until the global scope has been cleared in all related
|
||||
JSContexts (so that all LiveConnect objects are finalized) and a JavaScript
|
||||
GC is performed. Otherwise, accessed to free'ed memory could result. */
|
||||
PR_IMPLEMENT(void)
|
||||
JSJ_DisconnectFromJavaVM(JSJavaVM *);
|
||||
|
||||
/*
|
||||
* Reflect a Java object into a JS value. The source object, java_obj, must
|
||||
* be of type java.lang.Object or a subclass and may, therefore, be an array.
|
||||
*/
|
||||
PR_IMPLEMENT(JSBool)
|
||||
JSJ_ConvertJavaObjectToJSValue(JSContext *cx, jobject java_obj, jsval *vp);
|
||||
|
||||
PR_END_EXTERN_C
|
||||
#endif /* _JSJAVA_H */
|
||||
182
mozilla/js/src/liveconnect/makefile.win
Normal file
182
mozilla/js/src/liveconnect/makefile.win
Normal file
@@ -0,0 +1,182 @@
|
||||
# The contents of this file are subject to the Netscape Public License
|
||||
# Version 1.0 (the "NPL"); you may not use this file except in
|
||||
# compliance with the NPL. You may obtain a copy of the NPL at
|
||||
# http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
# for the specific language governing rights and limitations under the
|
||||
# NPL.
|
||||
#
|
||||
# The Initial Developer of this code under the NPL is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
# Reserved.
|
||||
|
||||
IGNORE_MANIFEST=1
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Makefile to build the Java reflections of JavaScript objects
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Specify the depth of the current directory relative to the
|
||||
#// root of NS
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DEPTH= ..\..\..
|
||||
|
||||
include <$(DEPTH)/config/config.mak>
|
||||
|
||||
!ifdef NSJVM
|
||||
DIRS = classes
|
||||
!endif
|
||||
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Make Variables here: (ie. PDFFILE, MAPFILE, ...)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
DLLNAME=jsj$(MOZ_BITS)$(VERSION_NUMBER)
|
||||
PDBFILE=$(DLLNAME).pdb
|
||||
MAPFILE = $(DLLNAME).map
|
||||
RESFILE = jsj1640.res
|
||||
DLL=.\$(OBJDIR)\$(DLLNAME).dll
|
||||
MAKE_OBJ_TYPE = DLL
|
||||
|
||||
!if "$(MOZ_BITS)" == "16"
|
||||
DEFFILE = $(DLLNAME).def
|
||||
!endif
|
||||
|
||||
LLIBS=$(LIBNSPR) $(DIST)\lib\js$(MOZ_BITS)$(VERSION_NUMBER).lib \
|
||||
$(DIST)\lib\xpcom32.lib
|
||||
|
||||
!if "$(MOZ_BITS)"=="32" && defined(MOZ_DEBUG) && defined(GLOWCODE)
|
||||
LLIBS=$(LLIBS) $(GLOWDIR)\glowcode.lib
|
||||
!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define the files necessary to build the target (ie. OBJS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
OBJS= \
|
||||
.\$(OBJDIR)\jsj.obj \
|
||||
.\$(OBJDIR)\jsj_JSObject.obj \
|
||||
.\$(OBJDIR)\jsj_JavaArray.obj \
|
||||
.\$(OBJDIR)\jsj_JavaClass.obj \
|
||||
.\$(OBJDIR)\jsj_JavaMember.obj \
|
||||
.\$(OBJDIR)\jsj_JavaObject.obj \
|
||||
.\$(OBJDIR)\jsj_JavaPackage.obj \
|
||||
.\$(OBJDIR)\jsj_array.obj \
|
||||
.\$(OBJDIR)\jsj_class.obj \
|
||||
.\$(OBJDIR)\jsj_convert.obj \
|
||||
.\$(OBJDIR)\jsj_field.obj \
|
||||
.\$(OBJDIR)\jsj_hash.obj \
|
||||
.\$(OBJDIR)\jsj_method.obj \
|
||||
.\$(OBJDIR)\jsj_utils.obj \
|
||||
.\$(OBJDIR)\nsCLiveconnect.obj \
|
||||
.\$(OBJDIR)\nsCLiveconnectFactory.obj \
|
||||
!if "$(MOZ_BITS)" == "16"
|
||||
.\$(OBJDIR)\jsj_nodl.obj \
|
||||
!endif
|
||||
$(NULL)
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// install headers
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
INSTALL_DIR=$(PUBLIC)\js
|
||||
INSTALL_FILE_LIST= \
|
||||
jsjava.h nsILiveconnect.h
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any Public Targets here (ie. PROGRAM, LIBRARY, DLL, ...)
|
||||
#// (these must be defined before the common makefiles are included)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
!ifdef NSJVM
|
||||
JNI_GEN= \
|
||||
netscape.javascript.JSObject \
|
||||
netscape.javascript.JSException \
|
||||
$(NULL)
|
||||
|
||||
!endif
|
||||
|
||||
MODULE = java
|
||||
EXPORTS = \
|
||||
$(JNI_GEN_DIR)\netscape_javascript_JSObject.h \
|
||||
$(JNI_GEN_DIR)\netscape_javascript_JSException.h \
|
||||
$(NULL)
|
||||
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Define any local options for the make tools
|
||||
#// (ie. LCFLAGS, LLFLAGS, LLIBS, LINCS)
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
|
||||
LINCS=$(LINCS) -I$(JNI_GEN_DIR) \
|
||||
-I$(PUBLIC)\js \
|
||||
-I$(PUBLIC)\java \
|
||||
-I$(PUBLIC)\xpcom \
|
||||
$(NULL)
|
||||
|
||||
|
||||
#!ifdef SERVER_BUILD
|
||||
#LLIBS=$(DIST)/lib/httpdlw.lib $(DIST)/lib/libsjboot.lib
|
||||
#!endif
|
||||
|
||||
#//------------------------------------------------------------------------
|
||||
#//
|
||||
#// Include the common makefile rules
|
||||
#//
|
||||
#//------------------------------------------------------------------------
|
||||
include <$(DEPTH)/config/rules.mak>
|
||||
|
||||
export:: INSTALL_FILES
|
||||
|
||||
libs:: $(DLL)
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).dll $(DIST)\bin
|
||||
$(MAKE_INSTALL) .\$(OBJDIR)\$(DLLNAME).lib $(DIST)\lib
|
||||
|
||||
|
||||
####
|
||||
# this bit of extreme scariness came from the js/src makefile
|
||||
# reproduced here since that's where jsjava.c lives now...
|
||||
|
||||
!if ("$(MOZ_BITS)" == "16")
|
||||
#//
|
||||
#// Win16 Hoovers SO BAD!!!
|
||||
#//
|
||||
|
||||
!if !defined(MOZ_DEBUG)
|
||||
#//
|
||||
#// We must turn off codeview debug info so jni.c can build.
|
||||
#// Otherwise the linker gives errors about data in the $SYMBOLS
|
||||
#// segment being beyond a segment boundary.
|
||||
#//
|
||||
$(OBJDIR)\jsjava.obj: jsjava.c
|
||||
@$(CC) @<<$(CFGFILE)
|
||||
-c
|
||||
-Od
|
||||
$(CFLAGS)
|
||||
$(LCFLAGS)
|
||||
$(LINCS)
|
||||
$(LINCS_1)
|
||||
$(INCS)
|
||||
-Fd$(PDBFILE)
|
||||
-Fo.\$(OBJDIR)\
|
||||
$(*B).c
|
||||
<<KEEP
|
||||
!endif
|
||||
!endif
|
||||
111
mozilla/js/src/liveconnect/netscape_javascript_JSObject.h
Normal file
111
mozilla/js/src/liveconnect/netscape_javascript_JSObject.h
Normal file
@@ -0,0 +1,111 @@
|
||||
/* -*- Mode: C; tab-width: 8 -*-
|
||||
* Copyright (C) 1998 Netscape Communications Corporation, All Rights Reserved.
|
||||
*/
|
||||
#include <jni.h>
|
||||
/* Header for class netscape_javascript_JSObject */
|
||||
|
||||
#ifndef _Included_netscape_javascript_JSObject
|
||||
#define _Included_netscape_javascript_JSObject
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: initClass
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_initClass
|
||||
(JNIEnv *, jclass);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getMember
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getMember
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getSlot
|
||||
* Signature: (I)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getSlot
|
||||
(JNIEnv *, jobject, jint);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: setMember
|
||||
* Signature: (Ljava/lang/String;Ljava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setMember
|
||||
(JNIEnv *, jobject, jstring, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: setSlot
|
||||
* Signature: (ILjava/lang/Object;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_setSlot
|
||||
(JNIEnv *, jobject, jint, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: removeMember
|
||||
* Signature: (Ljava/lang/String;)V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_removeMember
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: call
|
||||
* Signature: (Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_call
|
||||
(JNIEnv *, jobject, jstring, jobjectArray);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: eval
|
||||
* Signature: (Ljava/lang/String;)Ljava/lang/Object;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_eval
|
||||
(JNIEnv *, jobject, jstring);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: toString
|
||||
* Signature: ()Ljava/lang/String;
|
||||
*/
|
||||
JNIEXPORT jstring JNICALL Java_netscape_javascript_JSObject_toString
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: getWindow
|
||||
* Signature: (Ljava/applet/Applet;)Lnetscape/javascript/JSObject;
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_netscape_javascript_JSObject_getWindow
|
||||
(JNIEnv *, jclass, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: finalize
|
||||
* Signature: ()V
|
||||
*/
|
||||
JNIEXPORT void JNICALL Java_netscape_javascript_JSObject_finalize
|
||||
(JNIEnv *, jobject);
|
||||
|
||||
/*
|
||||
* Class: netscape_javascript_JSObject
|
||||
* Method: equals
|
||||
* Signature: (Ljava/lang/Object;)Z
|
||||
*/
|
||||
JNIEXPORT jboolean JNICALL Java_netscape_javascript_JSObject_equals
|
||||
(JNIEnv *, jobject, jobject);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
567
mozilla/js/src/liveconnect/nsCLiveconnect.cpp
Normal file
567
mozilla/js/src/liveconnect/nsCLiveconnect.cpp
Normal file
@@ -0,0 +1,567 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the implementation providing nsIFactory XP-COM interface.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "prtypes.h"
|
||||
#include "prprf.h"
|
||||
#include "prlog.h"
|
||||
PR_BEGIN_EXTERN_C
|
||||
|
||||
#ifdef XP_MAC
|
||||
#include "prosdep.h"
|
||||
#endif
|
||||
|
||||
#include "jsj_private.h"
|
||||
#include "jsjava.h"
|
||||
|
||||
#include "jscntxt.h" /* For js_ReportErrorAgain().
|
||||
TODO - get rid of private header */
|
||||
|
||||
#include "netscape_javascript_JSObject.h" /* javah-generated headers */
|
||||
|
||||
|
||||
/* A captured JavaScript error, created when JS_ReportError() is called while
|
||||
running JavaScript code that is itself called from Java. */
|
||||
struct CapturedJSError {
|
||||
char * message;
|
||||
JSErrorReport report; /* Line # of error, etc. */
|
||||
jthrowable java_exception; /* Java exception, error, or null */
|
||||
CapturedJSError * next; /* Next oldest captured JS error */
|
||||
};
|
||||
PR_END_EXTERN_C
|
||||
|
||||
#include "nsCLiveconnect.h"
|
||||
|
||||
static NS_DEFINE_IID(kILiveconnectIID, NS_ILIVECONNECT_IID);
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports and AggregatedQueryInterface:
|
||||
|
||||
// Thes macro expands to the aggregated query interface scheme.
|
||||
|
||||
NS_IMPL_AGGREGATED(nsCLiveconnect);
|
||||
|
||||
NS_METHOD
|
||||
nsCLiveconnect::AggregatedQueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
if (aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = GetInner();
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
if (aIID.Equals(kILiveconnectIID)) {
|
||||
*aInstancePtr = this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsILiveconnect:
|
||||
|
||||
/**
|
||||
* get member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
* @param pjobj - return parameter as a java object representing
|
||||
* the member. If it is a basic data type it is converted to
|
||||
* a corresponding java type. If it is a NJSObject, then it is
|
||||
* wrapped up as java wrapper netscape.javascript.JSObject.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::GetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject *pjobj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jobject member = NULL;
|
||||
jsval js_val = NULL;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!name) {
|
||||
JS_ReportError(cx, "illegal null member name");
|
||||
member = NULL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
if (!JS_GetProperty(cx, js_obj, name, &js_val))
|
||||
goto done;
|
||||
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &member, &dummy_bool);
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = member;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* get member of a Native JSObject for a given index.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param index - Index of a member.
|
||||
* @param pjobj - return parameter as a java object representing
|
||||
* the member.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::GetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject *pjobj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jobject member = NULL;
|
||||
jsval js_val = NULL;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// =-= sudu: check to see if slot can be passed in as is.
|
||||
// Should it be converted to a jsint?
|
||||
if (!JS_GetElement(cx, js_obj, slot, &js_val))
|
||||
goto done;
|
||||
if (!jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &member, &dummy_bool))
|
||||
goto done;
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = member;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* set member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
* @param jobj - Value to set. If this is a basic data type, it is converted
|
||||
* using standard JNI calls but if it is a wrapper to a JSObject
|
||||
* then a internal mapping is consulted to convert to a NJSObject.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::SetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject java_obj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jobject member = NULL;
|
||||
jsval js_val = NULL;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!name) {
|
||||
JS_ReportError(cx, "illegal null member name");
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
|
||||
goto done;
|
||||
|
||||
JS_SetProperty(cx, js_obj, name, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* set member of a Native JSObject for a given index.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param index - Index of a member.
|
||||
* @param jobj - Value to set. If this is a basic data type, it is converted
|
||||
* using standard JNI calls but if it is a wrapper to a JSObject
|
||||
* then a internal mapping is consulted to convert to a NJSObject.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::SetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject java_obj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jsval js_val = NULL;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, java_obj, &js_val))
|
||||
goto done;
|
||||
JS_SetElement(cx, js_obj, slot, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* remove member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::RemoveMember(JNIEnv *jEnv, jsobject obj, const char *name)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jsval js_val = NULL;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!name) {
|
||||
JS_ReportError(cx, "illegal null member name");
|
||||
goto done;
|
||||
}
|
||||
JS_DeleteProperty2(cx, js_obj, name, &js_val);
|
||||
|
||||
done:
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* call a method of Native JSObject.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a method.
|
||||
* @param jobjArr - Array of jobjects representing parameters of method being caled.
|
||||
* @param pjobj - return value.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::Call(JNIEnv *jEnv, jsobject obj, const char *name, jobjectArray java_args, jobject *pjobj)
|
||||
{
|
||||
int i = 0;
|
||||
int argc = 0;
|
||||
int arg_num = 0;
|
||||
jsval *argv = 0;
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jobject member = NULL;
|
||||
jsval js_val = NULL;
|
||||
jsval function_val = NULL;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
jobject result = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
result = NULL;
|
||||
if (!name) {
|
||||
JS_ReportError(cx, "illegal null JavaScript function name");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* FIXME: What about security stuff ? Don't principals need to be set here ? */
|
||||
|
||||
/* Allocate space for JS arguments */
|
||||
if (java_args) {
|
||||
argc = jEnv->GetArrayLength(java_args);
|
||||
argv = (jsval*)JS_malloc(cx, argc * sizeof(jsval));
|
||||
} else {
|
||||
argc = 0;
|
||||
argv = 0;
|
||||
}
|
||||
|
||||
/* Convert arguments from Java to JS values */
|
||||
for (arg_num = 0; arg_num < argc; arg_num++) {
|
||||
jobject arg = jEnv->GetObjectArrayElement(java_args, arg_num);
|
||||
|
||||
if (!jsj_ConvertJavaObjectToJSValue(cx, jEnv, arg, &argv[arg_num]))
|
||||
goto cleanup_argv;
|
||||
JS_AddRoot(cx, &argv[arg_num]);
|
||||
}
|
||||
|
||||
if (!JS_GetProperty(cx, js_obj, name, &function_val))
|
||||
goto cleanup_argv;
|
||||
|
||||
if (!JS_CallFunctionValue(cx, js_obj, function_val, argc, argv, &js_val))
|
||||
goto cleanup_argv;
|
||||
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &result, &dummy_bool);
|
||||
|
||||
cleanup_argv:
|
||||
if (argv) {
|
||||
for (i = 0; i < arg_num; i++)
|
||||
JS_RemoveRoot(cx, &argv[i]);
|
||||
JS_free(cx, argv);
|
||||
}
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*pjobj = result;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Evaluate a script with a Native JS Object representing scope.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
* @param pNSIPrincipaArray - Array of principals to be used to compare privileges.
|
||||
* @param numPrincipals - Number of principals being passed.
|
||||
* @param script - Script to be executed.
|
||||
* @param pjobj - return value.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::Eval(JNIEnv *jEnv, jsobject obj, const char *script, jobject *pjobj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
nsresult err = NS_OK;
|
||||
jobject member = NULL;
|
||||
jsval js_val = NULL;
|
||||
jsval function_val = NULL;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
jobject result = NULL;
|
||||
const char *codebase = NULL;
|
||||
JSPrincipals *principals = NULL;
|
||||
JSBool eval_succeeded = PR_FALSE;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
result = NULL;
|
||||
if (!script) {
|
||||
JS_ReportError(cx, "illegal null string eval argument");
|
||||
goto done;
|
||||
}
|
||||
|
||||
|
||||
/* Set up security stuff */
|
||||
principals = NULL;
|
||||
if (JSJ_callbacks->get_JSPrincipals_from_java_caller)
|
||||
principals = JSJ_callbacks->get_JSPrincipals_from_java_caller(jEnv, cx);
|
||||
codebase = principals ? principals->codebase : NULL;
|
||||
|
||||
/* Have the JS engine evaluate the unicode string */
|
||||
eval_succeeded = JS_EvaluateScriptForPrincipals(cx, js_obj, principals,
|
||||
script, strlen(script),
|
||||
codebase, 0, &js_val);
|
||||
if (!eval_succeeded)
|
||||
goto done;
|
||||
|
||||
/* Convert result to a subclass of java.lang.Object */
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &result, &dummy_bool);
|
||||
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
return NULL;
|
||||
|
||||
*pjobj = result;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param pJavaObject - Either a jobject or a pointer to a plugin instance
|
||||
* representing the java object.
|
||||
* @param pjobj - return value. This is a native js object
|
||||
* representing the window object of a frame
|
||||
* in which a applet/bean resides.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::GetWindow(JNIEnv *jEnv, void *pJavaObject, jsobject *pobj)
|
||||
{
|
||||
char *err_msg = NULL;
|
||||
JSContext *cx = NULL;
|
||||
JSObject *js_obj = NULL;
|
||||
jsval js_val = NULL;
|
||||
int dummy_cost = 0;
|
||||
JSBool dummy_bool = PR_FALSE;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
jobject java_obj = NULL;
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env)
|
||||
return NULL;
|
||||
|
||||
err_msg = NULL;
|
||||
java_obj = NULL;
|
||||
js_obj = JSJ_callbacks->map_java_object_to_js_object(jEnv, pJavaObject, &err_msg);
|
||||
if (!js_obj) {
|
||||
if (err_msg) {
|
||||
JS_ReportError(cx, err_msg);
|
||||
free(err_msg);
|
||||
}
|
||||
goto done;
|
||||
}
|
||||
#if 0
|
||||
js_val = OBJECT_TO_JSVAL(js_obj);
|
||||
jsj_ConvertJSValueToJavaObject(cx, jEnv, js_val, jsj_get_jlObject_descriptor(cx, jEnv),
|
||||
&dummy_cost, &java_obj, &dummy_bool);
|
||||
#endif
|
||||
done:
|
||||
if (!jsj_exit_js(cx, jsj_env, &saved_state))
|
||||
return NULL;
|
||||
|
||||
//*pjobj = java_obj;
|
||||
*pobj = (jint)js_obj;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
*/
|
||||
NS_METHOD
|
||||
nsCLiveconnect::FinalizeJSObject(JNIEnv *jEnv, jsobject obj)
|
||||
{
|
||||
JSContext *cx = NULL;
|
||||
JavaToJSSavedState saved_state = {NULL,NULL};
|
||||
JSJavaThreadState *jsj_env = NULL;
|
||||
JSObject *js_obj = (JSObject *)obj;
|
||||
|
||||
if(jEnv == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
jsj_env = jsj_enter_js(jEnv, NULL, &cx, NULL, &saved_state);
|
||||
if (!jsj_env) /* Note: memory leak if we exit here */
|
||||
return NS_ERROR_FAILURE;
|
||||
#ifdef PRESERVE_JSOBJECT_IDENTITY
|
||||
jsj_remove_js_obj_reflection_from_hashtable(cx, js_obj);
|
||||
#endif /* PRESERVE_JSOBJECT_IDENTITY */
|
||||
jsj_exit_js(cx, jsj_env, &saved_state);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCLiveconnect:
|
||||
|
||||
nsCLiveconnect::nsCLiveconnect(nsISupports *aOuter)
|
||||
{
|
||||
NS_INIT_AGGREGATED(aOuter);
|
||||
jsj_init_js_obj_reflections_table();
|
||||
}
|
||||
|
||||
nsCLiveconnect::~nsCLiveconnect()
|
||||
{
|
||||
}
|
||||
|
||||
166
mozilla/js/src/liveconnect/nsCLiveconnect.h
Normal file
166
mozilla/js/src/liveconnect/nsCLiveconnect.h
Normal file
@@ -0,0 +1,166 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains class definition implementing the public interface.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the class definition to implement nsILiveconnect XP-COM interface.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#ifndef nsCLiveconnect_h___
|
||||
#define nsCLiveconnect_h___
|
||||
|
||||
#include "nsILiveconnect.h"
|
||||
#include "nsAgg.h"
|
||||
|
||||
|
||||
/**
|
||||
* nsCLiveconnect implements nsILiveconnect interface for navigator.
|
||||
* This is used by a JVM to implement netscape.javascript.JSObject functionality.
|
||||
*/
|
||||
class nsCLiveconnect :public nsILiveconnect {
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports and AggregatedQueryInterface:
|
||||
|
||||
NS_DECL_AGGREGATED
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsILiveconnect:
|
||||
|
||||
/**
|
||||
* get member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
* @param pjobj - return parameter as a java object representing
|
||||
* the member. If it is a basic data type it is converted to
|
||||
* a corresponding java type. If it is a NJSObject, then it is
|
||||
* wrapped up as java wrapper netscape.javascript.JSObject.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject *pjobj);
|
||||
|
||||
/**
|
||||
* get member of a Native JSObject for a given index.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param index - Index of a member.
|
||||
* @param pjobj - return parameter as a java object representing
|
||||
* the member.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetSlot(JNIEnv *jEnv, jsobject obj, int index, jobject *pjobj);
|
||||
|
||||
/**
|
||||
* set member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
* @param jobj - Value to set. If this is a basic data type, it is converted
|
||||
* using standard JNI calls but if it is a wrapper to a JSObject
|
||||
* then a internal mapping is consulted to convert to a NJSObject.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
SetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject jobj);
|
||||
|
||||
/**
|
||||
* set member of a Native JSObject for a given index.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param index - Index of a member.
|
||||
* @param jobj - Value to set. If this is a basic data type, it is converted
|
||||
* using standard JNI calls but if it is a wrapper to a JSObject
|
||||
* then a internal mapping is consulted to convert to a NJSObject.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
SetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject jobj);
|
||||
|
||||
/**
|
||||
* remove member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
RemoveMember(JNIEnv *jEnv, jsobject obj, const char *name);
|
||||
|
||||
/**
|
||||
* call a method of Native JSObject.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a method.
|
||||
* @param jobjArr - Array of jobjects representing parameters of method being caled.
|
||||
* @param pjobj - return value.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Call(JNIEnv *jEnv, jsobject obj, const char *name, jobjectArray jobjArr, jobject *pjobj);
|
||||
|
||||
/**
|
||||
* Evaluate a script with a Native JS Object representing scope.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param pNSIPrincipaArray - Array of principals to be used to compare privileges.
|
||||
* @param numPrincipals - Number of principals being passed.
|
||||
* @param script - Script to be executed.
|
||||
* @param pjobj - return value.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
//Eval(JNIEnv *jEnv, jsobject obj, nsIPrincipal **pNSIPrincipaArray, PRInt32 numPrincipals, const char *script, jobject *pjobj);
|
||||
Eval(JNIEnv *jEnv, jsobject obj, const char *script, jobject *pjobj);
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param pJavaObject - Either a jobject or a pointer to a plugin instance
|
||||
* representing the java object.
|
||||
* @param pjobj - return value. This is a native js object
|
||||
* representing the window object of a frame
|
||||
* in which a applet/bean resides.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetWindow(JNIEnv *jEnv, void *pJavaObject, jsobject *pobj);
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
FinalizeJSObject(JNIEnv *jEnv, jsobject obj);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCLiveconnect:
|
||||
|
||||
nsCLiveconnect(nsISupports *aOuter);
|
||||
virtual ~nsCLiveconnect(void);
|
||||
|
||||
protected:
|
||||
};
|
||||
|
||||
#endif // nsCLiveconnect_h___
|
||||
168
mozilla/js/src/liveconnect/nsCLiveconnectFactory.cpp
Normal file
168
mozilla/js/src/liveconnect/nsCLiveconnectFactory.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the implementation providing nsILiveconnect XP-COM interface.
|
||||
*
|
||||
*/
|
||||
#include "prtypes.h"
|
||||
#include "nspr.h"
|
||||
#include "prmem.h"
|
||||
#include "prmon.h"
|
||||
#include "prlog.h"
|
||||
|
||||
#include "nsCLiveconnect.h"
|
||||
#include "nsCLiveconnectFactory.h"
|
||||
#include "nsRepository.h"
|
||||
|
||||
static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
|
||||
static NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
static NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
|
||||
static NS_DEFINE_IID(kILiveconnectIID, NS_ILIVECONNECT_IID);
|
||||
|
||||
nsIFactory *nsCLiveconnectFactory::m_pNSIFactory = NULL;
|
||||
nsCLiveconnect *nsCLiveconnectFactory::m_pNSCLiveconnect = NULL;
|
||||
|
||||
|
||||
|
||||
/*+++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
* NSGetFactory:
|
||||
* Provides entry point to liveconnect dll.
|
||||
+++++++++++++++++++++++++++++++++++++++++++++++++*/
|
||||
|
||||
extern "C" NS_EXPORT nsresult
|
||||
NSGetFactory(const nsCID &aClass, nsIFactory **aFactory)
|
||||
{
|
||||
|
||||
if (!aClass.Equals(kCLiveconnectCID)) {
|
||||
return NS_ERROR_FACTORY_NOT_LOADED; // XXX right error?
|
||||
}
|
||||
nsCLiveconnectFactory* pCLiveConnectFactory = new nsCLiveconnectFactory();
|
||||
if (pCLiveConnectFactory == NULL)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
pCLiveConnectFactory->AddRef();
|
||||
*aFactory = pCLiveConnectFactory;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
extern "C" NS_EXPORT PRBool
|
||||
NSCanUnload(void)
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports
|
||||
|
||||
NS_METHOD
|
||||
nsCLiveconnectFactory::QueryInterface(const nsIID& aIID, void** aInstancePtr)
|
||||
{
|
||||
PR_ASSERT(NULL != aInstancePtr);
|
||||
if (NULL == aInstancePtr) {
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
}
|
||||
if (aIID.Equals(kIFactoryIID) ||
|
||||
aIID.Equals(kISupportsIID)) {
|
||||
*aInstancePtr = (void*) this;
|
||||
AddRef();
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_NOINTERFACE;
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsCLiveconnectFactory)
|
||||
NS_IMPL_RELEASE(nsCLiveconnectFactory)
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsIFactory:
|
||||
|
||||
NS_METHOD
|
||||
nsCLiveconnectFactory::CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult)
|
||||
{
|
||||
nsCLiveconnect *pNSCLiveconnect = NULL;
|
||||
*aResult = NULL;
|
||||
|
||||
if (aOuter && !aIID.Equals(kISupportsIID))
|
||||
return NS_NOINTERFACE; // XXX right error?
|
||||
if (m_pNSCLiveconnect == NULL)
|
||||
{
|
||||
m_pNSCLiveconnect = new nsCLiveconnect(aOuter);
|
||||
}
|
||||
if (m_pNSCLiveconnect == NULL)
|
||||
{
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (m_pNSCLiveconnect->QueryInterface(aIID,
|
||||
(void**)aResult) != NS_OK) {
|
||||
// then we're trying get a interface other than nsISupports and
|
||||
// nsICapsManager
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsCLiveconnectFactory::LockFactory(PRBool aLock)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCLiveconnectFactory:
|
||||
|
||||
nsCLiveconnectFactory::nsCLiveconnectFactory(void)
|
||||
{
|
||||
if( m_pNSIFactory != NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
NS_INIT_REFCNT();
|
||||
nsresult err = NS_OK;
|
||||
NS_DEFINE_IID(kIFactoryIID, NS_IFACTORY_IID);
|
||||
|
||||
err = this->QueryInterface(kIFactoryIID, (void**)&m_pNSIFactory);
|
||||
if ( (err == NS_OK) && (m_pNSIFactory != NULL) )
|
||||
{
|
||||
NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
|
||||
nsRepository::RegisterFactory(kCLiveconnectCID, m_pNSIFactory,
|
||||
PR_FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
nsCLiveconnectFactory::~nsCLiveconnectFactory()
|
||||
{
|
||||
if(mRefCnt == 0)
|
||||
{
|
||||
NS_DEFINE_CID(kCLiveconnectCID, NS_CLIVECONNECT_CID);
|
||||
nsRepository::UnregisterFactory(kCLiveconnectCID, (nsIFactory *)m_pNSIFactory);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
59
mozilla/js/src/liveconnect/nsCLiveconnectFactory.h
Normal file
59
mozilla/js/src/liveconnect/nsCLiveconnectFactory.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the class definition to implement nsIFactory XP-COM interface.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsCLiveconnectFactory_h___
|
||||
#define nsCLiveconnectFactory_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
|
||||
class nsCLiveconnectFactory : public nsIFactory {
|
||||
public:
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsISupports and AggregatedQueryInterface:
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsIFactory:
|
||||
|
||||
NS_IMETHOD
|
||||
CreateInstance(nsISupports *aOuter, REFNSIID aIID, void **aResult);
|
||||
|
||||
NS_IMETHOD
|
||||
LockFactory(PRBool aLock);
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// from nsCLiveconnectFactory:
|
||||
|
||||
nsCLiveconnectFactory(void);
|
||||
virtual ~nsCLiveconnectFactory(void);
|
||||
|
||||
protected:
|
||||
static nsIFactory *m_pNSIFactory;
|
||||
static nsCLiveconnect *m_pNSCLiveconnect;
|
||||
};
|
||||
|
||||
#endif // nsCLiveconnectFactory_h___
|
||||
157
mozilla/js/src/liveconnect/nsILiveconnect.h
Normal file
157
mozilla/js/src/liveconnect/nsILiveconnect.h
Normal file
@@ -0,0 +1,157 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public License
|
||||
* Version 1.0 (the "NPL"); you may not use this file except in
|
||||
* compliance with the NPL. You may obtain a copy of the NPL at
|
||||
* http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the NPL is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
|
||||
* for the specific language governing rights and limitations under the
|
||||
* NPL.
|
||||
*
|
||||
* The Initial Developer of this code under the NPL is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
|
||||
* Reserved.
|
||||
*/
|
||||
/*
|
||||
* This file is part of the Java-vendor-neutral implementation of LiveConnect
|
||||
*
|
||||
* It contains the public XP-COM based interface for java to javascript communication.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef nsILiveconnect_h___
|
||||
#define nsILiveconnect_h___
|
||||
|
||||
#include "nsISupports.h"
|
||||
#include "nsIFactory.h"
|
||||
#include "jni.h"
|
||||
|
||||
|
||||
typedef jint jsobject;
|
||||
|
||||
class nsILiveconnect : public nsISupports {
|
||||
public:
|
||||
/**
|
||||
* get member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
* @param pjobj - return parameter as a java object representing
|
||||
* the member. If it is a basic data type it is converted to
|
||||
* a corresponding java type. If it is a NJSObject, then it is
|
||||
* wrapped up as java wrapper netscape.javascript.JSObject.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject *pjobj) = 0;
|
||||
|
||||
/**
|
||||
* get member of a Native JSObject for a given index.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param index - Index of a member.
|
||||
* @param pjobj - return parameter as a java object representing
|
||||
* the member.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetSlot(JNIEnv *jEnv, jsobject obj, int index, jobject *pjobj) = 0;
|
||||
|
||||
/**
|
||||
* set member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
* @param jobj - Value to set. If this is a basic data type, it is converted
|
||||
* using standard JNI calls but if it is a wrapper to a JSObject
|
||||
* then a internal mapping is consulted to convert to a NJSObject.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
SetMember(JNIEnv *jEnv, jsobject obj, const char *name, jobject jobj) = 0;
|
||||
|
||||
/**
|
||||
* set member of a Native JSObject for a given index.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param index - Index of a member.
|
||||
* @param jobj - Value to set. If this is a basic data type, it is converted
|
||||
* using standard JNI calls but if it is a wrapper to a JSObject
|
||||
* then a internal mapping is consulted to convert to a NJSObject.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
SetSlot(JNIEnv *jEnv, jsobject obj, int slot, jobject jobj) = 0;
|
||||
|
||||
/**
|
||||
* remove member of a Native JSObject for a given name.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a member.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
RemoveMember(JNIEnv *jEnv, jsobject obj, const char *name) = 0;
|
||||
|
||||
/**
|
||||
* call a method of Native JSObject.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param name - Name of a method.
|
||||
* @param jobjArr - Array of jobjects representing parameters of method being caled.
|
||||
* @param pjobj - return value.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
Call(JNIEnv *jEnv, jsobject obj, const char *name, jobjectArray jobjArr, jobject *pjobj) = 0;
|
||||
|
||||
/**
|
||||
* Evaluate a script with a Native JS Object representing scope.
|
||||
*
|
||||
* @param obj - A Native JS Object.
|
||||
* @param pNSIPrincipaArray - Array of principals to be used to compare privileges.
|
||||
* @param numPrincipals - Number of principals being passed.
|
||||
* @param script - Script to be executed.
|
||||
* @param pjobj - return value.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
//Eval(jsobject obj, nsIPrincipal **pNSIPrincipaArray, PRInt32 numPrincipals, const char *script, jobject *pjobj) = 0;
|
||||
Eval(JNIEnv *jEnv, jsobject obj, const char *script, jobject *pjobj) = 0;
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param pJavaObject - Either a jobject or a pointer to a plugin instance
|
||||
* representing the java object.
|
||||
* @param pjobj - return value. This is a native js object
|
||||
* representing the window object of a frame
|
||||
* in which a applet/bean resides.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
GetWindow(JNIEnv *jEnv, void *pJavaObject, jsobject *pobj) = 0;
|
||||
|
||||
/**
|
||||
* Get the window object for a plugin instance.
|
||||
*
|
||||
* @param jEnv - JNIEnv on which the call is being made.
|
||||
* @param obj - A Native JS Object.
|
||||
*/
|
||||
NS_IMETHOD
|
||||
FinalizeJSObject(JNIEnv *jEnv, jsobject obj) = 0;
|
||||
|
||||
};
|
||||
|
||||
#define NS_ILIVECONNECT_IID \
|
||||
{ /* 68190910-3318-11d2-97f0-00805f8a28d0 */ \
|
||||
0x68190910, \
|
||||
0x3318, \
|
||||
0x11d2, \
|
||||
{0x97, 0xf0, 0x00, 0x80, 0x5f, 0x8a, 0x28, 0xd0} \
|
||||
};
|
||||
|
||||
#define NS_CLIVECONNECT_CID \
|
||||
{ /* b8f0cef0-3931-11d2-97f0-00805f8a28d0 */ \
|
||||
0xb8f0cef0, \
|
||||
0x3931, \
|
||||
0x11d2, \
|
||||
{0x97, 0xf0, 0x00, 0x80, 0x5f, 0x8a, 0x28, 0xd0} \
|
||||
};
|
||||
|
||||
#endif // nsILiveconnect_h___
|
||||
@@ -1,12 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// stdafx.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#ifdef _ATL_STATIC_REGISTRY
|
||||
#include <statreg.h>
|
||||
#include <statreg.cpp>
|
||||
#endif
|
||||
|
||||
#include <atlimpl.cpp>
|
||||
@@ -1,28 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently,
|
||||
// but are changed infrequently
|
||||
|
||||
#if !defined(AFX_STDAFX_H__3B3A8A37_A147_4D96_BFA3_51B0F69B5D8D__INCLUDED_)
|
||||
#define AFX_STDAFX_H__3B3A8A37_A147_4D96_BFA3_51B0F69B5D8D__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#define STRICT
|
||||
#ifndef _WIN32_WINNT
|
||||
#define _WIN32_WINNT 0x0400
|
||||
#endif
|
||||
#define _ATL_APARTMENT_THREADED
|
||||
|
||||
#include <atlbase.h>
|
||||
//You may derive a class from CComModule and use it if you want to override
|
||||
//something, but do not change the name of _Module
|
||||
extern CComModule _Module;
|
||||
#include <atlcom.h>
|
||||
#include <comdef.h>
|
||||
|
||||
//{{AFX_INSERT_LOCATION}}
|
||||
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
|
||||
|
||||
#endif // !defined(AFX_STDAFX_H__3B3A8A37_A147_4D96_BFA3_51B0F69B5D8D__INCLUDED)
|
||||
@@ -1,28 +0,0 @@
|
||||
#ifndef XPCDispUtilities_h
|
||||
#define XPCDispUtilities_h
|
||||
|
||||
template <class T>
|
||||
inline
|
||||
HRESULT XPCCreateInstance(const CLSID & clsid, const IID & iid, T ** result)
|
||||
{
|
||||
return CoCreateInstance(clsid, 0, CLSCTX_ALL, iid, reinterpret_cast<void**>(result));
|
||||
}
|
||||
|
||||
DISPID GetIDsOfNames(IDispatch * pIDispatch , CComBSTR const & name)
|
||||
{
|
||||
DISPID dispid;
|
||||
OLECHAR * pName = name;
|
||||
HRESULT hresult = pIDispatch->GetIDsOfNames(
|
||||
IID_NULL,
|
||||
&pName,
|
||||
1,
|
||||
LOCALE_SYSTEM_DEFAULT,
|
||||
&dispid);
|
||||
if (!SUCCEEDED(hresult))
|
||||
{
|
||||
dispid = 0;
|
||||
}
|
||||
return dispid;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,86 +0,0 @@
|
||||
// XPCIDispatchTest.cpp : Implementation of DLL Exports.
|
||||
|
||||
|
||||
// Note: Proxy/Stub Information
|
||||
// To build a separate proxy/stub DLL,
|
||||
// run nmake -f IDispatchTestps.mk in the project directory.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "resource.h"
|
||||
#include <initguid.h>
|
||||
#include "XPCIDispatchTest.h"
|
||||
|
||||
#include "XPCIDispatchTest_i.c"
|
||||
#include "nsXPCDispTestMethods.h"
|
||||
#include "nsXPCDispSimple.h"
|
||||
#include "nsXPCDispTestNoIDispatch.h"
|
||||
#include "nsXPCDispTestProperties.h"
|
||||
#include "nsXPCDispTestArrays.h"
|
||||
#include "nsXPCDispTestScriptOn.h"
|
||||
#include "nsXPCDispTestScriptOff.h"
|
||||
#include "nsXPCDispTestWrappedJS.h"
|
||||
|
||||
CComModule _Module;
|
||||
|
||||
BEGIN_OBJECT_MAP(ObjectMap)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestMethods, nsXPCDispTestMethods)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispSimple, nsXPCDispSimple)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestNoIDispatch, nsXPCDispTestNoIDispatch)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestProperties, nsXPCDispTestProperties)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestArrays, nsXPCDispTestArrays)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestScriptOn, nsXPCDispTestScriptOn)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestScriptOff, nsXPCDispTestScriptOff)
|
||||
OBJECT_ENTRY(CLSID_nsXPCDispTestWrappedJS, nsXPCDispTestWrappedJS)
|
||||
END_OBJECT_MAP()
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DLL Entry Point
|
||||
|
||||
extern "C"
|
||||
BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID /*lpReserved*/)
|
||||
{
|
||||
if (dwReason == DLL_PROCESS_ATTACH)
|
||||
{
|
||||
_Module.Init(ObjectMap, hInstance, &LIBID_IDispatchTestLib);
|
||||
DisableThreadLibraryCalls(hInstance);
|
||||
}
|
||||
else if (dwReason == DLL_PROCESS_DETACH)
|
||||
_Module.Term();
|
||||
return TRUE; // ok
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Used to determine whether the DLL can be unloaded by OLE
|
||||
|
||||
STDAPI DllCanUnloadNow(void)
|
||||
{
|
||||
return (_Module.GetLockCount()==0) ? S_OK : S_FALSE;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Returns a class factory to create an object of the requested type
|
||||
|
||||
STDAPI DllGetClassObject(REFCLSID rclsid, REFIID riid, LPVOID* ppv)
|
||||
{
|
||||
return _Module.GetClassObject(rclsid, riid, ppv);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllRegisterServer - Adds entries to the system registry
|
||||
|
||||
STDAPI DllRegisterServer(void)
|
||||
{
|
||||
// registers object, typelib and all interfaces in typelib
|
||||
return _Module.RegisterServer(TRUE);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// DllUnregisterServer - Removes entries from the system registry
|
||||
|
||||
STDAPI DllUnregisterServer(void)
|
||||
{
|
||||
return _Module.UnregisterServer(TRUE);
|
||||
}
|
||||
|
||||
|
||||
#include "nsXPCDispTestWrappedJS.h"
|
||||
@@ -1,9 +0,0 @@
|
||||
; XPCIDispatchTest.def : Declares the module parameters.
|
||||
|
||||
LIBRARY "XPCIDispatchTest.DLL"
|
||||
|
||||
EXPORTS
|
||||
DllCanUnloadNow @1 PRIVATE
|
||||
DllGetClassObject @2 PRIVATE
|
||||
DllRegisterServer @3 PRIVATE
|
||||
DllUnregisterServer @4 PRIVATE
|
||||
@@ -1,318 +0,0 @@
|
||||
# Microsoft Developer Studio Project File - Name="XPCIDispatchTest" - Package Owner=<4>
|
||||
# Microsoft Developer Studio Generated Build File, Format Version 6.00
|
||||
# ** DO NOT EDIT **
|
||||
|
||||
# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102
|
||||
|
||||
CFG=XPCIDispatchTest - Win32 Debug
|
||||
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
|
||||
!MESSAGE use the Export Makefile command and run
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "XPCIDispatchTest.mak".
|
||||
!MESSAGE
|
||||
!MESSAGE You can specify a configuration when running NMAKE
|
||||
!MESSAGE by defining the macro CFG on the command line. For example:
|
||||
!MESSAGE
|
||||
!MESSAGE NMAKE /f "XPCIDispatchTest.mak" CFG="XPCIDispatchTest - Win32 Debug"
|
||||
!MESSAGE
|
||||
!MESSAGE Possible choices for configuration are:
|
||||
!MESSAGE
|
||||
!MESSAGE "XPCIDispatchTest - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE "XPCIDispatchTest - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
|
||||
!MESSAGE
|
||||
|
||||
# Begin Project
|
||||
# PROP AllowPerConfigDependencies 0
|
||||
# PROP Scc_ProjName ""
|
||||
# PROP Scc_LocalPath ""
|
||||
CPP=cl.exe
|
||||
MTL=midl.exe
|
||||
RSC=rc.exe
|
||||
|
||||
!IF "$(CFG)" == "XPCIDispatchTest - Win32 Debug"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 1
|
||||
# PROP BASE Output_Dir "Debug"
|
||||
# PROP BASE Intermediate_Dir "Debug"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 1
|
||||
# PROP Output_Dir "Debug"
|
||||
# PROP Intermediate_Dir "Debug"
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MTd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD CPP /nologo /MTd /W4 /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /Yu"stdafx.h" /FD /GZ /c
|
||||
# ADD BASE RSC /l 0x409 /d "_DEBUG"
|
||||
# ADD RSC /l 0x409 /d "_DEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /pdbtype:sept
|
||||
# Begin Custom Build - Performing registration
|
||||
OutDir=.\Debug
|
||||
TargetPath=.\Debug\XPCIDispatchTest.dll
|
||||
InputPath=.\Debug\XPCIDispatchTest.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
regsvr32 /s /c "$(TargetPath)"
|
||||
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ELSEIF "$(CFG)" == "XPCIDispatchTest - Win32 Release"
|
||||
|
||||
# PROP BASE Use_MFC 0
|
||||
# PROP BASE Use_Debug_Libraries 0
|
||||
# PROP BASE Output_Dir "XPCIDispatchTest___Win32_Release"
|
||||
# PROP BASE Intermediate_Dir "XPCIDispatchTest___Win32_Release"
|
||||
# PROP BASE Target_Dir ""
|
||||
# PROP Use_MFC 0
|
||||
# PROP Use_Debug_Libraries 0
|
||||
# PROP Output_Dir "Release"
|
||||
# PROP Intermediate_Dir "Release"
|
||||
# PROP Ignore_Export_Lib 0
|
||||
# PROP Target_Dir ""
|
||||
# ADD BASE CPP /nologo /MT /W3 /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
|
||||
# ADD CPP /nologo /MT /W3 /GX /O1 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "_ATL_DLL" /D "_ATL_MIN_CRT" /Yu"stdafx.h" /FD /c
|
||||
# ADD BASE RSC /l 0x409 /d "NDEBUG"
|
||||
# ADD RSC /l 0x409 /d "NDEBUG"
|
||||
BSC32=bscmake.exe
|
||||
# ADD BASE BSC32 /nologo
|
||||
# ADD BSC32 /nologo
|
||||
LINK32=link.exe
|
||||
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:windows /dll /machine:I386
|
||||
# Begin Custom Build - Performing registration
|
||||
OutDir=.\Release
|
||||
TargetPath=.\Release\XPCIDispatchTest.dll
|
||||
InputPath=.\Release\XPCIDispatchTest.dll
|
||||
SOURCE="$(InputPath)"
|
||||
|
||||
"$(OutDir)\regsvr32.trg" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
|
||||
regsvr32 /s /c "$(TargetPath)"
|
||||
echo regsvr32 exec. time > "$(OutDir)\regsvr32.trg"
|
||||
|
||||
# End Custom Build
|
||||
|
||||
!ENDIF
|
||||
|
||||
# Begin Target
|
||||
|
||||
# Name "XPCIDispatchTest - Win32 Debug"
|
||||
# Name "XPCIDispatchTest - Win32 Release"
|
||||
# Begin Group "Source Files"
|
||||
|
||||
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispSimple.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestArrays.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestMethods.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestNoIDispatch.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestProperties.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestScriptOff.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestScriptOn.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestWrappedJS.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.cpp
|
||||
# ADD CPP /Yc"stdafx.h"
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XPCIDispatchTest.cpp
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XPCIDispatchTest.def
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XPCIDispatchTest.idl
|
||||
# ADD MTL /tlb ".\XPCIDispatchTest.tlb" /h "XPCIDispatchTest.h" /iid "XPCIDispatchTest_i.c" /Oicf
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XPCIDispatchTest.rc
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Header Files"
|
||||
|
||||
# PROP Default_Filter "h;hpp;hxx;hm;inl"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispSimple.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestArrays.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestMethods.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestNoIDispatch.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestProperties.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestScriptOff.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestScriptOn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestWrappedJS.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\Resource.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\StdAfx.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\XPCDispUtilities.h
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Resource Files"
|
||||
|
||||
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispSimple.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestArrays.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestMethods.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestNoIDispatch.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestNoScript.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestProperties.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestScriptOff.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestScriptOn.rgs
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=.\nsXPCDispTestWrappedJS.rgs
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "JS Files"
|
||||
|
||||
# PROP Default_Filter "js"
|
||||
# Begin Group "WrappedCOM"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "Arrays"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedCOM\Arrays\XPCIDispatchArrayTests.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Attributes"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedCOM\Attributes\XPCIDispatchAttributeTests.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "General"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedCOM\General\XPCIDispatchInstantiations.js
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedCOM\General\XPCStress.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "Methods"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedCOM\Methods\XPCIDispatchMethodTests.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedCOM\shell.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "WrappedJS"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Group "General (WJS)"
|
||||
|
||||
# PROP Default_Filter ""
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedJS\General\XPCIDispatchTestWrappedJS.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\Tests\WrappedJS\shell.js
|
||||
# End Source File
|
||||
# End Group
|
||||
# End Group
|
||||
# End Target
|
||||
# End Project
|
||||
@@ -1,29 +0,0 @@
|
||||
Microsoft Developer Studio Workspace File, Format Version 6.00
|
||||
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
|
||||
|
||||
###############################################################################
|
||||
|
||||
Project: "XPCIDispatchTest"=.\XPCIDispatchTest.dsp - Package Owner=<4>
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<4>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
Global:
|
||||
|
||||
Package=<5>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
Package=<3>
|
||||
{{{
|
||||
}}}
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -1,454 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// XPCIDispatchTest.idl : IDL source for XPCIDispatchTest.dll
|
||||
//
|
||||
|
||||
// This file will be processed by the MIDL tool to
|
||||
// produce the type library (XPCIDispatchTest.tlb) and marshalling code.
|
||||
|
||||
import "oaidl.idl";
|
||||
import "ocidl.idl";
|
||||
import "objsafe.idl";
|
||||
|
||||
[
|
||||
uuid(83A51226-F49D-488A-8F78-75BB2F927F4C),
|
||||
version(1.0),
|
||||
helpstring("XPCIDispatchTest 1.0 Type Library")
|
||||
]
|
||||
library IDispatchTestLib
|
||||
{
|
||||
importlib("stdole32.tlb");
|
||||
importlib("stdole2.tlb");
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(0de5dbae-1d78-45cb-91a2-24516fef2837),
|
||||
dual,
|
||||
helpstring("nsIXPCDispSimple interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispSimple : IDispatch
|
||||
{
|
||||
[id(1), helpstring("Simple method returning the name of the class")]
|
||||
HRESULT ClassName([out]BSTR * name);
|
||||
[propget, id(2), helpstring("Simple number property")]
|
||||
HRESULT Number([out, retval]long * result);
|
||||
[propput, id(2), helpstring("Simple number property")]
|
||||
HRESULT Number([in]long result);
|
||||
}
|
||||
[
|
||||
uuid(9F39237C-D179-4260-8EF3-4B6D4D7D5570),
|
||||
helpstring("nsXPCDispSimple Class")
|
||||
]
|
||||
coclass nsXPCDispSimple
|
||||
{
|
||||
[default] interface nsIXPCDispSimple;
|
||||
};
|
||||
[
|
||||
object,
|
||||
uuid(47bf6c99-a30c-4105-8af6-de76dcfdd6dd),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestMethods interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestMethods : IDispatch
|
||||
{
|
||||
/* Return values test */
|
||||
[id(1), helpstring("method with no parameters")]
|
||||
HRESULT NoParameters();
|
||||
[id(2), helpstring("method that returns a string")]
|
||||
HRESULT ReturnBSTR([out, retval]BSTR * result);
|
||||
[id(3), helpstring("method that returns a 32 bit signed integer")]
|
||||
HRESULT ReturnI4([out, retval]int * result);
|
||||
[id(4), helpstring("method that returns an 8 bit unsigned integer")]
|
||||
HRESULT ReturnUI1([out, retval]unsigned char * result);
|
||||
[id(5), helpstring("method that returns a 16 bit signed integer")]
|
||||
HRESULT ReturnI2([out, retval]short * result);
|
||||
[id(6), helpstring("method that returns a 32 bit floating point number")]
|
||||
HRESULT ReturnR4([out, retval]float * result);
|
||||
[id(7), helpstring("method that returns a 64 bit floating point number")]
|
||||
HRESULT ReturnR8([out, retval]double * result);
|
||||
[id(8), helpstring("method that returns a boolean")]
|
||||
HRESULT ReturnBool([out, retval]VARIANT_BOOL * result);
|
||||
[id(9), helpstring("method that returns an IDispatch pointer")]
|
||||
HRESULT ReturnIDispatch([out, retval]IDispatch ** result);
|
||||
[id(10), helpstring("method that returns an error")]
|
||||
HRESULT ReturnError([out, retval]SCODE * result);
|
||||
[id(12), helpstring("method that returns a date")]
|
||||
HRESULT ReturnDate([out, retval]DATE * result);
|
||||
[id(13), helpstring("method that returns an IUnknown")]
|
||||
HRESULT ReturnIUnknown([out, retval]IUnknown ** result);
|
||||
[id(14), helpstring("method that returns a signed 8 bit integer")]
|
||||
HRESULT ReturnI1([out, retval]char * result);
|
||||
[id(15), helpstring("method that returns an unsigned 16 bit integer")]
|
||||
HRESULT ReturnUI2([out, retval]unsigned short * result);
|
||||
[id(16), helpstring("method that returns an unsigned 32 bit integer")]
|
||||
HRESULT ReturnUI4([out, retval]unsigned long * result);
|
||||
[id(17), helpstring("method that returns an integer")]
|
||||
HRESULT ReturnInt([out, retval]int * result);
|
||||
[id(18), helpstring("method that returns an unsigned integer")]
|
||||
HRESULT ReturnUInt([out, retval]unsigned int * result);
|
||||
|
||||
/* Single input parameter tests */
|
||||
[id(19), helpstring("method that takes a string")]
|
||||
HRESULT TakesBSTR([in]BSTR result);
|
||||
[id(20), helpstring("method that takes a 32 bit signed integer")]
|
||||
HRESULT TakesI4([in]int result);
|
||||
[id(21), helpstring("method that takes an 8 bit unsigned integer")]
|
||||
HRESULT TakesUI1([in]unsigned char result);
|
||||
[id(22), helpstring("method that takes a 16 bit signed integer")]
|
||||
HRESULT TakesI2([in]short result);
|
||||
[id(23), helpstring("method that takes a 32 bit floating point number")]
|
||||
HRESULT TakesR4([in]float result);
|
||||
[id(24), helpstring("method that takes a 64 bit floating point number")]
|
||||
HRESULT TakesR8([in]double result);
|
||||
[id(25), helpstring("method that takes a boolean")]
|
||||
HRESULT TakesBool([in]VARIANT_BOOL result);
|
||||
[id(26), helpstring("method that takes an IDispatch pointer")]
|
||||
HRESULT TakesIDispatch([in]IDispatch * result);
|
||||
[id(27), helpstring("method that takes an error")]
|
||||
HRESULT TakesError([in]SCODE result);
|
||||
[id(29), helpstring("method that takes a date")]
|
||||
HRESULT TakesDate([in]DATE result);
|
||||
[id(30), helpstring("method that takes an IUnknown")]
|
||||
HRESULT TakesIUnknown([in]IUnknown * result);
|
||||
[id(31), helpstring("method that takes a signed 8 bit integer")]
|
||||
HRESULT TakesI1([in]char result);
|
||||
[id(32), helpstring("method that takes an unsigned 16 bit integer")]
|
||||
HRESULT TakesUI2([in]unsigned short result);
|
||||
[id(33), helpstring("method that takes an unsigned 32 bit integer")]
|
||||
HRESULT TakesUI4([in]unsigned long result);
|
||||
[id(34), helpstring("method that takes an integer")]
|
||||
HRESULT TakesInt([in]int result);
|
||||
[id(35), helpstring("method that takes an unsigned integer")]
|
||||
HRESULT TakesUInt([in]unsigned int result);
|
||||
|
||||
/* output parameter tests */
|
||||
[id(36), helpstring("method that outputs a string")]
|
||||
HRESULT OutputsBSTR([out]BSTR * result);
|
||||
[id(37), helpstring("method that outputs a 32 bit signed integer")]
|
||||
HRESULT OutputsI4([out]long * result);
|
||||
[id(38), helpstring("method that outputs an 8 bit unsigned integer")]
|
||||
HRESULT OutputsUI1([out]unsigned char * result);
|
||||
[id(39), helpstring("method that outputs a 16 bit signed integer")]
|
||||
HRESULT OutputsI2([out]short * result);
|
||||
[id(40), helpstring("method that outputs a 32 bit floating point number")]
|
||||
HRESULT OutputsR4([out]float * result);
|
||||
[id(41), helpstring("method that outputs a 64 bit floating point number")]
|
||||
HRESULT OutputsR8([out]double * result);
|
||||
[id(42), helpstring("method that outputs a boolean")]
|
||||
HRESULT OutputsBool([out]VARIANT_BOOL * result);
|
||||
[id(43), helpstring("method that outputs an IDispatch pointer")]
|
||||
HRESULT OutputsIDispatch([out]IDispatch ** result);
|
||||
[id(44), helpstring("method that outputs an error")]
|
||||
HRESULT OutputsError([out]SCODE * result);
|
||||
[id(46), helpstring("method that outputs a date")]
|
||||
HRESULT OutputsDate([out]DATE * result);
|
||||
[id(47), helpstring("method that outputs an IUnknown")]
|
||||
HRESULT OutputsIUnknown([out]IUnknown ** result);
|
||||
[id(48), helpstring("method that outputs a signed 8 bit integer")]
|
||||
HRESULT OutputsI1([out]char * result);
|
||||
[id(49), helpstring("method that outputs an unsigned 16 bit integer")]
|
||||
HRESULT OutputsUI2([out]unsigned short * result);
|
||||
[id(50), helpstring("method that outputs an unsigned 32 bit integer")]
|
||||
HRESULT OutputsUI4([out]unsigned long * result);
|
||||
|
||||
/* in/outparameter tests */
|
||||
[id(53), helpstring("method that in/outs a string")]
|
||||
HRESULT InOutsBSTR([in, out]BSTR * result);
|
||||
[id(54), helpstring("method that in/outs a 32 bit signed integer")]
|
||||
HRESULT InOutsI4([in, out]long * result);
|
||||
[id(55), helpstring("method that in/outs an 8 bit unsigned integer")]
|
||||
HRESULT InOutsUI1([in, out]unsigned char * result);
|
||||
[id(56), helpstring("method that in/outs a 16 bit signed integer")]
|
||||
HRESULT InOutsI2([in, out]short * result);
|
||||
[id(57), helpstring("method that in/outs a 32 bit floating point number")]
|
||||
HRESULT InOutsR4([in, out]float * result);
|
||||
[id(58), helpstring("method that in/outs a 64 bit floating point number")]
|
||||
HRESULT InOutsR8([in, out]double * result);
|
||||
[id(59), helpstring("method that in/outs a boolean")]
|
||||
HRESULT InOutsBool([in, out]VARIANT_BOOL * result);
|
||||
[id(60), helpstring("method that in/outs an IDispatch pointer")]
|
||||
HRESULT InOutsIDispatch([in, out]IDispatch ** result);
|
||||
[id(61), helpstring("method that in/outs an error")]
|
||||
HRESULT InOutsError([in, out]SCODE * result);
|
||||
[id(63), helpstring("method that in/outs a date")]
|
||||
HRESULT InOutsDate([in, out]DATE * result);
|
||||
[id(64), helpstring("method that in/outs an IUnknown")]
|
||||
HRESULT InOutsIUnknown([in, out]IUnknown ** result);
|
||||
[id(65), helpstring("method that in/outs a signed 8 bit integer")]
|
||||
HRESULT InOutsI1([in, out]char * result);
|
||||
[id(66), helpstring("method that in/outs an unsigned 16 bit integer")]
|
||||
HRESULT InOutsUI2([in, out]unsigned short * result);
|
||||
[id(67), helpstring("method that in/outs an unsigned 32 bit integer")]
|
||||
HRESULT InOutsUI4([in, out]unsigned long * result);
|
||||
|
||||
/* input and return tests*/
|
||||
[id(70), helpstring("method that takes an long and returns it")]
|
||||
HRESULT OneParameterWithReturn([in]long input, [out,retval]long* result);
|
||||
[id(71), helpstring("method that takes a string and returns it")]
|
||||
HRESULT StringInputAndReturn([in]BSTR str, [out, retval]BSTR* result);
|
||||
[id(72), helpstring("method that takes an IDispatch and returns it")]
|
||||
HRESULT IDispatchInputAndReturn([in]IDispatch* input, [out,retval]IDispatch** result);
|
||||
|
||||
/* Multiple parameters */
|
||||
[id(73), helpstring("method that takes two parameters")]
|
||||
HRESULT TwoParameters([in]long one, [in]long two);
|
||||
[id(74), helpstring("method that takes 12 input parameters")]
|
||||
HRESULT TwelveInParameters([in]long one, [in]long two, [in]long three,
|
||||
[in]long four, [in]long five, [in]long six,
|
||||
[in]long seven, [in]long eight,
|
||||
[in]long nine, [in]long ten,
|
||||
[in]long eleven, [in]long twelve);
|
||||
[id(75), helpstring("method that takes 12 out parameters")]
|
||||
HRESULT TwelveOutParameters([out]long *one, [out]long *two,
|
||||
[out]long *three, [out]long *four,
|
||||
[out]long *five, [out]long *six,
|
||||
[out]long *seven, [out]long *eight,
|
||||
[out]long *nine, [out]long *ten,
|
||||
[out]long *eleven, [out]long *twelve);
|
||||
[id(76), helpstring("method that takes 12 input string parameters")]
|
||||
HRESULT TwelveStrings([in]BSTR one, [in]BSTR two, [in]BSTR three,
|
||||
[in]BSTR four, [in]BSTR five, [in]BSTR six,
|
||||
[in]BSTR seven, [in]BSTR eight, [in]BSTR nine,
|
||||
[in]BSTR ten, [in]BSTR eleven, [in]BSTR twelve);
|
||||
[id(77), helpstring("method that takes 12 input string parameters")]
|
||||
HRESULT TwelveOutStrings([out]BSTR* one, [out]BSTR* two,
|
||||
[out]BSTR* three, [out]BSTR* four,
|
||||
[out]BSTR* five, [out]BSTR* six,
|
||||
[out]BSTR* seven, [out]BSTR* eight,
|
||||
[out]BSTR* nine, [out]BSTR* ten,
|
||||
[out]BSTR* eleven, [out]BSTR* twelve);
|
||||
[id(78), helpstring("method that takes 12 input string parameters")]
|
||||
HRESULT TwelveIDispatch([in]IDispatch* one, [in]IDispatch* two,
|
||||
[in]IDispatch* three, [in]IDispatch* four,
|
||||
[in]IDispatch* five, [in]IDispatch* six,
|
||||
[in]IDispatch* seven, [in]IDispatch* eight,
|
||||
[in]IDispatch* nine, [in]IDispatch* ten,
|
||||
[in]IDispatch* eleven,
|
||||
[in]IDispatch* twelve);
|
||||
[id(79), helpstring("method that takes 12 input string parameters")]
|
||||
HRESULT TwelveOutIDispatch([out]IDispatch** one,
|
||||
[out]IDispatch** two,
|
||||
[out]IDispatch** three,
|
||||
[out]IDispatch** four,
|
||||
[out]IDispatch** five,
|
||||
[out]IDispatch** six,
|
||||
[out]IDispatch** seven,
|
||||
[out]IDispatch** eight,
|
||||
[out]IDispatch** nine,
|
||||
[out]IDispatch** ten,
|
||||
[out]IDispatch** eleven,
|
||||
[out]IDispatch** twelve);
|
||||
[id(80), helpstring("method that generates an error")]
|
||||
HRESULT CreateError();
|
||||
}
|
||||
[
|
||||
uuid(745D1149-9F46-418C-B176-71EAA98974BA),
|
||||
helpstring("nsXPCDispTestMethods Class")
|
||||
]
|
||||
coclass nsXPCDispTestMethods
|
||||
{
|
||||
[default] interface nsIXPCDispTestMethods;
|
||||
};
|
||||
[
|
||||
object,
|
||||
uuid(f876c083-ae00-4b78-93b8-8305980f0864),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestArrays interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestArrays : IDispatch
|
||||
{
|
||||
[id(1), helpstring("returns a SAFEARRAY")]
|
||||
HRESULT ReturnSafeArray([out, retval]SAFEARRAY(VARIANT)* result);
|
||||
[id(2), helpstring("returns a SAFEARRAY")]
|
||||
HRESULT ReturnSafeArrayBSTR([out, retval]SAFEARRAY(VARIANT)* result);
|
||||
[id(3), helpstring("returns a SAFEARRAY")]
|
||||
HRESULT ReturnSafeArrayIDispatch([out, retval]SAFEARRAY(VARIANT)* result);
|
||||
[id(4), helpstring("method that takes a SAFEARRAY")]
|
||||
HRESULT TakesSafeArray([in]SAFEARRAY(VARIANT) array);
|
||||
[id(5), helpstring("method that takes a SAFEARRAY")]
|
||||
HRESULT TakesSafeArrayBSTR([in]SAFEARRAY(VARIANT) array);
|
||||
[id(6), helpstring("method that takes a SAFEARRAY")]
|
||||
HRESULT TakesSafeArrayIDispatch([in]SAFEARRAY(VARIANT) array);
|
||||
[id(7), helpstring("method that takes a SAFEARRAY")]
|
||||
HRESULT InOutSafeArray([in, out]SAFEARRAY(VARIANT) * array);
|
||||
[id(8), helpstring("method that takes a SAFEARRAY")]
|
||||
HRESULT InOutSafeArrayBSTR([in, out]SAFEARRAY(VARIANT) * array);
|
||||
[id(9), helpstring("method that takes a SAFEARRAY")]
|
||||
HRESULT InOutSafeArrayIDispatch([in, out]SAFEARRAY(VARIANT) * array);
|
||||
}
|
||||
[
|
||||
uuid(AB085C43-C619-48C8-B68C-C495BDE12DFB),
|
||||
helpstring("nsXPCDispTestArrays Class")
|
||||
]
|
||||
coclass nsXPCDispTestArrays
|
||||
{
|
||||
[default] interface nsIXPCDispTestArrays;
|
||||
};
|
||||
[
|
||||
object,
|
||||
uuid(9782107f-14cc-40b2-b0cd-988d81a46e9e),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestNoIDispatch interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestNoIDispatch : IUnknown
|
||||
{
|
||||
}
|
||||
[
|
||||
uuid(7414404F-A4CC-4E3C-9B32-BB20CB22F541),
|
||||
helpstring("nsXPCDispTestNoIDispatch Class")
|
||||
]
|
||||
coclass nsXPCDispTestNoIDispatch
|
||||
{
|
||||
[default] interface nsIXPCDispTestNoIDispatch;
|
||||
};
|
||||
[
|
||||
object,
|
||||
uuid(7830CACE-5019-489D-8B69-029E70CF39B7),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestProperties Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestProperties : IDispatch
|
||||
{
|
||||
[propget, id(1), helpstring("property Short")] HRESULT Short([out, retval] short *pVal);
|
||||
[propput, id(1), helpstring("property Short")] HRESULT Short([in] short newVal);
|
||||
[propget, id(2), helpstring("property Long")] HRESULT Long([out, retval] long *pVal);
|
||||
[propput, id(2), helpstring("property Long")] HRESULT Long([in] long newVal);
|
||||
[propget, id(3), helpstring("property Float")] HRESULT Float([out, retval] float *pVal);
|
||||
[propput, id(3), helpstring("property Float")] HRESULT Float([in] float newVal);
|
||||
[propget, id(4), helpstring("property Double")] HRESULT Double([out, retval] double *pVal);
|
||||
[propput, id(4), helpstring("property Double")] HRESULT Double([in] double newVal);
|
||||
[propget, id(5), helpstring("property Currency")] HRESULT Currency([out, retval] CURRENCY *pVal);
|
||||
[propput, id(5), helpstring("property Currency")] HRESULT Currency([in] CURRENCY newVal);
|
||||
[propget, id(6), helpstring("property Date")] HRESULT Date([out, retval] DATE *pVal);
|
||||
[propput, id(6), helpstring("property Date")] HRESULT Date([in] DATE newVal);
|
||||
[propget, id(7), helpstring("property String")] HRESULT String([out, retval] BSTR *pVal);
|
||||
[propput, id(7), helpstring("property String")] HRESULT String([in] BSTR newVal);
|
||||
[propget, id(8), helpstring("property DispatchPtr")] HRESULT DispatchPtr([out, retval] IDispatch* *pVal);
|
||||
[propput, id(8), helpstring("property DispatchPtr")] HRESULT DispatchPtr([in] IDispatch* newVal);
|
||||
[propget, id(9), helpstring("property SCode")] HRESULT SCode([out, retval] SCODE *pVal);
|
||||
[propput, id(9), helpstring("property SCode")] HRESULT SCode([in] SCODE newVal);
|
||||
[propget, id(10), helpstring("property Boolean")] HRESULT Boolean([out, retval] BOOL *pVal);
|
||||
[propput, id(10), helpstring("property Boolean")] HRESULT Boolean([in] BOOL newVal);
|
||||
[propget, id(11), helpstring("property Variant")] HRESULT Variant([out, retval] VARIANT *pVal);
|
||||
[propput, id(11), helpstring("property Variant")] HRESULT Variant([in] VARIANT newVal);
|
||||
[propget, id(12), helpstring("property COMPtr")] HRESULT COMPtr([out, retval] IUnknown* *pVal);
|
||||
[propput, id(12), helpstring("property COMPtr")] HRESULT COMPtr([in] IUnknown* newVal);
|
||||
[propget, id(13), helpstring("property Char")] HRESULT Char([out, retval] unsigned char *pVal);
|
||||
[propput, id(13), helpstring("property Char")] HRESULT Char([in] unsigned char newVal);
|
||||
[propget, id(14), helpstring("property ParameterizedProperty")] HRESULT ParameterizedProperty([in]long aIndex, [out, retval] long *pVal);
|
||||
[propput, id(14), helpstring("property ParameterizedProperty")] HRESULT ParameterizedProperty([in]long aIndex, [in] long newVal);
|
||||
[propget, id(15), helpstring("property ParameterizedPropertyCount")] HRESULT ParameterizedPropertyCount([out, retval] long *pVal);
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(0797788A-CB08-4995-BD45-7BF8C468DE21),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestScriptOn Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestScriptOn : IDispatch
|
||||
{
|
||||
};
|
||||
|
||||
[
|
||||
uuid(2A06373F-3E61-4882-A3D7-A104F70B09ED),
|
||||
helpstring("nsXPCDispTestScriptOn Class")
|
||||
]
|
||||
coclass nsXPCDispTestScriptOn
|
||||
{
|
||||
[default] interface nsIXPCDispTestScriptOn;
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(EE6F9DB5-890F-422D-B9DC-9C5AB5A1D654),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestScriptOff Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestScriptOff : IDispatch
|
||||
{
|
||||
};
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(D84352CA-1A01-4E72-9072-77AFA669B3AD),
|
||||
dual,
|
||||
helpstring("nsIXPCDispTestWrappedJS Interface"),
|
||||
pointer_default(unique)
|
||||
]
|
||||
interface nsIXPCDispTestWrappedJS : IDispatch
|
||||
{
|
||||
[id(1), helpstring("method TestParamTypes")] HRESULT TestParamTypes([in] IDispatch * obj, [out, retval]BSTR * errMsg);
|
||||
};
|
||||
|
||||
[
|
||||
uuid(EAEE6BB2-C005-4B91-BCA7-6613236F6F69),
|
||||
helpstring("nsXPCDispTestWrappedJS Class")
|
||||
]
|
||||
coclass nsXPCDispTestWrappedJS
|
||||
{
|
||||
[default] interface nsIXPCDispTestWrappedJS;
|
||||
};
|
||||
|
||||
[
|
||||
uuid(959CD122-9826-4757-BA09-DE327D55F9E7),
|
||||
helpstring("nsXPCDispTestScriptOff Class")
|
||||
]
|
||||
coclass nsXPCDispTestScriptOff
|
||||
{
|
||||
[default] interface nsIXPCDispTestScriptOff;
|
||||
};
|
||||
|
||||
[
|
||||
uuid(D8B4265B-1768-4CA9-A285-7CCAEEB51C74),
|
||||
helpstring("nsXPCDispTestProperties Class")
|
||||
]
|
||||
coclass nsXPCDispTestProperties
|
||||
{
|
||||
[default] interface nsIXPCDispTestProperties;
|
||||
};
|
||||
|
||||
|
||||
};
|
||||
@@ -1,145 +0,0 @@
|
||||
//Microsoft Developer Studio generated resource script.
|
||||
//
|
||||
#include "resource.h"
|
||||
|
||||
#define APSTUDIO_READONLY_SYMBOLS
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 2 resource.
|
||||
//
|
||||
#include "winres.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#undef APSTUDIO_READONLY_SYMBOLS
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// English (U.S.) resources
|
||||
|
||||
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
|
||||
#ifdef _WIN32
|
||||
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
|
||||
#pragma code_page(1252)
|
||||
#endif //_WIN32
|
||||
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// TEXTINCLUDE
|
||||
//
|
||||
|
||||
1 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"resource.h\0"
|
||||
END
|
||||
|
||||
2 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"#include ""winres.h""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
3 TEXTINCLUDE DISCARDABLE
|
||||
BEGIN
|
||||
"1 TYPELIB ""XPCIDispatchTest.tlb""\r\n"
|
||||
"\0"
|
||||
END
|
||||
|
||||
#endif // APSTUDIO_INVOKED
|
||||
|
||||
|
||||
#ifndef _MAC
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION 1,0,0,1
|
||||
PRODUCTVERSION 1,0,0,1
|
||||
FILEFLAGSMASK 0x3fL
|
||||
#ifdef _DEBUG
|
||||
FILEFLAGS 0x1L
|
||||
#else
|
||||
FILEFLAGS 0x0L
|
||||
#endif
|
||||
FILEOS 0x4L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "XPCIDispatchTest Module\0"
|
||||
VALUE "FileVersion", "1, 0, 0, 1\0"
|
||||
VALUE "InternalName", "XPCIDispatchTest\0"
|
||||
VALUE "LegalCopyright", "Copyright 2002\0"
|
||||
VALUE "OriginalFilename", "XPCIDispatchTest.DLL\0"
|
||||
VALUE "ProductName", "XPCIDispatchTest Module\0"
|
||||
VALUE "ProductVersion", "1, 0, 0, 1\0"
|
||||
VALUE "OLESelfRegister", "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
||||
#endif // !_MAC
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// REGISTRY
|
||||
//
|
||||
|
||||
IDR_nsXPCDispTestMethods REGISTRY DISCARDABLE "nsXPCDispTestMethods.rgs"
|
||||
IDR_nsXPCDispSimple REGISTRY DISCARDABLE "nsXPCDispSimple.rgs"
|
||||
IDR_nsXPCDispTestNoIDispatch REGISTRY DISCARDABLE "nsXPCDispTestNoIDispatch.rgs"
|
||||
IDR_nsXPCDispTestProperties REGISTRY DISCARDABLE "nsXPCDispTestProperties.rgs"
|
||||
IDR_nsXPCDispTestArrays REGISTRY DISCARDABLE "nsXPCDispTestArrays.rgs"
|
||||
IDR_nsXPCDispTestScriptOn REGISTRY DISCARDABLE "nsXPCDispTestScriptOn.rgs"
|
||||
IDR_nsXPCDispTestScriptOff REGISTRY DISCARDABLE "nsXPCDispTestScriptOff.rgs"
|
||||
IDR_nsXPCDispTestWrappedJS REGISTRY DISCARDABLE "nsXPCDispTestWrappedJS.rgs"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// String Table
|
||||
//
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_PROJNAME "XPCIDispatchTest"
|
||||
IDS_NSXPCDISPTTESTMETHODS_DESC "nsXPCDisptTestMethods Class"
|
||||
IDS_NSXPCDISPTESTMETHODS_DESC "nsXPCDispTestMethods Class"
|
||||
IDS_NSXPCDISPSIMPLE_DESC "nsXPCDispSimple Class"
|
||||
IDS_NSXPCDISPTESTNOIDISPATCH_DESC "nsXPCDispTestNoIDispatch Class"
|
||||
IDS_NSXPCDISPTESTNOSCRIPT_DESC "nsXPCDispTestNoScript Class"
|
||||
IDS_NSXPCDISPTESTPROPERTIES_DESC "nsXPCDispTestProperties Class"
|
||||
END
|
||||
|
||||
STRINGTABLE DISCARDABLE
|
||||
BEGIN
|
||||
IDS_NSXPCDISPTESTARRAYS_DESC "nsXPCDispTestArrays Class"
|
||||
IDS_NSXPCDISPTESTSCRIPTON_DESC "nsXPCDispTestScriptOn Class"
|
||||
IDS_NSXPCDISPTESTSCRIPTOFF_DESC "nsXPCDispTestScriptOff Class"
|
||||
IDS_NSXPCDISPTESTWRAPPEDJS_DESC "nsXPCDispTestWrappedJS Class"
|
||||
END
|
||||
|
||||
#endif // English (U.S.) resources
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
|
||||
#ifndef APSTUDIO_INVOKED
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Generated from the TEXTINCLUDE 3 resource.
|
||||
//
|
||||
1 TYPELIB "XPCIDispatchTest.tlb"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
#endif // not APSTUDIO_INVOKED
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
// nsXPCDispSimple.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispSimple.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispSimple::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispSimple,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispSimple::ClassName(BSTR * name)
|
||||
{
|
||||
if (name == NULL)
|
||||
return E_POINTER;
|
||||
CComBSTR x("nsXPCDispSimple");
|
||||
*name = x.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispSimple::get_Number(LONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = mNumber;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispSimple::put_Number(LONG result)
|
||||
{
|
||||
mNumber = result;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,56 +0,0 @@
|
||||
// nsXPCDispSimple.h: Definition of the nsXPCDispSimple class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPSIMPLE_H__5502A675_46D9_4762_A7F9_1A023A052152__INCLUDED_)
|
||||
#define AFX_NSXPCDISPSIMPLE_H__5502A675_46D9_4762_A7F9_1A023A052152__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispSimple
|
||||
|
||||
class nsXPCDispSimple :
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispSimple,&CLSID_nsXPCDispSimple>,
|
||||
public IDispatchImpl<nsIXPCDispSimple, &IID_nsIXPCDispSimple, &LIBID_IDispatchTestLib>
|
||||
{
|
||||
public:
|
||||
nsXPCDispSimple() : mNumber(5) {}
|
||||
BEGIN_CATEGORY_MAP(nsXPCDispSimple)
|
||||
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
||||
END_CATEGORY_MAP()
|
||||
BEGIN_COM_MAP(nsXPCDispSimple)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispSimple)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispSimple)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispSimple)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispSimple
|
||||
public:
|
||||
// nsIXPCDispSimple
|
||||
STDMETHOD(ClassName)(BSTR * name);
|
||||
STDMETHOD(get_Number)(LONG * result);
|
||||
STDMETHOD(put_Number)(LONG result);
|
||||
template <class T>
|
||||
static HRESULT CreateInstance(T ** result)
|
||||
{
|
||||
return CoCreateInstance(CLSID_nsXPCDispSimple, 0, CLSCTX_ALL,
|
||||
__uuidof(T),
|
||||
reinterpret_cast<void**>(result));
|
||||
}
|
||||
private:
|
||||
long mNumber;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPSIMPLE_H__5502A675_46D9_4762_A7F9_1A023A052152__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispSimple.1 = s 'nsXPCDispSimple Class'
|
||||
{
|
||||
CLSID = s '{9F39237C-D179-4260-8EF3-4B6D4D7D5570}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispSimple = s 'nsXPCDispSimple Class'
|
||||
{
|
||||
CLSID = s '{9F39237C-D179-4260-8EF3-4B6D4D7D5570}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {9F39237C-D179-4260-8EF3-4B6D4D7D5570} = s 'nsXPCDispSimple Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispSimple.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispSimple'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
// nsXPCDispTestArrays.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestArrays.h"
|
||||
|
||||
unsigned int zero = 0;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestArrays::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestArrays,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestArrays::ReturnSafeArray(LPSAFEARRAY * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*result = SafeArrayCreateVector(VT_I4, 0, 3);
|
||||
for (long index = 0; index < 3; ++index)
|
||||
{
|
||||
SafeArrayPutElement(*result, &index, &index);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestArrays::ReturnSafeArrayBSTR(LPSAFEARRAY * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*result = SafeArrayCreateVector(VT_BSTR, 0, 3);
|
||||
for (long index = 0; index < 3; ++index)
|
||||
{
|
||||
_variant_t var(index);
|
||||
HRESULT hr = VariantChangeType(&var, &var, VARIANT_ALPHABOOL, VT_BSTR);
|
||||
|
||||
if (FAILED(hr))
|
||||
return hr;
|
||||
SafeArrayPutElement(*result, &index, var.bstrVal);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestArrays::ReturnSafeArrayIDispatch(LPSAFEARRAY * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*result = SafeArrayCreateVector(VT_DISPATCH, 0, 3);
|
||||
for (long index = 0; index < 3; ++index)
|
||||
{
|
||||
CComPtr<nsIXPCDispSimple> ptr;
|
||||
ptr.CoCreateInstance(CLSID_nsXPCDispSimple);
|
||||
SafeArrayPutElement(*result, &index, ptr.p);
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define RETURN_IF_FAIL(x) hr = x; if (FAILED(hr)) return hr;
|
||||
|
||||
STDMETHODIMP nsXPCDispTestArrays::TakesSafeArray(LPSAFEARRAY array)
|
||||
{
|
||||
long lbound;
|
||||
long ubound;
|
||||
HRESULT hr;
|
||||
|
||||
RETURN_IF_FAIL(SafeArrayGetLBound(array, 1, &lbound));
|
||||
if (lbound != 0)
|
||||
return E_FAIL;
|
||||
RETURN_IF_FAIL(SafeArrayGetUBound(array, 1, &ubound));
|
||||
if (ubound != 3)
|
||||
return E_FAIL;
|
||||
for (long index = lbound; index <= ubound; ++index)
|
||||
{
|
||||
_variant_t value;
|
||||
RETURN_IF_FAIL(SafeArrayGetElement(array, &index, &value));
|
||||
if (value != _variant_t(index))
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestArrays::TakesSafeArrayBSTR(LPSAFEARRAY array)
|
||||
{
|
||||
long lbound;
|
||||
long ubound;
|
||||
HRESULT hr;
|
||||
|
||||
RETURN_IF_FAIL(SafeArrayGetLBound(array, 1, &lbound));
|
||||
if (lbound != 0)
|
||||
return E_FAIL;
|
||||
RETURN_IF_FAIL(SafeArrayGetUBound(array, 1, &ubound));
|
||||
if (ubound != 3)
|
||||
return E_FAIL;
|
||||
for (long index = lbound; index <= ubound; ++index)
|
||||
{
|
||||
_variant_t value;
|
||||
RETURN_IF_FAIL(SafeArrayGetElement(array, &index, &value));
|
||||
_variant_t test(index);
|
||||
if (_bstr_t(value) != _bstr_t(test))
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestArrays::TakesSafeArrayIDispatch(LPSAFEARRAY array)
|
||||
{
|
||||
long lbound;
|
||||
long ubound;
|
||||
HRESULT hr;
|
||||
|
||||
RETURN_IF_FAIL(SafeArrayGetLBound(array, 0, &lbound));
|
||||
if (lbound != 0)
|
||||
return E_FAIL;
|
||||
RETURN_IF_FAIL(SafeArrayGetUBound(array, 0, &ubound));
|
||||
if (ubound != 3)
|
||||
return E_FAIL;
|
||||
for (long index = lbound; index <= ubound; ++index)
|
||||
{
|
||||
_variant_t value;
|
||||
RETURN_IF_FAIL(SafeArrayGetElement(array, &index, &value));
|
||||
// We need to do more here, but this is good enough for now
|
||||
if (!value.pdispVal)
|
||||
return E_FAIL;
|
||||
}
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestArrays::InOutSafeArray(LPSAFEARRAY * array)
|
||||
{
|
||||
if (array == NULL)
|
||||
return E_POINTER;
|
||||
long lbound;
|
||||
long ubound;
|
||||
HRESULT hr;
|
||||
|
||||
RETURN_IF_FAIL(SafeArrayGetLBound(*array, 0, &lbound));
|
||||
if (lbound != 0)
|
||||
return E_FAIL;
|
||||
RETURN_IF_FAIL(SafeArrayGetUBound(*array, 0, &ubound));
|
||||
if (ubound != 3)
|
||||
return E_FAIL;
|
||||
LPSAFEARRAY newArray = SafeArrayCreateVector(VT_I4, lbound, ubound);
|
||||
for (long index = lbound; index <= ubound; ++index)
|
||||
{
|
||||
long value;
|
||||
RETURN_IF_FAIL(SafeArrayGetElement(*array, &index, &value));
|
||||
if (value != index)
|
||||
return E_FAIL;
|
||||
value += 42;
|
||||
RETURN_IF_FAIL(SafeArrayPutElement(newArray, &index, &value));
|
||||
}
|
||||
SafeArrayDestroy(*array);
|
||||
*array = newArray;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestArrays::InOutSafeArrayBSTR(LPSAFEARRAY * array)
|
||||
{
|
||||
if (array == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
long lbound;
|
||||
long ubound;
|
||||
HRESULT hr;
|
||||
|
||||
RETURN_IF_FAIL(SafeArrayGetLBound(*array, 0, &lbound));
|
||||
if (lbound != 0)
|
||||
return E_FAIL;
|
||||
RETURN_IF_FAIL(SafeArrayGetUBound(*array, 0, &ubound));
|
||||
if (ubound != 3)
|
||||
return E_FAIL;
|
||||
LPSAFEARRAY newArray = SafeArrayCreateVector(VT_BSTR, lbound, ubound);
|
||||
for (long index = lbound; index <= ubound; ++index)
|
||||
{
|
||||
BSTR value;
|
||||
RETURN_IF_FAIL(SafeArrayGetElement(*array, &index, &value));
|
||||
_bstr_t newValue(value, TRUE);
|
||||
newValue += L"Appended";
|
||||
RETURN_IF_FAIL(SafeArrayPutElement(newArray, &index, newValue.copy()));
|
||||
}
|
||||
SafeArrayDestroy(*array);
|
||||
*array = newArray;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestArrays::InOutSafeArrayIDispatch(LPSAFEARRAY * array)
|
||||
{
|
||||
if (array == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
long lbound;
|
||||
long ubound;
|
||||
HRESULT hr;
|
||||
|
||||
RETURN_IF_FAIL(SafeArrayGetLBound(*array, 0, &lbound));
|
||||
if (lbound != 0)
|
||||
return E_FAIL;
|
||||
RETURN_IF_FAIL(SafeArrayGetUBound(*array, 0, &ubound));
|
||||
if (ubound != 3)
|
||||
return E_FAIL;
|
||||
LPSAFEARRAY newArray = SafeArrayCreateVector(VT_DISPATCH, lbound, ubound);
|
||||
for (long index = lbound; index <= ubound; ++index)
|
||||
{
|
||||
IDispatch* value;
|
||||
RETURN_IF_FAIL(SafeArrayGetElement(*array, &index, &value));
|
||||
RETURN_IF_FAIL(SafeArrayPutElement(newArray, &index, &value));
|
||||
}
|
||||
SafeArrayDestroy(*array);
|
||||
*array = newArray;
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
// nsXPCDispTestArrays.h: Definition of the nsXPCDispTestArrays class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTARRAYS_H__5F59BD4C_16A4_4BD6_8281_796DE6A2889C__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTARRAYS_H__5F59BD4C_16A4_4BD6_8281_796DE6A2889C__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestArrays
|
||||
|
||||
class nsXPCDispTestArrays :
|
||||
public IDispatchImpl<nsIXPCDispTestArrays, &IID_nsIXPCDispTestArrays, &LIBID_IDispatchTestLib>,
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestArrays,&CLSID_nsXPCDispTestArrays>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestArrays() {}
|
||||
BEGIN_CATEGORY_MAP(nsXPCDispTestArrays)
|
||||
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
||||
END_CATEGORY_MAP()
|
||||
BEGIN_COM_MAP(nsXPCDispTestArrays)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestArrays)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispTestArrays)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestArrays)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestArrays
|
||||
public:
|
||||
// nsIXPCDispTestArrays
|
||||
STDMETHOD(ReturnSafeArray)(LPSAFEARRAY * result);
|
||||
STDMETHOD(ReturnSafeArrayBSTR)(LPSAFEARRAY * result);
|
||||
STDMETHOD(ReturnSafeArrayIDispatch)(LPSAFEARRAY * result);
|
||||
STDMETHOD(TakesSafeArray)(LPSAFEARRAY array);
|
||||
STDMETHOD(TakesSafeArrayBSTR)(LPSAFEARRAY array);
|
||||
STDMETHOD(TakesSafeArrayIDispatch)(LPSAFEARRAY array);
|
||||
STDMETHOD(InOutSafeArray)(LPSAFEARRAY * array);
|
||||
STDMETHOD(InOutSafeArrayBSTR)(LPSAFEARRAY * array);
|
||||
STDMETHOD(InOutSafeArrayIDispatch)(LPSAFEARRAY * array);
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTARRAYS_H__5F59BD4C_16A4_4BD6_8281_796DE6A2889C__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestArrays.1 = s 'nsXPCDispTestArrays Class'
|
||||
{
|
||||
CLSID = s '{AB085C43-C619-48C8-B68C-C495BDE12DFB}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestArrays = s 'nsXPCDispTestArrays Class'
|
||||
{
|
||||
CLSID = s '{AB085C43-C619-48C8-B68C-C495BDE12DFB}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {AB085C43-C619-48C8-B68C-C495BDE12DFB} = s 'nsXPCDispTestArrays Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestArrays.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestArrays'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,699 +0,0 @@
|
||||
// nsXPCDispTestMethods.cpp : Implementation of CIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestMethods.h"
|
||||
#include "XPCDispUtilities.h"
|
||||
#include "nsXPCDispSimple.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestMethods::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestMethods,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestMethods::NoParameters()
|
||||
{
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnBSTR(BSTR * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
CComBSTR x("Boo");
|
||||
*result = x.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnI4(INT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnUI1(BYTE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnI2(SHORT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 9999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnR4(FLOAT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99999.1f;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnR8(DOUBLE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99999999999.99;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnBool(VARIANT_BOOL * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = VARIANT_TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnIDispatch(IDispatch * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
return nsXPCDispSimple::CreateInstance(result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnError(SCODE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnDate(DATE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
CComBSTR dateStr(L"5/2/02");
|
||||
return VarDateFromStr(dateStr, LOCALE_SYSTEM_DEFAULT,
|
||||
LOCALE_NOUSEROVERRIDE, result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnIUnknown(IUnknown * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
return XPCCreateInstance<IUnknown>(CLSID_nsXPCDispTestNoIDispatch, IID_IUnknown, result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnI1(unsigned char * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*result = 120;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnUI2(USHORT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 9999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnUI4(ULONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 3000000000;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnInt(INT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = -999999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::ReturnUInt(UINT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*result = 3000000000;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesBSTR(BSTR result)
|
||||
{
|
||||
CComBSTR str(result);
|
||||
static CComBSTR test(L"TakesBSTR");
|
||||
return str == test ? S_OK: E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesI4(INT result)
|
||||
{
|
||||
return result == 999999 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesUI1(BYTE result)
|
||||
{
|
||||
return result == 42 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesI2(SHORT result)
|
||||
{
|
||||
return result == 32000 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesR4(FLOAT result)
|
||||
{
|
||||
// Hopefully we won't run into any precision/rounding issues
|
||||
return result == 99999.99f ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesR8(DOUBLE result)
|
||||
{
|
||||
// Hopefully we won't run into any precision/rounding issues
|
||||
return result == 999999999.99 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesBool(VARIANT_BOOL result)
|
||||
{
|
||||
return result ? S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
inline
|
||||
HRESULT GetProperty(IDispatch *pDisp, const CComBSTR & name, CComVariant& output)
|
||||
{
|
||||
DISPID dispid = GetIDsOfNames(pDisp, name);
|
||||
DISPPARAMS dispParams;
|
||||
dispParams.cArgs = 0;
|
||||
dispParams.cNamedArgs = 0;
|
||||
dispParams.rgdispidNamedArgs = 0;
|
||||
dispParams.rgvarg = 0;
|
||||
return pDisp->Invoke(dispid, IID_NULL, LOCALE_SYSTEM_DEFAULT,DISPATCH_PROPERTYGET, &dispParams, &output, 0, 0);
|
||||
}
|
||||
|
||||
inline
|
||||
HRESULT PutProperty(IDispatch *pDisp, const CComBSTR & name, const CComVariant& input)
|
||||
{
|
||||
DISPPARAMS dispParams;
|
||||
DISPID did = DISPID_PROPERTYPUT;
|
||||
dispParams.cArgs = 1;
|
||||
CComVariant var(input);
|
||||
dispParams.rgvarg = &var;
|
||||
dispParams.cNamedArgs = 1;
|
||||
dispParams.rgdispidNamedArgs = &did;
|
||||
CComVariant result;
|
||||
DISPID dispID = GetIDsOfNames(pDisp, name);
|
||||
return pDisp->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT,
|
||||
DISPATCH_PROPERTYPUT, &dispParams, &result,
|
||||
0, 0);
|
||||
}
|
||||
|
||||
HRESULT VerifynsXPCDispSimple(IDispatch * result)
|
||||
{
|
||||
CComVariant property;
|
||||
HRESULT hResult = GetProperty(result, L"Number", property);
|
||||
CComVariant test((long)5);
|
||||
if (FAILED(hResult))
|
||||
return hResult;
|
||||
if (property != test)
|
||||
return E_FAIL;
|
||||
return PutProperty(result, L"Number", 76);
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesIDispatch(IDispatch * result)
|
||||
{
|
||||
return VerifynsXPCDispSimple(result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesError(SCODE result)
|
||||
{
|
||||
return result == E_FAIL ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesDate(DATE result)
|
||||
{
|
||||
CComBSTR dateStr(L"5/2/02");
|
||||
DATE myDate;
|
||||
HRESULT hResult = VarDateFromStr(dateStr, LOCALE_SYSTEM_DEFAULT,
|
||||
LOCALE_NOUSEROVERRIDE, &myDate);
|
||||
if (SUCCEEDED(hResult))
|
||||
return myDate == result ? S_OK : E_FAIL;
|
||||
else
|
||||
return hResult;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesIUnknown(IUnknown * result)
|
||||
{
|
||||
CComPtr<IUnknown> ptr(result);
|
||||
ULONG before = result->AddRef();
|
||||
ULONG after = result->Release();
|
||||
CComQIPtr<nsIXPCDispTestNoIDispatch> noIDispatch(ptr);
|
||||
return before - 1 == after ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesI1(unsigned char result)
|
||||
{
|
||||
return result == 42 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesUI2(USHORT result)
|
||||
{
|
||||
return result == 50000 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesUI4(ULONG result)
|
||||
{
|
||||
return result == 0xF0000000 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesInt(INT result)
|
||||
{
|
||||
return result == -10000000 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TakesUInt(UINT result)
|
||||
{
|
||||
return result == 0xE0000000 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsBSTR(BSTR * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
CComBSTR x("Boo");
|
||||
*result = x.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsI4(LONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsUI1(BYTE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsI2(SHORT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 9999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsR4(FLOAT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 999999.1f;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsR8(DOUBLE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 99999999999.99;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsBool(VARIANT_BOOL * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = VARIANT_TRUE;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsIDispatch(IDispatch * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
return nsXPCDispSimple::CreateInstance(result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsError(SCODE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = E_FAIL;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsDate(DATE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
CComBSTR dateStr(L"5/2/02");
|
||||
return VarDateFromStr(dateStr, LOCALE_SYSTEM_DEFAULT,
|
||||
LOCALE_NOUSEROVERRIDE, result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsIUnknown(IUnknown * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
return XPCCreateInstance<IUnknown>(CLSID_nsXPCDispTestNoIDispatch, IID_IUnknown, result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsI1(unsigned char * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
*result = L'x';
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsUI2(USHORT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 9999;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OutputsUI4(ULONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = 3000000000;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsBSTR(BSTR * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
CComBSTR str(*result);
|
||||
str += L"Appended";
|
||||
SysFreeString(*result);
|
||||
*result = str.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsI4(LONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result -= 4000000;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsUI1(BYTE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result -= 42;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsI2(SHORT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result += 10000;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsR4(FLOAT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result += 5.05f;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsR8(DOUBLE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result += 50000000.00000005;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsBool(VARIANT_BOOL * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = !*result;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsIDispatch(IDispatch * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
CComPtr<nsIXPCDispSimple> ptr;
|
||||
ptr.CoCreateInstance(CLSID_nsXPCDispSimple);
|
||||
CComPtr<IDispatch> incoming(*result);
|
||||
CComVariant value;
|
||||
HRESULT hResult = GetProperty(incoming, L"Number", value);
|
||||
if (FAILED(hResult))
|
||||
return hResult;
|
||||
if (value.lVal != 10)
|
||||
return E_FAIL;
|
||||
hResult = ptr->put_Number(value.lVal + 5);
|
||||
if (FAILED(hResult))
|
||||
return hResult;
|
||||
|
||||
*result = ptr.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsError(SCODE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result += 1;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsDate(DATE * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
ULONG days;
|
||||
HRESULT hResult = VarUI4FromDate(*result, &days);
|
||||
if (FAILED(hResult))
|
||||
return hResult;
|
||||
|
||||
return VarDateFromUI4(days + 1, result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsIUnknown(IUnknown * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
|
||||
CComPtr<IUnknown> ptr(*result);
|
||||
ULONG before = (*result)->AddRef();
|
||||
ULONG after = (*result)->Release();
|
||||
if (before - 1 != after)
|
||||
return E_FAIL;
|
||||
return nsXPCDispSimple::CreateInstance(result);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsI1(unsigned char * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
++*result;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsUI2(USHORT * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result += 42;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::InOutsUI4(ULONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result -= 42;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::OneParameterWithReturn(LONG input,
|
||||
LONG * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
*result = input + 42;
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::StringInputAndReturn(BSTR str,
|
||||
BSTR * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
CComBSTR input(str);
|
||||
input += L"Appended";
|
||||
*result = input.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::IDispatchInputAndReturn(IDispatch * input, IDispatch * * result)
|
||||
{
|
||||
if (result == NULL)
|
||||
return E_POINTER;
|
||||
HRESULT hResult = VerifynsXPCDispSimple(input);
|
||||
|
||||
hResult = XPCCreateInstance<IDispatch>(CLSID_nsXPCDispSimple, IID_IDispatch, result);
|
||||
if (FAILED(hResult))
|
||||
return hResult;
|
||||
CComVariant variant;
|
||||
hResult = GetProperty(input, L"Number", variant);
|
||||
if (FAILED(hResult))
|
||||
return hResult;
|
||||
return PutProperty(*result, L"Number", variant.lVal + 5);
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwoParameters(LONG one, LONG two)
|
||||
{
|
||||
return one + 1 == two ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwelveInParameters(LONG one, LONG two,
|
||||
LONG three, LONG four,
|
||||
LONG five, LONG six,
|
||||
LONG seven, LONG eight,
|
||||
LONG nine, LONG ten,
|
||||
LONG eleven, LONG twelve)
|
||||
{
|
||||
return one + two + three + four + five + six + seven + eight + nine +
|
||||
ten + eleven + twelve == 78 ? S_OK : E_FAIL;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwelveOutParameters(LONG * one, LONG * two,
|
||||
LONG * three,
|
||||
LONG * four,
|
||||
LONG * five, LONG * six,
|
||||
LONG * seven,
|
||||
LONG * eight,
|
||||
LONG * nine, LONG * ten,
|
||||
LONG * eleven,
|
||||
LONG * twelve)
|
||||
{
|
||||
if (one == 0 || two == 0 || three == 0 || four == 0 ||
|
||||
five == 0 || six == 0 || seven == 0 || eight == 0 ||
|
||||
nine == 0 || ten == 0 || eleven == 0 || twelve == 0)
|
||||
return E_POINTER;
|
||||
|
||||
*one = 1;
|
||||
*two = 2;
|
||||
*three = 3;
|
||||
*four = 4;
|
||||
*five = 5;
|
||||
*six = 6;
|
||||
*seven = 7;
|
||||
*eight = 8;
|
||||
*nine = 9;
|
||||
*ten = 10;
|
||||
*eleven = 11;
|
||||
*twelve = 12;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
inline
|
||||
boolean Equals(BSTR left, const char * str)
|
||||
{
|
||||
return CComBSTR(left) == str;
|
||||
}
|
||||
#define TESTPARAM(val) Equals(val, #val)
|
||||
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwelveStrings(BSTR one, BSTR two, BSTR three, BSTR four, BSTR five, BSTR six, BSTR seven, BSTR eight, BSTR nine, BSTR ten, BSTR eleven, BSTR twelve)
|
||||
{
|
||||
return TESTPARAM(one) && TESTPARAM(two) && TESTPARAM(three) &&
|
||||
TESTPARAM(four) && TESTPARAM(five) && TESTPARAM(six) &&
|
||||
TESTPARAM(seven) && TESTPARAM(eight) && TESTPARAM(nine) &&
|
||||
TESTPARAM(ten) && TESTPARAM(eleven) && TESTPARAM(twelve) ?
|
||||
S_OK : E_FAIL;
|
||||
}
|
||||
|
||||
#define ASSIGNPARAM(val) \
|
||||
if (val == 0) \
|
||||
return E_POINTER; \
|
||||
*val = CComBSTR(#val).Detach()
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwelveOutStrings(BSTR * one, BSTR * two, BSTR * three, BSTR * four, BSTR * five, BSTR * six, BSTR * seven, BSTR * eight, BSTR * nine, BSTR * ten, BSTR * eleven, BSTR * twelve)
|
||||
{
|
||||
ASSIGNPARAM(one);
|
||||
ASSIGNPARAM(two);
|
||||
ASSIGNPARAM(three);
|
||||
ASSIGNPARAM(four);
|
||||
ASSIGNPARAM(five);
|
||||
ASSIGNPARAM(six);
|
||||
ASSIGNPARAM(seven);
|
||||
ASSIGNPARAM(eight);
|
||||
ASSIGNPARAM(nine);
|
||||
ASSIGNPARAM(ten);
|
||||
ASSIGNPARAM(eleven);
|
||||
ASSIGNPARAM(twelve);
|
||||
return S_OK;
|
||||
}
|
||||
#define VERIFYSIMPLE(param) \
|
||||
hResult = VerifynsXPCDispSimple(param); \
|
||||
if (FAILED(hResult)) \
|
||||
return hResult
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwelveIDispatch(IDispatch * one,
|
||||
IDispatch * two,
|
||||
IDispatch * three,
|
||||
IDispatch * four,
|
||||
IDispatch * five,
|
||||
IDispatch * six,
|
||||
IDispatch * seven,
|
||||
IDispatch * eight,
|
||||
IDispatch * nine,
|
||||
IDispatch * ten,
|
||||
IDispatch * eleven,
|
||||
IDispatch * twelve)
|
||||
{
|
||||
HRESULT hResult;
|
||||
VERIFYSIMPLE(one);
|
||||
VERIFYSIMPLE(two);
|
||||
VERIFYSIMPLE(three);
|
||||
VERIFYSIMPLE(four);
|
||||
VERIFYSIMPLE(five);
|
||||
VERIFYSIMPLE(six);
|
||||
VERIFYSIMPLE(seven);
|
||||
VERIFYSIMPLE(eight);
|
||||
VERIFYSIMPLE(nine);
|
||||
VERIFYSIMPLE(ten);
|
||||
VERIFYSIMPLE(eleven);
|
||||
VERIFYSIMPLE(twelve);
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
#define ASSIGNSIMPLE(param) \
|
||||
if (param == 0) \
|
||||
return E_POINTER; \
|
||||
hResult = nsXPCDispSimple::CreateInstance(param); \
|
||||
if (FAILED(hResult)) \
|
||||
return hResult; \
|
||||
|
||||
STDMETHODIMP nsXPCDispTestMethods::TwelveOutIDispatch(IDispatch * * one,
|
||||
IDispatch * * two,
|
||||
IDispatch * * three,
|
||||
IDispatch * * four,
|
||||
IDispatch * * five,
|
||||
IDispatch * * six,
|
||||
IDispatch * * seven,
|
||||
IDispatch * * eight,
|
||||
IDispatch * * nine,
|
||||
IDispatch * * ten,
|
||||
IDispatch * * eleven,
|
||||
IDispatch * * twelve){
|
||||
HRESULT hResult;
|
||||
ASSIGNSIMPLE(one);
|
||||
ASSIGNSIMPLE(two);
|
||||
ASSIGNSIMPLE(three);
|
||||
ASSIGNSIMPLE(four);
|
||||
ASSIGNSIMPLE(five);
|
||||
ASSIGNSIMPLE(six);
|
||||
ASSIGNSIMPLE(seven);
|
||||
ASSIGNSIMPLE(eight);
|
||||
ASSIGNSIMPLE(nine);
|
||||
ASSIGNSIMPLE(ten);
|
||||
ASSIGNSIMPLE(eleven);
|
||||
ASSIGNSIMPLE(twelve);
|
||||
return S_OK;
|
||||
}
|
||||
STDMETHODIMP nsXPCDispTestMethods::CreateError()
|
||||
{
|
||||
CComBSTR someText(L"CreateError Test");
|
||||
ICreateErrorInfo * pCreateError;
|
||||
IErrorInfo * pError;
|
||||
HRESULT result = CreateErrorInfo(&pCreateError);
|
||||
if (FAILED(result))
|
||||
return E_NOTIMPL;
|
||||
result = pCreateError->QueryInterface(&pError);
|
||||
if (FAILED(result))
|
||||
return E_NOTIMPL;
|
||||
result = pCreateError->SetDescription(someText);
|
||||
if (FAILED(result))
|
||||
return E_NOTIMPL;
|
||||
result = pCreateError->SetGUID(IID_nsIXPCDispTestMethods);
|
||||
if (FAILED(result))
|
||||
return E_NOTIMPL;
|
||||
CComBSTR source(L"XPCIDispatchTest.nsXPCDispTestMethods.1");
|
||||
result = pCreateError->SetSource(source);
|
||||
if (FAILED(result))
|
||||
return E_NOTIMPL;
|
||||
result = SetErrorInfo(0, pError);
|
||||
if (FAILED(result))
|
||||
return E_NOTIMPL;
|
||||
pError->Release();
|
||||
pCreateError->Release();
|
||||
return E_FAIL;
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
// nsXPCDispTestMethods.h: Definition of the nsXPCDispTestMethods class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTMETHODS_H__A516B1D7_1971_419C_AE35_EDFAC27D1227__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTMETHODS_H__A516B1D7_1971_419C_AE35_EDFAC27D1227__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include "XPCIDispatchTest.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestMethods
|
||||
|
||||
class nsXPCDispTestMethods :
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestMethods,&CLSID_nsXPCDispTestMethods>,
|
||||
public IDispatchImpl<nsIXPCDispTestMethods, &IID_nsIXPCDispTestMethods, &LIBID_IDispatchTestLib>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestMethods() {}
|
||||
BEGIN_CATEGORY_MAP(nsXPCDispTestMethods)
|
||||
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
||||
END_CATEGORY_MAP()
|
||||
BEGIN_COM_MAP(nsXPCDispTestMethods)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestMethods)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispTestMethods)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestMethods)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestMethods
|
||||
public:
|
||||
// nsIXPCDispTestMethod
|
||||
STDMETHOD(NoParameters)();
|
||||
STDMETHOD(ReturnBSTR)(BSTR * result);
|
||||
STDMETHOD(ReturnI4)(INT * result);
|
||||
STDMETHOD(ReturnUI1)(BYTE * result);
|
||||
STDMETHOD(ReturnI2)(SHORT * result);
|
||||
STDMETHOD(ReturnR4)(FLOAT * result);
|
||||
STDMETHOD(ReturnR8)(DOUBLE * result);
|
||||
STDMETHOD(ReturnBool)(VARIANT_BOOL * result);
|
||||
STDMETHOD(ReturnIDispatch)(IDispatch * * result);
|
||||
STDMETHOD(ReturnError)(SCODE * result);
|
||||
STDMETHOD(ReturnDate)(DATE * result);
|
||||
STDMETHOD(ReturnIUnknown)(IUnknown * * result);
|
||||
STDMETHOD(ReturnI1)(unsigned char * result);
|
||||
STDMETHOD(ReturnUI2)(USHORT * result);
|
||||
STDMETHOD(ReturnUI4)(ULONG * result);
|
||||
STDMETHOD(ReturnInt)(INT * result);
|
||||
STDMETHOD(ReturnUInt)(UINT * result);
|
||||
STDMETHOD(TakesBSTR)(BSTR result);
|
||||
STDMETHOD(TakesI4)(INT result);
|
||||
STDMETHOD(TakesUI1)(BYTE result);
|
||||
STDMETHOD(TakesI2)(SHORT result);
|
||||
STDMETHOD(TakesR4)(FLOAT result);
|
||||
STDMETHOD(TakesR8)(DOUBLE result);
|
||||
STDMETHOD(TakesBool)(VARIANT_BOOL result);
|
||||
STDMETHOD(TakesIDispatch)(IDispatch * result);
|
||||
STDMETHOD(TakesError)(SCODE result);
|
||||
STDMETHOD(TakesDate)(DATE result);
|
||||
STDMETHOD(TakesIUnknown)(IUnknown * result);
|
||||
STDMETHOD(TakesI1)(unsigned char result);
|
||||
STDMETHOD(TakesUI2)(USHORT result);
|
||||
STDMETHOD(TakesUI4)(ULONG result);
|
||||
STDMETHOD(TakesInt)(INT result);
|
||||
STDMETHOD(TakesUInt)(UINT result);
|
||||
STDMETHOD(OutputsBSTR)(BSTR * result);
|
||||
STDMETHOD(OutputsI4)(LONG * result);
|
||||
STDMETHOD(OutputsUI1)(BYTE * result);
|
||||
STDMETHOD(OutputsI2)(SHORT * result);
|
||||
STDMETHOD(OutputsR4)(FLOAT * result);
|
||||
STDMETHOD(OutputsR8)(DOUBLE * result);
|
||||
STDMETHOD(OutputsBool)(VARIANT_BOOL * result);
|
||||
STDMETHOD(OutputsIDispatch)(IDispatch * * result);
|
||||
STDMETHOD(OutputsError)(SCODE * result);
|
||||
STDMETHOD(OutputsDate)(DATE * result);
|
||||
STDMETHOD(OutputsIUnknown)(IUnknown * * result);
|
||||
STDMETHOD(OutputsI1)(unsigned char * result);
|
||||
STDMETHOD(OutputsUI2)(USHORT * result);
|
||||
STDMETHOD(OutputsUI4)(ULONG * result);
|
||||
STDMETHOD(InOutsBSTR)(BSTR * result);
|
||||
STDMETHOD(InOutsI4)(LONG * result);
|
||||
STDMETHOD(InOutsUI1)(BYTE * result);
|
||||
STDMETHOD(InOutsI2)(SHORT * result);
|
||||
STDMETHOD(InOutsR4)(FLOAT * result);
|
||||
STDMETHOD(InOutsR8)(DOUBLE * result);
|
||||
STDMETHOD(InOutsBool)(VARIANT_BOOL * result);
|
||||
STDMETHOD(InOutsIDispatch)(IDispatch * * result);
|
||||
STDMETHOD(InOutsError)(SCODE * result);
|
||||
STDMETHOD(InOutsDate)(DATE * result);
|
||||
STDMETHOD(InOutsIUnknown)(IUnknown * * result);
|
||||
STDMETHOD(InOutsI1)(unsigned char * result);
|
||||
STDMETHOD(InOutsUI2)(USHORT * result);
|
||||
STDMETHOD(InOutsUI4)(ULONG * result);
|
||||
STDMETHOD(OneParameterWithReturn)(LONG input, LONG * result);
|
||||
STDMETHOD(StringInputAndReturn)(BSTR str, BSTR * result);
|
||||
STDMETHOD(IDispatchInputAndReturn)(IDispatch * input, IDispatch** result);
|
||||
STDMETHOD(TwoParameters)(LONG one, LONG two);
|
||||
STDMETHOD(TwelveInParameters)(LONG one, LONG two, LONG three, LONG four,
|
||||
LONG five, LONG six, LONG seven, LONG eight,
|
||||
LONG nine, LONG ten, LONG eleven,
|
||||
LONG twelve);
|
||||
STDMETHOD(TwelveOutParameters)(LONG * one, LONG * two, LONG * three,
|
||||
LONG * four, LONG * five, LONG * six,
|
||||
LONG * seven, LONG * eight, LONG * nine,
|
||||
LONG * ten, LONG * eleven, LONG * twelve);
|
||||
STDMETHOD(TwelveStrings)(BSTR one, BSTR two, BSTR three, BSTR four,
|
||||
BSTR five, BSTR six, BSTR seven, BSTR eight,
|
||||
BSTR nine, BSTR ten, BSTR eleven, BSTR twelve);
|
||||
STDMETHOD(TwelveOutStrings)(BSTR * one, BSTR * two, BSTR * three,
|
||||
BSTR * four, BSTR * five, BSTR * six,
|
||||
BSTR * seven, BSTR * eight, BSTR * nine,
|
||||
BSTR * ten, BSTR * eleven, BSTR * twelve);
|
||||
STDMETHOD(TwelveIDispatch)(IDispatch * one, IDispatch * two,
|
||||
IDispatch * three, IDispatch * four,
|
||||
IDispatch * five, IDispatch * six,
|
||||
IDispatch * seven, IDispatch * eight,
|
||||
IDispatch * nine, IDispatch * ten,
|
||||
IDispatch * eleven, IDispatch * twelve);
|
||||
STDMETHOD(TwelveOutIDispatch)(IDispatch * * one, IDispatch * * two,
|
||||
IDispatch * * three, IDispatch * * four,
|
||||
IDispatch * * five, IDispatch * * six,
|
||||
IDispatch * * seven, IDispatch * * eight,
|
||||
IDispatch * * nine, IDispatch * * ten,
|
||||
IDispatch * * eleven, IDispatch * * twelve);
|
||||
STDMETHOD(CreateError)();
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTMETHODS_H__A516B1D7_1971_419C_AE35_EDFAC27D1227__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestMethods.1 = s 'nsXPCDispTestMethods Class'
|
||||
{
|
||||
CLSID = s '{745D1149-9F46-418C-B176-71EAA98974BA}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestMethods = s 'nsXPCDispTestMethods Class'
|
||||
{
|
||||
CLSID = s '{745D1149-9F46-418C-B176-71EAA98974BA}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {745D1149-9F46-418C-B176-71EAA98974BA} = s 'nsXPCDispTestMethods Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestMethods.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestMethods'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// nsXPCDispTestNoIDispatch.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestNoIDispatch.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestNoIDispatch::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestNoIDispatch,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
// nsXPCDispTestNoIDispatch.h: Definition of the nsXPCDispTestNoIDispatch class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTNOIDISPATCH_H__E4B74F67_BA6B_4654_8674_E60E487129F7__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTNOIDISPATCH_H__E4B74F67_BA6B_4654_8674_E60E487129F7__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestNoIDispatch
|
||||
|
||||
class nsXPCDispTestNoIDispatch :
|
||||
public nsIXPCDispTestNoIDispatch,
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestNoIDispatch,&CLSID_nsXPCDispTestNoIDispatch>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestNoIDispatch() {}
|
||||
BEGIN_COM_MAP(nsXPCDispTestNoIDispatch)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestNoIDispatch)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
END_COM_MAP()
|
||||
//DECLARE_NOT_AGGREGATABLE(nsXPCDispTestNoIDispatch)
|
||||
// Remove the comment from the line above if you don't want your object to
|
||||
// support aggregation.
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestNoIDispatch)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestNoIDispatch
|
||||
public:
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTNOIDISPATCH_H__E4B74F67_BA6B_4654_8674_E60E487129F7__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestNoIDispatch.1 = s 'nsXPCDispTestNoIDispatch Class'
|
||||
{
|
||||
CLSID = s '{7414404F-A4CC-4E3C-9B32-BB20CB22F541}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestNoIDispatch = s 'nsXPCDispTestNoIDispatch Class'
|
||||
{
|
||||
CLSID = s '{7414404F-A4CC-4E3C-9B32-BB20CB22F541}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {7414404F-A4CC-4E3C-9B32-BB20CB22F541} = s 'nsXPCDispTestNoIDispatch Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestNoIDispatch.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestNoIDispatch'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,256 +0,0 @@
|
||||
// nsXPCDispTestProperties.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestProperties.h"
|
||||
|
||||
const long PARAMETERIZED_PROPERTY_COUNT = 5;
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestProperties,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
nsXPCDispTestProperties::nsXPCDispTestProperties() :
|
||||
mChar('a'),
|
||||
mBOOL(FALSE),
|
||||
mSCode(0),
|
||||
mDATE(0),
|
||||
mDouble(0.0),
|
||||
mFloat(0.0f),
|
||||
mLong(0),
|
||||
mShort(0),
|
||||
mParameterizedProperty(new long[PARAMETERIZED_PROPERTY_COUNT])
|
||||
{
|
||||
mCURRENCY.int64 = 0;
|
||||
CComBSTR string("Initial value");
|
||||
mBSTR = string.Detach();
|
||||
for (long index = 0; index < PARAMETERIZED_PROPERTY_COUNT; ++index)
|
||||
mParameterizedProperty[index] = index + 1;
|
||||
}
|
||||
|
||||
nsXPCDispTestProperties::~nsXPCDispTestProperties()
|
||||
{
|
||||
delete [] mParameterizedProperty;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Short(short *pVal)
|
||||
{
|
||||
*pVal = mShort;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Short(short newVal)
|
||||
{
|
||||
mShort = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Long(long *pVal)
|
||||
{
|
||||
*pVal = mLong;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Long(long newVal)
|
||||
{
|
||||
mLong = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Float(float *pVal)
|
||||
{
|
||||
*pVal = mFloat;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Float(float newVal)
|
||||
{
|
||||
mFloat = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Double(double *pVal)
|
||||
{
|
||||
*pVal = mDouble;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Double(double newVal)
|
||||
{
|
||||
mDouble = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Currency(CURRENCY *pVal)
|
||||
{
|
||||
*pVal = mCURRENCY;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Currency(CURRENCY newVal)
|
||||
{
|
||||
mCURRENCY = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Date(DATE *pVal)
|
||||
{
|
||||
*pVal = mDATE;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Date(DATE newVal)
|
||||
{
|
||||
mDATE = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_String(BSTR *pVal)
|
||||
{
|
||||
*pVal = mBSTR.Copy();
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_String(BSTR newVal)
|
||||
{
|
||||
mBSTR = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_DispatchPtr(IDispatch **pVal)
|
||||
{
|
||||
mIDispatch.CopyTo(pVal);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_DispatchPtr(IDispatch *newVal)
|
||||
{
|
||||
mIDispatch = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_SCode(SCODE *pVal)
|
||||
{
|
||||
*pVal = mSCode;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_SCode(SCODE newVal)
|
||||
{
|
||||
mSCode = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Boolean(BOOL *pVal)
|
||||
{
|
||||
*pVal = mBOOL;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Boolean(BOOL newVal)
|
||||
{
|
||||
mBOOL = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Variant(VARIANT *pVal)
|
||||
{
|
||||
::VariantCopy(pVal, &mVariant);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Variant(VARIANT newVal)
|
||||
{
|
||||
mVariant = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_COMPtr(IUnknown **pVal)
|
||||
{
|
||||
mIUnknown.CopyTo(pVal);
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_COMPtr(IUnknown *newVal)
|
||||
{
|
||||
mIUnknown = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_Char(unsigned char *pVal)
|
||||
{
|
||||
*pVal = mChar;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_Char(unsigned char newVal)
|
||||
{
|
||||
mChar = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_ParameterizedProperty(long aIndex, long *pVal)
|
||||
{
|
||||
if (aIndex < 0 || aIndex >= PARAMETERIZED_PROPERTY_COUNT)
|
||||
return E_FAIL;
|
||||
|
||||
*pVal = mParameterizedProperty[aIndex];
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::put_ParameterizedProperty(long aIndex, long newVal)
|
||||
{
|
||||
if (aIndex < 0 || aIndex >= PARAMETERIZED_PROPERTY_COUNT)
|
||||
return E_FAIL;
|
||||
|
||||
mParameterizedProperty[aIndex] = newVal;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestProperties::get_ParameterizedPropertyCount(long *pVal)
|
||||
{
|
||||
*pVal = PARAMETERIZED_PROPERTY_COUNT;
|
||||
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,88 +0,0 @@
|
||||
// nsXPCDispTestProperties.h: Definition of the nsXPCDispTestProperties class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTPROPERTIES_H__9E10C7AC_36AF_4A3A_91C7_2CFB9EB166A5__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTPROPERTIES_H__9E10C7AC_36AF_4A3A_91C7_2CFB9EB166A5__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestProperties
|
||||
|
||||
class nsXPCDispTestProperties :
|
||||
public IDispatchImpl<nsIXPCDispTestProperties, &IID_nsIXPCDispTestProperties, &LIBID_IDispatchTestLib>,
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestProperties,&CLSID_nsXPCDispTestProperties>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestProperties();
|
||||
virtual ~nsXPCDispTestProperties();
|
||||
BEGIN_CATEGORY_MAP(nsXPCDispTestProperties)
|
||||
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
||||
END_CATEGORY_MAP()
|
||||
BEGIN_COM_MAP(nsXPCDispTestProperties)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestProperties)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispTestProperties)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestProperties)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestProperties
|
||||
public:
|
||||
STDMETHOD(get_ParameterizedPropertyCount)(/*[out, retval]*/ long *pVal);
|
||||
STDMETHOD(get_ParameterizedProperty)(/*[in]*/long aIndex, /*[out, retval]*/ long *pVal);
|
||||
STDMETHOD(put_ParameterizedProperty)(/*[in]*/long aIndex, /*[in]*/ long newVal);
|
||||
STDMETHOD(get_Char)(/*[out, retval]*/ unsigned char *pVal);
|
||||
STDMETHOD(put_Char)(/*[in]*/ unsigned char newVal);
|
||||
STDMETHOD(get_COMPtr)(/*[out, retval]*/ IUnknown* *pVal);
|
||||
STDMETHOD(put_COMPtr)(/*[in]*/ IUnknown* newVal);
|
||||
STDMETHOD(get_Variant)(/*[out, retval]*/ VARIANT *pVal);
|
||||
STDMETHOD(put_Variant)(/*[in]*/ VARIANT newVal);
|
||||
STDMETHOD(get_Boolean)(/*[out, retval]*/ BOOL *pVal);
|
||||
STDMETHOD(put_Boolean)(/*[in]*/ BOOL newVal);
|
||||
STDMETHOD(get_SCode)(/*[out, retval]*/ SCODE *pVal);
|
||||
STDMETHOD(put_SCode)(/*[in]*/ SCODE newVal);
|
||||
STDMETHOD(get_DispatchPtr)(/*[out, retval]*/ IDispatch* *pVal);
|
||||
STDMETHOD(put_DispatchPtr)(/*[in]*/ IDispatch* newVal);
|
||||
STDMETHOD(get_String)(/*[out, retval]*/ BSTR *pVal);
|
||||
STDMETHOD(put_String)(/*[in]*/ BSTR newVal);
|
||||
STDMETHOD(get_Date)(/*[out, retval]*/ DATE *pVal);
|
||||
STDMETHOD(put_Date)(/*[in]*/ DATE newVal);
|
||||
STDMETHOD(get_Currency)(/*[out, retval]*/ CURRENCY *pVal);
|
||||
STDMETHOD(put_Currency)(/*[in]*/ CURRENCY newVal);
|
||||
STDMETHOD(get_Double)(/*[out, retval]*/ double *pVal);
|
||||
STDMETHOD(put_Double)(/*[in]*/ double newVal);
|
||||
STDMETHOD(get_Float)(/*[out, retval]*/ float *pVal);
|
||||
STDMETHOD(put_Float)(/*[in]*/ float newVal);
|
||||
STDMETHOD(get_Long)(/*[out, retval]*/ long *pVal);
|
||||
STDMETHOD(put_Long)(/*[in]*/ long newVal);
|
||||
STDMETHOD(get_Short)(/*[out, retval]*/ short *pVal);
|
||||
STDMETHOD(put_Short)(/*[in]*/ short newVal);
|
||||
private:
|
||||
unsigned char mChar;
|
||||
CComPtr<IUnknown> mIUnknown;
|
||||
CComVariant mVariant;
|
||||
BOOL mBOOL;
|
||||
SCODE mSCode;
|
||||
CComPtr<IDispatch> mIDispatch;
|
||||
CComBSTR mBSTR;
|
||||
DATE mDATE;
|
||||
CURRENCY mCURRENCY;
|
||||
double mDouble;
|
||||
float mFloat;
|
||||
long mLong;
|
||||
short mShort;
|
||||
long * mParameterizedProperty;
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTPROPERTIES_H__9E10C7AC_36AF_4A3A_91C7_2CFB9EB166A5__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestProperties.1 = s 'nsXPCDispTestProperties Class'
|
||||
{
|
||||
CLSID = s '{D8B4265B-1768-4CA9-A285-7CCAEEB51C74}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestProperties = s 'nsXPCDispTestProperties Class'
|
||||
{
|
||||
CLSID = s '{D8B4265B-1768-4CA9-A285-7CCAEEB51C74}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {D8B4265B-1768-4CA9-A285-7CCAEEB51C74} = s 'nsXPCDispTestProperties Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestProperties.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestProperties'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
// nsXPCDispTestScriptOff.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestScriptOff.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestScriptOff::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestScriptOff,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
// nsXPCDispTestScriptOff.h: Definition of the nsXPCDispTestScriptOff class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTSCRIPTOFF_H__EEC88DE0_F502_4893_9918_4E435DBC9815__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTSCRIPTOFF_H__EEC88DE0_F502_4893_9918_4E435DBC9815__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include <ATLCTL.H>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestScriptOff
|
||||
|
||||
class nsXPCDispTestScriptOff :
|
||||
public IDispatchImpl<nsIXPCDispTestScriptOff, &IID_nsIXPCDispTestScriptOff, &LIBID_IDispatchTestLib>,
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestScriptOff,&CLSID_nsXPCDispTestScriptOff>,
|
||||
public IObjectSafetyImpl<nsXPCDispTestScriptOff, 0>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestScriptOff() {}
|
||||
BEGIN_COM_MAP(nsXPCDispTestScriptOff)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestScriptOff)
|
||||
COM_INTERFACE_ENTRY(IObjectSafety)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispTestScriptOff)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestScriptOff)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestScriptOff
|
||||
public:
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTSCRIPTOFF_H__EEC88DE0_F502_4893_9918_4E435DBC9815__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestScriptOff.1 = s 'nsXPCDispTestScriptOff Class'
|
||||
{
|
||||
CLSID = s '{959CD122-9826-4757-BA09-DE327D55F9E7}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestScriptOff = s 'nsXPCDispTestScriptOff Class'
|
||||
{
|
||||
CLSID = s '{959CD122-9826-4757-BA09-DE327D55F9E7}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {959CD122-9826-4757-BA09-DE327D55F9E7} = s 'nsXPCDispTestScriptOff Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestScriptOff.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestScriptOff'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
// nsXPCDispTestScriptOn.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestScriptOn.h"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestScriptOn::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestScriptOn,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
nsXPCDispTestScriptOn::nsXPCDispTestScriptOn()
|
||||
{
|
||||
m_dwCurrentSafety = INTERFACESAFE_FOR_UNTRUSTED_CALLER |
|
||||
INTERFACESAFE_FOR_UNTRUSTED_DATA;
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
// nsXPCDispTestScriptOn.h: Definition of the nsXPCDispTestScriptOn class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTSCRIPTON_H__C037D462_C403_48FF_A02F_6C36544F0833__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTSCRIPTON_H__C037D462_C403_48FF_A02F_6C36544F0833__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
#include <ATLCTL.H>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestScriptOn
|
||||
|
||||
class nsXPCDispTestScriptOn :
|
||||
public IDispatchImpl<nsIXPCDispTestScriptOn, &IID_nsIXPCDispTestScriptOn, &LIBID_IDispatchTestLib>,
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestScriptOn,&CLSID_nsXPCDispTestScriptOn>,
|
||||
public IObjectSafetyImpl<nsXPCDispTestScriptOn,
|
||||
INTERFACESAFE_FOR_UNTRUSTED_CALLER |
|
||||
INTERFACESAFE_FOR_UNTRUSTED_DATA>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestScriptOn();
|
||||
BEGIN_COM_MAP(nsXPCDispTestScriptOn)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestScriptOn)
|
||||
COM_INTERFACE_ENTRY(IObjectSafety)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispTestScriptOn)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestScriptOn)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestScriptOn
|
||||
public:
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTSCRIPTON_H__C037D462_C403_48FF_A02F_6C36544F0833__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestScriptOn.1 = s 'nsXPCDispTestScriptOn Class'
|
||||
{
|
||||
CLSID = s '{2A06373F-3E61-4882-A3D7-A104F70B09ED}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestScriptOn = s 'nsXPCDispTestScriptOn Class'
|
||||
{
|
||||
CLSID = s '{2A06373F-3E61-4882-A3D7-A104F70B09ED}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {2A06373F-3E61-4882-A3D7-A104F70B09ED} = s 'nsXPCDispTestScriptOn Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestScriptOn.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestScriptOn'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
// nsXPCDispTestWrappedJS.cpp : Implementation of CXPCIDispatchTestApp and DLL registration.
|
||||
|
||||
#include "stdafx.h"
|
||||
#include "XPCIDispatchTest.h"
|
||||
#include "nsXPCDispTestWrappedJS.h"
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
|
||||
STDMETHODIMP nsXPCDispTestWrappedJS::InterfaceSupportsErrorInfo(REFIID riid)
|
||||
{
|
||||
static const IID* arr[] =
|
||||
{
|
||||
&IID_nsIXPCDispTestWrappedJS,
|
||||
};
|
||||
|
||||
for (int i=0;i<sizeof(arr)/sizeof(arr[0]);i++)
|
||||
{
|
||||
if (InlineIsEqualGUID(*arr[i],riid))
|
||||
return S_OK;
|
||||
}
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
struct TestData
|
||||
{
|
||||
typedef bool (*CompFunc)(const _variant_t & left, const _variant_t & right);
|
||||
TestData(const char * name, const _variant_t & value, CompFunc cf) :
|
||||
mName(name), mValue(value), mCompFunc(cf) {}
|
||||
const char * mName;
|
||||
_variant_t mValue;
|
||||
CompFunc mCompFunc;
|
||||
|
||||
};
|
||||
|
||||
bool CompareVariant(const _variant_t & left, const _variant_t & right)
|
||||
{
|
||||
return left == right;
|
||||
}
|
||||
|
||||
// These should be a template but VC++6 is brain dead in this area
|
||||
#define CompareFunction(type) \
|
||||
bool CompareVariant##type(const _variant_t & left, const _variant_t & right) \
|
||||
{ \
|
||||
return static_cast<type>(left) == static_cast<type>(right); \
|
||||
}
|
||||
|
||||
CompareFunction(long);
|
||||
CompareFunction(float);
|
||||
CompareFunction(double);
|
||||
CompareFunction(_bstr_t);
|
||||
|
||||
DISPID GetIDsOfNames(IDispatch * pIDispatch , char const * i_Method)
|
||||
{
|
||||
DISPID dispid;
|
||||
CComBSTR method(i_Method);
|
||||
OLECHAR * pMethod = method;
|
||||
HRESULT hresult = pIDispatch->GetIDsOfNames(
|
||||
IID_NULL,
|
||||
&pMethod,
|
||||
1,
|
||||
LOCALE_SYSTEM_DEFAULT,
|
||||
&dispid);
|
||||
if (!SUCCEEDED(hresult))
|
||||
{
|
||||
dispid = 0;
|
||||
}
|
||||
return dispid;
|
||||
}
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
inline
|
||||
_bstr_t ConvertVariantFromBSTR(_variant_t & variant)
|
||||
{
|
||||
VARIANT temp = variant;
|
||||
if (SUCCEEDED(VariantChangeType(&temp, &temp, 0, VT_BSTR)))
|
||||
{
|
||||
variant.Attach(temp);
|
||||
return static_cast<_bstr_t>(variant);
|
||||
}
|
||||
return "**Type Conversion failed";
|
||||
}
|
||||
|
||||
std::string DispInvoke(IDispatch * obj, const TestData & testData)
|
||||
{
|
||||
// Perform a put on the property
|
||||
ITypeInfo * pTypeInfo;
|
||||
obj->GetTypeInfo(0, LOCALE_SYSTEM_DEFAULT, &pTypeInfo);
|
||||
DISPID dispID = ::GetIDsOfNames(obj, testData.mName);
|
||||
DISPPARAMS dispParams;
|
||||
dispParams.cArgs = 1;
|
||||
dispParams.rgvarg = const_cast<VARIANT*>(&reinterpret_cast<const VARIANT&>(testData.mValue));
|
||||
dispParams.cNamedArgs = 1;
|
||||
DISPID propPut = DISPID_PROPERTYPUT;
|
||||
dispParams.rgdispidNamedArgs = &propPut;
|
||||
_variant_t result1;
|
||||
HRESULT hResult = obj->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYPUT, &dispParams, &result1, 0, 0);
|
||||
if (FAILED(hResult))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "IDispatch::Invoke on " << testData.mName << " failed to set property with result " << hResult;
|
||||
return msg.str();
|
||||
}
|
||||
dispParams.cArgs = 1;
|
||||
dispParams.rgvarg = const_cast<VARIANT*>(&reinterpret_cast<const VARIANT&>(testData.mValue));
|
||||
dispParams.cNamedArgs = 0;
|
||||
dispParams.rgdispidNamedArgs = 0;
|
||||
_variant_t result2;
|
||||
hResult = obj->Invoke(dispID, IID_NULL, LOCALE_SYSTEM_DEFAULT, DISPATCH_PROPERTYGET, &dispParams, &result2, 0, 0);
|
||||
if (FAILED(hResult))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg << "IDispatch::Invoke on " << testData.mName << " failed to retrieve property with result " << hResult;
|
||||
return msg.str();
|
||||
}
|
||||
if (!testData.mCompFunc(result2,testData.mValue))
|
||||
{
|
||||
std::ostringstream msg;
|
||||
VARIANT temp = testData.mValue;
|
||||
char const * const desired = SUCCEEDED(VariantChangeType(&temp, &temp, 0, VT_BSTR)) ? 0 : "**Conversion Failed";
|
||||
char const * const actual = SUCCEEDED(VariantChangeType(&result2, &result2, 0, VT_BSTR)) ? 0 : "**Conversion Failed";
|
||||
|
||||
msg << testData.mName << " ["
|
||||
<< (desired ? desired : static_cast<char const *>(static_cast<_bstr_t>(testData.mValue))) << "] ["
|
||||
<< (actual ? actual : static_cast<char const *>(static_cast<_bstr_t>(result2))) << "]";
|
||||
return msg.str();
|
||||
}
|
||||
return std::string();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
STDMETHODIMP nsXPCDispTestWrappedJS::TestParamTypes(IDispatch *obj, BSTR *errMsg)
|
||||
{
|
||||
CComPtr<IDispatch> ptr;
|
||||
CComBSTR progID("XPCIDispatchTest.nsXPCDispSimple.1");
|
||||
ptr.CoCreateInstance(progID);
|
||||
_variant_t dispatchPtr;
|
||||
dispatchPtr = static_cast<IDispatch*>(ptr);
|
||||
CURRENCY currency;
|
||||
currency.int64 = 55555;
|
||||
_variant_t date(3000.0, VT_DATE);
|
||||
_variant_t nullVariant;
|
||||
nullVariant.ChangeType(VT_NULL);
|
||||
const TestData tests[] =
|
||||
{
|
||||
TestData("Boolean", _variant_t(true), CompareVariant),
|
||||
TestData("Short", _variant_t(short(4200)), reinterpret_cast<TestData::CompFunc>(CompareVariantlong)),
|
||||
TestData("Long", _variant_t(long(-42000000)), CompareVariantlong),
|
||||
TestData("Float", _variant_t(float(4.5)), CompareVariantfloat),
|
||||
TestData("Double", _variant_t(-11111.11), CompareVariant),
|
||||
// TestData("Currency", _variant_t(currency), CompareVariantdouble),
|
||||
TestData("Date", date, CompareVariant_bstr_t),
|
||||
TestData("String", _variant_t("A String"), CompareVariant),
|
||||
TestData("DispatchPtr", dispatchPtr, CompareVariant),
|
||||
// TestData("SCode", _variant_t(long(5), VT_ERROR), CompareVariant_bstr_t),
|
||||
TestData("Variant", nullVariant, CompareVariant),
|
||||
TestData("Char", _variant_t(BYTE('x')), CompareVariant_bstr_t)
|
||||
};
|
||||
std::string errors;
|
||||
for (size_t index = 0; index < sizeof(tests) / sizeof(TestData); ++index)
|
||||
{
|
||||
std::string msg = DispInvoke(obj, tests[index]);
|
||||
if (!msg.empty())
|
||||
{
|
||||
errors += msg;
|
||||
errors += "\r\n";
|
||||
}
|
||||
}
|
||||
CComBSTR errorMsg(errors.c_str());
|
||||
*errMsg = errorMsg.Detach();
|
||||
return S_OK;
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
// nsXPCDispTestWrappedJS.h: Definition of the nsXPCDispTestWrappedJS class
|
||||
//
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(AFX_NSXPCDISPTESTWRAPPEDJS_H__DAAB3C99_1894_40C2_B12B_A360739F8977__INCLUDED_)
|
||||
#define AFX_NSXPCDISPTESTWRAPPEDJS_H__DAAB3C99_1894_40C2_B12B_A360739F8977__INCLUDED_
|
||||
|
||||
#if _MSC_VER > 1000
|
||||
#pragma once
|
||||
#endif // _MSC_VER > 1000
|
||||
|
||||
#include "resource.h" // main symbols
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// nsXPCDispTestWrappedJS
|
||||
|
||||
class nsXPCDispTestWrappedJS :
|
||||
public IDispatchImpl<nsIXPCDispTestWrappedJS, &IID_nsIXPCDispTestWrappedJS, &LIBID_IDispatchTestLib>,
|
||||
public ISupportErrorInfo,
|
||||
public CComObjectRoot,
|
||||
public CComCoClass<nsXPCDispTestWrappedJS,&CLSID_nsXPCDispTestWrappedJS>
|
||||
{
|
||||
public:
|
||||
nsXPCDispTestWrappedJS() {}
|
||||
BEGIN_CATEGORY_MAP(nsXPCDispTestWrappedJS)
|
||||
IMPLEMENTED_CATEGORY(CATID_SafeForScripting)
|
||||
END_CATEGORY_MAP()
|
||||
BEGIN_COM_MAP(nsXPCDispTestWrappedJS)
|
||||
COM_INTERFACE_ENTRY(IDispatch)
|
||||
COM_INTERFACE_ENTRY(nsIXPCDispTestWrappedJS)
|
||||
COM_INTERFACE_ENTRY(ISupportErrorInfo)
|
||||
END_COM_MAP()
|
||||
DECLARE_NOT_AGGREGATABLE(nsXPCDispTestWrappedJS)
|
||||
|
||||
DECLARE_REGISTRY_RESOURCEID(IDR_nsXPCDispTestWrappedJS)
|
||||
// ISupportsErrorInfo
|
||||
STDMETHOD(InterfaceSupportsErrorInfo)(REFIID riid);
|
||||
|
||||
// nsIXPCDispTestWrappedJS
|
||||
public:
|
||||
/**
|
||||
* This tests interacting with JS Objects via IDispatch
|
||||
* @param obj the object being tested
|
||||
* @param errMsg string receiving any error message, blank if no error
|
||||
*/
|
||||
STDMETHOD(TestParamTypes)(/*[in]*/ IDispatch * obj,
|
||||
/*[out]*/BSTR * errMsg);
|
||||
};
|
||||
|
||||
#endif // !defined(AFX_NSXPCDISPTESTWRAPPEDJS_H__DAAB3C99_1894_40C2_B12B_A360739F8977__INCLUDED_)
|
||||
@@ -1,23 +0,0 @@
|
||||
HKCR
|
||||
{
|
||||
XPCIDispatchTest.nsXPCDispTestWrappedJS.1 = s 'nsXPCDispTestWrappedJS Class'
|
||||
{
|
||||
CLSID = s '{EAEE6BB2-C005-4B91-BCA7-6613236F6F69}'
|
||||
}
|
||||
XPCIDispatchTest.nsXPCDispTestWrappedJS = s 'nsXPCDispTestWrappedJS Class'
|
||||
{
|
||||
CLSID = s '{EAEE6BB2-C005-4B91-BCA7-6613236F6F69}'
|
||||
}
|
||||
NoRemove CLSID
|
||||
{
|
||||
ForceRemove {EAEE6BB2-C005-4B91-BCA7-6613236F6F69} = s 'nsXPCDispTestWrappedJS Class'
|
||||
{
|
||||
ProgID = s 'XPCIDispatchTest.nsXPCDispTestWrappedJS.1'
|
||||
VersionIndependentProgID = s 'XPCIDispatchTest.nsXPCDispTestWrappedJS'
|
||||
InprocServer32 = s '%MODULE%'
|
||||
{
|
||||
val ThreadingModel = s 'both'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
//{{NO_DEPENDENCIES}}
|
||||
// Microsoft Developer Studio generated include file.
|
||||
// Used by XPCIDispatchTest.rc
|
||||
//
|
||||
#define IDS_PROJNAME 100
|
||||
#define IDS_NSXPCDISPTTESTMETHODS_DESC 101
|
||||
#define IDR_nsXPCDisptTestMethods 102
|
||||
#define IDS_NSXPCDISPTESTMETHODS_DESC 103
|
||||
#define IDR_nsXPCDispTestMethods 104
|
||||
#define IDS_NSXPCDISPSIMPLE_DESC 105
|
||||
#define IDR_nsXPCDispSimple 106
|
||||
#define IDS_NSXPCDISPTESTNOIDISPATCH_DESC 107
|
||||
#define IDR_nsXPCDispTestNoIDispatch 108
|
||||
#define IDS_NSXPCDISPTESTNOSCRIPT_DESC 109
|
||||
#define IDR_nsXPCDispTestNoScript 110
|
||||
#define IDS_NSXPCDISPTESTPROPERTIES_DESC 111
|
||||
#define IDR_nsXPCDispTestProperties 112
|
||||
#define IDS_NSXPCDISPTESTARRAYS_DESC 113
|
||||
#define IDR_nsXPCDispTestArrays 114
|
||||
#define IDS_NSXPCDISPTESTSCRIPTON_DESC 115
|
||||
#define IDR_nsXPCDispTestScriptOn 116
|
||||
#define IDS_NSXPCDISPTESTSCRIPTOFF_DESC 117
|
||||
#define IDR_nsXPCDispTestScriptOff 118
|
||||
#define IDS_NSXPCDISPTESTWRAPPEDJS_DESC 119
|
||||
#define IDR_nsXPCDispTestWrappedJS 120
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 204
|
||||
#define _APS_NEXT_COMMAND_VALUE 32768
|
||||
#define _APS_NEXT_CONTROL_VALUE 201
|
||||
#define _APS_NEXT_SYMED_VALUE 121
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,54 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Verify that we can access but not overwrite the values of read-only
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
test();
|
||||
|
||||
function test()
|
||||
{
|
||||
printStatus("Testing arrays");
|
||||
var obj = COMObject(CLSID_nsXPCDispTestArrays);
|
||||
var anArray = [ 0, 1, 2, 3];
|
||||
obj.TakesSafeArray(anArray);
|
||||
var strArray = [ "0", "1", "2", "3"];
|
||||
obj.TakesSafeArrayBSTR(strArray);
|
||||
return 0;
|
||||
}
|
||||
@@ -1,150 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* \file XPCIDispatchAttributeTests.js
|
||||
* Test IDispatch properties and also type conversion
|
||||
*/
|
||||
|
||||
try
|
||||
{
|
||||
// Test object used to test IDispatch property.
|
||||
testObject = { one : 1, two : 2, three : 'three' };
|
||||
test();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Unhandled exception encountered: " + e.toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* Main function to perform test
|
||||
*/
|
||||
function test()
|
||||
{
|
||||
printStatus("Read-Write Attributes");
|
||||
|
||||
/*
|
||||
* These values come from xpctest_attributes.idl and xpctest_attributes.cpp
|
||||
*/
|
||||
|
||||
o = COMObject(CLSID_nsXPCDispTestProperties);
|
||||
|
||||
// Check the class an interface to make sure they're ok
|
||||
reportCompare(
|
||||
"object",
|
||||
typeof o,
|
||||
"typeof COMObject(CLSID_nsXPCDispTestProperties)");
|
||||
// Make sure we can read the values
|
||||
testProperty("o.Boolean", ["true", "1","testObject", "'T'", "'F'", "'true'","'false'"], false);
|
||||
testProperty("o.Char", ["32"], true);
|
||||
testProperty("o.COMPtr", ["0"], true);
|
||||
testProperty("o.Currency", ["0", "0.5", "10000.00"], true);
|
||||
testProperty("o.Date", ["'04/01/03'"], false);
|
||||
testProperty("o.DispatchPtr", ["testObject"], false);
|
||||
testProperty("o.Double", ["5.555555555555555555555", "5.555555555555555555555", "5", "-5"], true);
|
||||
testProperty("o.Float", ["-5.55555555", "5.5555555", "5", "-5"], true);
|
||||
testProperty("o.Long", ["-5", "1073741823", "-1073741824", "1073741824", "-1073741825", "5.5"], true);
|
||||
testProperty("o.SCode", ["5"], true);
|
||||
testProperty("o.Short", ["5", "-5", "32767", "-32768"], true);
|
||||
testProperty("o.String", ["'A String'", "'c'", "5", "true"], false);
|
||||
testProperty("o.Variant", ["'A Variant String'", "testObject", "10", "5.5"], false);
|
||||
|
||||
// Parameterized property tests
|
||||
for (index = 0; index < o.ParameterizedPropertyCount; ++index)
|
||||
compareExpression(
|
||||
"o.ParameterizedProperty(index)",
|
||||
index + 1,
|
||||
"Reading initial value from parameterized property " + index);
|
||||
for (index = 0; index < o.ParameterizedPropertyCount; ++index)
|
||||
compareExpression(
|
||||
"o.ParameterizedProperty(index) = index + 5",
|
||||
index + 5,
|
||||
"Assigning parameterized property " + index);
|
||||
|
||||
for (index = 0; index < o.ParameterizedPropertyCount; ++index)
|
||||
compareExpression(
|
||||
"o.ParameterizedProperty(index)",
|
||||
index + 5,
|
||||
"Reading new value from parameterized property " + index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests retrieving a value from a property and setting multiple values on
|
||||
* the property
|
||||
*/
|
||||
function testProperty(propertyExpression, values, tryString)
|
||||
{
|
||||
print(propertyExpression);
|
||||
try
|
||||
{
|
||||
reportCompare(
|
||||
eval(propertyExpression),
|
||||
eval(propertyExpression),
|
||||
propertyExpression);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing initial value of " + propertyExpression + " Exception: " + e.toString());
|
||||
}
|
||||
for (i = 0; i < values.length; ++i)
|
||||
{
|
||||
var value = values[i];
|
||||
var expression = propertyExpression + "=" + value;
|
||||
print(expression);
|
||||
try
|
||||
{
|
||||
reportCompare(
|
||||
eval(expression),
|
||||
eval(value),
|
||||
expression);
|
||||
if (tryString)
|
||||
{
|
||||
expression = propertyExpression + "='" + value + "'";
|
||||
print(expression);
|
||||
reportCompare(
|
||||
eval(expression),
|
||||
eval("'" + value + "'"),
|
||||
expression);
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing assignment: " + expression + " Exception: " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,122 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Verify that we can access but not overwrite the values of read-only
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
test();
|
||||
|
||||
function testInstantiate(name, id, scriptable, methods)
|
||||
{
|
||||
var IDISPATCH_TEXT = "[xpconnect wrapped IDispatch";
|
||||
var obj = COMObject(id);
|
||||
var value = obj.toString().substr(0, IDISPATCH_TEXT.length);
|
||||
reportCompare(
|
||||
IDISPATCH_TEXT,
|
||||
value,
|
||||
"var obj = COMObject(" + id + ");");
|
||||
try
|
||||
{
|
||||
obj = COMObject(id);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
if (scriptable)
|
||||
{
|
||||
reportFailure("COMObject('" + id + "') generated an exception");
|
||||
}
|
||||
return;
|
||||
}
|
||||
value = obj.toString().substr(0, IDISPATCH_TEXT.length);
|
||||
reportCompare(
|
||||
scriptable ? IDISPATCH_TEXT : undefined,
|
||||
scriptable ? value : obj,
|
||||
"var obj = COMObject(" + id + ");");
|
||||
}
|
||||
|
||||
function testEnumeration(compInfo)
|
||||
{
|
||||
var obj = COMObject(compInfo.cid);
|
||||
compareObject(obj, compInfo, "Enumeration Test");
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
printStatus("Instantiation Tests - " + objectsDesc.length + " objects to test");
|
||||
for (index = 0; index < objectsDesc.length; ++index)
|
||||
{
|
||||
compInfo = objectsDesc[index];
|
||||
printStatus("Testing " + compInfo.name);
|
||||
testInstantiate(compInfo.name, compInfo.cid, compInfo.scriptable);
|
||||
testInstantiate(compInfo.name, compInfo.progid, compInfo.scriptable);
|
||||
}
|
||||
// Test a non-existant COM object
|
||||
var obj;
|
||||
try
|
||||
{
|
||||
obj = COMObject("dwbnonexistantobject");
|
||||
printFailure("var obj = COMObject('dwbnonexistantobject'); did not throw an exception");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
}
|
||||
try
|
||||
{
|
||||
obj = COMObject("dwbnonexistantobject");
|
||||
printFailure("obj = COMObject('dwbnonexistantobject'); did not throw an exception");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
}
|
||||
printStatus("Enumeration Tests - testing " + objectsDesc.length + " objects");
|
||||
for (var index = 0; index < objectsDesc.length; ++index)
|
||||
{
|
||||
printStatus("Enumerating " + objectsDesc[index].name);
|
||||
testEnumeration(objectsDesc[index]);
|
||||
}
|
||||
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Unhandled exception occured:" + e.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Make repeated calls so GC kicks in and we can check for memory leaks.
|
||||
*/
|
||||
|
||||
test();
|
||||
|
||||
function test()
|
||||
{
|
||||
printStatus("Stress testing");
|
||||
for (index = 0; index < 10000; ++index)
|
||||
{
|
||||
for (x = 0; x < objectsDesc.length; ++x)
|
||||
{
|
||||
var obj = COMObject(objectsDesc[x].cid);
|
||||
for (prop in obj)
|
||||
{
|
||||
print(index + ":" +objectsDesc[x].name + ":" + prop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,376 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* Verify that we can access but not overwrite the values of read-only
|
||||
* attributes.
|
||||
*/
|
||||
|
||||
test();
|
||||
|
||||
function TestOutMethod(obj, method, value)
|
||||
{
|
||||
printDebug("TestOutMethod - " + method);
|
||||
var x = new Object();
|
||||
try
|
||||
{
|
||||
obj[method](x);
|
||||
reportCompare(value, x.value, "Testing output parameter: " + method);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing output parameter failed: " + method + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function TestReturnMethod(obj, method, value)
|
||||
{
|
||||
printDebug("TestReturnMethod - " + method);
|
||||
try
|
||||
{
|
||||
reportCompare(value, obj[method](), "Testing output parameter: " + method);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing return value failed: " + method + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function TestInputMethod(obj, method, value)
|
||||
{
|
||||
printDebug("TestInputMethod - " + method);
|
||||
try
|
||||
{
|
||||
obj[method.toLowerCase()](value);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing input parameter failed: " + method + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function TestInOutMethod(obj, method, inValue, outValue)
|
||||
{
|
||||
printDebug("TestInOutMethod - " + method);
|
||||
try
|
||||
{
|
||||
var param = { value : inValue };
|
||||
obj[method](param);
|
||||
reportCompare(outValue, param.value, "Testing in/out parameter: " + method);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing in/out parameter failed: " + method + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
printStatus("Testing methods");
|
||||
var obj = COMObject(CLSID_nsXPCDispTestMethods);
|
||||
try
|
||||
{
|
||||
obj.NoParameters();
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("NoParameters failed: " + e.toString());
|
||||
}
|
||||
printStatus("Test method - Return values");
|
||||
TestReturnMethod(obj, "ReturnBSTR", "Boo");
|
||||
TestReturnMethod(obj, "ReturnI4",99999);
|
||||
TestReturnMethod(obj, "ReturnUI1", 99);
|
||||
TestReturnMethod(obj, "ReturnI2",9999);
|
||||
TestReturnMethod(obj, "ReturnR4",99999.1);
|
||||
TestReturnMethod(obj, "ReturnR8", 99999999999.99);
|
||||
TestReturnMethod(obj, "ReturnBool", true);
|
||||
|
||||
printStatus("TestReturnMethod - ReturnIDispatch");
|
||||
compareObject(obj.ReturnIDispatch(), nsXPCDispSimpleDesc, "Test method - Return IDispatch");
|
||||
var E_FAIL= -2147467259;
|
||||
TestReturnMethod(obj, "ReturnError", E_FAIL);
|
||||
TestReturnMethod(obj, "ReturnDate", "5/2/2002");
|
||||
// TestReturnMethod(obj, ReturnIUnknown(IUnknown * * result)
|
||||
TestReturnMethod(obj, "ReturnI1", 120);
|
||||
TestReturnMethod(obj, "ReturnUI2", 9999);
|
||||
TestReturnMethod(obj, "ReturnUI4", 3000000000);
|
||||
TestReturnMethod(obj, "ReturnInt", -999999);
|
||||
TestReturnMethod(obj, "ReturnUInt", 3000000000);
|
||||
|
||||
printStatus("Test method - Input params");
|
||||
TestInputMethod(obj, "TakesBSTR", "TakesBSTR");
|
||||
TestInputMethod(obj, "TakesI4", 999999);
|
||||
TestInputMethod(obj, "TakesUI1", 42);
|
||||
TestInputMethod(obj, "TakesI2", 32000);
|
||||
TestInputMethod(obj, "TakesR4", 99999.99);
|
||||
TestInputMethod(obj, "TakesR8", 999999999.99);
|
||||
TestInputMethod(obj, "TakesBool", true);
|
||||
var x = { Number : 5, ClassName : "nsXPCDispSimple" };
|
||||
TestInputMethod(obj, "TakesIDispatch", x);
|
||||
// This would always fail, type mismatch (no way to indicate this is going
|
||||
// to an error, and there's no automatic conversion from integers to error
|
||||
// codes
|
||||
// TestInputMethod(obj, "TakesError", E_FAIL);
|
||||
TestInputMethod(obj, "TakesDate", "5/2/2002");
|
||||
// TestInputMethod(obj, TakesIUnknown, );
|
||||
TestInputMethod(obj, "TakesI1", 42);
|
||||
TestInputMethod(obj, "TakesUI2", 50000);
|
||||
TestInputMethod(obj, "TakesUI4", 4026531840);
|
||||
TestInputMethod(obj, "TakesInt", -10000000);
|
||||
TestInputMethod(obj, "TakesUInt", 3758096384);
|
||||
|
||||
printStatus("Test method - Output params");
|
||||
TestOutMethod(obj, "OutputsBSTR", "Boo");
|
||||
TestOutMethod(obj, "OutputsI4",99999);
|
||||
TestOutMethod(obj, "OutputsUI1", 99);
|
||||
TestOutMethod(obj, "OutputsI2",9999);
|
||||
TestOutMethod(obj, "OutputsR4",999999.1);
|
||||
TestOutMethod(obj, "OutputsR8", 99999999999.99);
|
||||
TestOutMethod(obj, "OutputsBool", true);
|
||||
|
||||
var outParam = new Object();
|
||||
obj.OutputsIDispatch(outParam);
|
||||
compareObject(outParam.value, nsXPCDispSimpleDesc, "Test method - Output params");
|
||||
TestOutMethod(obj, "OutputsError", E_FAIL);
|
||||
TestOutMethod(obj, "OutputsDate", "5/2/2002");
|
||||
// TestOutMethod(obj, OutputsIUnknown(IUnknown * * result)
|
||||
TestOutMethod(obj, "OutputsI1", 120);
|
||||
TestOutMethod(obj, "OutputsUI2", 9999);
|
||||
TestOutMethod(obj, "OutputsUI4", 3000000000);
|
||||
|
||||
printStatus("Test method - In/out params");
|
||||
TestInOutMethod(obj, "InOutsBSTR", "String", "StringAppended");
|
||||
TestInOutMethod(obj, "InOutsI4", 2000000, -2000000);
|
||||
TestInOutMethod(obj, "InOutsUI1", 50, 8);
|
||||
TestInOutMethod(obj, "InOutsI2", -1000, 9000);
|
||||
TestInOutMethod(obj, "InOutsR4", -2.05, 3.0);
|
||||
TestInOutMethod(obj, "InOutsR8", -5.5, 49999994.50000005);
|
||||
TestInOutMethod(obj, "InOutsBool", true, false);
|
||||
TestInOutMethod(obj, "InOutsBool", false, true);
|
||||
var inoutParam = { value : {ClassName : "InOutTest", Number : 10 } };
|
||||
try
|
||||
{
|
||||
obj.InOutsIDispatch(inoutParam);
|
||||
if (inoutParam.value.Number != 15)
|
||||
reportFailure("Testing in/out parameter failed: IDispatch");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing in/out parameter failed: IDispatch - " + e.toString());
|
||||
}
|
||||
// See the TakesError case
|
||||
//TestInOutMethod(obj, "InOutsError", E_FAIL, E_FAIL + 1);
|
||||
TestInOutMethod(obj, "InOutsDate", "5/23/2001", "5/24/2001");
|
||||
//TestInOutMethod(obj, InOutsIUnknown(IUnknown * * result)
|
||||
TestInOutMethod(obj, "InOutsI1", -42, -41);
|
||||
TestInOutMethod(obj, "InOutsUI2", 43, 85);
|
||||
TestInOutMethod(obj, "InOutsUI4", 88, 46);
|
||||
|
||||
try
|
||||
{
|
||||
reportCompare(obj.OneParameterWithReturn(-20), 22, "Testing OneParameterWithReturn");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing OneParameterWithReturn: " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
reportCompare(obj.StringInputAndReturn("A String "), "A String Appended", "Testing StringInputAndReturn");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing StringInputAndReturn: " + e.toString());
|
||||
}
|
||||
try
|
||||
{
|
||||
var inoutIDispatch = { className : "inouttest", Number : 5 };
|
||||
var result = obj.IDispatchInputAndReturn(inoutIDispatch);
|
||||
reportCompare(81, result.Number, "IDispatchInputAndReturn");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing IDispatchInputAndReturn: " + e.toString());
|
||||
}
|
||||
try
|
||||
{
|
||||
obj.TwoParameters(1, 2);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwoParameters: " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
obj.TwelveInParameters(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwelveInParameters: " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var out1 = new Object();
|
||||
var out2 = new Object();
|
||||
var out3 = new Object();
|
||||
var out4 = new Object();
|
||||
var out5 = new Object();
|
||||
var out6 = new Object();
|
||||
var out7 = new Object();
|
||||
var out8 = new Object();
|
||||
var out9 = new Object();
|
||||
var out10 = new Object();
|
||||
var out11 = new Object();
|
||||
var out12 = new Object();
|
||||
obj.TwelveOutParameters(out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11, out12);
|
||||
reportCompare(78, out1.value + out2.value + out3.value + out4.value + out5.value + out6.value + out7.value + out8.value + out9.value + out10.value + out11.value + out12.value, "Testing TwelveOutParameters");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwelveOutParameters: " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
obj.TwelveStrings("one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "ten", "eleven", "twelve");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwelveStrings: " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var out1 = new Object();
|
||||
var out2 = new Object();
|
||||
var out3 = new Object();
|
||||
var out4 = new Object();
|
||||
var out5 = new Object();
|
||||
var out6 = new Object();
|
||||
var out7 = new Object();
|
||||
var out8 = new Object();
|
||||
var out9 = new Object();
|
||||
var out10 = new Object();
|
||||
var out11 = new Object();
|
||||
var out12 = new Object();
|
||||
obj.TwelveOutStrings(out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11, out12);
|
||||
reportCompare(true, out1.value == "one" && out2.value == "two" &&
|
||||
out3.value == "three" && out4.value == "four" &&
|
||||
out5.value == "five" && out6.value == "six" &&
|
||||
out7.value == "seven" && out8.value == "eight" &&
|
||||
out9.value == "nine" && out10.value == "ten" &&
|
||||
out11.value == "eleven" && out12.value == "twelve",
|
||||
"Testing TwelveOutString");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwelveOutParameters: " + e.toString());
|
||||
}
|
||||
try
|
||||
{
|
||||
var out1 = { className : "out1", Number : 5 };
|
||||
var out2 = { className : "out2", Number : 5 };
|
||||
var out3 = { className : "out3", Number : 5 };
|
||||
var out4 = { className : "out4", Number : 5 };
|
||||
var out5 = { className : "out5", Number : 5 };
|
||||
var out6 = { className : "out6", Number : 5 };
|
||||
var out7 = { className : "out7", Number : 5 };
|
||||
var out8 = { className : "out8", Number : 5 };
|
||||
var out9 = { className : "out9", Number : 5 };
|
||||
var out10 = { className : "out10", Number : 5 };
|
||||
var out11 = { className : "out11", Number : 5 };
|
||||
var out12 = { className : "out12", Number : 5 };
|
||||
obj.TwelveIDispatch(out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11, out12);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwelveIDispatch: " + e.toString());
|
||||
}
|
||||
try
|
||||
{
|
||||
var out1 = new Object();
|
||||
var out2 = new Object();
|
||||
var out3 = new Object();
|
||||
var out4 = new Object();
|
||||
var out5 = new Object();
|
||||
var out6 = new Object();
|
||||
var out7 = new Object();
|
||||
var out8 = new Object();
|
||||
var out9 = new Object();
|
||||
var out10 = new Object();
|
||||
var out11 = new Object();
|
||||
var out12 = new Object();
|
||||
obj.TwelveOutIDispatch(out1, out2, out3, out4, out5, out6, out7, out8, out9, out10, out11, out12);
|
||||
print("out1.value" + out1.value.Number);
|
||||
reportCompare(true, out1.value.Number == 5 && out2.value.Number == 5 &&
|
||||
out3.value.Number == 5 && out4.value.Number == 5 &&
|
||||
out5.value.Number == 5 && out6.value.Number == 5 &&
|
||||
out7.value.Number == 5 && out8.value.Number == 5 &&
|
||||
out9.value.Number == 5 && out10.value.Number == 5 &&
|
||||
out11.value.Number == 5 && out12.value.Number == 5,
|
||||
"Testing TwelveOutIDispatch");
|
||||
compareObject(out1.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out1");
|
||||
compareObject(out2.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out2");
|
||||
compareObject(out3.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out3");
|
||||
compareObject(out4.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out4");
|
||||
compareObject(out5.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out5");
|
||||
compareObject(out6.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out6");
|
||||
compareObject(out7.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out7");
|
||||
compareObject(out8.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out8");
|
||||
compareObject(out9.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out9");
|
||||
compareObject(out10.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out10");
|
||||
compareObject(out11.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out11");
|
||||
compareObject(out12.value, nsXPCDispSimpleDesc, "Testing TwelveOutParameters - out12");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure("Testing TwelveOutIDispatch: " + e.toString());
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
obj.CreateError();
|
||||
reportFailure("Testing CreateError: Didn't generate a catchable exception");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportCompare(true, e.toString().search("CreateError Test") != -1, "Testing CreateError");
|
||||
}
|
||||
}
|
||||
@@ -1,361 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released March
|
||||
* 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Ginda rginda@netscape.com
|
||||
*/
|
||||
|
||||
FAILED = "FAILED!: ";
|
||||
STATUS = "STATUS: ";
|
||||
BUGNUMBER = "BUGNUMBER: ";
|
||||
DEBUGLINE = "DEBUG: ";
|
||||
|
||||
DEBUG = false;
|
||||
VERBOSE = false;
|
||||
|
||||
var CLSID_nsXPCDispSimple = "{9F39237C-D179-4260-8EF3-4B6D4D7D5570}";
|
||||
var ProgID_nsXPCDispSimple = "XPCIDispatchTest.nsXPCDispSimple.1";
|
||||
var nsXPCDispSimpleDesc =
|
||||
{
|
||||
name : "nsXPCDispSimple",
|
||||
cid : CLSID_nsXPCDispSimple,
|
||||
progid : ProgID_nsXPCDispSimple,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"ClassName",
|
||||
"Number"
|
||||
]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestMethods = "{745D1149-9F46-418C-B176-71EAA98974BA}";
|
||||
var ProgID_nsXPCDispTestMethods = "XPCIDispatchTest.nsXPCDispTestMethods.1";
|
||||
var nsXPCDispTestMethodsDesc =
|
||||
{
|
||||
name : "nsXPCDispTestMethods",
|
||||
cid : CLSID_nsXPCDispTestMethods,
|
||||
progid : ProgID_nsXPCDispTestMethods,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"NoParameters", "ReturnBSTR", "ReturnI4",
|
||||
"ReturnUI1", "ReturnI2", "ReturnR4", "ReturnR8", "ReturnBool",
|
||||
"ReturnIDispatch", "ReturnError", "ReturnDate",
|
||||
"ReturnIUnknown", "ReturnI1", "ReturnUI2", "ReturnUI4",
|
||||
"ReturnInt", "ReturnUInt", "TakesBSTR", "TakesI4", "TakesUI1",
|
||||
"TakesI2", "TakesR4", "TakesR8", "TakesBool",
|
||||
"TakesIDispatch", "TakesError", "TakesDate", "TakesIUnknown",
|
||||
"TakesI1", "TakesUI2", "TakesUI4", "TakesInt", "TakesUInt",
|
||||
"OutputsBSTR", "OutputsI4", "OutputsUI1", "OutputsI2",
|
||||
"OutputsR4", "OutputsR8", "OutputsBool", "OutputsIDispatch",
|
||||
"OutputsError", "OutputsDate", "OutputsIUnknown", "OutputsI1",
|
||||
"OutputsUI2", "OutputsUI4", "InOutsBSTR", "InOutsI4",
|
||||
"InOutsUI1", "InOutsI2", "InOutsR4", "InOutsR8", "InOutsBool",
|
||||
"InOutsIDispatch", "InOutsError", "InOutsDate",
|
||||
"InOutsIUnknown", "InOutsI1", "InOutsUI2", "InOutsUI4",
|
||||
"InOutsInt", "InOutsUInt", "OneParameterWithReturn",
|
||||
"StringInputAndReturn", "IDispatchInputAndReturn",
|
||||
"TwoParameters", "TwelveInParameters", "TwelveOutParameters",
|
||||
"TwelveStrings", "TwelveOutStrings", "TwelveIDispatch",
|
||||
"TwelveOutIDispatch", "CreateError"
|
||||
]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestArrays = "{AB085C43-C619-48C8-B68C-C495BDE12DFB}";
|
||||
var ProgID_nsXPCDispTestArrays = "XPCIDispatchTest.nsXPCDispTestArrays.1";
|
||||
var nsXPCDispTestArraysDesc =
|
||||
{
|
||||
name : "nsXPCDispTestArrays",
|
||||
cid : CLSID_nsXPCDispTestArrays,
|
||||
progid : ProgID_nsXPCDispTestArrays,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"ReturnSafeArray", "ReturnSafeArrayBSTR", "ReturnSafeArrayIDispatch",
|
||||
"TakesSafeArray", "TakesSafeArrayBSTR", "TakesSafeArrayIDispatch",
|
||||
"InOutSafeArray", "InOutSafeArrayBSTR", "InOutSafeArrayIDispatch"
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var CLSID_nsXPCDispTestNoIDispatch = "{7414404F-A4CC-4E3C-9B32-BB20CB22F541}";
|
||||
var ProgID_nsXPCDispTestNoIDispatch = "XPCIDispatchTest.nsXPCDispTestNoIDispatch.1";
|
||||
|
||||
var CLSID_nsXPCDispTestNoScript = "{F8D54F00-4FC4-4731-B467-10F1CB8DB0AD}";
|
||||
var ProgID_nsXPCDispTestNoScript = "XPCIDispatchTest.nsXPCDispTestNoScript.1";
|
||||
|
||||
var CLSID_nsXPCDispTestProperties = "{D8B4265B-1768-4CA9-A285-7CCAEEB51C74}";
|
||||
var ProgID_nsXPCDispTestProperties = "XPCIDispatchTest.nsXPCDispTestProperties.1";
|
||||
var nsXPCDispTestPropertiesDesc =
|
||||
{
|
||||
name : "nsXPCDispTestProperties",
|
||||
cid : CLSID_nsXPCDispTestProperties,
|
||||
progid : ProgID_nsXPCDispTestProperties,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"Short", "Long", "Float", "Double", "Currency",
|
||||
"Date", "String", "DispatchPtr", "SCode", "Boolean", "Variant",
|
||||
"COMPtr", "Char"
|
||||
]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestScriptOn = "{2A06373F-3E61-4882-A3D7-A104F70B09ED}";
|
||||
var ProgID_nsXPCDispTestScriptOn = "XPCIDispatchTest.nsXPCDispTestScriptOn.1";
|
||||
var nsXPCDispTestScriptOnDesc =
|
||||
{
|
||||
name : "nsXPCDispTestScriptOn",
|
||||
cid : CLSID_nsXPCDispTestScriptOn,
|
||||
progid : ProgID_nsXPCDispTestScriptOn,
|
||||
scriptable : true,
|
||||
methods : [ ]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestScriptOff = "{959CD122-9826-4757-BA09-DE327D55F9E7}";
|
||||
var ProgID_nsXPCDispTestScriptOff = "XPCIDispatchTest.nsXPCDispTestScriptOff.1";
|
||||
var nsXPCDispTestScriptOffDesc =
|
||||
{
|
||||
name : "nsXPCDispTestScriptOff",
|
||||
cid : CLSID_nsXPCDispTestScriptOff,
|
||||
progid : ProgID_nsXPCDispTestScriptOff,
|
||||
scriptable : false,
|
||||
methods : [ ]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestWrappedJS = "{EAEE6BB2-C005-4B91-BCA7-6613236F6F69}";
|
||||
var ProgID_nsXPCDispTestWrappedJS = "XPCIDispatchTest.nsXPCDispTestWrappedJS.1";
|
||||
var nsXPCDispTestWrappedJSDesc =
|
||||
{
|
||||
name : "nsXPCDispTestWrappedJS",
|
||||
cid : CLSID_nsXPCDispTestWrappedJS,
|
||||
progid : ProgID_nsXPCDispTestWrappedJS,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"TestParamTypes"
|
||||
]
|
||||
};
|
||||
|
||||
// create list of COM components
|
||||
var objectsDesc =
|
||||
[
|
||||
nsXPCDispSimpleDesc,
|
||||
nsXPCDispTestMethodsDesc,
|
||||
nsXPCDispTestArraysDesc,
|
||||
nsXPCDispTestPropertiesDesc,
|
||||
nsXPCDispTestScriptOnDesc,
|
||||
nsXPCDispTestScriptOffDesc,
|
||||
nsXPCDispTestWrappedJSDesc
|
||||
];
|
||||
|
||||
function findProp(prop, array, marked)
|
||||
{
|
||||
len = array.length;
|
||||
for (index = 0; index < len; ++index)
|
||||
{
|
||||
if (prop == array[index])
|
||||
{
|
||||
marked[index] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function compareObject(obj, objDesc, testName)
|
||||
{
|
||||
if (obj == undefined)
|
||||
{
|
||||
reportFailure("compareObject passed an invalid object");
|
||||
return;
|
||||
}
|
||||
var marked = new Array();
|
||||
for (prop in obj)
|
||||
{
|
||||
printDebug("Found " + prop);
|
||||
reportCompare(
|
||||
true,
|
||||
findProp(prop, objDesc.methods, marked),
|
||||
testName + ": " + prop + " exists on " + objDesc.name + ", but was not expected");
|
||||
}
|
||||
len = objDesc.methods.length;
|
||||
for (var index = 0; index < len; ++index)
|
||||
{
|
||||
reportCompare(
|
||||
true,
|
||||
marked[index],
|
||||
testName + ": " + objDesc.methods[index] + " does not exist on " + objDesc.name);
|
||||
}
|
||||
}
|
||||
|
||||
function compareExpression(expression, expectedResult, testName)
|
||||
{
|
||||
if (VERBOSE && (typeof testName != "undefined"))
|
||||
printStatus(testName + " - evaluating:" + expression);
|
||||
|
||||
try
|
||||
{
|
||||
reportCompare(
|
||||
expectedResult,
|
||||
eval(expression),
|
||||
testName);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure(expression + " generated the following exception:" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
var callStack = new Array();
|
||||
|
||||
/*
|
||||
* Report a failure in the 'accepted' manner
|
||||
*/
|
||||
function reportFailure (msg)
|
||||
{
|
||||
var lines = msg.split ("\n");
|
||||
var l;
|
||||
var funcName = currentFunc();
|
||||
var prefix = (funcName) ? "[reported from " + funcName + "] ": "";
|
||||
|
||||
for (var i=0; i<lines.length; i++)
|
||||
print (FAILED + prefix + lines[i]);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a non-failure message.
|
||||
*/
|
||||
function printDebug (msg)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
var lines = msg.split ("\n");
|
||||
var l;
|
||||
|
||||
for (var i=0; i<lines.length; i++)
|
||||
print (DEBUGLINE + lines[i]);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Print a non-failure message.
|
||||
*/
|
||||
function printStatus (msg)
|
||||
{
|
||||
var lines = msg.split ("\n");
|
||||
var l;
|
||||
|
||||
for (var i=0; i<lines.length; i++)
|
||||
print (STATUS + lines[i]);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a bugnumber message.
|
||||
*/
|
||||
function printBugNumber (num)
|
||||
{
|
||||
|
||||
print (BUGNUMBER + num);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare expected result to actual result, if they differ (in value and/or
|
||||
* type) report a failure. If description is provided, include it in the
|
||||
* failure report.
|
||||
*/
|
||||
function reportCompare (expected, actual, description)
|
||||
{
|
||||
var expected_t = typeof expected;
|
||||
var actual_t = typeof actual;
|
||||
var output = "";
|
||||
|
||||
if ((VERBOSE) && (typeof description != "undefined"))
|
||||
printStatus ("Comparing '" + description + "'");
|
||||
|
||||
if (expected_t != actual_t)
|
||||
output += "Type mismatch, expected type " + expected_t +
|
||||
", actual type " + actual_t + "\n";
|
||||
else if (VERBOSE)
|
||||
printStatus ("Expected type '" + actual_t + "' matched actual " +
|
||||
"type '" + expected_t + "'");
|
||||
|
||||
if (expected != actual)
|
||||
output += "Expected value '" + expected + "', Actual value '" + actual +
|
||||
"'\n";
|
||||
else if (VERBOSE)
|
||||
printStatus ("Expected value '" + actual + "' matched actual " +
|
||||
"value '" + expected + "'");
|
||||
|
||||
if (output != "")
|
||||
{
|
||||
if (typeof description != "undefined")
|
||||
reportFailure (description);
|
||||
reportFailure (output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Puts funcName at the top of the call stack. This stack is used to show
|
||||
* a function-reported-from field when reporting failures.
|
||||
*/
|
||||
function enterFunc (funcName)
|
||||
{
|
||||
|
||||
if (!funcName.match(/\(\)$/))
|
||||
funcName += "()";
|
||||
|
||||
callStack.push(funcName);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Pops the top funcName off the call stack. funcName is optional, and can be
|
||||
* used to check push-pop balance.
|
||||
*/
|
||||
function exitFunc (funcName)
|
||||
{
|
||||
var lastFunc = callStack.pop();
|
||||
|
||||
if (funcName)
|
||||
{
|
||||
if (!funcName.match(/\(\)$/))
|
||||
funcName += "()";
|
||||
|
||||
if (lastFunc != funcName)
|
||||
reportFailure ("Test driver failure, expected to exit function '" +
|
||||
funcName + "' but '" + lastFunc + "' came off " +
|
||||
"the stack");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Peeks at the top of the call stack.
|
||||
*/
|
||||
function currentFunc()
|
||||
{
|
||||
|
||||
return callStack[callStack.length - 1];
|
||||
|
||||
}
|
||||
@@ -1,76 +0,0 @@
|
||||
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (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.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is the IDispatch implementation for XPConnect
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* David Bradley.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
/**
|
||||
* \file
|
||||
* This file contains the tests for making sure that JS Objects access via the IDispatch interface
|
||||
* work properly
|
||||
*/
|
||||
|
||||
test();
|
||||
|
||||
function test()
|
||||
{
|
||||
try
|
||||
{
|
||||
var variantObj = Components.classes["@mozilla.org/variant;1"].createInstance(Components.interfaces.nsIVariant);
|
||||
var jsobj =
|
||||
{
|
||||
Boolean : false,
|
||||
Short : 0,
|
||||
Long : 0,
|
||||
Float : 0.0,
|
||||
Double : 0.0,
|
||||
Currency : 0.0,
|
||||
Date : new Date(),
|
||||
String : "",
|
||||
DispatchPtr : {},
|
||||
SCode : 0,
|
||||
Variant : variantObj,
|
||||
Char : 'a'
|
||||
};
|
||||
var obj = COMObject(CLSID_nsXPCDispTestWrappedJS);
|
||||
reportCompare(
|
||||
obj.TestParamTypes(jsobj),
|
||||
"",
|
||||
"Testing IDispatch wrapped JS objects");
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure(e.toString());
|
||||
}
|
||||
}
|
||||
@@ -1,361 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (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.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator client code, released March
|
||||
* 31, 1998.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape Communications
|
||||
* Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Ginda rginda@netscape.com
|
||||
*/
|
||||
|
||||
FAILED = "FAILED!: ";
|
||||
STATUS = "STATUS: ";
|
||||
BUGNUMBER = "BUGNUMBER: ";
|
||||
DEBUGLINE = "DEBUG: ";
|
||||
|
||||
DEBUG = false;
|
||||
VERBOSE = false;
|
||||
|
||||
var CLSID_nsXPCDispSimple = "{9F39237C-D179-4260-8EF3-4B6D4D7D5570}";
|
||||
var ProgID_nsXPCDispSimple = "XPCIDispatchTest.nsXPCDispSimple.1";
|
||||
var nsXPCDispSimpleDesc =
|
||||
{
|
||||
name : "nsXPCDispSimple",
|
||||
cid : CLSID_nsXPCDispSimple,
|
||||
progid : ProgID_nsXPCDispSimple,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"ClassName",
|
||||
"Number"
|
||||
]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestMethods = "{745D1149-9F46-418C-B176-71EAA98974BA}";
|
||||
var ProgID_nsXPCDispTestMethods = "XPCIDispatchTest.nsXPCDispTestMethods.1";
|
||||
var nsXPCDispTestMethodsDesc =
|
||||
{
|
||||
name : "nsXPCDispTestMethods",
|
||||
cid : CLSID_nsXPCDispTestMethods,
|
||||
progid : ProgID_nsXPCDispTestMethods,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"NoParameters", "ReturnBSTR", "ReturnI4",
|
||||
"ReturnUI1", "ReturnI2", "ReturnR4", "ReturnR8", "ReturnBool",
|
||||
"ReturnIDispatch", "ReturnError", "ReturnDate",
|
||||
"ReturnIUnknown", "ReturnI1", "ReturnUI2", "ReturnUI4",
|
||||
"ReturnInt", "ReturnUInt", "TakesBSTR", "TakesI4", "TakesUI1",
|
||||
"TakesI2", "TakesR4", "TakesR8", "TakesBool",
|
||||
"TakesIDispatch", "TakesError", "TakesDate", "TakesIUnknown",
|
||||
"TakesI1", "TakesUI2", "TakesUI4", "TakesInt", "TakesUInt",
|
||||
"OutputsBSTR", "OutputsI4", "OutputsUI1", "OutputsI2",
|
||||
"OutputsR4", "OutputsR8", "OutputsBool", "OutputsIDispatch",
|
||||
"OutputsError", "OutputsDate", "OutputsIUnknown", "OutputsI1",
|
||||
"OutputsUI2", "OutputsUI4", "InOutsBSTR", "InOutsI4",
|
||||
"InOutsUI1", "InOutsI2", "InOutsR4", "InOutsR8", "InOutsBool",
|
||||
"InOutsIDispatch", "InOutsError", "InOutsDate",
|
||||
"InOutsIUnknown", "InOutsI1", "InOutsUI2", "InOutsUI4",
|
||||
"InOutsInt", "InOutsUInt", "OneParameterWithReturn",
|
||||
"StringInputAndReturn", "IDispatchInputAndReturn",
|
||||
"TwoParameters", "TwelveInParameters", "TwelveOutParameters",
|
||||
"TwelveStrings", "TwelveOutStrings", "TwelveIDispatch",
|
||||
"TwelveOutIDispatch", "CreateError"
|
||||
]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestArrays = "{AB085C43-C619-48C8-B68C-C495BDE12DFB}";
|
||||
var ProgID_nsXPCDispTestArrays = "XPCIDispatchTest.nsXPCDispTestArrays.1";
|
||||
var nsXPCDispTestArraysDesc =
|
||||
{
|
||||
name : "nsXPCDispTestArrays",
|
||||
cid : CLSID_nsXPCDispTestArrays,
|
||||
progid : ProgID_nsXPCDispTestArrays,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"ReturnSafeArray", "ReturnSafeArrayBSTR", "ReturnSafeArrayIDispatch",
|
||||
"TakesSafeArray", "TakesSafeArrayBSTR", "TakesSafeArrayIDispatch",
|
||||
"InOutSafeArray", "InOutSafeArrayBSTR", "InOutSafeArrayIDispatch"
|
||||
]
|
||||
};
|
||||
|
||||
|
||||
var CLSID_nsXPCDispTestNoIDispatch = "{7414404F-A4CC-4E3C-9B32-BB20CB22F541}";
|
||||
var ProgID_nsXPCDispTestNoIDispatch = "XPCIDispatchTest.nsXPCDispTestNoIDispatch.1";
|
||||
|
||||
var CLSID_nsXPCDispTestNoScript = "{F8D54F00-4FC4-4731-B467-10F1CB8DB0AD}";
|
||||
var ProgID_nsXPCDispTestNoScript = "XPCIDispatchTest.nsXPCDispTestNoScript.1";
|
||||
|
||||
var CLSID_nsXPCDispTestProperties = "{D8B4265B-1768-4CA9-A285-7CCAEEB51C74}";
|
||||
var ProgID_nsXPCDispTestProperties = "XPCIDispatchTest.nsXPCDispTestProperties.1";
|
||||
var nsXPCDispTestPropertiesDesc =
|
||||
{
|
||||
name : "nsXPCDispTestProperties",
|
||||
cid : CLSID_nsXPCDispTestProperties,
|
||||
progid : ProgID_nsXPCDispTestProperties,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"Short", "Long", "Float", "Double", "Currency",
|
||||
"Date", "String", "DispatchPtr", "SCode", "Boolean", "Variant",
|
||||
"COMPtr", "Char"
|
||||
]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestScriptOn = "{2A06373F-3E61-4882-A3D7-A104F70B09ED}";
|
||||
var ProgID_nsXPCDispTestScriptOn = "XPCIDispatchTest.nsXPCDispTestScriptOn.1";
|
||||
var nsXPCDispTestScriptOnDesc =
|
||||
{
|
||||
name : "nsXPCDispTestScriptOn",
|
||||
cid : CLSID_nsXPCDispTestScriptOn,
|
||||
progid : ProgID_nsXPCDispTestScriptOn,
|
||||
scriptable : true,
|
||||
methods : [ ]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestScriptOff = "{959CD122-9826-4757-BA09-DE327D55F9E7}";
|
||||
var ProgID_nsXPCDispTestScriptOff = "XPCIDispatchTest.nsXPCDispTestScriptOff.1";
|
||||
var nsXPCDispTestScriptOffDesc =
|
||||
{
|
||||
name : "nsXPCDispTestScriptOff",
|
||||
cid : CLSID_nsXPCDispTestScriptOff,
|
||||
progid : ProgID_nsXPCDispTestScriptOff,
|
||||
scriptable : false,
|
||||
methods : [ ]
|
||||
};
|
||||
|
||||
var CLSID_nsXPCDispTestWrappedJS = "{EAEE6BB2-C005-4B91-BCA7-6613236F6F69}";
|
||||
var ProgID_nsXPCDispTestWrappedJS = "XPCIDispatchTest.nsXPCDispTestWrappedJS.1";
|
||||
var nsXPCDispTestWrappedJSDesc =
|
||||
{
|
||||
name : "nsXPCDispTestWrappedJS",
|
||||
cid : CLSID_nsXPCDispTestWrappedJS,
|
||||
progid : ProgID_nsXPCDispTestWrappedJS,
|
||||
scriptable : true,
|
||||
methods :
|
||||
[
|
||||
"TestParamTypes"
|
||||
]
|
||||
};
|
||||
|
||||
// create list of COM components
|
||||
var objectsDesc =
|
||||
[
|
||||
nsXPCDispSimpleDesc,
|
||||
nsXPCDispTestMethodsDesc,
|
||||
nsXPCDispTestArraysDesc,
|
||||
nsXPCDispTestPropertiesDesc,
|
||||
nsXPCDispTestScriptOnDesc,
|
||||
nsXPCDispTestScriptOffDesc,
|
||||
nsXPCDispTestWrappedJSDesc
|
||||
];
|
||||
|
||||
function findProp(prop, array, marked)
|
||||
{
|
||||
len = array.length;
|
||||
for (index = 0; index < len; ++index)
|
||||
{
|
||||
if (prop == array[index])
|
||||
{
|
||||
marked[index] = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function compareObject(obj, objDesc, testName)
|
||||
{
|
||||
if (obj == undefined)
|
||||
{
|
||||
reportFailure("compareObject passed an invalid object");
|
||||
return;
|
||||
}
|
||||
var marked = new Array();
|
||||
for (prop in obj)
|
||||
{
|
||||
printDebug("Found " + prop);
|
||||
reportCompare(
|
||||
true,
|
||||
findProp(prop, objDesc.methods, marked),
|
||||
testName + ": " + prop + " exists on " + objDesc.name + ", but was not expected");
|
||||
}
|
||||
len = objDesc.methods.length;
|
||||
for (var index = 0; index < len; ++index)
|
||||
{
|
||||
reportCompare(
|
||||
true,
|
||||
marked[index],
|
||||
testName + ": " + objDesc.methods[index] + " does not exist on " + objDesc.name);
|
||||
}
|
||||
}
|
||||
|
||||
function compareExpression(expression, expectedResult, testName)
|
||||
{
|
||||
if (VERBOSE && (typeof testName != "undefined"))
|
||||
printStatus(testName + " - evaluating:" + expression);
|
||||
|
||||
try
|
||||
{
|
||||
reportCompare(
|
||||
expectedResult,
|
||||
eval(expression),
|
||||
testName);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
reportFailure(expression + " generated the following exception:" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
var callStack = new Array();
|
||||
|
||||
/*
|
||||
* Report a failure in the 'accepted' manner
|
||||
*/
|
||||
function reportFailure (msg)
|
||||
{
|
||||
var lines = msg.split ("\n");
|
||||
var l;
|
||||
var funcName = currentFunc();
|
||||
var prefix = (funcName) ? "[reported from " + funcName + "] ": "";
|
||||
|
||||
for (var i=0; i<lines.length; i++)
|
||||
print (FAILED + prefix + lines[i]);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a non-failure message.
|
||||
*/
|
||||
function printDebug (msg)
|
||||
{
|
||||
if (DEBUG)
|
||||
{
|
||||
var lines = msg.split ("\n");
|
||||
var l;
|
||||
|
||||
for (var i=0; i<lines.length; i++)
|
||||
print (DEBUGLINE + lines[i]);
|
||||
}
|
||||
|
||||
}
|
||||
/*
|
||||
* Print a non-failure message.
|
||||
*/
|
||||
function printStatus (msg)
|
||||
{
|
||||
var lines = msg.split ("\n");
|
||||
var l;
|
||||
|
||||
for (var i=0; i<lines.length; i++)
|
||||
print (STATUS + lines[i]);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Print a bugnumber message.
|
||||
*/
|
||||
function printBugNumber (num)
|
||||
{
|
||||
|
||||
print (BUGNUMBER + num);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare expected result to actual result, if they differ (in value and/or
|
||||
* type) report a failure. If description is provided, include it in the
|
||||
* failure report.
|
||||
*/
|
||||
function reportCompare (expected, actual, description)
|
||||
{
|
||||
var expected_t = typeof expected;
|
||||
var actual_t = typeof actual;
|
||||
var output = "";
|
||||
|
||||
if ((VERBOSE) && (typeof description != "undefined"))
|
||||
printStatus ("Comparing '" + description + "'");
|
||||
|
||||
if (expected_t != actual_t)
|
||||
output += "Type mismatch, expected type " + expected_t +
|
||||
", actual type " + actual_t + "\n";
|
||||
else if (VERBOSE)
|
||||
printStatus ("Expected type '" + actual_t + "' matched actual " +
|
||||
"type '" + expected_t + "'");
|
||||
|
||||
if (expected != actual)
|
||||
output += "Expected value '" + expected + "', Actual value '" + actual +
|
||||
"'\n";
|
||||
else if (VERBOSE)
|
||||
printStatus ("Expected value '" + actual + "' matched actual " +
|
||||
"value '" + expected + "'");
|
||||
|
||||
if (output != "")
|
||||
{
|
||||
if (typeof description != "undefined")
|
||||
reportFailure (description);
|
||||
reportFailure (output);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Puts funcName at the top of the call stack. This stack is used to show
|
||||
* a function-reported-from field when reporting failures.
|
||||
*/
|
||||
function enterFunc (funcName)
|
||||
{
|
||||
|
||||
if (!funcName.match(/\(\)$/))
|
||||
funcName += "()";
|
||||
|
||||
callStack.push(funcName);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Pops the top funcName off the call stack. funcName is optional, and can be
|
||||
* used to check push-pop balance.
|
||||
*/
|
||||
function exitFunc (funcName)
|
||||
{
|
||||
var lastFunc = callStack.pop();
|
||||
|
||||
if (funcName)
|
||||
{
|
||||
if (!funcName.match(/\(\)$/))
|
||||
funcName += "()";
|
||||
|
||||
if (lastFunc != funcName)
|
||||
reportFailure ("Test driver failure, expected to exit function '" +
|
||||
funcName + "' but '" + lastFunc + "' came off " +
|
||||
"the stack");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Peeks at the top of the call stack.
|
||||
*/
|
||||
function currentFunc()
|
||||
{
|
||||
|
||||
return callStack[callStack.length - 1];
|
||||
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
perl jsDriver.pl -e xpcshell %1 %2 %3 %4 %5 %6 %7 %8 %9
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user