0bd42fbe7c3aae6e37a32302d0be798958b7418e
[occt.git] / src / OSD / OSD_Disk.cxx
1 // Copyright (c) 1998-1999 Matra Datavision
2 // Copyright (c) 1999-2014 OPEN CASCADE SAS
3 //
4 // This file is part of Open CASCADE Technology software library.
5 //
6 // This library is free software; you can redistribute it and/or modify it under
7 // the terms of the GNU Lesser General Public License version 2.1 as published
8 // by the Free Software Foundation, with special exception defined in the file
9 // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
10 // distribution for complete text of the license and disclaimer of any warranty.
11 //
12 // Alternatively, this file may be used under the terms of Open CASCADE
13 // commercial license or contractual agreement.
14
15 #include <OSD_Disk.hxx>
16
17 #include <OSD_OSDError.hxx>
18 #include <OSD_Path.hxx>
19 #include <OSD_WhoAmI.hxx>
20 #include <Standard_ProgramError.hxx>
21 #include <NCollection_Array1.hxx>
22 #include <NCollection_String.hxx>
23 #include <TCollection_ExtendedString.hxx>
24
25 #ifdef _WIN32
26   #include <windows.h>
27
28   void _osd_wnt_set_error (OSD_Error&, OSD_WhoAmI, ... );
29
30   static TCollection_AsciiString _osd_wnt_set_disk_name (const OSD_Path& thePath)
31   {
32     {
33       TCollection_AsciiString aDisk = thePath.Disk();
34       if (aDisk.UsefullLength() != 0)
35       {
36         return aDisk + '/';
37       }
38     }
39
40     TCollection_AsciiString aDir = thePath.Trek();
41     const int j = aDir.UsefullLength();
42     if (j < 3
43     || aDir.Value (1) != '|'
44     || aDir.Value (2) != '|')
45     {
46       throw Standard_ProgramError ("OSD_Disk: bad disk name");
47     }
48
49     aDir.SetValue (1, '\\');
50     aDir.SetValue (2, '\\');
51     int k = 0;
52     for (int i = 3; i <= j; ++i)
53     {
54       if (aDir.Value (i) == '|')
55       {
56         if (k == 0)
57         {
58           aDir.SetValue (i, '\\');
59           ++k;
60           continue;
61         }
62
63         aDir.SetValue (i, '\\');
64         break;
65       }
66     }
67
68     if (k == 0)
69     {
70       if (thePath.Name().UsefullLength() == 0
71        && thePath.Extension().UsefullLength() == 0)
72       {
73         throw Standard_ProgramError ("OSD_Disk: bad disk name");
74       }
75       else
76       {
77         aDir += '\\';
78         aDir += thePath.Name();
79         aDir += thePath.Extension();
80       }
81     }
82
83     if (aDir.Value (aDir.UsefullLength()) != '\\')
84     {
85       aDir += '\\';
86     }
87     return aDir;
88   }
89
90 #else
91   const OSD_WhoAmI Iam = OSD_WDisk;
92   extern "C" {
93   #if defined(__ANDROID__)
94     #include <sys/vfs.h>
95     #define statvfs  statfs
96     #define fstatvfs fstatfs
97   #else
98     #include <sys/statvfs.h>
99   #endif
100   }
101   #include <errno.h>
102 #endif
103
104 // =======================================================================
105 // function : OSD_Disk
106 // purpose  :
107 // =======================================================================
108 OSD_Disk::OSD_Disk()
109 {
110 #ifdef _WIN32
111   const DWORD aBuffLen = GetCurrentDirectoryW (0, NULL);
112   NCollection_Array1<wchar_t> aBuff (0, aBuffLen);
113   GetCurrentDirectoryW (aBuffLen, &aBuff.ChangeFirst());
114   aBuff.ChangeValue (aBuffLen - 1) = (aBuff.Value (aBuffLen - 2) == L'\\') ? L'\0' : L'\\';
115   aBuff.ChangeLast() = L'\0';
116   if (aBuffLen > 3 && aBuff.First() != L'\\')
117   {
118     aBuff.ChangeValue (3) = L'\0';
119     myDiskName = TCollection_AsciiString (&aBuff.ChangeFirst());
120   }
121 #endif
122 }
123
124 // =======================================================================
125 // function : OSD_Disk
126 // purpose  :
127 // =======================================================================
128 OSD_Disk::OSD_Disk (const OSD_Path& theName)
129 : myDiskName (theName.Disk())
130 {
131 #ifdef _WIN32
132   myDiskName = _osd_wnt_set_disk_name (theName);
133 #endif
134 }
135
136 OSD_Disk::OSD_Disk (const Standard_CString theName)
137 : myDiskName (theName)
138 {
139 #ifdef _WIN32
140   OSD_Path aPath (theName);
141   myDiskName = _osd_wnt_set_disk_name (aPath);
142 #endif
143 }
144
145 // =======================================================================
146 // function : SetName
147 // purpose  :
148 // =======================================================================
149 void OSD_Disk::SetName (const OSD_Path& theName)
150 {
151   myDiskName = theName.Disk();
152 }
153
154 // =======================================================================
155 // function : Name
156 // purpose  :
157 // =======================================================================
158 OSD_Path OSD_Disk::Name() const
159 {
160 #ifdef _WIN32
161   return myDiskName;
162 #else
163   OSD_Path aPath;
164   aPath.SetDisk (myDiskName);
165   return aPath;
166 #endif
167 }
168
169 // =======================================================================
170 // function : DiskSize
171 // purpose  :
172 // =======================================================================
173 Standard_Integer OSD_Disk::DiskSize()
174 {
175 #ifdef _WIN32
176   ULARGE_INTEGER aNbFreeAvailableBytes, aNbTotalBytes, aNbTotalFreeBytes;
177   const TCollection_ExtendedString aDiskNameW (myDiskName);
178   if (!GetDiskFreeSpaceExW (aDiskNameW.ToWideString(),
179                             &aNbFreeAvailableBytes,
180                             &aNbTotalBytes,
181                             &aNbTotalFreeBytes))
182   {
183     _osd_wnt_set_error (myError, OSD_WDisk);
184     return 0;
185   }
186
187   ULONGLONG aSize = aNbTotalBytes.QuadPart / 512;
188   return (Standard_Integer )aSize; // may be an overflow
189 #else
190   struct statvfs buffer;
191   if (statvfs (myDiskName.ToCString(), &buffer) == 0)
192   {
193     int BSize512 = buffer.f_frsize / 512;
194     return buffer.f_blocks * BSize512;
195   }
196   myError.SetValue (errno, Iam, "OSD_Disk: statvfs failed.");
197   return 0;
198 #endif
199 }
200
201 // =======================================================================
202 // function : DiskFree
203 // purpose  :
204 // =======================================================================
205 Standard_Integer OSD_Disk::DiskFree()
206 {
207 #ifdef _WIN32
208   ULARGE_INTEGER aNbFreeAvailableBytes, aNbTotalBytes, aNbTotalFreeBytes;
209   const TCollection_ExtendedString aDiskNameW (myDiskName);
210   if (!GetDiskFreeSpaceExW (aDiskNameW.ToWideString(),
211                             &aNbFreeAvailableBytes,
212                             &aNbTotalBytes,
213                             &aNbTotalFreeBytes))
214   {
215     _osd_wnt_set_error (myError, OSD_WDisk);
216     return 0;
217   }
218
219   ULONGLONG aSize = aNbFreeAvailableBytes.QuadPart / 512;
220   return (Standard_Integer )aSize; // may be an overflow
221 #else
222   struct statvfs buffer;
223   if (statvfs (myDiskName.ToCString(), &buffer) == 0)
224   {
225     int BSize512 = buffer.f_frsize / 512;
226     return buffer.f_bavail * BSize512;
227   }
228   myError.SetValue (errno, Iam, "OSD_Disk: statvfs failed.");
229   return 0;
230 #endif
231 }