Ignore:
Timestamp:
Sep 24, 2014, 9:34:21 PM (11 years ago)
Author:
dmik
Message:

icedtea-web: Merge version 1.5.1 from vendor to trunk.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/icedtea-web/plugin/icedteanp/IcedTeaPluginUtils.cc

    r418 r429  
    4444#include "IcedTeaScriptablePluginObject.h"
    4545#include "IcedTeaPluginUtils.h"
     46#include <fstream>
    4647
    4748/**
     
    5859std::map<void*, NPP>* IcedTeaPluginUtilities::instance_map = new std::map<void*, NPP>();
    5960std::map<std::string, NPObject*>* IcedTeaPluginUtilities::object_map = new std::map<std::string, NPObject*>();
     61std::queue<std::string> pre_jvm_message;
    6062
    6163/* Plugin async call queue */
    6264static std::vector< PluginThreadCall* >* pendingPluginThreadRequests = new std::vector< PluginThreadCall* >();
     65
     66void *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
     86void 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
     92void reset_pre_init_messages(){
     93    pre_jvm_message = std::queue<std::string>();
     94  }
    6395
    6496/**
     
    403435        wchar_t c;
    404436
    405         if (plugin_debug) printf("Converted UTF-16LE string: ");
     437        PLUGIN_DEBUG("Converted UTF-16LE string: \n");
    406438
    407439        result_unicode_str->clear();
     
    417449                (c >= '0' && c <= '9'))
    418450        {
    419                 if (plugin_debug) printf("%c", c);
     451                PLUGIN_DEBUG("%c\n", c);
    420452        }
    421453
     
    424456
    425457        // 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());
    427459}
    428460
     
    502534}
    503535
     536/* Clear instance_map. Useful for tests. */
     537void
     538IcedTeaPluginUtilities::clearInstanceIDs()
     539{
     540    delete instance_map;
     541    instance_map = new std::map<void*, NPP>();
     542}
     543
    504544/**
    505545 * Removes all mappings to a given instance, and all associated objects
     
    605645    PLUGIN_DEBUG("Removing key %s from object map\n", key.c_str());
    606646    object_map->erase(key);
     647}
     648
     649/* Clear object_map. Useful for tests. */
     650void
     651IcedTeaPluginUtilities::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*>();
    607659}
    608660
     
    720772}
    721773
     774/**
     775 * Convert either a void, boolean, or a number
     776 */
     777static void
     778javaPrimitiveResultToNPVariant(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
     814static bool
     815javaStringResultToNPVariant(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
     834static bool
     835javaJSObjectResultToNPVariant(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
     842static bool
     843javaObjectResultToNPVariant(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
    722873bool
    723874IcedTeaPluginUtilities::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)
    784894        {
    785895            return false;
    786896        }
    787897
    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);
    832905        }
    833906    }
     
    903976IcedTeaPluginUtilities::NPVariantAsString(NPVariant variant)
    904977{
    905 #if MOZILLA_VERSION_COLLAPSED < 1090200
    906   return std::string(
    907     NPVARIANT_TO_STRING(variant).utf8characters,
    908     NPVARIANT_TO_STRING(variant).utf8length);
    909 #else
    910978  return std::string(
    911979    NPVARIANT_TO_STRING(variant).UTF8Characters,
    912980    NPVARIANT_TO_STRING(variant).UTF8Length);
    913 #endif
    914981}
    915982
     
    921988 * @param data Arguments to *func
    922989 */
     990NPString 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
     998NPVariant 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
    9231005void
    9241006IcedTeaPluginUtilities::callAndWaitForResult(NPP instance, void (*func) (void *), AsyncCallThreadData* data)
     
    9931075
    9941076/**
     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 */
     1080std::vector<gchar*>
     1081IcedTeaPluginUtilities::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/**
    9951095 * Runs through the async call wait queue and executes all calls
    9961096 *
     
    10251125}
    10261126
     1127void 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
     1135std::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
     1147bool IcedTeaPluginUtilities::file_exists(std::string filename)
     1148{
     1149    std::ifstream infile(filename.c_str());
     1150    return infile.good();
     1151}
     1152
     1153void 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
     1172std::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 (&current_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
     1185void 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
     1221std::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
     1240std::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
    10271251/******************************************
    10281252 * Begin JavaMessageSender implementation *
     
    11601384    PLUGIN_DEBUG("%p unlocked...\n", &msg_queue_mutex);
    11611385}
     1386
Note: See TracChangeset for help on using the changeset viewer.