Explorar o código

Add ai_str_toprintable; fixed garbage messages in HMP, MDL, Q3D loaders.

- ai_str_toprintable: See docs in StringUtils.h.
- HMP, MDL, Q3D: In particular, newlines in binary data were complicating logging.
Jason C %!s(int64=4) %!d(string=hai) anos
pai
achega
a9fb1e56ae

+ 2 - 6
code/AssetLib/HMP/HMPLoader.cpp

@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #include "AssetLib/HMP/HMPLoader.h"
 #include "AssetLib/MD2/MD2FileData.h"
 
+#include <assimp/StringUtils.h>
 #include <assimp/importerdesc.h>
 #include <assimp/scene.h>
 #include <assimp/DefaultLogger.hpp>
@@ -151,12 +152,7 @@ void HMPImporter::InternReadFile(const std::string &pFile,
         InternReadFile_HMP7();
     } else {
         // Print the magic word to the logger
-        char szBuffer[5];
-        szBuffer[0] = ((char *)&iMagic)[0];
-        szBuffer[1] = ((char *)&iMagic)[1];
-        szBuffer[2] = ((char *)&iMagic)[2];
-        szBuffer[3] = ((char *)&iMagic)[3];
-        szBuffer[4] = '\0';
+        std::string szBuffer = ai_str_toprintable((const char *)&iMagic, sizeof(iMagic));
     
         delete[] mBuffer;
         mBuffer = nullptr;

+ 1 - 1
code/AssetLib/MDL/MDLLoader.cpp

@@ -252,7 +252,7 @@ void MDLImporter::InternReadFile(const std::string &pFile,
         } else {
             // print the magic word to the log file
             throw DeadlyImportError("Unknown MDL subformat ", pFile,
-                                    ". Magic word (", std::string((char *)&iMagicWord, 4), ") is not known");
+                                    ". Magic word (", ai_str_toprintable((const char *)&iMagicWord, sizeof(iMagicWord)), ") is not known");
         }
 
         // Now rotate the whole scene 90 degrees around the x axis to convert to internal coordinate system

+ 2 - 1
code/AssetLib/Q3D/Q3DLoader.cpp

@@ -47,6 +47,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 // internal headers
 #include "Q3DLoader.h"
+#include <assimp/StringUtils.h>
 #include <assimp/StreamReader.h>
 #include <assimp/fast_atof.h>
 #include <assimp/importerdesc.h>
@@ -115,7 +116,7 @@ void Q3DImporter::InternReadFile(const std::string &pFile,
     // Check the file's signature
     if (ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Do", 8) &&
             ASSIMP_strincmp((const char *)stream.GetPtr(), "quick3Ds", 8)) {
-        throw DeadlyImportError("Not a Quick3D file. Signature string is: ", std::string((const char *)stream.GetPtr(), 8));
+        throw DeadlyImportError("Not a Quick3D file. Signature string is: ", ai_str_toprintable((const char *)stream.GetPtr(), 8));
     }
 
     // Print the file format version

+ 27 - 0
include/assimp/StringUtils.h

@@ -249,4 +249,31 @@ AI_FORCE_INLINE std::string ai_str_toupper(const std::string &in) {
     return out;
 }
 
+// ---------------------------------------------------------------------------------
+/// @brief  Make a string printable by replacing all non-printable characters with
+///         the specified placeholder character.
+/// @param  in  The incoming string.
+/// @param  placeholder  Placeholder character, default is a question mark.
+/// @return The string, with all non-printable characters replaced.
+AI_FORCE_INLINE std::string ai_str_toprintable(const std::string &in, char placeholder = '?') {
+    std::string out(in);
+    std::transform(out.begin(), out.end(), out.begin(), [placeholder] (unsigned char c) {
+        return isprint(c) ? (char)c :  placeholder;
+    });
+    return out;
+}
+
+// ---------------------------------------------------------------------------------
+/// @brief  Make a string printable by replacing all non-printable characters with
+///         the specified placeholder character.
+/// @param  in  The incoming string.
+/// @param  len The length of the incoming string.
+/// @param  placeholder  Placeholder character, default is a question mark.
+/// @return The string, with all non-printable characters replaced. Will return an
+///         empty string if in is null or len is <= 0.
+AI_FORCE_INLINE std::string ai_str_toprintable(const char *in, int len, char placeholder = '?') {
+    return (in && len > 0) ? ai_str_toprintable(std::string(in, len), placeholder) : std::string();
+}
+
+
 #endif