/src/gdal/ogr/ogrsf_frmts/cad/libopencad/opencad.cpp
Line | Count | Source |
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 | | * SPDX-License-Identifier: MIT |
14 | | *******************************************************************************/ |
15 | | #include "opencad_api.h" |
16 | | #include "cadfilestreamio.h" |
17 | | #include "dwg/r2000.h" |
18 | | |
19 | | #include <cctype> |
20 | | #include <cstdarg> |
21 | | #include <cstdlib> |
22 | | #include <cstring> |
23 | | #include <iostream> |
24 | | |
25 | | static int gLastError = CADErrorCodes::SUCCESS; |
26 | | |
27 | | /** |
28 | | * @brief Check CAD file |
29 | | * @param pCADFileIO CAD file reader pointer owned by function |
30 | | * @return returns and int, 0 if CAD file has unsupported format |
31 | | */ |
32 | | static int CheckCADFile(CADFileIO * pCADFileIO) |
33 | 14.0k | { |
34 | 14.0k | if( pCADFileIO == nullptr ) |
35 | 0 | return 0; |
36 | | |
37 | | #if !defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) && !defined(OPENCAD_DISABLE_EXTENSION_CHECK) |
38 | | const char * pszFilePath = pCADFileIO->GetFilePath(); |
39 | | size_t nPathLen = strlen( pszFilePath ); |
40 | | |
41 | | if( nPathLen > 3 && |
42 | | toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 3]) ) == 'D' && |
43 | | toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 2]) ) == 'X' && |
44 | | toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 1]) ) == 'F' ) |
45 | | { |
46 | | //TODO: "AutoCAD Binary DXF" |
47 | | //std::cerr << "DXF ASCII and binary is not supported yet."; |
48 | | return 0; |
49 | | } |
50 | | if( ! ( nPathLen > 3 && |
51 | | toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 3]) ) == 'D' && |
52 | | toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 2]) ) == 'W' && |
53 | | toupper( static_cast<unsigned char>(pszFilePath[nPathLen - 1]) ) == 'G' ) ) |
54 | | { |
55 | | return 0; |
56 | | } |
57 | | #endif |
58 | | |
59 | 14.0k | if( !pCADFileIO->IsOpened() ) |
60 | 7.01k | pCADFileIO->Open( CADFileIO::OpenMode::in | CADFileIO::OpenMode::binary ); |
61 | 14.0k | if( !pCADFileIO->IsOpened() ) |
62 | 0 | return 0; |
63 | | |
64 | 14.0k | char pabyDWGVersion[DWG_VERSION_STR_SIZE + 1] = { 0 }; |
65 | 14.0k | pCADFileIO->Rewind (); |
66 | 14.0k | pCADFileIO->Read( pabyDWGVersion, DWG_VERSION_STR_SIZE ); |
67 | 14.0k | return atoi( pabyDWGVersion + 2 ); |
68 | 14.0k | } |
69 | | |
70 | | /** |
71 | | * @brief Open CAD file |
72 | | * @param pCADFileIO CAD file reader pointer ownd by function |
73 | | * @param eOptions Open options |
74 | | * @param bReadUnsupportedGeometries Unsupported geoms will be returned as CADUnknown |
75 | | * @return CADFile pointer or NULL if failed. The pointer have to be freed by user |
76 | | */ |
77 | | CADFile * OpenCADFile( CADFileIO * pCADFileIO, enum CADFile::OpenOptions eOptions, bool bReadUnsupportedGeometries ) |
78 | 7.00k | { |
79 | 7.00k | int nCADFileVersion = CheckCADFile( pCADFileIO ); |
80 | 7.00k | CADFile * poCAD = nullptr; |
81 | | |
82 | 7.00k | switch( nCADFileVersion ) |
83 | 7.00k | { |
84 | 6.97k | case CADVersions::DWG_R2000: |
85 | 6.97k | poCAD = new DWGFileR2000( pCADFileIO ); |
86 | 6.97k | break; |
87 | 35 | default: |
88 | 35 | gLastError = CADErrorCodes::UNSUPPORTED_VERSION; |
89 | 35 | delete pCADFileIO; |
90 | 35 | return nullptr; |
91 | 7.00k | } |
92 | | |
93 | 6.97k | gLastError = poCAD->ParseFile( eOptions, bReadUnsupportedGeometries ); |
94 | 6.97k | if( gLastError != CADErrorCodes::SUCCESS ) |
95 | 5.17k | { |
96 | 5.17k | delete poCAD; |
97 | 5.17k | return nullptr; |
98 | 5.17k | } |
99 | | |
100 | 1.79k | return poCAD; |
101 | 6.97k | } |
102 | | |
103 | | |
104 | | /** |
105 | | * @brief Get library version number as major * 10000 + minor * 100 + rev |
106 | | * @return library version number |
107 | | */ |
108 | | int GetVersion() |
109 | 0 | { |
110 | 0 | return OCAD_VERSION_NUM; |
111 | 0 | } |
112 | | |
113 | | /** |
114 | | * @brief Get library version string |
115 | | * @return library version string |
116 | | */ |
117 | | const char * GetVersionString() |
118 | 5.20k | { |
119 | 5.20k | return OCAD_VERSION; |
120 | 5.20k | } |
121 | | |
122 | | /** |
123 | | * @brief Get last error code |
124 | | * @return last error code |
125 | | */ |
126 | | int GetLastErrorCode() |
127 | 20.4k | { |
128 | 20.4k | return gLastError; |
129 | 20.4k | } |
130 | | |
131 | | /** |
132 | | * @brief GetDefaultFileIO return default file in/out class. |
133 | | * @param pszFileName CAD file path |
134 | | * @return CADFileIO pointer or null if error. The pointer have to be freed by |
135 | | * user |
136 | | */ |
137 | | CADFileIO* GetDefaultFileIO( const char * pszFileName ) |
138 | 0 | { |
139 | 0 | return new CADFileStreamIO( pszFileName ); |
140 | 0 | } |
141 | | |
142 | | /** |
143 | | * @brief IdentifyCADFile |
144 | | * @param pCADFileIO pointer to file in/out class |
145 | | * @return positive number for dwg version, negative for dxf version, 0 if error |
146 | | * occurred |
147 | | */ |
148 | | int IdentifyCADFile( CADFileIO * pCADFileIO, bool bOwn ) |
149 | 7.01k | { |
150 | 7.01k | int result = CheckCADFile(pCADFileIO); |
151 | 7.01k | if(bOwn) |
152 | 0 | { |
153 | 0 | delete pCADFileIO; |
154 | 0 | } |
155 | 7.01k | return result; |
156 | 7.01k | } |
157 | | |
158 | | /** |
159 | | * @brief List supported CAD Formats |
160 | | * @return String describes supported CAD formats |
161 | | */ |
162 | | const char * GetCADFormats() |
163 | 5.20k | { |
164 | 5.20k | return "DWG R2000 [ACAD1015]\n"; |
165 | 5.20k | } |
166 | | |
167 | | /** |
168 | | * @brief Open CAD file |
169 | | * @param pszFileName Path to CAD file |
170 | | * @param eOptions Open options |
171 | | * @return CADFile pointer or NULL if failed. The pointer have to be freed by user. |
172 | | */ |
173 | | CADFile * OpenCADFile( const char * pszFileName, enum CADFile::OpenOptions eOptions, bool bReadUnsupportedGeometries ) |
174 | 0 | { |
175 | 0 | return OpenCADFile( GetDefaultFileIO( pszFileName ), eOptions, bReadUnsupportedGeometries ); |
176 | 0 | } |
177 | | |
178 | | #ifdef _DEBUG |
179 | | void DebugMsg( const char* format, ... ) |
180 | | #else |
181 | | void DebugMsg( const char*, ... ) |
182 | | #endif |
183 | 1.20M | { |
184 | | #ifdef _DEBUG |
185 | | va_list argptr; |
186 | | va_start( argptr, format ); |
187 | | vfprintf( stdout, format, argptr ); |
188 | | va_end( argptr ); |
189 | | #endif //_DEBUG |
190 | 1.20M | } |