ast: use a human-readable memory number on allocation error 06/21006/2
Clément DAVID [Wed, 12 Jun 2019 08:48:07 +0000 (10:48 +0200)]
Change-Id: Id4ef7ad049e6e2a1e6248ad4b07e5b738f186cec

scilab/modules/ast/includes/types/arrayof.hxx
scilab/modules/ast/src/cpp/types/arrayof.cpp
scilab/modules/ast/src/cpp/types/singlepoly.cpp
scilab/modules/ast/src/cpp/types/string.cpp

index b1433c4..7ffe6b8 100644 (file)
@@ -110,7 +110,9 @@ protected :
                 if (m_iSize != 0 && iTmpSize / m_iSize != m_piDims[i])
                 {
                     char message[bsiz];
-                    os_sprintf(message, _("Can not allocate %.2f MB memory.\n"),  (double) ((double) m_iSize * (double) m_piDims[i] * sizeof(T)) / 1.e6);
+                    char byteString[9];
+                    humanReadableByteCount(((size_t) m_iSize) * ((size_t) m_piDims[i]) * sizeof(T), byteString);
+                    os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
                     throw ast::InternalError(message);
                 }
 
@@ -154,7 +156,9 @@ protected :
         catch (std::bad_alloc & /*e*/)
         {
             char message[bsiz];
-            os_sprintf(message, _("Can not allocate %.2f MB memory.\n"), (double)(m_iSize * sizeof(T)) / 1.e6);
+            char byteString[9];
+            humanReadableByteCount(((size_t) m_iSize) * sizeof(T), byteString);
+            os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
             throw ast::InternalError(message);
         }
 
@@ -502,6 +506,8 @@ public :
 
     virtual bool getMemory(long long* _piSize, long long* _piSizePlusType);
 
+    void humanReadableByteCount(size_t n, char (&str)[9]);
+
     ArrayOf<T>* getColumnValues(int _iPos)
     {
         ArrayOf<T>* pOut = NULL;
index 945b67e..d3c7d99 100644 (file)
@@ -61,6 +61,23 @@ bool ArrayOf<T>::getMemory(long long* _piSize, long long* _piSizePlusType)
 }
 
 template <typename T>
+void ArrayOf<T>::humanReadableByteCount(size_t n, char (&str)[9])
+{
+    double unit = 1024.;
+    if (n < unit)
+    {
+        std::snprintf(str, 9, "%lu B", n);
+        return;
+    }
+
+    int exp = (int) std::log(n) / std::log(unit);
+    char preUnit[] = "kMGTPE";
+    char pre = preUnit[exp - 1];
+
+    std::snprintf(str, 9, "%.1f %cB", n / std::pow(unit, exp), pre);
+}
+
+template <typename T>
 void ArrayOf<T>::getIndexes(int _iIndex, int* _piIndexes)
 {
     getIndexesWithDims(_iIndex, _piIndexes, m_piDims, m_iDims);
@@ -158,15 +175,18 @@ ArrayOf<T>* ArrayOf<T>::insert(typed_list* _pArgs, InternalType* _pSource)
     {
         int *piSourceDims = pSource->getDimsArray();
         int sDims = pSource->getDims();
-        int j=0;
+        int j = 0;
 
-        for (int i=0; i<iDims; i++)
+        for (int i = 0; i < iDims; i++)
         {
-            if (piCountDim[i]==1)
+            if (piCountDim[i] == 1)
             {
                 continue;
             }
-            while (j<sDims && piSourceDims[j]==1) j++;
+            while (j < sDims && piSourceDims[j] == 1)
+            {
+                j++;
+            }
             if (piSourceDims[j] != piCountDim[i])
             {
                 delete[] piCountDim;
@@ -338,18 +358,18 @@ ArrayOf<T>* ArrayOf<T>::insert(typed_list* _pArgs, InternalType* _pSource)
             {
                 bNeedToResize = true;
                 iNewDims = 2;
-                piNewDims = new int[2]{1,1};
+                piNewDims = new int[2] {1, 1};
 
                 if (isScalar() || getSize() == 0)
                 {
                     int *piSourceDims = pSource->getDimsArray();
                     // if source is scalar then resize indexed array as a column vector
                     // otherwise resize with shape of source
-                    piNewDims[(int)(piSourceDims[0] == 1 && pSource->getSize()>1)]=piMaxDim[0];
+                    piNewDims[(int)(piSourceDims[0] == 1 && pSource->getSize() > 1)] = piMaxDim[0];
                 }
                 else // resize with same shape as indexed array
                 {
-                    piNewDims[(int)(getRows() == 1)]=piMaxDim[0];
+                    piNewDims[(int)(getRows() == 1)] = piMaxDim[0];
                 }
             }
         }
@@ -642,9 +662,9 @@ GenericType* ArrayOf<T>::insertNew(typed_list* _pArgs)
                     //by default, replace colon by current source dimension
                     piMaxDim[i] = piSourceDims[iSource];
                     //if there are more index dimensions left than source dimensions left
-                    if (iDims-i > iSourceDims-iSource)
+                    if (iDims - i > iSourceDims - iSource)
                     {
-                        for (int j = i+1; j < iDims - iSourceDims + iSource +1; ++j)
+                        for (int j = i + 1; j < iDims - iSourceDims + iSource + 1; ++j)
                         {
                             //when first explicit index is reached
                             if (pArg[j] != NULL)
@@ -669,7 +689,7 @@ GenericType* ArrayOf<T>::insertNew(typed_list* _pArgs)
                 pArg[i] = createDoubleVector(piMaxDim[i]);
                 --iNbColon;
             }
-            else if (piCountDim[i] == piSourceDims[iSource] && (piCountDim[i]>1 || iNbColon < iSourceDims))
+            else if (piCountDim[i] == piSourceDims[iSource] && (piCountDim[i] > 1 || iNbColon < iSourceDims))
             {
                 ++iSource;
             }
index 9e33a42..6361219 100644 (file)
@@ -117,7 +117,9 @@ double* SinglePoly::allocData(int _iSize)
     catch (std::bad_alloc &/*e*/)
     {
         char message[bsiz];
-        os_sprintf(message, _("Can not allocate %.2f MB memory.\n"),  (double) (_iSize * sizeof(double)) / 1.e6);
+        char byteString[9];
+        humanReadableByteCount(((size_t) m_iSize) * sizeof(double), byteString);
+        os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
         throw ast::InternalError(message);
     }
 
@@ -136,7 +138,7 @@ int SinglePoly::getRank()
 
 double SinglePoly::getDegree()
 {
-    return m_iSize==1 && m_pRealData[0]==0 && (m_pImgData == NULL || m_pImgData[0]==0) ? -INFINITY : m_iSize - 1;
+    return m_iSize == 1 && m_pRealData[0] == 0 && (m_pImgData == NULL || m_pImgData[0] == 0) ? -INFINITY : m_iSize - 1;
 }
 
 bool SinglePoly::setRank(int _iRank, bool bSave)
index a0748ee..a579d61 100644 (file)
@@ -104,10 +104,10 @@ String::String(int _iRows, int _iCols, wchar_t const* const* _pstData)
 
 bool String::getMemory(long long* _piSize, long long* _piSizePlusType)
 {
-    *_piSize = getSize()*sizeof(wchar_t*);
+    *_piSize = getSize() * sizeof(wchar_t*);
     for (int i = 0; i < getSize(); i++)
     {
-        *_piSize += wcslen(get(i))*sizeof(wchar_t);
+        *_piSize += wcslen(get(i)) * sizeof(wchar_t);
     }
     *_piSizePlusType = *_piSize + sizeof(*this);
     return true;
@@ -701,7 +701,9 @@ wchar_t** String::allocData(int _iSize)
     catch (std::bad_alloc & /*e*/)
     {
         char message[bsiz];
-        os_sprintf(message, _("Can not allocate %.2f MB memory.\n"), (double)(_iSize * sizeof(char*)) / 1.e6);
+        char byteString[9];
+        humanReadableByteCount(((size_t) m_iSize) * sizeof(char*), byteString);
+        os_sprintf(message, _("Can not allocate %s memory.\n"), byteString);
         throw ast::InternalError(message);
     }
     return pStr;