2828
2929#include " geoipdatabase.h"
3030
31- #include < QByteArray>
3231#include < QDateTime>
3332#include < QDebug>
3433#include < QFile>
3736
3837#include " base/global.h"
3938#include " base/path.h"
39+ #include " base/utils/io.h"
4040
4141namespace
4242{
43- const qint32 MAX_FILE_SIZE = 67108864 ; // 64MB
44- const quint32 MAX_METADATA_SIZE = 131072 ; // 128KB
43+ const qint32 MAX_FILE_SIZE = 64 * 1024 * 1024 ;
44+ const quint32 MAX_METADATA_SIZE = 128 * 1024 ;
4545 const QByteArray METADATA_BEGIN_MARK = QByteArrayLiteral(" \xab\xcd\xef MaxMind.com" );
4646 const char DATA_SECTION_SEPARATOR [16 ] = {0 };
4747
@@ -76,39 +76,30 @@ struct DataFieldDescriptor
7676 };
7777};
7878
79- GeoIPDatabase::GeoIPDatabase (const quint32 size)
80- : m_size(size)
81- , m_data(new uchar[size])
79+ GeoIPDatabase::GeoIPDatabase (const QByteArray &data)
80+ : m_data {data}
8281{
8382}
8483
8584GeoIPDatabase *GeoIPDatabase::load (const Path &filename, QString &error)
8685{
87- QFile file {filename. data ()} ;
86+ error. clear () ;
8887
89- if (!file.open (QFile::ReadOnly))
88+ const auto readResult = Utils::IO::readFile (filename, MAX_FILE_SIZE );
89+ if (!readResult)
9090 {
91- error = file. errorString () ;
91+ error = readResult. error (). message ;
9292 return nullptr ;
9393 }
9494
95- const qint64 fileSize = file. size ();
96- if ((fileSize <= 0 ) || (fileSize > MAX_FILE_SIZE ) )
95+ const QByteArray &data = readResult. value ();
96+ if (data. size () <= 0 )
9797 {
9898 error = tr (" Unsupported database file size." );
9999 return nullptr ;
100100 }
101101
102- auto *db = new GeoIPDatabase (static_cast <quint32>(fileSize));
103-
104- if (file.read (reinterpret_cast <char *>(db->m_data ), fileSize) != fileSize)
105- {
106- error = file.errorString ();
107- delete db;
108- return nullptr ;
109- }
110-
111-
102+ auto *db = new GeoIPDatabase (data);
112103 if (!db->parseMetadata (db->readMetadata (), error) || !db->loadDB (error))
113104 {
114105 delete db;
@@ -120,17 +111,16 @@ GeoIPDatabase *GeoIPDatabase::load(const Path &filename, QString &error)
120111
121112GeoIPDatabase *GeoIPDatabase::load (const QByteArray &data, QString &error)
122113{
123- const qint64 dataSize = data.size ();
114+ error.clear ();
115+
116+ const qsizetype dataSize = data.size ();
124117 if ((dataSize <= 0 ) || (dataSize > MAX_FILE_SIZE ))
125118 {
126119 error = tr (" Unsupported database file size." );
127120 return nullptr ;
128121 }
129122
130- auto *db = new GeoIPDatabase (static_cast <quint32>(dataSize));
131-
132- memcpy (reinterpret_cast <char *>(db->m_data ), data.constData (), dataSize);
133-
123+ auto *db = new GeoIPDatabase (data);
134124 if (!db->parseMetadata (db->readMetadata (), error) || !db->loadDB (error))
135125 {
136126 delete db;
@@ -140,11 +130,6 @@ GeoIPDatabase *GeoIPDatabase::load(const QByteArray &data, QString &error)
140130 return db;
141131}
142132
143- GeoIPDatabase::~GeoIPDatabase ()
144- {
145- delete [] m_data;
146- }
147-
148133QString GeoIPDatabase::type () const
149134{
150135 return m_dbType;
@@ -164,7 +149,7 @@ QString GeoIPDatabase::lookup(const QHostAddress &hostAddr) const
164149{
165150 Q_IPV6ADDR addr = hostAddr.toIPv6Address ();
166151
167- const uchar *ptr = m_data;
152+ auto *ptr = reinterpret_cast < const uchar *>( m_data. constData ()) ;
168153
169154 for (int i = 0 ; i < 16 ; ++i)
170155 {
@@ -201,7 +186,7 @@ QString GeoIPDatabase::lookup(const QHostAddress &hostAddr) const
201186 return country;
202187 }
203188
204- ptr = m_data + (id * m_nodeSize);
189+ ptr = reinterpret_cast < const uchar *>( m_data. constData ()) + (id * m_nodeSize);
205190 }
206191 }
207192
@@ -287,9 +272,10 @@ bool GeoIPDatabase::loadDB(QString &error) const
287272
288273 const int nodeSize = m_recordSize / 4 ; // in bytes
289274 const int indexSize = m_nodeCount * nodeSize;
290- if ((m_size < (indexSize + sizeof (DATA_SECTION_SEPARATOR )))
291- || (memcmp (m_data + indexSize, DATA_SECTION_SEPARATOR , sizeof (DATA_SECTION_SEPARATOR )) != 0 ))
292- {
275+ const int totalSize = indexSize + sizeof (DATA_SECTION_SEPARATOR );
276+ if ((m_data.size () < totalSize)
277+ || (memcmp ((m_data.constData () + indexSize), DATA_SECTION_SEPARATOR , sizeof (DATA_SECTION_SEPARATOR )) != 0 ))
278+ {
293279 error = tr (" Database corrupted: no data section found." );
294280 return false ;
295281 }
@@ -299,20 +285,20 @@ bool GeoIPDatabase::loadDB(QString &error) const
299285
300286QVariantHash GeoIPDatabase::readMetadata () const
301287{
302- const char *ptr = reinterpret_cast < const char *>( m_data);
303- quint32 size = m_size ;
304- if (m_size > MAX_METADATA_SIZE )
288+ const char *ptr = m_data. constData ( );
289+ qsizetype size = m_data. size () ;
290+ if (m_data. size () > MAX_METADATA_SIZE )
305291 {
306- ptr += m_size - MAX_METADATA_SIZE ;
292+ ptr += m_data. size () - MAX_METADATA_SIZE ;
307293 size = MAX_METADATA_SIZE ;
308294 }
309295
310296 const QByteArray data = QByteArray::fromRawData (ptr, size);
311297 qsizetype index = data.lastIndexOf (METADATA_BEGIN_MARK );
312298 if (index >= 0 )
313299 {
314- if (m_size > MAX_METADATA_SIZE )
315- index += (m_size - MAX_METADATA_SIZE ); // from begin of all data
300+ if (m_data. size () > MAX_METADATA_SIZE )
301+ index += (m_data. size () - MAX_METADATA_SIZE ); // from begin of all data
316302 auto offset = static_cast <quint32>(index + METADATA_BEGIN_MARK .size ());
317303 const QVariant metadata = readDataField (offset);
318304 if (metadata.userType () == QMetaType::QVariantHash)
@@ -346,7 +332,7 @@ QVariant GeoIPDatabase::readDataField(quint32 &offset) const
346332 qDebug () << " * Illegal Pointer using" ;
347333 break ;
348334 case DataType::String:
349- fieldValue = QString::fromUtf8 (reinterpret_cast < const char *> (m_data + locOffset), descr.fieldSize );
335+ fieldValue = QString::fromUtf8 ((m_data. constData () + locOffset), descr.fieldSize );
350336 locOffset += descr.fieldSize ;
351337 break ;
352338 case DataType::Double:
@@ -356,7 +342,7 @@ QVariant GeoIPDatabase::readDataField(quint32 &offset) const
356342 qDebug () << " * Invalid field size for type: Double" ;
357343 break ;
358344 case DataType::Bytes:
359- fieldValue = QByteArray (reinterpret_cast < const char *> (m_data + locOffset), descr.fieldSize );
345+ fieldValue = QByteArray ((m_data. constData () + locOffset), descr.fieldSize );
360346 locOffset += descr.fieldSize ;
361347 break ;
362348 case DataType::Integer16:
@@ -406,8 +392,8 @@ QVariant GeoIPDatabase::readDataField(quint32 &offset) const
406392
407393bool GeoIPDatabase::readDataFieldDescriptor (quint32 &offset, DataFieldDescriptor &out) const
408394{
409- const uchar *dataPtr = m_data + offset;
410- const int availSize = m_size - offset;
395+ auto *dataPtr = reinterpret_cast < const uchar *>( m_data. constData ()) + offset;
396+ const qsizetype availSize = m_data. size () - offset;
411397 if (availSize < 1 ) return false ;
412398
413399 out.fieldType = static_cast <DataType>((dataPtr[0 ] & 0xE0 ) >> 5 );
@@ -514,8 +500,8 @@ template <typename T>
514500QVariant GeoIPDatabase::readPlainValue (quint32 &offset, const quint8 len) const
515501{
516502 T value = 0 ;
517- const uchar *const data = m_data + offset;
518- const quint32 availSize = m_size - offset;
503+ auto *const data = reinterpret_cast < const uchar *>( m_data. constData ()) + offset;
504+ const qsizetype availSize = m_data. size () - offset;
519505
520506 if ((len > 0 ) && (len <= sizeof (T) && (availSize >= len)))
521507 {
0 commit comments