Changeset 429 for trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginUtils.cc
- Timestamp:
- Sep 24, 2014, 9:34:21 PM (11 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginUtils.cc
r418 r429 44 44 #include "IcedTeaScriptablePluginObject.h" 45 45 #include "IcedTeaPluginUtils.h" 46 #include <fstream> 46 47 47 48 /** … … 58 59 std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>(); 59 60 std::map<std::string, NPObject*>* IcedTeaPluginUtilities::object_map = new std::map<std::string, NPObject*>(); 61 std::queue<std::string> pre_jvm_message; 60 62 61 63 /* Plugin async call queue */ 62 64 static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >(); 65 66 void *flush_pre_init_messages(void* data) { 67 while (true){ 68 struct timespec ts; 69 ts.tv_sec = 1; 70 ts.tv_nsec = 0; 71 nanosleep(&ts ,0); 72 if (jvm_up) { 73 while (!pre_jvm_message.empty()) { 74 pthread_mutex_lock(&debug_pipe_lock); 75 std::string message = pre_jvm_message.front(); 76 pre_jvm_message.pop(); 77 pthread_mutex_unlock(&debug_pipe_lock); 78 plugin_send_message_to_appletviewer_console(message.c_str()); 79 } 80 flush_plugin_send_message_to_appletviewer_console(); 81 } 82 } 83 return NULL; 84 } 85 86 void push_pre_init_messages(char * ldm){ 87 pthread_mutex_lock(&debug_pipe_lock); 88 pre_jvm_message.push(std::string(ldm)); 89 pthread_mutex_unlock(&debug_pipe_lock); 90 } 91 92 void reset_pre_init_messages(){ 93 pre_jvm_message = std::queue<std::string>(); 94 } 63 95 64 96 /** … … 403 435 wchar_t c; 404 436 405 if (plugin_debug) printf("Converted UTF-16LE string:");437 PLUGIN_DEBUG("Converted UTF-16LE string: \n"); 406 438 407 439 result_unicode_str->clear(); … … 417 449 (c >= '0' && c <= '9')) 418 450 { 419 if (plugin_debug) printf("%c", c);451 PLUGIN_DEBUG("%c\n", c); 420 452 } 421 453 … … 424 456 425 457 // not routing via debug print macros due to wide-string issues 426 if (plugin_debug) printf(". Length=%d\n", result_unicode_str->length());458 PLUGIN_DEBUG(". Length=%d\n", result_unicode_str->length()); 427 459 } 428 460 … … 502 534 } 503 535 536 /* Clear instance_map. Useful for tests. */ 537 void 538 IcedTeaPluginUtilities::clearInstanceIDs() 539 { 540 delete instance_map; 541 instance_map = new std::map<void*, NPP>(); 542 } 543 504 544 /** 505 545 * Removes all mappings to a given instance, and all associated objects … … 605 645 PLUGIN_DEBUG("Removing key %s from object map\n", key.c_str()); 606 646 object_map->erase(key); 647 } 648 649 /* Clear object_map. Useful for tests. */ 650 void 651 IcedTeaPluginUtilities::clearObjectMapping() 652 { 653 std::map<std::string, NPObject*>::iterator iter = object_map->begin(); 654 for (; iter != object_map->end(); ++iter) { 655 browser_functions.releaseobject(iter->second); 656 } 657 delete object_map; 658 object_map = new std::map<std::string, NPObject*>(); 607 659 } 608 660 … … 720 772 } 721 773 774 /** 775 * Convert either a void, boolean, or a number 776 */ 777 static void 778 javaPrimitiveResultToNPVariant(const std::string& value, NPVariant* variant) 779 { 780 if (value == "void") 781 { 782 PLUGIN_DEBUG("Method call returned void\n"); 783 VOID_TO_NPVARIANT(*variant); 784 } else if (value == "null") 785 { 786 PLUGIN_DEBUG("Method call returned null\n"); 787 NULL_TO_NPVARIANT(*variant); 788 } else if (value == "true") 789 { 790 PLUGIN_DEBUG("Method call returned a boolean (true)\n"); 791 BOOLEAN_TO_NPVARIANT(true, *variant); 792 } else if (value == "false") 793 { 794 PLUGIN_DEBUG("Method call returned a boolean (false)\n"); 795 BOOLEAN_TO_NPVARIANT(false, *variant); 796 } else 797 { 798 double d = strtod(value.c_str(), NULL); 799 800 // See if it is convertible to int 801 if (value.find(".") != std::string::npos || d < -(0x7fffffffL - 1L) || d > 0x7fffffffL) 802 { 803 PLUGIN_DEBUG("Method call returned a double %f\n", d); 804 DOUBLE_TO_NPVARIANT(d, *variant); 805 } else 806 { 807 int32_t i = (int32_t) d; 808 PLUGIN_DEBUG("Method call returned an int %d\n", i); 809 INT32_TO_NPVARIANT(i, *variant); 810 } 811 } 812 } 813 814 static bool 815 javaStringResultToNPVariant(const std::string& jobject_id, NPVariant* variant) 816 { 817 JavaRequestProcessor jrequest_processor; 818 JavaResultData* jstring_result = jrequest_processor.getString(jobject_id); 819 820 if (jstring_result->error_occurred) 821 { 822 return false; 823 } 824 825 std::string str = *jstring_result->return_string; 826 827 PLUGIN_DEBUG( "Method call returned a string:\"%s\"\n", str.c_str()); 828 829 *variant = IcedTeaPluginUtilities::NPVariantStringCopy(str); 830 831 return true; 832 } 833 834 static bool 835 javaJSObjectResultToNPVariant(const std::string& js_id, NPVariant* variant) 836 { 837 NPVariant* result_variant = (NPVariant*) IcedTeaPluginUtilities::stringToJSID(js_id); 838 *variant = *result_variant; 839 return true; 840 } 841 842 static bool 843 javaObjectResultToNPVariant(NPP instance, const std::string& jobject_id, NPVariant* variant) 844 { 845 // Reference the class object so we can construct an NPObject with it and the instance 846 847 JavaRequestProcessor jrequest_processor; 848 JavaResultData* jclass_result = jrequest_processor.getClassID(jobject_id); 849 850 if (jclass_result->error_occurred) 851 { 852 return false; 853 } 854 855 std::string jclass_id = *jclass_result->return_string; 856 857 NPObject* obj; 858 if (jclass_id.at(0) == '[') // array 859 { 860 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, 861 jobject_id, true); 862 } else 863 { 864 obj = IcedTeaScriptableJavaObject::get_scriptable_java_object(instance, jclass_id, 865 jobject_id, false); 866 } 867 868 OBJECT_TO_NPVARIANT(obj, *variant); 869 870 return true; 871 } 872 722 873 bool 723 874 IcedTeaPluginUtilities::javaResultToNPVariant(NPP instance, 724 std::string* java_value, 725 NPVariant* variant) 726 { 727 JavaRequestProcessor java_request = JavaRequestProcessor(); 728 JavaResultData* java_result; 729 730 if (java_value->find("literalreturn") == 0) 731 { 732 // 'literalreturn ' == 14 to skip 733 std::string value = java_value->substr(14); 734 735 // VOID/BOOLEAN/NUMBER 736 737 if (value == "void") 738 { 739 PLUGIN_DEBUG("Method call returned void\n"); 740 VOID_TO_NPVARIANT(*variant); 741 } else if (value == "null") 742 { 743 PLUGIN_DEBUG("Method call returned null\n"); 744 NULL_TO_NPVARIANT(*variant); 745 }else if (value == "true") 746 { 747 PLUGIN_DEBUG("Method call returned a boolean (true)\n"); 748 BOOLEAN_TO_NPVARIANT(true, *variant); 749 } else if (value == "false") 750 { 751 PLUGIN_DEBUG("Method call returned a boolean (false)\n"); 752 BOOLEAN_TO_NPVARIANT(false, *variant); 753 } else 754 { 755 double d = strtod(value.c_str(), NULL); 756 757 // See if it is convertible to int 758 if (value.find(".") != std::string::npos || 759 d < -(0x7fffffffL - 1L) || 760 d > 0x7fffffffL) 761 { 762 PLUGIN_DEBUG("Method call returned a double %f\n", d); 763 DOUBLE_TO_NPVARIANT(d, *variant); 764 } else 765 { 766 int32_t i = (int32_t) d; 767 PLUGIN_DEBUG("Method call returned an int %d\n", i); 768 INT32_TO_NPVARIANT(i, *variant); 769 } 770 } 771 } else { 772 // Else this is a complex java object 773 774 // To keep code a little bit cleaner, we create variables with proper descriptive names 775 std::string return_obj_instance_id = std::string(); 776 std::string return_obj_class_id = std::string(); 777 std::string return_obj_class_name = std::string(); 778 return_obj_instance_id.append(*java_value); 779 780 // Find out the class name first, because string is a special case 781 java_result = java_request.getClassName(return_obj_instance_id); 782 783 if (java_result->error_occurred) 875 std::string* java_value, NPVariant* variant) 876 { 877 int literal_n = sizeof("literalreturn"); // Accounts for one space char 878 int jsobject_n = sizeof("jsobject"); // Accounts for one space char 879 880 if (strncmp("literalreturn ", java_value->c_str(), literal_n) == 0) 881 { 882 javaPrimitiveResultToNPVariant(java_value->substr(literal_n), variant); 883 } else if (strncmp("jsobject ", java_value->c_str(), jsobject_n) == 0) 884 { 885 javaJSObjectResultToNPVariant(java_value->substr(jsobject_n), variant); 886 } else 887 { 888 std::string jobject_id = *java_value; 889 890 JavaRequestProcessor jrequest_processor; 891 JavaResultData* jclassname_result = jrequest_processor.getClassName(jobject_id); 892 893 if (jclassname_result->error_occurred) 784 894 { 785 895 return false; 786 896 } 787 897 788 return_obj_class_name.append(*(java_result->return_string)); 789 790 if (return_obj_class_name == "java.lang.String") 791 { 792 // String is a special case as NPVariant can handle it directly 793 java_result = java_request.getString(return_obj_instance_id); 794 795 if (java_result->error_occurred) 796 { 797 return false; 798 } 799 800 // needs to be on the heap 801 NPUTF8* return_str = (NPUTF8*) malloc(sizeof(NPUTF8)*java_result->return_string->size() + 1); 802 strcpy(return_str, java_result->return_string->c_str()); 803 804 PLUGIN_DEBUG("Method call returned a string: \"%s\"\n", return_str); 805 STRINGZ_TO_NPVARIANT(return_str, *variant); 806 807 } else { 808 809 // Else this is a regular class. Reference the class object so 810 // we can construct an NPObject with it and the instance 811 java_result = java_request.getClassID(return_obj_instance_id); 812 813 if (java_result->error_occurred) 814 { 815 return false; 816 } 817 818 return_obj_class_id.append(*(java_result->return_string)); 819 820 NPObject* obj; 821 822 if (return_obj_class_name.find('[') == 0) // array 823 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( 824 instance, 825 return_obj_class_id, return_obj_instance_id, true); 826 else 827 obj = IcedTeaScriptableJavaPackageObject::get_scriptable_java_object( 828 instance, 829 return_obj_class_id, return_obj_instance_id, false); 830 831 OBJECT_TO_NPVARIANT(obj, *variant); 898 // Special-case for NPString if string 899 if (*jclassname_result->return_string == "java.lang.String") 900 { 901 return javaStringResultToNPVariant(jobject_id, variant); 902 } else // Else this needs a java object wrapper 903 { 904 return javaObjectResultToNPVariant(instance, jobject_id, variant); 832 905 } 833 906 } … … 903 976 IcedTeaPluginUtilities::NPVariantAsString(NPVariant variant) 904 977 { 905 #if MOZILLA_VERSION_COLLAPSED < 1090200906 return std::string(907 NPVARIANT_TO_STRING(variant).utf8characters,908 NPVARIANT_TO_STRING(variant).utf8length);909 #else910 978 return std::string( 911 979 NPVARIANT_TO_STRING(variant).UTF8Characters, 912 980 NPVARIANT_TO_STRING(variant).UTF8Length); 913 #endif914 981 } 915 982 … … 921 988 * @param data Arguments to *func 922 989 */ 990 NPString IcedTeaPluginUtilities::NPStringCopy(const std::string& result) { 991 char* utf8 = (char*)browser_functions.memalloc(result.size() + 1); 992 strncpy(utf8, result.c_str(), result.size() + 1); 993 994 NPString npstr = {utf8, result.size()}; 995 return npstr; 996 } 997 998 NPVariant IcedTeaPluginUtilities::NPVariantStringCopy(const std::string& result) { 999 NPString npstr = NPStringCopy(result); 1000 NPVariant npvar; 1001 STRINGN_TO_NPVARIANT(npstr.UTF8Characters, npstr.UTF8Length, npvar); 1002 return npvar; 1003 } 1004 923 1005 void 924 1006 IcedTeaPluginUtilities::callAndWaitForResult(NPP instance, void (*func) (void *), AsyncCallThreadData* data) … … 993 1075 994 1076 /** 1077 * Returns a vector of gchar* pointing to the elements of the vector string passed in. 1078 * @param stringVec The vector of strings reference. 1079 */ 1080 std::vector<gchar*> 1081 IcedTeaPluginUtilities::vectorStringToVectorGchar(const std::vector<std::string>* stringVec) 1082 { 1083 std::vector<gchar*> charVec; 1084 1085 for (int i = 0; i < stringVec->size(); i++) 1086 { 1087 gchar* element = (gchar*) stringVec->at(i).c_str(); //cast from const char 1088 charVec.push_back(element); 1089 } 1090 charVec.push_back(NULL); 1091 return charVec; 1092 } 1093 1094 /** 995 1095 * Runs through the async call wait queue and executes all calls 996 1096 * … … 1025 1125 } 1026 1126 1127 void IcedTeaPluginUtilities::trim(std::string& str) { 1128 size_t start = str.find_first_not_of(" \t\n"), end = str.find_last_not_of(" \t\n"); 1129 if (start == std::string::npos) { 1130 return; 1131 } 1132 str = str.substr(start, end - start + 1); 1133 } 1134 1135 std::string IcedTeaPluginUtilities::NPIdentifierAsString(NPIdentifier id) { 1136 NPUTF8* cstr = browser_functions.utf8fromidentifier(id); 1137 if (cstr == NULL) { 1138 /* Treat not-existing strings as empty. To tell if it was a valid string, 1139 * use browser_functions.identifierisstring. */ 1140 return std::string(); 1141 } 1142 std::string str = cstr; 1143 browser_functions.memfree(cstr); 1144 return str; 1145 } 1146 1147 bool IcedTeaPluginUtilities::file_exists(std::string filename) 1148 { 1149 std::ifstream infile(filename.c_str()); 1150 return infile.good(); 1151 } 1152 1153 void IcedTeaPluginUtilities::initFileLog(){ 1154 if (plugin_file_log != NULL ) { 1155 //reusing 1156 return; 1157 } 1158 plugin_file_log_name = get_log_dir() + "/" + IcedTeaPluginUtilities::generateLogFileName(); 1159 int plugin_file_log_fd = open(plugin_file_log_name.c_str(), O_WRONLY | O_CREAT | O_EXCL, 0600); 1160 if (plugin_file_log_fd <=0 ) { 1161 plugin_debug_to_file = false; 1162 } else { 1163 plugin_file_log = fdopen(plugin_file_log_fd, "w"); 1164 } 1165 if (plugin_file_log == NULL ) { 1166 plugin_debug_to_file = false; 1167 } 1168 } 1169 1170 1171 1172 std::string IcedTeaPluginUtilities::generateLogFileName(){ 1173 char times[96]; 1174 char result[100]; 1175 time_t t = time(NULL); 1176 struct tm p; 1177 localtime_r(&t, &p); 1178 struct timeval current_time; \ 1179 gettimeofday (¤t_time, NULL);\ 1180 strftime(times, 96, "%Y-%m-%d_%H:%M:%S", &p); 1181 snprintf(result, 100, "%s.%i",times, current_time.tv_usec/1000); 1182 return "itw-cplugin-"+std::string(result)+".log"; 1183 } 1184 1185 void IcedTeaPluginUtilities::printDebugStatus(){ 1186 if (plugin_debug){ 1187 PLUGIN_DEBUG("plugin_debug: true, initialised\n"); 1188 if (plugin_debug_headers){ 1189 PLUGIN_DEBUG("plugin_debug_headers: true\n"); 1190 } else { 1191 PLUGIN_DEBUG("plugin_debug_headers: false\n"); 1192 } 1193 if (plugin_debug_to_file){ 1194 PLUGIN_DEBUG("plugin_debug_to_file: true, using %s\n", plugin_file_log_name.c_str()); 1195 } else { 1196 PLUGIN_DEBUG("plugin_debug_to_file: false\n"); 1197 } 1198 if (plugin_debug_to_streams){ 1199 PLUGIN_DEBUG("plugin_debug_to_streams: true\n"); 1200 } else { 1201 PLUGIN_DEBUG("plugin_debug_to_streams: false\n"); 1202 } 1203 if (plugin_debug_to_system){ 1204 PLUGIN_DEBUG("plugin_debug_to_system: true\n"); 1205 } else { 1206 PLUGIN_DEBUG("plugin_debug_to_system: false\n"); 1207 } 1208 if (plugin_debug_to_console){ 1209 if (debug_pipe_name){ 1210 PLUGIN_DEBUG("plugin_debug_to_console: true, pipe %s\n", debug_pipe_name); 1211 } else { 1212 PLUGIN_DEBUG("plugin_debug_to_console: true, pipe not yet known or broken\n"); 1213 } 1214 } else { 1215 PLUGIN_DEBUG("plugin_debug_to_console: false\n"); 1216 } 1217 } 1218 } 1219 1220 1221 std::string IcedTeaPluginUtilities::getTmpPath(){ 1222 const char* tmpdir_env = getenv("TMPDIR"); 1223 if (tmpdir_env != NULL && g_file_test (tmpdir_env, 1224 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 1225 { 1226 return std::string(tmpdir_env); 1227 } 1228 else if (g_file_test (P_tmpdir, 1229 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 1230 { 1231 return std::string(P_tmpdir); 1232 } 1233 else 1234 { 1235 // If TMPDIR and P_tmpdir do not exist, try /tmp directly 1236 return "/tmp"; 1237 } 1238 } 1239 1240 std::string IcedTeaPluginUtilities::getRuntimePath(){ 1241 const char* rntdir_env = getenv("XDG_RUNTIME_DIR"); 1242 if (rntdir_env != NULL && g_file_test (rntdir_env, 1243 (GFileTest) (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 1244 { 1245 return std::string(rntdir_env); 1246 } 1247 return IcedTeaPluginUtilities::getTmpPath(); 1248 } 1249 1250 1027 1251 /****************************************** 1028 1252 * Begin JavaMessageSender implementation * … … 1160 1384 PLUGIN_DEBUG("%p unlocked...\n", &msg_queue_mutex); 1161 1385 } 1386
Note:
See TracChangeset
for help on using the changeset viewer.