OSDN Git Service

Moved translation support into MUtilities library + make clean-up of temporary files...
[mutilities/MUtilities.git] / src / DirLocker.h
1 ///////////////////////////////////////////////////////////////////////////////
2 // MuldeR's Utilities for Qt
3 // Copyright (C) 2004-2014 LoRd_MuldeR <MuldeR2@GMX.de>
4 //
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 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 // Lesser General Public License for more details.
14 //
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
18 //
19 // http://www.gnu.org/licenses/lgpl-2.1.txt
20 //////////////////////////////////////////////////////////////////////////////////
21
22 #pragma once
23
24 //MUtils
25 #include <MUtils/Global.h>
26
27 //StdLib
28 #include <stdexcept>
29
30 //Qt
31 #include <QString>
32 #include <QFile>
33
34 ///////////////////////////////////////////////////////////////////////////////
35 // Directory Locker
36 ///////////////////////////////////////////////////////////////////////////////
37
38 namespace MUtils
39 {
40         namespace Internal
41         {
42                 class DirLockException : public std::runtime_error
43                 {
44                 public:
45                         DirLockException(const char *const message)
46                         :
47                                 std::runtime_error(message)
48                         {
49                         }
50                 };
51
52                 class DirLock
53                 {
54                 public:
55                         DirLock(const QString dirPath)
56                         :
57                                 m_dirPath(dirPath)
58                         {
59                                 bool okay = false;
60                                 const QByteArray testData = QByteArray(TEST_DATA);
61                                 if(m_dirPath.isEmpty())
62                                 {
63                                         throw DirLockException("Path must not be empty!");
64                                 }
65                                 for(int i = 0; i < 32; i++)
66                                 {
67                                         m_lockFile.reset(new QFile(QString("%1/~%2.lck").arg(m_dirPath, MUtils::rand_str())));
68                                         if(m_lockFile->open(QIODevice::WriteOnly | QIODevice::Truncate | QIODevice::Unbuffered))
69                                         {
70                                                 if(m_lockFile->write(testData) >= testData.size())
71                                                 {
72                                                         okay = true;
73                                                         break;
74                                                 }
75                                                 m_lockFile->remove();
76                                         }
77                                 }
78                                 if(!okay)
79                                 {
80                                         throw DirLockException("Locking has failed!");
81                                 }
82                         }
83
84                         ~DirLock(void)
85                         {
86                                 bool okay = false;
87                                 if(!m_lockFile.isNull())
88                                 {
89                                         for(int i = 0; i < 8; i++)
90                                         {
91                                                 if(m_lockFile->remove())
92                                                 {
93                                                         break;
94                                                 }
95                                                 OS::sleep_ms(1);
96                                         }
97                                 }
98                                 for(int i = 0; i < 8; i++)
99                                 {
100                                         if(MUtils::remove_directory(m_dirPath))
101                                         {
102                                                 okay = true;
103                                                 break;
104                                         }
105                                         OS::sleep_ms(1);
106                                 }
107                                 if(!okay)
108                                 {
109                                         OS::system_message_wrn(L"Directory Lock", L"Warning: Not all temporary files could be removed!");
110                                 }
111                         }
112
113                         inline const QString &getPath(void) const
114                         {
115                                 return m_dirPath;
116                         }
117
118                 private:
119                         static const char *const TEST_DATA;
120                         const QString m_dirPath;
121                         QScopedPointer<QFile> m_lockFile;
122                 };
123
124                 const char *const DirLock::TEST_DATA = "7QtDxPWotHGQYv1xHyQHFKjTB5u5VYKHE20NMDAgLRYoy16CZN7mEYijbjCJpORnoBbtHCzqyy1a6BLCMMiTUZpLzgjg4qnN505egUBqk3wMhPsYjFpkng9i37mWd1iF";
125         }
126 }