23 #include "ip2cparser.h"
25 #include "datastreamoperatorwrapper.h"
29 #include <QElapsedTimer>
32 #include <QMutexLocker>
34 IP2CParser::IP2CParser()
36 currentParsingThread =
nullptr;
40 bool IP2CParser::doReadDatabase(
const QString &filePath)
42 QMutexLocker mutexLocker(&thisLock);
45 ConstructorDestructorParserStateSetter stateSetter(
this);
47 QFile dataBase(filePath);
48 gLog << tr(
"Parsing IP2C database: %1").arg(dataBase.fileName());
50 if (!dataBase.exists()
51 || !dataBase.open(QIODevice::ReadOnly)
52 || !dataBase.isReadable())
54 gLog << tr(
"Unable to open IP2C file.");
61 QByteArray dataArray = dataBase.readAll();
65 if (pos >= dataArray.size())
68 const char *data = dataArray.constData();
69 unsigned short version = READINT16(&data[pos]);
71 bool wasReadSuccessful =
false;
75 wasReadSuccessful = readDatabaseVersion2(dataArray);
79 wasReadSuccessful =
false;
83 if (!wasReadSuccessful)
86 gLog << tr(
"IP2C database read in %1 ms; IP ranges: %2")
87 .arg(time.elapsed()).arg(ranges_.size());
91 void IP2CParser::parsingThreadFinished()
93 bool bSuccessState = currentParsingThread->bSuccessState;
94 gLog << tr(
"IP2C parsing thread has finished.");
96 delete currentParsingThread;
97 currentParsingThread =
nullptr;
102 bool IP2CParser::readDatabase(
const QString &filePath)
104 bool bSuccess = doReadDatabase(filePath);
110 void IP2CParser::readDatabaseThreaded(
const QString &filePath)
112 if (currentParsingThread !=
nullptr)
115 auto pParsingThread =
new ParsingThread(
this, filePath);
116 connect(pParsingThread, SIGNAL(finished()),
this, SLOT(parsingThreadFinished()));
118 currentParsingThread = pParsingThread;
120 pParsingThread->start();
123 bool IP2CParser::readDatabaseVersion2(
const QByteArray &dataArray)
126 buffer.setData(dataArray);
127 buffer.open(QIODevice::ReadOnly);
128 QDataStream dstream(&buffer);
129 dstream.setByteOrder(QDataStream::LittleEndian);
131 stream.skipRawData(6);
136 QMap<unsigned, IP2CRange> hashTable;
138 while (stream.hasRemaining())
142 QString::fromUtf8(stream.readRawUntilByte(
'\0'));
143 QString countryCode = QString::fromUtf8(stream.readRawUntilByte(
'\0'));
147 baseEntry.country = countryCode;
148 if (!stream.hasRemaining())
151 quint32 numOfIpBlocks = stream.readQUInt32();
153 for (quint32 x = 0; x < numOfIpBlocks; ++x)
158 entry.ipStart = stream.readQUInt32();
159 if (!stream.hasRemaining())
161 entry.ipEnd = stream.readQUInt32();
163 hashTable[entry.ipStart] = entry;
167 this->ranges_ = hashTable.values();
174 IP2CParser::ConstructorDestructorParserStateSetter::ConstructorDestructorParserStateSetter(
IP2CParser *pParser)
176 this->pParser = pParser;
177 pParser->bIsParsing =
true;
180 IP2CParser::ConstructorDestructorParserStateSetter::~ConstructorDestructorParserStateSetter()
182 pParser->bIsParsing =
false;
187 void IP2CParser::ParsingThread::run()
189 bSuccessState = pParser->doReadDatabase(filePath);