Fix memory leaks found by coverity (CID 1098781 & 1098880)
[scilab.git] / scilab / modules / external_objects_java / src / cpp / ScilabJavaEnvironment.cpp
index 6499ed2..fea094e 100644 (file)
@@ -23,6 +23,7 @@
 #include "ScilabJavaObject.hxx"
 #include "ScilabJavaArray.hxx"
 #include "ScilabJavaCompiler.hxx"
+#include "ScilabOperations.hxx"
 #include "NoMoreScilabMemoryException.hxx"
 #include "ScilabAutoCleaner.hxx"
 
@@ -46,44 +47,25 @@ ScilabJavaEnvironment::ScilabJavaEnvironment() :
     wrapper(*new ScilabJavaEnvironmentWrapper(helper)),
     traceEnabled(false),
     isInit(false),
-    scilabStream(*new ScilabStream()),
-    file(0) { }
+    scilabStream(*new ScilabStream()) { }
 
-//    ScilabJavaEnvironment::ScilabJavaEnvironment() {}
 ScilabJavaEnvironment::~ScilabJavaEnvironment()
 {
     //    delete &scope;
     delete &helper;
     delete &gwOptions;
     delete &wrapper;
-
-    if (file)
-    {
-        file->flush();
-        file->close();
-        delete file;
-        file = 0;
-    }
 }
 
 int ScilabJavaEnvironment::start()
 {
-    /*    if (!usable)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Due to Java interpreter limitations, Scilab must be restarted"));
-            }*/
-
     if (envId == -1)
     {
         instance = new ScilabJavaEnvironment();
         envId = ScilabEnvironments::registerScilabEnvironment(instance);
         instance->Initialize();
-        /*        ScilabJavaOStream::initJavaStreams();
-                ScilabJavaOStream::setStdOutStream(&instance->scilabStream);
-                ScilabJavaOStream::setStdErrStream(&instance->scilabStream);*/
         instance->helper.setUseLastName(true);
         instance->helper.setNewAllowed(true);
-        instance->enabletrace((std::string(getTMPDIR()) + std::string("/eo_java.log")).c_str());
     }
 
     return envId;
@@ -95,9 +77,9 @@ void ScilabJavaEnvironment::finish()
     {
         ScilabEnvironments::unregisterScilabEnvironment(envId);
         envId = -1;
+        instance->Finalize();
         delete instance;
         instance = 0;
-        instance->Finalize();
         usable = false;
     }
 }
@@ -138,31 +120,18 @@ const std::string & ScilabJavaEnvironment::getEnvironmentName()
 
 void ScilabJavaEnvironment::getEnvironmentInfos(const ScilabStringStackAllocator & allocator)
 {
+    JavaVM * vm = getScilabJavaVM();
+    int len;
+    char ** info = ScilabJavaObject::getInfos(vm, &len);
 
-    /*
-        std::vector<char *> version = breakInLines(std::string(Py_GetVersion()));
-        std::vector<char *> platform = breakInLines(std::string(Py_GetPlatform()));
-        std::vector<char *> copyright = breakInLines(std::string(Py_GetCopyright()));
-        std::vector<char *> compiler = breakInLines(std::string(Py_GetCompiler()));
-        std::vector<char *> buildInfo = breakInLines(std::string(Py_GetBuildInfo()));
-
-        int nbRows = version.size() + platform.size() + copyright.size() + compiler.size() + buildInfo.size();
-
-        std::vector<char *> all(nbRows, const_cast<char* >(""));
-        all[0] = const_cast<char* >("Version");
-        all[version.size()] = const_cast<char* >("Platform");
-        all[version.size() + platform.size()] = const_cast<char* >("Copyright");
-        all[version.size() + platform.size() + copyright.size()] = const_cast<char* >("Compiler");
-        all[version.size() + platform.size() + copyright.size() + compiler.size()] = const_cast<char* >("Build info");
+    allocator.allocate(len, 1, info);
 
-        all.insert(all.end(), version.begin(), version.end());
-        all.insert(all.end(), platform.begin(), platform.end());
-        all.insert(all.end(), copyright.begin(), copyright.end());
-        all.insert(all.end(), compiler.begin(), compiler.end());
-        all.insert(all.end(), buildInfo.begin(), buildInfo.end());
+    for (int i = 0; i < len; i++)
+    {
+        delete[] info[i];
+    }
 
-        allocator.allocate(nbRows, 2, &(all[0]));
-    */
+    delete[] info;
 }
 
 int ScilabJavaEnvironment::extract(int id, int * args, int argsSize)
@@ -177,99 +146,24 @@ int ScilabJavaEnvironment::extract(int id, int * args, int argsSize)
 
 void ScilabJavaEnvironment::insert(int id, int * args, int argsSize)
 {
-    /*
-        PyObject * obj = scope.getObject(id);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid object with id %d"), id);
-        }
-
-        if (argsSize != 2)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert more than one element in a dictionary"));
-        }
-
-        PyObject * key = scope.getObject(args[0]);
-        if (!obj)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object"));
-        }
-
-        PyObject * value = scope.getObject(args[1]);
-        if (!value)
-        {
-            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid value object"));
-        }
-
-        if (PyDict_Check(obj))
-        {
-            PyDict_SetItem(obj, key, value);
-
-            writeLog("insert", "success.");
-
-            return;
-        }
-        else
-        {
-            if (!PyString_Check(key))
-            {
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid key object: A string expected"));
-            }
-
-            int ret = PyObject_SetAttr(obj, key, value);
-            if (ret == -1)
-            {
-                if (PyErr_Occurred())
-                {
-                    PyObject *type, *value, *traceback;
-                    PyErr_Fetch(&type, &value, &traceback);
-                    PyErr_NormalizeException(&type, &value, &traceback);
-                    PyErr_Clear();
-
-                    throw ScilabJavaException(__LINE__, __FILE__, type, value, traceback, gettext("Cannot evaluate the code"));
-                }
-                throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot set the attribute."));
-            }
-
-            writeLog("insert", "success.");
-
-            return;
-        }
-    */
-    throw ScilabJavaException(__LINE__, __FILE__, gettext("Cannot insert in Java object"));
+    JavaVM * vm = getScilabJavaVM();
+    ScilabJavaObject::insert(vm, id, args, argsSize - 1, args[argsSize - 1]);
 }
 
-void ScilabJavaEnvironment::garbagecollect() { }
+void ScilabJavaEnvironment::garbagecollect()
+{
+    JavaVM *vm = getScilabJavaVM();
+    ScilabJavaObject::garbageCollect(vm);
+}
 
 void ScilabJavaEnvironment::addtoclasspath(const char * path)
 {
-    /*
-        PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
-        PyObject * _path = PyString_FromString(path);
-        PyList_Append(syspath, _path);
-    */
+    // Useless: we already have javaclasspath
 }
 
 void ScilabJavaEnvironment::getclasspath(const ScilabStringStackAllocator & allocator)
 {
-    /*
-        PyObject * syspath = PySys_GetObject(const_cast<char *>("path"));
-        int size = PyList_Size(syspath);
-        char ** arr = new char*[size];
-
-        for (int i = 0; i < size; i++)
-        {
-            PyObject * item = PyList_GetItem(syspath, i);
-            arr[i] = strdup(PyString_AsString(item));
-        }
-
-        allocator.allocate(size, 1, arr);
-        for (int i = 0; i < size; i++)
-        {
-            free(arr[i]);
-        }
-        delete arr;
-    */
+    // Useless: we already have javaclasspath
 }
 
 void ScilabJavaEnvironment::addNamedVariable(int id, const char * varName)
@@ -339,9 +233,24 @@ int ScilabJavaEnvironment::newinstance(int id, int * args, int argsSize)
 
 int ScilabJavaEnvironment::operation(int idA, int idB, const OperatorsType type)
 {
-    // TODO: plug String concatenation and maybe others things like operations on double, int, ...
+    JavaVM *vm = getScilabJavaVM();
+    int ret;
 
-    return 0;
+    switch (type)
+    {
+        case Add :
+            ret = ScilabOperations::add(vm, idA, idB);
+            break;
+        default :
+            throw ScilabJavaException(__LINE__, __FILE__, gettext("Invalid operation"));
+    }
+
+    if (ret != 0 && ret != -1)
+    {
+        ScilabAutoCleaner::registerVariable(envId, ret);
+    }
+
+    return ret;
 }
 
 int * ScilabJavaEnvironment::invoke(int id, const char * methodName, int * args, int argsSize)
@@ -354,7 +263,10 @@ int * ScilabJavaEnvironment::invoke(int id, const char * methodName, int * args,
     invokedId[0] = 1 ; //1 object returned
     invokedId[1] = ScilabJavaObject::invoke(vm, id, methodName, args, argsSize);
 
-    ScilabAutoCleaner::registerVariable(envId, invokedId[1]);
+    if (invokedId[1] != 0 && invokedId[1] != -1)
+    {
+        ScilabAutoCleaner::registerVariable(envId, invokedId[1]);
+    }
 
     return invokedId;
 }
@@ -441,6 +353,20 @@ void ScilabJavaEnvironment::removeobject(int id)
     ScilabAutoCleaner::unregisterVariable(envId, id);
 }
 
+void ScilabJavaEnvironment::removeobject(const int * id, const int length)
+{
+    if (length == 1)
+    {
+        removeobject(*id);
+    }
+    else
+    {
+        JavaVM *vm = getScilabJavaVM();
+        ScilabJavaObject::removeScilabJavaObject(vm, id, length);
+        ScilabAutoCleaner::unregisterVariable(envId, id, length);
+    }
+}
+
 void ScilabJavaEnvironment::autoremoveobject(int id)
 {
     JavaVM *vm = getScilabJavaVM();
@@ -470,7 +396,9 @@ std::vector<std::string> ScilabJavaEnvironment::getCompletion(int id, char ** fi
     for (int i = 0; i < len; i++)
     {
         v.push_back(fields[i]);
+        delete fields[i];
     }
+    delete fields;
 
     return v;
 }
@@ -488,17 +416,13 @@ VariableType ScilabJavaEnvironment::isunwrappable(int id)
 
 int ScilabJavaEnvironment::compilecode(char * className, char ** code, int size)
 {
-    std::ostringstream os;
-    for (int i = 0; i < size; i++)
-    {
-        os << code[i] << std::endl;
-    }
-    os.flush();
-
     JavaVM *vm = getScilabJavaVM();
     const int ret = ScilabJavaCompiler::compileCode(vm, className, code, size);
 
-    ScilabAutoCleaner::registerVariable(envId, ret);
+    if (ret != 0 && ret != -1)
+    {
+        ScilabAutoCleaner::registerVariable(envId, ret);
+    }
 
     return ret;
 }