23 #ifndef QT_NO_SHAREDMEMORY
25 #include <QtCore/QSharedMemory>
26 #include <QtCore/QCryptographicHash>
27 #include <QtCore/QFile>
28 #include <QtCore/QDir>
35 struct sharedInfoData {
40 memset (
this, 0,
sizeof ( *
this ) );
43 Private (
KMemFile *_parent ) : readWritePos ( 0 ), shmDataSize ( 0 ), parent ( _parent ) {}
45 QString getShmKey (
int iCounter = -1 );
46 static QString getShmKey (
const QString &filename,
int iCounter = -1 );
47 bool loadContentsFromFile();
51 QSharedMemory shmInfo;
52 QSharedMemory shmData;
59 QString KMemFile::Private::getShmKey (
int iCounter )
61 return getShmKey ( filename, iCounter );
64 QString KMemFile::Private::getShmKey (
const QString &filename,
int iCounter )
66 QByteArray tmp =
QString ( QDir ( filename ).canonicalPath() + QString::number ( iCounter ) ).toUtf8();
67 return QString::fromLatin1 ( QCryptographicHash::hash ( tmp, QCryptographicHash::Sha1 ) );
70 bool KMemFile::Private::loadContentsFromFile()
75 parent->setErrorString (
i18n (
"File %1 does not exist" , filename ) );
78 if ( !f.open ( QIODevice::ReadOnly ) ) {
80 parent->setErrorString (
i18n (
"Cannot open %1 for reading" , filename ) );
84 sharedInfoData *infoPtr =
static_cast<sharedInfoData*
> ( shmInfo.data() );
86 infoPtr->shmDataSize = f.size();
87 shmData.setKey ( getShmKey ( infoPtr->shmCounter ) );
88 if ( !shmData.create ( infoPtr->shmDataSize ) ) {
90 parent->setErrorString (
i18n (
"Cannot create memory segment for file %1" , filename ) );
96 char *data =
static_cast<char*
> ( shmData.data() );
97 bytesRead = f.read ( data, infoPtr->shmDataSize );
98 if ( bytesRead != infoPtr->shmDataSize ) {
100 parent->setErrorString (
i18n (
"Could not read data from %1 into shm" , filename ) );
108 void KMemFile::Private::close()
119 :
QIODevice ( parent ), d ( new Private ( this ) )
121 d->filename = filename;
150 if ( mode != QIODevice::ReadOnly ) {
151 setErrorString (
i18n (
"Only 'ReadOnly' allowed" ) );
155 if ( !QFile::exists ( d->filename ) ) {
156 setErrorString (
i18n (
"File %1 does not exist" , d->filename ) );
160 QSharedMemory lock ( QDir ( d->filename ).canonicalPath() );
163 Private::sharedInfoData *infoPtr;
164 d->shmInfo.setKey ( d->getShmKey() );
166 if ( !d->shmInfo.attach ( QSharedMemory::ReadWrite ) ) {
167 if ( !d->shmInfo.create ( sizeof ( Private::sharedInfoData ) ) ) {
169 setErrorString (
i18n (
"Cannot create memory segment for file %1" , d->filename ) );
174 infoPtr =
static_cast<Private::sharedInfoData*
> ( d->shmInfo.data() );
175 memset ( infoPtr, 0,
sizeof ( Private::sharedInfoData ) );
176 infoPtr->shmCounter = 1;
177 if ( !d->loadContentsFromFile() ) {
185 infoPtr =
static_cast<Private::sharedInfoData*
> ( d->shmInfo.data() );
186 d->shmData.setKey ( d->getShmKey ( infoPtr->shmCounter ) );
187 if ( !d->shmData.attach ( QSharedMemory::ReadOnly ) ) {
188 if ( !d->loadContentsFromFile() ) {
196 d->shmDataSize = infoPtr->shmDataSize;
200 setOpenMode ( mode );
206 if ( d->shmDataSize < pos ) {
207 setErrorString (
i18n (
"Cannot seek past eof" ) );
210 d->readWritePos = pos;
211 QIODevice::seek ( pos );
217 return d->shmDataSize;
222 if ( ( openMode() & QIODevice::ReadOnly ) == 0 )
226 qint64 bytesToRead = qMin ( maxRead, maxSize );
227 const char *src =
static_cast<const char*
> ( d->shmData.data() );
228 memcpy ( data, &src[d->readWritePos], bytesToRead );
229 d->readWritePos += bytesToRead;
240 QSharedMemory lock ( QDir ( filename ).canonicalPath() );
243 QSharedMemory shmData ( Private::getShmKey ( filename ) );
244 if ( !shmData.attach() )
247 Private::sharedInfoData *infoPtr =
static_cast<Private::sharedInfoData*
> ( shmData.data() );
248 infoPtr->shmCounter++;
249 infoPtr->shmDataSize = 0;
253 #endif //QT_NO_SHAREDMEMORY
QString i18n(const char *text)
Returns a localized version of a string.
virtual qint64 readData(char *data, qint64 maxSize)
virtual bool isSequential() const
As KMemFile is a random access device, it returns false.
int open(const QString &pathname, int flags, mode_t mode)
virtual bool seek(qint64 pos)
Sets the current read/write position to pos.
static void fileContentsChanged(const QString &filename)
This static function updates the internal information about the file loaded into shared memory...
virtual qint64 writeData(const char *data, qint64 maxSize)
virtual qint64 size() const
Returns the size of the file.
virtual bool open(OpenMode mode)
KMemFile(const QString &filename, QObject *parent=0)
ctor
virtual void close()
closes the KMemFile