void Spells::loadSpells(const QString& spellsFileName) { // unload any previously loaded spells unloadSpells(); // create a QFile on the past in spell file QFile spellsFile(spellsFileName); // open the spell file if possible if (spellsFile.open(IO_ReadOnly)) { // QPtrQueue to temporarily store our Spells until we know the maxSpell QPtrQueue<Spell> spellQueue; spellQueue.setAutoDelete(false); // allocate memory in a QCString to hold the entire file contents QCString textData(spellsFile.size() + 1); // read the file as one big chunk spellsFile.readBlock(textData.data(), textData.size()); // construct a regex to deal with either style line termination QRegExp lineTerm("[\r\n]{1,2}"); uint16_t unicodeIndicator = *(uint16_t*)textData.data(); QString text; if ((unicodeIndicator != 0xfffe) && (unicodeIndicator != 0xfeff)) text = textData; else { #if (QT_VERSION > 0x030100) text = QString::fromUcs2((uint16_t*)textData.data()); #else if (sizeof(QChar) == 2) text.setUnicode(QChar*(textData.data()), textData.size() / 2); else { seqWarn("Spells::loadSpells(): Upgrade your version of Qt to at least 3.1 to properly handle UTF-16 encoded files!"); text = textData; } #endif } // split the file into at the line termination QStringList lines = QStringList::split(lineTerm, text, false); Spell* newSpell; // iterate over the lines and process the spell entries therein. for (QStringList::Iterator it = lines.begin(); it != lines.end(); ++it) { newSpell = new Spell(*it); // calculate the maximum spell ID if (newSpell->spell() > m_maxSpell) m_maxSpell = newSpell->spell(); // enqueue the new spell entry for later insertion spellQueue.enqueue(newSpell); } seqInfo("Loaded %d spells from '%s' maxSpell=%#.04x", spellQueue.count(), spellsFileName.latin1(), m_maxSpell); // allocate the spell array // Notes: Yeah, it is slightly sparse, but as of this writing there are // only 126 empty entries, so allocating this way for fastest access m_spells = new Spell*[m_maxSpell + 1]; memset((void*)m_spells, 0, sizeof(Spell*) * (m_maxSpell+1)); // iterate over the queue, removing spells from it and inserting them into // the spells table while (!spellQueue.isEmpty()) { // remove from queue newSpell = spellQueue.dequeue(); // insert into table m_spells[newSpell->spell()] = newSpell; } } else seqWarn("Spells::Spells(): Failed to open: '%s'", spellsFileName.latin1()); }