Line data Source code
1 : /******************************************************************************* 2 : * Project: libopencad_api.cpp 3 : * Purpose: libOpenCAD OpenSource CAD formats support library 4 : * Author: Alexandr Borzykh, mush3d at gmail.com 5 : * Author: Dmitry Baryshnikov, bishop.dev@gmail.com 6 : * Language: C++ 7 : ******************************************************************************* 8 : * The MIT License (MIT) 9 : * 10 : * Copyright (c) 2016 Alexandr Borzykh 11 : * Copyright (c) 2016-2019 NextGIS, <info@nextgis.com> 12 : * 13 : * Permission is hereby granted, free of charge, to any person obtaining a copy 14 : * of this software and associated documentation files (the "Software"), to deal 15 : * in the Software without restriction, including without limitation the rights 16 : * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 : * copies of the Software, and to permit persons to whom the Software is 18 : * furnished to do so, subject to the following conditions: 19 : * 20 : * The above copyright notice and this permission notice shall be included in all 21 : * copies or substantial portions of the Software. 22 : * 23 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 : * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 : * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 : * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 : * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 : * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 29 : * SOFTWARE. 30 : *******************************************************************************/ 31 : #include "opencad_api.h" 32 : #include "cadfilestreamio.h" 33 : #include "dwg/r2000.h" 34 : 35 : #include <cctype> 36 : #include <cstdarg> 37 : #include <cstdlib> 38 : #include <cstring> 39 : #include <iostream> 40 : 41 : static int gLastError = CADErrorCodes::SUCCESS; 42 : 43 : /** 44 : * @brief Check CAD file 45 : * @param pCADFileIO CAD file reader pointer owned by function 46 : * @return returns and int, 0 if CAD file has unsupported format 47 : */ 48 18 : static int CheckCADFile(CADFileIO * pCADFileIO) 49 : { 50 18 : if( pCADFileIO == nullptr ) 51 0 : return 0; 52 : 53 : #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(OPENCAD_DISABLE_EXTENSION_CHECK) 54 18 : const char * pszFilePath = pCADFileIO->GetFilePath(); 55 18 : size_t nPathLen = strlen( pszFilePath ); 56 : 57 18 : if( nPathLen > 3 && 58 18 : toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 3]) ) == 'D' && 59 18 : toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 2]) ) == 'X' && 60 0 : toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 1]) ) == 'F' ) 61 : { 62 : //TODO: "AutoCAD Binary DXF" 63 : //std::cerr << "DXF ASCII and binary is not supported yet."; 64 0 : return 0; 65 : } 66 18 : if( ! ( nPathLen > 3 && 67 18 : toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 3]) ) == 'D' && 68 18 : toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 2]) ) == 'W' && 69 18 : toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 1]) ) == 'G' ) ) 70 : { 71 0 : return 0; 72 : } 73 : #endif 74 : 75 18 : if( !pCADFileIO->IsOpened() ) 76 9 : pCADFileIO->Open( CADFileIO::OpenMode::in | CADFileIO::OpenMode::binary ); 77 18 : if( !pCADFileIO->IsOpened() ) 78 0 : return 0; 79 : 80 18 : char pabyDWGVersion[DWG_VERSION_STR_SIZE + 1] = { 0 }; 81 18 : pCADFileIO->Rewind (); 82 18 : pCADFileIO->Read( pabyDWGVersion, DWG_VERSION_STR_SIZE ); 83 18 : return atoi( pabyDWGVersion + 2 ); 84 : } 85 : 86 : /** 87 : * @brief Open CAD file 88 : * @param pCADFileIO CAD file reader pointer ownd by function 89 : * @param eOptions Open options 90 : * @param bReadUnsupportedGeometries Unsupported geoms will be returned as CADUnknown 91 : * @return CADFile pointer or NULL if failed. The pointer have to be freed by user 92 : */ 93 9 : CADFile * OpenCADFile( CADFileIO * pCADFileIO, enum CADFile::OpenOptions eOptions, bool bReadUnsupportedGeometries ) 94 : { 95 9 : int nCADFileVersion = CheckCADFile( pCADFileIO ); 96 9 : CADFile * poCAD = nullptr; 97 : 98 9 : switch( nCADFileVersion ) 99 : { 100 8 : case CADVersions::DWG_R2000: 101 8 : poCAD = new DWGFileR2000( pCADFileIO ); 102 8 : break; 103 1 : default: 104 1 : gLastError = CADErrorCodes::UNSUPPORTED_VERSION; 105 1 : delete pCADFileIO; 106 1 : return nullptr; 107 : } 108 : 109 8 : gLastError = poCAD->ParseFile( eOptions, bReadUnsupportedGeometries ); 110 8 : if( gLastError != CADErrorCodes::SUCCESS ) 111 : { 112 0 : delete poCAD; 113 0 : return nullptr; 114 : } 115 : 116 8 : return poCAD; 117 : } 118 : 119 : 120 : /** 121 : * @brief Get library version number as major * 10000 + minor * 100 + rev 122 : * @return library version number 123 : */ 124 0 : int GetVersion() 125 : { 126 0 : return OCAD_VERSION_NUM; 127 : } 128 : 129 : /** 130 : * @brief Get library version string 131 : * @return library version string 132 : */ 133 1 : const char * GetVersionString() 134 : { 135 1 : return OCAD_VERSION; 136 : } 137 : 138 : /** 139 : * @brief Get last error code 140 : * @return last error code 141 : */ 142 30 : int GetLastErrorCode() 143 : { 144 30 : return gLastError; 145 : } 146 : 147 : /** 148 : * @brief GetDefaultFileIO return default file in/out class. 149 : * @param pszFileName CAD file path 150 : * @return CADFileIO pointer or null if error. The pointer have to be freed by 151 : * user 152 : */ 153 0 : CADFileIO* GetDefaultFileIO( const char * pszFileName ) 154 : { 155 0 : return new CADFileStreamIO( pszFileName ); 156 : } 157 : 158 : /** 159 : * @brief IdentifyCADFile 160 : * @param pCADFileIO pointer to file in/out class 161 : * @return positive number for dwg version, negative for dxf version, 0 if error 162 : * occurred 163 : */ 164 9 : int IdentifyCADFile( CADFileIO * pCADFileIO, bool bOwn ) 165 : { 166 9 : int result = CheckCADFile(pCADFileIO); 167 9 : if(bOwn) 168 : { 169 0 : delete pCADFileIO; 170 : } 171 9 : return result; 172 : } 173 : 174 : /** 175 : * @brief List supported CAD Formats 176 : * @return String describes supported CAD formats 177 : */ 178 1 : const char * GetCADFormats() 179 : { 180 1 : return "DWG R2000 [ACAD1015]\n"; 181 : } 182 : 183 : /** 184 : * @brief Open CAD file 185 : * @param pszFileName Path to CAD file 186 : * @param eOptions Open options 187 : * @return CADFile pointer or NULL if failed. The pointer have to be freed by user. 188 : */ 189 0 : CADFile * OpenCADFile( const char * pszFileName, enum CADFile::OpenOptions eOptions, bool bReadUnsupportedGeometries ) 190 : { 191 0 : return OpenCADFile( GetDefaultFileIO( pszFileName ), eOptions, bReadUnsupportedGeometries ); 192 : } 193 : 194 : #ifdef _DEBUG 195 : void DebugMsg( const char* format, ... ) 196 : #else 197 251 : void DebugMsg( const char*, ... ) 198 : #endif 199 : { 200 : #ifdef _DEBUG 201 : va_list argptr; 202 : va_start( argptr, format ); 203 : vfprintf( stdout, format, argptr ); 204 : va_end( argptr ); 205 : #endif //_DEBUG 206 251 : }