Port set version bug from solvespace fork and cleanup version handling in DRW_TextCodec.

One of the most intrusive changes in QGIS' fork was that the debugging code was replaced with hardcoded changes to redirect the output to QGIS' internal logging mechanism. In this PR I've setup an interface to allow clients to create custom output debugging classes and assign these to be used by the library.

This will allow me to remove all the related downstream changes in QGIS' fork and re-sync these files back to upstream.
Interface for debug printers.
This commit is contained in:
Roman Telezhynskyi 2021-11-23 13:11:56 +02:00
parent a8d8fa0946
commit 6a219c5ed4
7 changed files with 189 additions and 71 deletions

View File

@ -0,0 +1,19 @@
/******************************************************************************
** libDXFrw - Library to read/write DXF files (ascii & binary) **
** **
** Copyright (C) 2011-2015 José F. Soriano, rallazz@gmail.com **
** **
** This library is free software, licensed under the terms of the GNU **
** General Public License as published by the Free Software Foundation, **
** either version 2 of the License, or (at your option) any later version. **
** You should have received a copy of the GNU General Public License **
** along with this program. If not, see <http://www.gnu.org/licenses/>. **
******************************************************************************/
#include "drw_base.h"
#include "intern/drw_dbg.h"
void DRW::setCustomDebugPrinter(DebugPrinter *printer)
{
DRW_dbg::getInstance()->setCustomDebugPrinter(std::unique_ptr<DebugPrinter>(printer));
}

View File

@ -18,6 +18,7 @@
#include <string>
#include <list>
#include <cmath>
#include <unordered_map>
#include <QtGlobal>
#include <ciso646>
@ -100,16 +101,46 @@ namespace DRW {
//! Version numbers for the DXF Format.
enum Version {
UNKNOWNV, /*!< UNKNOWN VERSION. */
AC1006, /*!< R10. */
AC1009, /*!< R11 & R12. */
AC1012, /*!< R13. */
AC1014, /*!< R14. */
AC1015, /*!< ACAD 2000. */
AC1018, /*!< ACAD 2004. */
AC1021, /*!< ACAD 2007. */
AC1024, /*!< ACAD 2010. */
AC1027 /*!< ACAD 2013. */
UNKNOWNV, //!< UNKNOWN VERSION.
MC00, //!< DWG Release 1.1
AC12, //!< DWG Release 1.2
AC14, //!< DWG Release 1.4
AC150, //!< DWG Release 2.0
AC210, //!< DWG Release 2.10
AC1002, //!< DWG Release 2.5
AC1003, //!< DWG Release 2.6
AC1004, //!< DWG Relase 9
AC1006, //!< DWG Release 10 (R10)
AC1009, //!< DWG Release 11/12 (LT R1/R2) (R11 & R12)
AC1012, //!< DWG Release 13 (LT95) (R13)
AC1014, //!< DWG Release 14/14.01 (LT97/LT98) (R14)
AC1015, //!< AutoCAD 2000/2000i/2002 (ACAD 2000)
AC1018, //!< AutoCAD 2004/2005/2006 (ACAD 2004)
AC1021, //!< AutoCAD 2007/2008/2009 (ACAD 2007)
AC1024, //!< AutoCAD 2010/2011/2012 (ACAD 2010)
AC1027, //!< AutoCAD 2013/2014/2015/2016/2017 (ACAD 2013)
AC1032, //!< AutoCAD 2018/2019/2020 (ACAD 2018)
};
const std::unordered_map< const char*, DRW::Version > dwgVersionStrings {
{ "MC0.0", DRW::MC00 },
{ "AC1.2", DRW::AC12 },
{ "AC1.4", DRW::AC14 },
{ "AC1.50", DRW::AC150 },
{ "AC2.10", DRW::AC210 },
{ "AC1002", DRW::AC1002 },
{ "AC1003", DRW::AC1003 },
{ "AC1004", DRW::AC1004 },
{ "AC1006", DRW::AC1006 },
{ "AC1009", DRW::AC1009 },
{ "AC1012", DRW::AC1012 },
{ "AC1014", DRW::AC1014 },
{ "AC1015", DRW::AC1015 },
{ "AC1018", DRW::AC1018 },
{ "AC1021", DRW::AC1021 },
{ "AC1024", DRW::AC1024 },
{ "AC1027", DRW::AC1027 },
{ "AC1032", DRW::AC1032 },
};
enum error {
@ -133,6 +164,32 @@ enum class DebugLevel {
Debug
};
/**
* Interface for debug printers.
*
* The base class is silent and ignores all debugging.
*/
class DebugPrinter {
public:
virtual void printS(const std::string &s){(void)s;}
virtual void printI(long long int i){(void)i;}
virtual void printUI(long long unsigned int i){(void)i;}
virtual void printD(double d){(void)d;}
virtual void printH(long long int i){(void)i;}
virtual void printB(int i){(void)i;}
virtual void printHL(int c, int s, int h){(void)c;(void)s;(void)h;}
virtual void printPT(double x, double y, double z){(void)x;(void)y;(void)z;}
DebugPrinter()=default;
virtual ~DebugPrinter()=default;
};
/**
* Sets a custom debug printer to use when outputting debug messages.
*
* Ownership of `printer` is transferred.
*/
void setCustomDebugPrinter( DebugPrinter* printer );
//! Special codes for colors
enum ColorCodes {
black = 250,

View File

@ -18,21 +18,8 @@
DRW_dbg *DRW_dbg::instance{nullptr};
/*********private clases*************/
class print_none {
public:
virtual void printS(const std::string &s){(void)s;}
virtual void printI(long long int i){(void)i;}
virtual void printUI(long long unsigned int i){(void)i;}
virtual void printD(double d){(void)d;}
virtual void printH(long long int i){(void)i;}
virtual void printB(int i){(void)i;}
virtual void printHL(int c, int s, int h){(void)c;(void)s;(void)h;}
virtual void printPT(double x, double y, double z){(void)x;(void)y;(void)z;}
print_none()= default;
virtual ~print_none()=default;
};
class print_debug : public print_none {
class print_debug : public DRW::DebugPrinter {
public:
void printS(const std::string &s) override;
void printI(long long int i) override;
@ -56,17 +43,28 @@ DRW_dbg *DRW_dbg::getInstance(){
}
DRW_dbg::DRW_dbg() :
prClass(std::make_unique<print_none>())
{}
debugPrinter(std::make_unique<print_debug>())
{
currentPrinter = &silentDebug;
}
void DRW_dbg::setCustomDebugPrinter(std::unique_ptr<DRW::DebugPrinter> printer)
{
debugPrinter = std::move( printer );
if (level == Level::Debug){
currentPrinter = debugPrinter.get();
}
}
void DRW_dbg::setLevel(Level lvl){
level = lvl;
switch (level){
case Level::Debug:
prClass = std::make_unique<print_debug>();
currentPrinter = debugPrinter.get();
break;
default:
prClass = std::make_unique<print_none>();
currentPrinter = &silentDebug;
break;
}
}
@ -75,46 +73,46 @@ DRW_dbg::Level DRW_dbg::getLevel() const{
}
void DRW_dbg::print(const std::string &s){
prClass->printS(s);
currentPrinter->printS(s);
}
void DRW_dbg::print(int i){
prClass->printI(i);
currentPrinter->printI(i);
}
void DRW_dbg::print(unsigned int i){
prClass->printUI(i);
currentPrinter->printUI(i);
}
void DRW_dbg::print(long long int i){
prClass->printI(i);
currentPrinter->printI(i);
}
void DRW_dbg::print(long unsigned int i){
prClass->printUI(i);
currentPrinter->printUI(i);
}
void DRW_dbg::print(long long unsigned int i){
prClass->printUI(i);
currentPrinter->printUI(i);
}
void DRW_dbg::print(double d){
prClass->printD(d);
currentPrinter->printD(d);
}
void DRW_dbg::printH(long long int i){
prClass->printH(i);
currentPrinter->printH(i);
}
void DRW_dbg::printB(int i){
prClass->printB(i);
currentPrinter->printB(i);
}
void DRW_dbg::printHL(int c, int s, int h){
prClass->printHL(c, s, h);
currentPrinter->printHL(c, s, h);
}
void DRW_dbg::printPT(double x, double y, double z){
prClass->printPT(x, y, z);
currentPrinter->printPT(x, y, z);
}
void print_debug::printS(const std::string &s){

View File

@ -17,6 +17,7 @@
#include <iostream>
#include <QtGlobal>
#include <memory>
#include "../drw_base.h"
//#include <iomanip>
#define DRW_DBGSL(a) DRW_dbg::getInstance()->setLevel(a)
@ -37,6 +38,11 @@ public:
Debug
};
void setLevel(Level lvl);
/**
* Sets a custom debug printer to use when non-silent output
* is required.
*/
void setCustomDebugPrinter(std::unique_ptr<DRW::DebugPrinter> printer);
Level getLevel() const;
static DRW_dbg *getInstance();
void print(const std::string &s);
@ -57,8 +63,9 @@ private:
~DRW_dbg();
static DRW_dbg *instance;
Level level{Level::None};
std::ios_base::fmtflags flags{std::cerr.flags()};
std::unique_ptr<print_none> prClass;
DRW::DebugPrinter silentDebug{};
std::unique_ptr< DRW::DebugPrinter > debugPrinter;
DRW::DebugPrinter* currentPrinter{nullptr};
};

View File

@ -2,6 +2,7 @@
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cstring>
#include <QString>
#include <QTextCodec>
#include <QDebug>
@ -42,44 +43,78 @@ QMap<QString, QStringList> QtCodecs()
{"UTF-16", {"UTF-16", "UTF16", "UTF16-BIT"}},
};
}
}
} // namespace
DRW_TextCodec::DRW_TextCodec()
: version(DRW::AC1021)
{}
void DRW_TextCodec::setVersion(int v, bool dxfFormat){
if (v == DRW::AC1009 || v == DRW::AC1006) {
void DRW_TextCodec::setVersion(DRW::Version v, bool dxfFormat){
switch (v)
{
case DRW::UNKNOWNV:
case DRW::MC00:
case DRW::AC12:
case DRW::AC14:
case DRW::AC150:
case DRW::AC210:
case DRW::AC1002:
case DRW::AC1003:
case DRW::AC1004:
// unhandled?
break;
case DRW::AC1006:
case DRW::AC1009:
{
version = DRW::AC1009;
cp = "ANSI_1252";
setCodePage(cp, dxfFormat);
} else if (v == DRW::AC1012 || v == DRW::AC1014
|| v == DRW::AC1015 || v == DRW::AC1018) {
break;
}
case DRW::AC1012:
case DRW::AC1014:
case DRW::AC1015:
case DRW::AC1018:
{
version = DRW::AC1015;
// if (cp.empty()) { //codepage not set, initialize
cp = "ANSI_1252";
setCodePage(cp, dxfFormat);
// }
} else {
break;
}
case DRW::AC1021:
case DRW::AC1024:
case DRW::AC1027:
case DRW::AC1032:
{
version = DRW::AC1021;
if (dxfFormat)
{
cp = "UTF-8";//RLZ: can be UCS2 or UTF-16 16bits per char
else
cp = "UTF-16";//RLZ: can be UCS2 or UTF-16 16bits per char
setCodePage(cp, dxfFormat);
}
}
void DRW_TextCodec::setVersion(const std::string &versionStr, bool dxfFormat){
if (versionStr == "AC1009" || versionStr == "AC1006") {
setVersion(DRW::AC1009, dxfFormat);
} else if (versionStr == "AC1012" || versionStr == "AC1014"
|| versionStr == "AC1015" || versionStr == "AC1018") {
setVersion(DRW::AC1015, dxfFormat);
}
else
{
setVersion(DRW::AC1021, dxfFormat);
cp = "UTF-16";//RLZ: can be UCS2 or UTF-16 16bits per char
}
setCodePage(cp, dxfFormat);
break;
}
default:
break;
}
}
void DRW_TextCodec::setVersion(const std::string &v, bool dxfFormat){
version = DRW::UNKNOWNV;
for (auto dwgVersionString : DRW::dwgVersionStrings)
{
if (std::strcmp( v.c_str(), dwgVersionString.first ) == 0)
{
version = dwgVersionString.second;
setVersion( dwgVersionString.second, dxfFormat);
break;
}
}
}

View File

@ -3,6 +3,7 @@
#include <string>
#include <QtGlobal>
#include "../drw_base.h"
class QTextCodec;
class QStringList;
@ -15,8 +16,8 @@ public:
std::string fromUtf8(const std::string &s);
std::string toUtf8(const std::string &s);
int getVersion() const {return version;}
void setVersion(const std::string &versionStr, bool dxfFormat);
void setVersion(int v, bool dxfFormat);
void setVersion(const std::string &v, bool dxfFormat);
void setVersion(DRW::Version v, bool dxfFormat);
void setCodePage(const std::string &c, bool dxfFormat);
std::string getCodePage() const {return cp;}
@ -28,7 +29,7 @@ private:
private:
Q_DISABLE_COPY(DRW_TextCodec)
int version;
DRW::Version version{DRW::UNKNOWNV};
std::string cp{};
QTextCodec *conv{nullptr};
};

View File

@ -2,6 +2,7 @@
# This need for corect working file translations.pro
SOURCES += \
$$PWD/libdxfrw/drw_base.cpp \
$$PWD/vdxfengine.cpp \
$$PWD/vdxfpaintdevice.cpp \
$$PWD/libdxfrw/intern/drw_dbg.cpp \