• Skip to content
  • Skip to link menu
  • KDE API Reference
  • kdelibs-4.14.38 API Reference
  • KDE Home
  • Contact Us
 

KDECore

  • kdecore
  • sycoca
kmemfile.cpp
Go to the documentation of this file.
1/*
2 This file is part of the KDE libraries
3 Copyright (C) 2008 Christian Ehrlicher <ch.ehrlicher@gmx.de>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public License
16 along with this library; see the file COPYING.LIB. If not, write to
17 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 Boston, MA 02110-1301, USA.
19*/
20
21#include "kmemfile.h"
22
23#ifndef QT_NO_SHAREDMEMORY
24
25#include <QtCore/QSharedMemory>
26#include <QtCore/QCryptographicHash>
27#include <QtCore/QFile>
28#include <QtCore/QDir>
29
30#include "klocalizedstring.h"
31
32class KMemFile::Private
33{
34public:
35 struct sharedInfoData {
36 int shmCounter;
37 qint64 shmDataSize;
38
39 sharedInfoData() {
40 memset ( this, 0, sizeof ( *this ) );
41 }
42 };
43 Private ( KMemFile *_parent ) : readWritePos ( 0 ), shmDataSize ( 0 ), parent ( _parent ) {}
44
45 QString getShmKey ( int iCounter = -1 );
46 static QString getShmKey ( const QString &filename, int iCounter = -1 );
47 bool loadContentsFromFile();
48 void close();
49
50 QString filename;
51 QSharedMemory shmInfo;
52 QSharedMemory shmData;
53 qint64 readWritePos;
54 qint64 shmDataSize;
55
56 KMemFile *parent;
57};
58
59QString KMemFile::Private::getShmKey ( int iCounter )
60{
61 return getShmKey ( filename, iCounter );
62}
63
64QString KMemFile::Private::getShmKey ( const QString &filename, int iCounter )
65{
66 QByteArray tmp = QString ( QDir ( filename ).canonicalPath() + QString::number ( iCounter ) ).toUtf8();
67 return QString::fromLatin1 ( QCryptographicHash::hash ( tmp, QCryptographicHash::Sha1 ) );
68}
69
70bool KMemFile::Private::loadContentsFromFile()
71{
72 QFile f ( filename );
73 if ( !f.exists() ) {
74 close();
75 parent->setErrorString ( i18n ( "File %1 does not exist" , filename ) );
76 return false;
77 }
78 if ( !f.open ( QIODevice::ReadOnly ) ) {
79 close();
80 parent->setErrorString ( i18n ( "Cannot open %1 for reading" , filename ) );
81 return false;
82 }
83
84 sharedInfoData *infoPtr = static_cast<sharedInfoData*> ( shmInfo.data() );
85
86 infoPtr->shmDataSize = f.size();
87 shmData.setKey ( getShmKey ( infoPtr->shmCounter ) );
88 if ( !shmData.create ( infoPtr->shmDataSize ) ) {
89 close();
90 parent->setErrorString ( i18n ( "Cannot create memory segment for file %1" , filename ) );
91 return false;
92 }
93 shmData.lock();
94 qint64 size = 0;
95 qint64 bytesRead;
96 char *data = static_cast<char*> ( shmData.data() );
97 bytesRead = f.read ( data, infoPtr->shmDataSize );
98 if ( bytesRead != infoPtr->shmDataSize ) {
99 close();
100 parent->setErrorString ( i18n ( "Could not read data from %1 into shm" , filename ) );
101 return false;
102 }
103 shmDataSize = size;
104 shmData.unlock();
105 return true;
106}
107
108void KMemFile::Private::close()
109{
110 shmData.unlock();
111 shmData.detach();
112 shmInfo.unlock();
113 shmInfo.detach();
114 readWritePos = 0;
115 shmDataSize = 0;
116}
117
118KMemFile::KMemFile ( const QString &filename, QObject *parent )
119 : QIODevice ( parent ), d ( new Private ( this ) )
120{
121 d->filename = filename;
122}
123
124KMemFile::~KMemFile()
125{
126 close();
127 delete d;
128}
129
130void KMemFile::close ()
131{
132 QIODevice::close();
133 if ( !isOpen() )
134 return;
135 d->close();
136}
137
138bool KMemFile::isSequential () const
139{
140 return false;
141}
142
143bool KMemFile::open ( OpenMode mode )
144{
145 if ( isOpen() ) {
146 QIODevice::open ( mode );
147 return false;
148 }
149
150 if ( mode != QIODevice::ReadOnly ) {
151 setErrorString ( i18n ( "Only 'ReadOnly' allowed" ) );
152 return false;
153 }
154
155 if ( !QFile::exists ( d->filename ) ) {
156 setErrorString ( i18n ( "File %1 does not exist" , d->filename ) );
157 return false;
158 }
159
160 QSharedMemory lock ( QDir ( d->filename ).canonicalPath() );
161 lock.lock();
162
163 Private::sharedInfoData *infoPtr;
164 d->shmInfo.setKey ( d->getShmKey() );
165 // see if it's already in memory
166 if ( !d->shmInfo.attach ( QSharedMemory::ReadWrite ) ) {
167 if ( !d->shmInfo.create ( sizeof ( Private::sharedInfoData ) ) ) {
168 lock.unlock();
169 setErrorString ( i18n ( "Cannot create memory segment for file %1" , d->filename ) );
170 return false;
171 }
172 d->shmInfo.lock();
173 // no -> create it
174 infoPtr = static_cast<Private::sharedInfoData*> ( d->shmInfo.data() );
175 memset ( infoPtr, 0, sizeof ( Private::sharedInfoData ) );
176 infoPtr->shmCounter = 1;
177 if ( !d->loadContentsFromFile() ) {
178 d->shmInfo.unlock();
179 d->shmInfo.detach();
180 lock.unlock();
181 return false;
182 }
183 } else {
184 d->shmInfo.lock();
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() ) {
189 d->shmInfo.unlock();
190 d->shmInfo.detach();
191 lock.unlock();
192 return false;
193 }
194 }
195 }
196 d->shmDataSize = infoPtr->shmDataSize;
197 d->shmInfo.unlock();
198 lock.unlock();
199
200 setOpenMode ( mode );
201 return true;
202}
203
204bool KMemFile::seek ( qint64 pos )
205{
206 if ( d->shmDataSize < pos ) {
207 setErrorString ( i18n ( "Cannot seek past eof" ) );
208 return false;
209 }
210 d->readWritePos = pos;
211 QIODevice::seek ( pos );
212 return true;
213}
214
215qint64 KMemFile::size () const
216{
217 return d->shmDataSize;
218}
219
220qint64 KMemFile::readData ( char * data, qint64 maxSize )
221{
222 if ( ( openMode() & QIODevice::ReadOnly ) == 0 )
223 return -1;
224
225 qint64 maxRead = size() - d->readWritePos;
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;
230 return bytesToRead;
231}
232
233qint64 KMemFile::writeData ( const char *, qint64 )
234{
235 return -1;
236}
237
238void KMemFile::fileContentsChanged ( const QString &filename )
239{
240 QSharedMemory lock ( QDir ( filename ).canonicalPath() );
241 lock.lock();
242
243 QSharedMemory shmData ( Private::getShmKey ( filename ) );
244 if ( !shmData.attach() )
245 return;
246 shmData.lock();
247 Private::sharedInfoData *infoPtr = static_cast<Private::sharedInfoData*> ( shmData.data() );
248 infoPtr->shmCounter++;
249 infoPtr->shmDataSize = 0;
250 shmData.unlock();
251}
252
253#endif //QT_NO_SHAREDMEMORY
KMemFile
Definition: kmemfile.h:40
KMemFile::size
virtual qint64 size() const
Returns the size of the file.
Definition: kmemfile.cpp:215
KMemFile::writeData
virtual qint64 writeData(const char *data, qint64 maxSize)
Definition: kmemfile.cpp:233
KMemFile::open
virtual bool open(OpenMode mode)
Definition: kmemfile.cpp:143
KMemFile::KMemFile
KMemFile(const QString &filename, QObject *parent=0)
ctor
Definition: kmemfile.cpp:118
KMemFile::fileContentsChanged
static void fileContentsChanged(const QString &filename)
This static function updates the internal information about the file loaded into shared memory.
Definition: kmemfile.cpp:238
KMemFile::seek
virtual bool seek(qint64 pos)
Sets the current read/write position to pos.
Definition: kmemfile.cpp:204
KMemFile::readData
virtual qint64 readData(char *data, qint64 maxSize)
Definition: kmemfile.cpp:220
KMemFile::isSequential
virtual bool isSequential() const
As KMemFile is a random access device, it returns false.
Definition: kmemfile.cpp:138
KMemFile::~KMemFile
virtual ~KMemFile()
dtor
Definition: kmemfile.cpp:124
KMemFile::close
virtual void close()
closes the KMemFile
Definition: kmemfile.cpp:130
QIODevice
QObject
QString
qint64
klocalizedstring.h
i18n
QString i18n(const char *text)
Returns a localized version of a string.
Definition: klocalizedstring.h:630
kmemfile.h
This file is part of the KDE documentation.
Documentation copyright © 1996-2023 The KDE developers.
Generated on Mon Feb 20 2023 00:00:00 by doxygen 1.9.6 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

KDECore

Skip menu "KDECore"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdelibs-4.14.38 API Reference

Skip menu "kdelibs-4.14.38 API Reference"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal