예제 #1
0
void PropertyMap::save(SavedProperties &p) const
{
    int count = 0;

    if (!_table) {
#if USE_SINGLE_ENTRY
        if (_singleEntry.key && !(_singleEntry.attributes & (ReadOnly | Function)))
            ++count;
#endif
    } else {
        int size = _table->size;
        Entry *entries = _table->entries;
        for (int i = 0; i != size; ++i)
            if (isValid(entries[i].key) && !(entries[i].attributes & (ReadOnly | Function)))
                ++count;
    }

    p._properties.clear();
    p._count = count;

    if (count == 0)
        return;
    
    p._properties.set(new SavedProperty [count]);
    
    SavedProperty *prop = p._properties.get();
    
    if (!_table) {
#if USE_SINGLE_ENTRY
        if (_singleEntry.key && !(_singleEntry.attributes & (ReadOnly | Function))) {
            prop->key = Identifier(_singleEntry.key);
            prop->value = _singleEntry.value;
            prop->attributes = _singleEntry.attributes;
            ++prop;
        }
#endif
    } else {
        // Save in the right order so we don't lose the order.
        // Another possibility would be to save the indices.

        // Allocate a buffer to use to sort the keys.
        Vector<Entry*, smallMapThreshold> sortedEntries(count);

        // Get pointers to the entries in the buffer.
        Entry** p = sortedEntries.data();
        int size = _table->size;
        Entry* entries = _table->entries;
        for (int i = 0; i != size; ++i) {
            Entry *e = &entries[i];
            if (isValid(e->key) && !(e->attributes & (ReadOnly | Function)))
                *p++ = e;
        }
        assert(p - sortedEntries.data() == count);

        // Sort the entries by index.
        qsort(sortedEntries.data(), p - sortedEntries.data(), sizeof(Entry*), comparePropertyMapEntryIndices);

        // Put the sorted entries into the saved properties list.
        for (Entry** q = sortedEntries.data(); q != p; ++q, ++prop) {
            Entry* e = *q;
            prop->key = Identifier(e->key);
            prop->value = e->value;
            prop->attributes = e->attributes;
        }
    }
}
예제 #2
0
int ArcWriter::buildArchive(QString sourceDir, QString outputPath)
{
    QHash<quint32, size_offset_t> oldOffsetToNewSizeOffset;

    QFile outputFile(outputPath);

    if(!outputFile.open(QIODevice::WriteOnly))
    {
        return 1;
    }

    // Write entries count and data offset
    outputFile.write((char*)&entriesCount, sizeof(quint32));
    outputFile.write((char*)&dataOffset, sizeof(quint32));

    // Write undecoded header
    outputFile.write(undecodedHeader);

    // Update entries data
    QVector<arc_entry_t>::iterator it;
    QVector<arc_entry_t> sortedEntries(entries);

    qSort(sortedEntries.begin(), sortedEntries.end(), arc_entry_t::lessThan);

    quint32 accumOffset = sortedEntries.begin()->offset;
    for( it = sortedEntries.begin(); it != sortedEntries.end(); ++it)
    {
        arc_entry_t entry = *it;
        QString fileName = offsetToFileName.value(entry.offset);

        QString path = sourceDir + QString("\\") + fileName;
        QFile fileTmp(path);
        fileTmp.open(QIODevice::ReadOnly);

        quint32 realSize = fileTmp.size();

        fileTmp.close();

        oldOffsetToNewSizeOffset.insert(it->offset, size_offset_t(realSize, accumOffset));

        accumOffset += realSize;
    }

    sortedEntries.clear();

    // Write entries list
    for( it = entries.begin(); it != entries.end(); ++it)
    {
        arc_entry_t entry = *it;

        // Apply corrections
        size_offset_t newInfo = oldOffsetToNewSizeOffset.value(entry.offset);
        entry.offset = newInfo.offset;
        entry.size = newInfo.size;

        outputFile.write((char*)&entry, sizeof(arc_entry_t));
    }

    // Copy files data
    QVector<QString>::iterator file_it;

    for( file_it = files.begin(); file_it != files.end(); ++file_it)
    {
        QString path = sourceDir + QString("\\") + *file_it;
        QFile fileIn(path);

        if(!fileIn.open(QIODevice::ReadOnly))
        {
            fprintf(stderr, "File [%s] open failed!\n", path.toAscii().data());
            return 1;
        }

        /*if (checkSize && (fileIn.size() != file_it->second))
        {
            fprintf(stderr, "File [%s] size check failed!\n", path.toAscii().data());
            return 1;
        }*/

        outputFile.write(fileIn.readAll());
        fileIn.close();
    }

    outputFile.close();

    return 0;
}