File: DriveManagement.cpp

package info (click to toggle)
ultracopier 2.2.6.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 40,480 kB
  • sloc: ansic: 60,903; cpp: 59,790; sh: 6,882; asm: 723; xml: 675; makefile: 320; perl: 264
file content (180 lines) | stat: -rwxr-xr-x 6,452 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
#include "DriveManagement.h"

#include <QDir>
#include <QFileInfoList>
#include <QStorageInfo>

#include "../../../cpp11addition.h"

DriveManagement::DriveManagement()
{
    tryUpdate();
    #ifdef Q_OS_WIN32
    reg3=std::regex("^[a-zA-Z]:[\\\\/].*");
    reg4=std::regex("^([a-zA-Z]:[\\\\/]).*$");
    #endif
    /// \warn ULTRACOPIER_DEBUGCONSOLE() don't work here because the sinal slot is not connected!
}

//get drive of an file or folder
/// \todo do network drive support for windows
std::string DriveManagement::getDrive(const std::string &fileOrFolder) const
{
    const std::string &inode=fileOrFolder;
    Q_UNUSED(inode);
    #ifdef Q_OS_WIN32
    //optimized to windows version:
    if(fileOrFolder.size()>=3)
    {
        if(fileOrFolder.at(1)==L':' && (fileOrFolder.at(2)==L'\\' || fileOrFolder.at(2)==L'/'))
        {
            char driveLetter=toupper(fileOrFolder.at(0));
            return driveLetter+std::string(":/");
        }
    }

    if(fileOrFolder.size()>=5)
    {
        char f1=fileOrFolder.at(0);
        char f2=fileOrFolder.at(1);
        if(f1=='/' || f1=='\\')
            if(f2=='/' || f2=='\\')
            {
                bool postSeparador=false;
                std::string post;
                unsigned int index=2;
                unsigned int s=2;
                while(index<fileOrFolder.size())
                {
                    const char c=fileOrFolder.at(index);
                    if(c=='/' || c=='\\')
                    {
                        if(postSeparador==false)
                        {
                            post="//"+fileOrFolder.substr(2,index-2);
                            postSeparador=true;
                            char c;
                            do
                            {
                                index++;
                                c=fileOrFolder.at(index);
                            } while((c=='/' || c=='\\') && index<fileOrFolder.size());
                            s=index;
                        }
                        else
                            return post+"/"+fileOrFolder.substr(s,index-s);
                    }
                    index++;
                }
                return post;
            }
        /*std::string returnString=fileOrFolder;
        std::regex_replace(returnString,reg2,"$1");
        return returnString;*/
    }
    //due to lack of WMI support into mingw, the new drive event is never called, this is a workaround
    if(std::regex_match(fileOrFolder,reg3))
    {
        std::string returnString=fileOrFolder;
        std::regex_replace(returnString,reg4,"$1");
        return QDir::toNativeSeparators(QString::fromStdString(returnString)).toUpper().toStdString();
    }
    #else
    int size=mountSysPoint.size();
    for (int i = 0; i < size; ++i) {
        if(stringStartWith(inode,mountSysPoint.at(i)))
            return mountSysPoint.at(i);
    }
    #endif
    //if unable to locate the right mount point
    ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"unable to locate the right mount point for: "+inode+", mount point: "+stringimplode(mountSysPoint,";"));
    return std::string();
}

std::string DriveManagement::getDriveType(const std::string &drive) const
{
    int index=vectorindexOf(mountSysPoint,drive);
    if(index!=-1)
        return driveType.at(index);
    return std::string();
}

bool DriveManagement::isSameDrive(const std::string &file1,const std::string &file2) const
{
    if(file1.empty())
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"file1 is empty");
        return false;
    }
    if(file2.empty())
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Critical,"file2 is empty");
        return false;
    }
    if(mountSysPoint.size()==0)
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"no mount point found");
        return false;
    }
    const std::string &drive1=getDrive(file1);
    if(drive1.empty())
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"drive for the file1 not found: "+file1);
        return false;
    }
    const std::string &drive2=getDrive(file2);
    if(drive2.empty())
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,"drive for the file2 not found: "+file2);
        return false;
    }
    if(drive1==drive2)
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,drive1+" is egal to "+drive2);
        return true;
    }
    else
    {
        ULTRACOPIER_DEBUGCONSOLE(Ultracopier::DebugLevel_Notice,drive1+" is NOT egal to "+drive2);
        return false;
    }
}

void DriveManagement::tryUpdate()
{
    mountSysPoint.clear();
    driveType.clear();
    std::vector<std::pair<std::string/*mountSysPoint*/,std::string/*driveType*/> > temp;
    const QList<QStorageInfo> mountedVolumesList=QStorageInfo::mountedVolumes();
    int index=0;
    while(index<mountedVolumesList.size())
    {
        std::string mountSysPoint=QDir::toNativeSeparators(mountedVolumesList.at(index).rootPath()).toStdString();
        #ifdef Q_OS_WIN32
        std::string driveType;
        if(mountSysPoint!="A:\\" && mountSysPoint!="A:/" && mountSysPoint!="A:" && mountSysPoint!="A" &&
                mountSysPoint!="a:\\" && mountSysPoint!="a:/" && mountSysPoint!="a:" && mountSysPoint!="a")
        {
            const QByteArray &data=mountedVolumesList.at(index).fileSystemType();
            driveType=std::string(data.constData(),data.size());
        }
        #else
        const QByteArray &data=mountedVolumesList.at(index).fileSystemType();
        std::string driveType=std::string(data.constData(),data.size());
        #endif
        temp.push_back(std::pair<std::string/*mountSysPoint*/,std::string/*driveType*/>(mountSysPoint,driveType));
        index++;
    }
    /*sort larger to small mount point, to correctly detect it: /mnt, /
    then /mnt/folder/file will be detected as /mnt
    then /folder/file will be detected as / */
    std::sort(temp.begin(), temp.end(), [](
              std::pair<std::string/*mountSysPoint*/,std::string/*driveType*/> a,
              std::pair<std::string/*mountSysPoint*/,std::string/*driveType*/> b) {
            return a.first.size() > b.first.size();
        });
    for(const std::pair<std::string/*mountSysPoint*/,std::string/*driveType*/> &a : temp) {
        mountSysPoint.push_back(a.first);
        driveType.push_back(a.second);
    }
}