00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 module mango.io.FileProxy;
00040
00041 private import mango.base.System;
00042
00043 private import mango.io.Utf8,
00044 mango.io.FilePath,
00045 mango.io.FileStyle,
00046 mango.io.Exception;
00047
00048 version (Posix)
00049 private extern (C) int strlen (char *s);
00050
00051 version (Win32)
00052 private extern (C) int wcslen (wchar *s);
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 class FileProxy
00065 {
00066 private FilePath path;
00067
00068
00069
00070
00071
00072
00073
00074 this (FilePath path)
00075 {
00076 this.path = path;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085 this (char[] path)
00086 {
00087 this (new FilePath (path));
00088 }
00089
00090
00091
00092
00093
00094
00095
00096 FilePath getPath ()
00097 {
00098 return path;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107 char[] toString ()
00108 {
00109 return path.toString();
00110 }
00111
00112
00113
00114
00115
00116
00117
00118 bool isExisting ()
00119 {
00120 try {
00121 getSize();
00122 return true;
00123 } catch (IOException){}
00124 return false;
00125 }
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 FilePath[] toList ()
00141 {
00142 bool accept (FilePath fp) {return true;}
00143
00144 return toList (&accept);
00145 }
00146
00147
00148
00149
00150
00151 version (Win32)
00152 {
00153 private import std.c.windows.windows;
00154
00155
00156
00157
00158
00159
00160
00161 private void exception ()
00162 {
00163 throw new IOException (path.toString ~ ": " ~ System.error);
00164 }
00165
00166
00167
00168
00169
00170
00171
00172 private uint getInfo (void delegate (WIN32_FIND_DATAW info) dg)
00173 {
00174 WIN32_FIND_DATAW info;
00175
00176 HANDLE h = FindFirstFileW (path.toUtf16, &info);
00177 if (h == INVALID_HANDLE_VALUE)
00178 exception ();
00179
00180 if (dg)
00181 dg (info);
00182 FindClose (h);
00183
00184 return info.dwFileAttributes;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193 long getSize ()
00194 {
00195 long _size;
00196
00197 void size (WIN32_FIND_DATAW info)
00198 {
00199 _size = (cast(ulong) info.nFileSizeHigh << 32) +
00200 info.nFileSizeLow;
00201 }
00202
00203 getInfo (&size);
00204 return _size;
00205 }
00206
00207
00208
00209
00210
00211
00212
00213 bool isWritable ()
00214 {
00215 return (getInfo(null) & FILE_ATTRIBUTE_READONLY) == 0;
00216 }
00217
00218
00219
00220
00221
00222
00223
00224 bool isDirectory ()
00225 {
00226 return (getInfo(null) & FILE_ATTRIBUTE_DIRECTORY) != 0;
00227 }
00228
00229
00230
00231
00232
00233
00234
00235 long getModifiedTime ()
00236 {
00237 long _time;
00238
00239 void time (WIN32_FIND_DATAW info)
00240 {
00241 _time = (cast(ulong) info.ftLastWriteTime.dwHighDateTime << 32) +
00242 info.ftLastWriteTime.dwLowDateTime;
00243 }
00244
00245 getInfo (&time);
00246 return _time;
00247 }
00248
00249
00250
00251
00252
00253
00254
00255 void remove ()
00256 {
00257 if (isDirectory ())
00258 {
00259 if (! RemoveDirectoryW (path.toUtf16))
00260 exception();
00261 }
00262 else
00263 {
00264 if (! DeleteFileW (path.toUtf16))
00265 exception();
00266 }
00267 }
00268
00269
00270
00271
00272
00273
00274
00275 FileProxy createFile ()
00276 {
00277 HANDLE h;
00278
00279 h = CreateFileW (path.toUtf16, GENERIC_WRITE, 0, null,
00280 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, null);
00281
00282 if (h == INVALID_HANDLE_VALUE)
00283 exception();
00284
00285 if (! CloseHandle (h))
00286 exception();
00287
00288 return this;
00289 }
00290
00291
00292
00293
00294
00295
00296
00297 FileProxy createDirectory ()
00298 {
00299 if (! CreateDirectoryW (path.toUtf16, null))
00300 exception();
00301
00302 return this;
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312 FilePath[] toList (bool delegate(FilePath fp) filter)
00313 {
00314 int i;
00315 wchar[] c;
00316 HANDLE h;
00317 FilePath[] list;
00318 WIN32_FIND_DATAW fileinfo;
00319
00320 list = new FilePath[50];
00321
00322 c = path.toUtf16 ~ cast(wchar[]) "\\*\0";
00323 h = FindFirstFileW (c, &fileinfo);
00324
00325 if (h != INVALID_HANDLE_VALUE)
00326 try {
00327 do {
00328 int len = wcslen (fileinfo.cFileName);
00329
00330
00331 FilePath fp = new FilePath (Utf8.encode(fileinfo.cFileName [0 .. len]));
00332
00333 if (i >= list.length)
00334 list.length = list.length * 2;
00335
00336 if (filter (fp))
00337 {
00338 list[i] = fp;
00339 ++i;
00340 }
00341 } while (FindNextFileW (h, &fileinfo));
00342 } finally {
00343 FindClose (h);
00344 }
00345 list.length = i;
00346 return list;
00347 }
00348 }
00349
00350
00351
00352
00353
00354 version (Posix)
00355 {
00356 version(linux) {
00357 private import std.c.linux.linux;
00358 alias std.c.linux.linux posix;
00359 }
00360 version(darwin) {
00361 private import std.c.darwin.darwin;
00362 alias std.c.darwin.darwin posix;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 private void exception ()
00372 {
00373 throw new IOException (path.toString ~ ": " ~ System.error);
00374 }
00375
00376
00377
00378
00379
00380
00381
00382 private uint getInfo (void delegate (struct_stat info) dg)
00383 {
00384 struct_stat stats;
00385
00386 if (posix.stat (path.toUtf8, &stats))
00387 exception();
00388
00389 if (dg)
00390 dg (stats);
00391
00392 return stats.st_mode;
00393 }
00394
00395
00396
00397
00398
00399
00400
00401 long getSize ()
00402 {
00403 long _size;
00404
00405 void size (struct_stat info)
00406 {
00407 _size = cast(ulong) info.st_size;
00408 }
00409
00410 getInfo (&size);
00411 return _size;
00412 }
00413
00414
00415
00416
00417
00418
00419
00420 bool isWritable ()
00421 {
00422 return (getInfo(null) & O_RDONLY) == 0;
00423 }
00424
00425
00426
00427
00428
00429
00430
00431 bool isDirectory ()
00432 {
00433 return (getInfo(null) & S_IFDIR) != 0;
00434 }
00435
00436
00437
00438
00439
00440
00441
00442 long getModifiedTime ()
00443 {
00444 long _time;
00445
00446 void time (struct_stat info)
00447 {
00448 _time = cast(ulong) info.st_mtime;
00449 }
00450
00451 getInfo (&time);
00452 return _time;
00453 }
00454
00455
00456
00457
00458
00459
00460
00461 void remove ()
00462 {
00463 if (isDirectory())
00464 {
00465 if (posix.rmdir (path.toUtf8))
00466 exception ();
00467 }
00468 else
00469 if (std.c.stdio.remove (path.toUtf8) == -1)
00470 exception ();
00471 }
00472
00473
00474
00475
00476
00477
00478
00479 FileProxy createFile ()
00480 {
00481 int fd;
00482
00483 fd = posix.open (path.toUtf8, O_CREAT | O_WRONLY | O_TRUNC, 0660);
00484 if (fd == -1)
00485 exception();
00486
00487 if (posix.close(fd) == -1)
00488 exception();
00489
00490 return this;
00491 }
00492
00493
00494
00495
00496
00497
00498
00499 FileProxy createDirectory ()
00500 {
00501 if (posix.mkdir (path.toUtf8, 0777))
00502 exception();
00503
00504 return this;
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514 FilePath[] toList (bool delegate(FilePath fp) filter)
00515 {
00516 int i;
00517 DIR* dir;
00518 dirent* entry;
00519 FilePath[] list;
00520
00521 dir = opendir (path.toUtf8);
00522 if (! dir)
00523 exception();
00524
00525 list = new FilePath [50];
00526 while ((entry = readdir(dir)) != null)
00527 {
00528 int len = strlen (entry.d_name);
00529
00530
00531 FilePath fp = new FilePath (entry.d_name[0 ..len].dup);
00532
00533 if (i >= list.length)
00534 list.length = list.length * 2;
00535
00536 if (filter (fp))
00537 {
00538 list[i] = fp;
00539 ++i;
00540 }
00541 }
00542
00543 list.length = i;
00544 closedir (dir);
00545 return list;
00546 }
00547
00548 }
00549 }
00550
00551 version(darwin)
00552 {
00553
00554
00555 alias long off_t;
00556
00557 extern(C)
00558 {
00559 struct dirent
00560 {
00561 int d_ino;
00562 off_t d_off;
00563 ushort d_reclen;
00564 ubyte d_type;
00565 char[256] d_name;
00566 }
00567
00568 struct DIR
00569 {
00570
00571 }
00572
00573 DIR* opendir(char* name);
00574 int closedir(DIR* dir);
00575 dirent* readdir(DIR* dir);
00576 void rewinddir(DIR* dir);
00577 off_t telldir(DIR* dir);
00578 void seekdir(DIR* dir, off_t offset);
00579 }
00580
00581 }