⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 translator.cpp

📁 QT 开发环境里面一个很重要的文件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************** Copyright (C) 1992-2006 Trolltech ASA. All rights reserved.**** This file is part of the Qt Linguist of the Qt Toolkit.**** This file may be used under the terms of the GNU General Public** License version 2.0 as published by the Free Software Foundation** and appearing in the file LICENSE.GPL included in the packaging of** this file.  Please review the following information to ensure GNU** General Public Licensing requirements will be met:** http://www.trolltech.com/products/qt/opensource.html**** If you are unsure which license is appropriate for your use, please** review the following information:** http://www.trolltech.com/products/qt/licensing.html or contact the** sales department at sales@trolltech.com.**** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.******************************************************************************/#include "translator.h"#include <qplatformdefs.h>#ifndef QT_NO_TRANSLATION#include <QFileInfo>#include <QString>#include <QCoreApplication>#include <QDataStream>#include <QFile>#include <QMap>#include <QtAlgorithms>#include <stdlib.h>/*$ mcookie3cb86418caef9c95cd211cbf60a1bddd$*/// magic number for the filestatic const int MagicLength = 16;static const uchar magic[MagicLength] = {    0x3c, 0xb8, 0x64, 0x18, 0xca, 0xef, 0x9c, 0x95,    0xcd, 0x21, 0x1c, 0xbf, 0x60, 0xa1, 0xbd, 0xdd};static uint elfHash(const char * name){    const uchar *k;    uint h = 0;    uint g;    if (name) {        k = (const uchar *) name;        while (*k) {            h = (h << 4) + *k++;            if ((g = (h & 0xf0000000)) != 0)                h ^= g >> 24;            h &= ~g;        }    }    if (!h)        h = 1;    return h;}extern bool qt_detectRTLLanguage();class TranslatorPrivate{public:    struct Offset {        Offset()            : h(0), o(0) { }        Offset(const TranslatorMessage& m, int offset)            : h(m.hash()), o(offset) { }        bool operator<(const Offset &other) const {            return (h != other.h) ? h < other.h : o < other.o;        }        bool operator==(const Offset &other) const {            return h == other.h && o == other.o;        }        uint h;        uint o;    };    enum { Contexts = 0x2f, Hashes = 0x42, Messages = 0x69, NumerusRules = 0x88 };    TranslatorPrivate(Translator *qq) : q(qq), unmapPointer(0), unmapLength(0) {}    // Translator must finalize this before deallocating it    Translator *q;    // for mmap'ed files, this is what needs to be unmapped.    char *unmapPointer;    unsigned int unmapLength;    // for squeezed but non-file data, this is what needs to be deleted    QByteArray messageArray;    QByteArray offsetArray;    QByteArray contextArray;#ifndef QT_NO_TRANSLATION_BUILDER    QMap<TranslatorMessage, void *> messages;#endif    QByteArray numerusRules;#if 0    bool do_load(const uchar *data, int len);#endif};Translator::Translator(QObject * parent)    : QObject(parent){    d = new TranslatorPrivate(this);}Translator::~Translator(){    clear();    delete d;}bool Translator::save(const QString & filename, SaveMode mode){    QFile file(filename);    if (!file.open(QIODevice::WriteOnly)) return false;    return save(&file, mode);}bool Translator::save(QIODevice *iod, SaveMode mode){    squeeze(mode);    QDataStream s(iod);    s.writeRawData((const char *)magic, MagicLength);    quint8 tag;    if (!d->offsetArray.isEmpty()) {        tag = (quint8)TranslatorPrivate::Hashes;        quint32 oas = (quint32)d->offsetArray.size();        s << tag << oas;        s.writeRawData(d->offsetArray, oas);    }    if (!d->messageArray.isEmpty()) {        tag = (quint8)TranslatorPrivate::Messages;        quint32 mas = (quint32)d->messageArray.size();        s << tag << mas;        s.writeRawData(d->messageArray, mas);    }    if (!d->contextArray.isEmpty()) {        tag = (quint8)TranslatorPrivate::Contexts;        quint32 cas = (quint32)d->contextArray.size();        s << tag << cas;        s.writeRawData(d->contextArray, cas);    }    if (!d->numerusRules.isEmpty()) {        quint32 nrs = d->numerusRules.size();        s << quint8(TranslatorPrivate::NumerusRules) << nrs;        s.writeRawData(d->numerusRules.constData(), nrs);    }    return true;}void Translator::clear(){    if (d->unmapPointer && d->unmapLength) {        delete [] d->unmapPointer;        d->unmapPointer = 0;        d->unmapLength = 0;    }    d->messageArray.clear();    d->offsetArray.clear();    d->contextArray.clear();    d->messages.clear();    QEvent ev(QEvent::LanguageChange);    QCoreApplication::sendEvent(QCoreApplication::instance(), &ev);}void Translator::squeeze(SaveMode mode){    if (d->messages.isEmpty()) {        if (mode == Stripped)            unsqueeze();        else            return;    }    QMap<TranslatorMessage, void *> messages = d->messages;    clear();    QMap<TranslatorPrivate::Offset, void *> offsets;    QDataStream ms(&d->messageArray, QIODevice::WriteOnly);    QMap<TranslatorMessage, void *>::const_iterator it, next;    int cpPrev = 0, cpNext = 0;    for (it = messages.constBegin(); it != messages.constEnd(); ++it) {        cpPrev = cpNext;        next = it;        ++next;        if (next == messages.constEnd())            cpNext = 0;        else            cpNext = (int) it.key().commonPrefix(next.key());        offsets.insert(TranslatorPrivate::Offset(it.key(), ms.device()->pos()), (void *)0);        it.key().write(ms, mode == Stripped, (TranslatorMessage::Prefix)qMax(cpPrev, cpNext + 1));    }    QMap<TranslatorPrivate::Offset, void *>::Iterator offset;    offset = offsets.begin();    QDataStream ds(&d->offsetArray, QIODevice::WriteOnly);    while (offset != offsets.end()) {        TranslatorPrivate::Offset k = offset.key();        ++offset;        ds << (quint32)k.h << (quint32)k.o;    }    if (mode == Stripped) {        QMap<QByteArray, int> contextSet;        for (it = messages.constBegin(); it != messages.constEnd(); ++it)            ++contextSet[it.key().context()];        quint16 hTableSize;        if (contextSet.size() < 200)            hTableSize = (contextSet.size() < 60) ? 151 : 503;        else if (contextSet.size() < 2500)            hTableSize = (contextSet.size() < 750) ? 1511 : 5003;        else            hTableSize = (contextSet.size() < 10000) ? 15013 : 3 * contextSet.size() / 2;        QMultiMap<int, const char *> hashMap;        QMap<QByteArray, int>::const_iterator c;        for (c = contextSet.constBegin(); c != contextSet.constEnd(); ++c)            hashMap.insert(elfHash(c.key()) % hTableSize, c.key());        /*          The contexts found in this translator are stored in a hash          table to provide fast lookup. The context array has the          following format:              quint16 hTableSize;              quint16 hTable[hTableSize];              quint8  contextPool[...];          The context pool stores the contexts as Pascal strings:              quint8  len;              quint8  data[len];          Let's consider the look-up of context "FunnyDialog".  A          hash value between 0 and hTableSize - 1 is computed, say h.          If hTable[h] is 0, "FunnyDialog" is not covered by this          translator. Else, we check in the contextPool at offset          2 * hTable[h] to see if "FunnyDialog" is one of the          contexts stored there, until we find it or we meet the          empty string.        */        d->contextArray.resize(2 + (hTableSize << 1));        QDataStream t(&d->contextArray, QIODevice::WriteOnly);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -