Custom IO Device/de: Difference between revisions
AutoSpider (talk | contribs) (Convert ExpressionEngine section headers) |
m (Wieland moved page Custom IO Device German to Custom IO Device/de: Proper localization) |
||
(3 intermediate revisions by one other user not shown) | |||
Line 6: | Line 6: | ||
'''German''' | [[Custom_IO_Device|English]] | '''German''' | [[Custom_IO_Device|English]] | ||
= Wie man ein benutzerdefiniertes I/O-Gerät schreibt = | = Wie man ein benutzerdefiniertes I/O-Gerät schreibt = | ||
Line 20: | Line 19: | ||
<code> | <code> | ||
QFile file("output.dat"); | QFile file("output.dat"); | ||
CryptDevice cryptDevice(& | CryptDevice cryptDevice(&file) | ||
QTextStream out(& | QTextStream out(&cryptDevice); | ||
cryptDevice.open(QIODevice::WriteOnly); | cryptDevice.open(QIODevice::WriteOnly); | ||
out << "Hello World"; | out << "Hello World"; | ||
Line 28: | Line 27: | ||
Zur möglichen Verwendung siehe auch unseren Beispiel-Code in git [http://www.gitorious.org/qtdevnet-wiki-mvc/qtdevnet-custom-iodevice qtdevnet-wiki-mvc/qtdevnet-custom-iodevice] . | Zur möglichen Verwendung siehe auch unseren Beispiel-Code in git [http://www.gitorious.org/qtdevnet-wiki-mvc/qtdevnet-custom-iodevice qtdevnet-wiki-mvc/qtdevnet-custom-iodevice] . | ||
=== Verschlüsselung === | === Verschlüsselung === | ||
Line 35: | Line 34: | ||
QByteArray dataArray; | QByteArray dataArray; | ||
QBuffer bufferUsedLikeAFile(& | QBuffer bufferUsedLikeAFile(&dataArray); | ||
CryptDevice deviceFilter(& | CryptDevice deviceFilter(&bufferUsedLikeAFile); | ||
deviceFilter.open(QIODevice::WriteOnly); | deviceFilter.open(QIODevice::WriteOnly); | ||
QTextStream stream(& | QTextStream stream(&deviceFilter); | ||
QString szText = rawText->toPlainText(); | QString szText = rawText->toPlainText(); | ||
stream << szText; | stream << szText; | ||
</code> | </code> | ||
=== Entschlüsselung === | === Entschlüsselung === | ||
<code> | <code> | ||
QBuffer bufferUsedLikeAFile(& | QBuffer bufferUsedLikeAFile(&dataArray); | ||
CryptDevice deviceFilter(& | CryptDevice deviceFilter(&bufferUsedLikeAFile); | ||
deviceFilter.open(QIODevice::ReadOnly); | deviceFilter.open(QIODevice::ReadOnly); | ||
QTextStream stream(& | QTextStream stream(&deviceFilter); | ||
QString szText = stream.readAll(); | QString szText = stream.readAll(); | ||
decryptedText->setPlainText(szText); | decryptedText->setPlainText(szText); |
Latest revision as of 13:16, 28 June 2015
This article may require cleanup to meet the Qt Wiki's quality standards. Reason: Auto-imported from ExpressionEngine. Please improve this article if you can. Remove the {{cleanup}} tag and add this page to Updated pages list after it's clean. |
German | English
Wie man ein benutzerdefiniertes I/O-Gerät schreibt
Dies ist eine Portierung des Artikels Qt Quarterly 12 about writing a custom QIODevice
- Hinweis: Ein etwas komplexeres Beispiel findet sich in Simple_Crypt_IO_Device
Benutzung:
Der folgende Code-Schnipsel zeigt, wie man das benutzerdefinierte I/O-Gerät benutzen würde, um Daten zu verschlüsseln und das Ergebnis in einer Datei zu speichern:
QFile file("output.dat");
CryptDevice cryptDevice(&file)
QTextStream out(&cryptDevice);
cryptDevice.open(QIODevice::WriteOnly);
out << "Hello World";
Zur möglichen Verwendung siehe auch unseren Beispiel-Code in git qtdevnet-wiki-mvc/qtdevnet-custom-iodevice .
Verschlüsselung
QByteArray dataArray;
QBuffer bufferUsedLikeAFile(&dataArray);
CryptDevice deviceFilter(&bufferUsedLikeAFile);
deviceFilter.open(QIODevice::WriteOnly);
QTextStream stream(&deviceFilter);
QString szText = rawText->toPlainText();
stream << szText;
Entschlüsselung
QBuffer bufferUsedLikeAFile(&dataArray);
CryptDevice deviceFilter(&bufferUsedLikeAFile);
deviceFilter.open(QIODevice::ReadOnly);
QTextStream stream(&deviceFilter);
QString szText = stream.readAll();
decryptedText->setPlainText(szText);
Das Beispiel-Bild aus dem Testprogramm:
Das benutzerdefinierte I/O-Gerät
Das Schreiben eines benutzerdefinierten I/O-Gerätes in Qt 4 umfasst das Erstellen einer von QIODevice abgeleiteten Klasse und das Reimplementieren einiger virtueller Funktionen.
Im Vergleich zu Qt 3 gibt dabei einen großen Unterschied: Man muss nur noch 2 Funktionen neu schreiben:
- qint64 QIODevice::readData ( char * data, qint64 maxSize )
- qint64 QIODevice::writeData ( const char * data, qint64 maxSize )
Unsere CryptDevice-Klasse wird ein sequenzielles I/O-Gerät. Ob es synchron oder asynchron arbeitet, hängt vom darunter liegenden QIODevice ab.
Quelltext
Die Klassendefinition sieht folgendermaßen aus:
class CryptDevice : public QIODevice
{
Q_OBJECT
public:
CryptDevice(QIODevice* deviceToUse, QObject* parent = 0);
bool open(OpenMode mode);
void close();
bool isSequential() const;
protected:
qint64 readData(char* data, qint64 maxSize);
qint64 writeData(const char* data, qint64 maxSize);
private:
QIODevice* underlyingDevice;
Q_DISABLE_COPY(CryptDevice)
};
Die Definition des Constructors ist ganz einfach:
CryptDevice::CryptDevice(QIODevice* deviceToUse, QObject* parent) :
QIODevice(parent),
underlyingDevice(deviceToUse)
{
}
Weil wir ein sequenzielles Gerät haben wollen, reimplementieren wir isSequential:
bool CryptDevice::isSequential() const
{
return true;
}
in
open()
öffnen wir das darunter liegende Gerät, falls es nicht schon geöffnet ist, und setzetn den Gerätezustand auf mode.
bool CryptDevice::open(OpenMode mode)
{
bool underlyingOk;
if (underlyingDevice->isOpen())
underlyingOk = (underlyingDevice->openMode() != mode);
else
underlyingOk = underlyingDevice->open(mode);
if (underlyingOk)
{
setOpenMode(mode);
return true;
}
return false;
}
Das Schließen ist trivial.
void CryptDevice::close()
{
underlyingDevice->close();
setOpenMode(NotOpen);
}
Um einen Block zu lesen, rufen wir von dem darunter liegenden Gerät
read()
auf. Am Ende verknüpfen wir alle gelesenen Bytes XOR mit der magischen Konstante 0x5E.
qint64 CryptDevice::readData(char* data, qint64 maxSize)
{
qint64 deviceRead = underlyingDevice->read(data, maxSize);
if (deviceRead == –1)
return -1;
for (qint64 i = 0; i < deviceRead; +''i)
data[i] = data[i] ^ 0x5E;
return deviceRead;
}
Um einen Block zu schreiben, erzeugen wir einen temporären Puffer mit unseren ge-XOR-ten Daten. Eine effizientere Implementierung würde einen 4096-Byte-Puffer auf dem Stack nutzen und
write()
mehrfach aufrufen, wenn die Größe der Daten die des Puffers übersteigt.
qint64 CryptDevice::writeData(const char* data, qint64 maxSize)
{
QByteArray buffer((int)maxSize, 0);
for (int i = 0; i < (int)maxSize;''+i)
buffer[i] = data[i] ^ 0x5E;
return underlyingDevice->write(buffer.data(), maxSize);
}