This commit was manufactured by cvs2svn to create branch 'mono-1-0'.
[mono.git] / mcs / class / Microsoft.VisualBasic / Microsoft.VisualBasic / FileSystem.cs
1 /*
2  * Copyright (c) 2002-2003 Mainsoft Corporation.
3  * Copyright (C) 2004 Novell, Inc (http://www.novell.com)
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a
6  * copy of this software and associated documentation files (the "Software"),
7  * to deal in the Software without restriction, including without limitation
8  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
9  * and/or sell copies of the Software, and to permit persons to whom the
10  * Software is furnished to do so, subject to the following conditions:
11  * 
12  * The above copyright notice and this permission notice shall be included in
13  * all copies or substantial portions of the Software.
14  * 
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21  * DEALINGS IN THE SOFTWARE.
22  */
23  
24
25 using System;
26 using System.IO;
27 using System.Text;
28 using System.Collections;
29 using System.Globalization;
30 using Microsoft.VisualBasic;
31 using Microsoft.VisualBasic.CompilerServices;
32
33 /**
34  * CURRENT LIMITATIONS
35  * @limit TAB(int) - not supported.
36  * @limit not all file attributes are supported. supported are: Hidden, Directory, ReadOnly
37  * @limit ChDir(..) - not supported.
38  * @limit ChDrive - not supported.
39  * @limit CurDir(Char) - ignores the parameter.
40  */
41
42 namespace Microsoft.VisualBasic
43 {
44         [StandardModuleAttribute]
45         sealed public class FileSystem
46         {
47
48                 private static Hashtable _fileNameIdMap = new Hashtable();
49                 private static Hashtable _openFilesMap = new Hashtable();
50                 private static Hashtable _randomRecordLength = new Hashtable();
51
52                 static String _pattern;
53                 static int _fileAttrs;
54                 private static int _fileIndex;
55                 private static FileInfo[] _files;
56                 private static bool _isEndOfFiles = true;
57
58
59                 public static void Reset()
60                 {
61                         Object value;
62
63                         ICollection s = _openFilesMap.Keys;
64
65                         int [] iArr = new int[s.Count];
66                         s.CopyTo(iArr, 0);
67                         close(iArr);
68                 }
69
70                 public static void FileClose(int[] fileNumbers)
71                 {
72                         int[] iArr = null;
73                         if (fileNumbers.Length == 0)
74                         {
75                                 ICollection keySet = FileSystem._openFilesMap.Keys;
76                                 iArr = new int[keySet.Count];
77                                 keySet.CopyTo(iArr, 0);
78                         }
79                         else
80                         {
81                                 iArr = new int[fileNumbers.Length];
82                                 for (int i = 0; i < fileNumbers.Length; i++)
83                                         iArr[i] = fileNumbers[i];
84                         }
85                         close(iArr);
86                 }
87
88                 private static void close(int [] keys)
89                 {
90                         Object obj;
91
92                         for (int i = 0; i < keys.Length; i++)
93                         {
94                                 if (keys[i] < 0 || keys[i] > 255)
95                                 {
96                                         ExceptionUtils.VbMakeException(
97                                                                        VBErrors.IllegalFuncCall);
98                                         throw new ArgumentOutOfRangeException();
99                                 }
100                                 obj = _openFilesMap[keys[i]];
101
102                                 if (obj == null)
103                                 {
104                                         String message = VBUtils.GetResourceString(52);
105                                         throw (IOException)VBUtils.VBException(new IOException(message), 52);
106                                 }
107                                 String fileName = null;
108                                 if (obj is VBFile)
109                                 {
110                                         ((VBFile)obj).closeFile();
111                                         fileName = ((VBFile)obj).getFullPath();
112                                 }
113
114
115                                 _openFilesMap.Remove(keys[i]);
116                                 _fileNameIdMap.Remove(fileName);
117                         }
118                 }
119
120                 public static void FileOpen(
121                                             int fileNumber,
122                                             String fileName,
123                                             OpenMode mode,
124                                             [System.Runtime.InteropServices.Optional] 
125                                             [System.ComponentModel.DefaultValue(-1)] OpenAccess access, 
126                                             [System.Runtime.InteropServices.Optional]  
127                                             [System.ComponentModel.DefaultValue(-1)] OpenShare share, 
128                                             [System.Runtime.InteropServices.Optional] 
129                                             [System.ComponentModel.DefaultValue(-1)] int recordLength)
130
131                 {
132                         if (!isFileNumberFree(fileNumber))
133                                 throw ExceptionUtils.VbMakeException(VBErrors.FileAlreadyOpen);
134                         if (fileNumber < 0 || fileNumber > 255)
135                                 throw ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
136                         if (recordLength != -1 && recordLength <= 0)
137                                 throw ExceptionUtils.VbMakeException(VBErrors.IllegalFuncCall);
138                         if (share != OpenShare.Shared && _fileNameIdMap.ContainsKey(Path.GetFullPath(string.Intern(fileName))))
139                                 throw ExceptionUtils.VbMakeException(VBErrors.FileAlreadyOpen);
140                         if (mode == OpenMode.Input)
141                         {
142                                 VBFile vbFile = new InputVBFile(fileName, (FileAccess) access,(recordLength == -1)? 4096:recordLength);
143                                 _openFilesMap.Add(fileNumber, vbFile);
144                         }
145                         else if (mode == OpenMode.Output || mode == OpenMode.Append)
146                         {
147                                 VBFile vbFile = new OutPutVBFile(fileName,mode,access,recordLength);
148                                 _openFilesMap.Add(fileNumber, vbFile);
149                         }
150                         else if (mode == OpenMode.Random)
151                         {
152                                 VBFile vbFile = new RandomVBFile(fileName,mode,access,recordLength);
153                                 _openFilesMap.Add(fileNumber, vbFile);
154                         }
155                         else if (mode == OpenMode.Binary)
156                         {
157                                 VBFile vbFile = new BinaryVBFile(fileName,mode,access,recordLength);
158                                 _openFilesMap.Add(fileNumber, vbFile);
159                         }
160                         _fileNameIdMap.Add(Path.GetFullPath(string.Intern(fileName)),fileNumber);
161                 }
162
163                 public static void FilePut(int fileNumber,
164                                            bool value,
165                                            [System.Runtime.InteropServices.Optional]
166                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
167                 {
168                         checkRecordNumber(recordNumber,false);
169                         VBFile vbFile = getVBFile(fileNumber);
170                         vbFile.put(value,recordNumber);
171                 }
172
173
174                 public static void FilePut(int fileNumber, 
175                                            byte value, 
176                                            [System.Runtime.InteropServices.Optional]
177                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
178                 {
179                         checkRecordNumber(recordNumber,false);
180                         VBFile vbFile = getVBFile(fileNumber);
181                         vbFile.put(value,recordNumber);
182                 }
183
184                 public static void FilePut(int fileNumber, 
185                                            short value, 
186                                            [System.Runtime.InteropServices.Optional]
187                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
188                 {
189                         checkRecordNumber(recordNumber,false);
190                         VBFile vbFile = getVBFile(fileNumber);
191                         vbFile.put(value,recordNumber);
192                 }
193
194
195                 public static void FilePut(int fileNumber, 
196                                            char value, 
197                                            [System.Runtime.InteropServices.Optional]
198                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
199                 {
200                         checkRecordNumber(recordNumber,false);
201                         VBFile vbFile = getVBFile(fileNumber);
202                         vbFile.put(value,recordNumber);
203                 }
204
205                 public static void FilePut(int fileNumber, 
206                                            int value, 
207                                            [System.Runtime.InteropServices.Optional]
208                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
209                 {
210                         checkRecordNumber(recordNumber,false);
211                         VBFile vbFile = getVBFile(fileNumber);
212                         vbFile.put(value,recordNumber);
213                 }
214
215                 public static void FilePut(int fileNumber, 
216                                            long value, 
217                                            [System.Runtime.InteropServices.Optional]
218                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
219                 {
220                         checkRecordNumber(recordNumber,false);
221                         VBFile vbFile = getVBFile(fileNumber);
222                         vbFile.put(value,recordNumber);
223                 }
224
225
226                 public static void FilePut(int fileNumber, 
227                                            float value, 
228                                            [System.Runtime.InteropServices.Optional]
229                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
230                 {
231                         checkRecordNumber(recordNumber,false);
232                         VBFile vbFile = getVBFile(fileNumber);
233                         vbFile.put(value,recordNumber);
234                 }
235
236                 public static void FilePut(int fileNumber, 
237                                            double value, 
238                                            [System.Runtime.InteropServices.Optional]
239                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
240                 {
241                         checkRecordNumber(recordNumber,false);
242                         VBFile vbFile = getVBFile(fileNumber);
243                         vbFile.put(value,recordNumber);
244                 }
245
246                 public static void FilePut(int fileNumber,
247                                            String value,
248                                            [System.Runtime.InteropServices.Optional]
249                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber,
250                                            [System.Runtime.InteropServices.Optional]
251                                            [System.ComponentModel.DefaultValue(false)] bool stringIsFixedLength)
252                 {
253                         checkRecordNumber(recordNumber,true);
254                         VBFile vbFile = getVBFile(fileNumber);
255                         vbFile.put(value,recordNumber,stringIsFixedLength);
256                 }
257
258                 public static void FilePut(int fileNumber,
259                                            DateTime value,
260                                            [System.Runtime.InteropServices.Optional]
261                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
262                 {
263                         checkRecordNumber(recordNumber,false);
264                         VBFile vbFile = getVBFile(fileNumber);
265                         vbFile.put(value,recordNumber);
266                 }
267
268                 public static void FileGet(int fileNumber,
269                                            ref bool value,
270                                            [System.Runtime.InteropServices.Optional] 
271                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
272
273                 {
274                         checkRecordNumber(recordNumber,false);
275                         VBFile vbFile = getVBFile(fileNumber);
276                         vbFile.get(out value,recordNumber);
277                 }
278
279                 private static void checkRecordNumber(long recordNumber,bool throwArgExc)
280                 {
281                         if ((recordNumber < 1) && (recordNumber != -1))
282                         {
283                                 if (!throwArgExc)
284                                         throw (IOException) ExceptionUtils.VbMakeException(
285                                                                                            new ArgumentException(
286                                                                                                                  Utils.GetResourceString(
287                                                                                                                                          "Argument_InvalidValue1",
288                                                                                                                                          "RecordNumber")),
289                                                                                            VBErrors.BadRecordNum);
290                                 else
291                                 {
292                                         ExceptionUtils.VbMakeException(VBErrors.BadRecordNum);
293                                         throw new ArgumentException(
294                                                                     Utils.GetResourceString(
295                                                                                             "Argument_InvalidValue1",
296                                                                                             "RecordNumber"));
297                                 }
298
299                         }
300                 }
301
302                 private static VBFile getVBFile(int fileNumber)
303                 {
304                         if ((fileNumber < 1) || (fileNumber > 255))
305                                 throw (IOException) ExceptionUtils.VbMakeException(
306                                                                                    VBErrors.BadFileNameOrNumber);
307                         Object obj = _openFilesMap[fileNumber];
308                         if (obj == null)
309                                 throw (IOException) ExceptionUtils.VbMakeException(
310                                                                                    VBErrors.BadFileNameOrNumber);
311                         return (VBFile)obj;
312                 }
313
314                 private static VBFile getVBFile(String pathName)
315                 {
316                         object o = _fileNameIdMap[pathName];
317                         int fileNumber = o == null ? 0 : (int) o ;
318                         if (fileNumber == 0)
319                                 throw (IOException) ExceptionUtils.VbMakeException(
320                                                                                    VBErrors.BadFileNameOrNumber);
321                         Object obj = _openFilesMap[fileNumber];
322                         if (obj == null)
323                                 throw (IOException) ExceptionUtils.VbMakeException(
324                                                                                    VBErrors.BadFileNameOrNumber);
325                         return (VBFile)obj;
326                 }
327
328                 public static void FileGet(
329                                            int fileNumber,
330                                            ref byte value,
331                                            [System.Runtime.InteropServices.Optional] 
332                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
333
334                 {
335                         checkRecordNumber(recordNumber,false);
336                         VBFile vbFile = getVBFile(fileNumber);
337                         vbFile.get(out value,recordNumber);
338                 }
339
340                 public static void FileGet(
341                                            int fileNumber,
342                                            ref short value,
343                                            [System.Runtime.InteropServices.Optional] 
344                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
345
346                 {
347                         checkRecordNumber(recordNumber,false);
348                         VBFile vbFile = getVBFile(fileNumber);
349                         vbFile.get(out value,recordNumber);
350                 }
351
352                 public static void FileGet(
353                                            int fileNumber,
354                                            ref char value,
355                                            [System.Runtime.InteropServices.Optional] 
356                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
357
358
359                 {
360                         checkRecordNumber(recordNumber,false);
361                         VBFile vbFile = getVBFile(fileNumber);
362                         vbFile.get(out value,recordNumber);
363                 }
364
365
366                 public static void FileGet(int fileNumber, 
367                                            ref int value,
368                                            [System.Runtime.InteropServices.Optional] 
369                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
370                 {
371                         checkRecordNumber(recordNumber,false);
372                         VBFile vbFile = getVBFile(fileNumber);
373                         vbFile.get(out value,recordNumber);
374                 }
375
376                 public static void FileGet(int fileNumber, 
377                                            ref long value, 
378                                            [System.Runtime.InteropServices.Optional] 
379                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
380                 {
381                         checkRecordNumber(recordNumber,false);
382                         VBFile vbFile = getVBFile(fileNumber);
383                         vbFile.get(out value,recordNumber);
384                 }
385
386                 public static void FileGet(int fileNumber,
387                                            ref float value,
388                                            [System.Runtime.InteropServices.Optional] 
389                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
390                 {
391                         checkRecordNumber(recordNumber,false);
392                         VBFile vbFile = getVBFile(fileNumber);
393                         vbFile.get(out value,recordNumber);
394                 }
395
396                 public static void FileGet(int fileNumber,
397                                            ref double value,
398                                            [System.Runtime.InteropServices.Optional] 
399                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
400                                            
401                 {
402                         checkRecordNumber(recordNumber,false);
403                         VBFile vbFile = getVBFile(fileNumber);
404                         vbFile.get(out value,recordNumber);
405                 }
406
407                 public static void FileGet(int fileNumber,
408                                            ref Decimal value,
409                                            [System.Runtime.InteropServices.Optional] 
410                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
411                                            
412                 {
413                         checkRecordNumber(recordNumber,false);
414                         VBFile vbFile = getVBFile(fileNumber);
415                         vbFile.get(out value,recordNumber);
416                 }
417
418                 public static void FileGet(int fileNumber,
419                                            ref string value,
420                                            [System.Runtime.InteropServices.Optional]
421                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber,
422                                            [System.Runtime.InteropServices.Optional]
423                                            [System.ComponentModel.DefaultValue(false)] bool bIgnored)
424                 {
425                         checkRecordNumber(recordNumber,true);
426                         VBFile vbFile = getVBFile(fileNumber);
427                         vbFile.get(ref value,recordNumber,bIgnored);
428                 }
429
430                 public static void FileGet(int fileNumber,
431                                            ref Object value,
432                                            [System.Runtime.InteropServices.Optional] 
433                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
434                 {
435                         checkRecordNumber(recordNumber,false);
436                         VBFile vbFile = getVBFile(fileNumber);
437                         vbFile.get(ref value,recordNumber);
438                 }
439
440                 public static long Seek(int fileNumber)
441                 {
442                         VBFile vbFile = getVBFile(fileNumber);
443                         return vbFile.seek();
444                 }
445
446                 public static void Seek(int fileNumber, long position)
447                 {
448                         VBFile vbFile = getVBFile(fileNumber);
449                         vbFile.seek(position);
450
451                 }
452
453                 public static long Loc(int fileNumber)
454                 {
455                         VBFile vbFile = getVBFile(fileNumber);
456                         return vbFile.getPosition();
457                 }
458
459                 public static long LOF(int fileNumber)
460                 {
461                         VBFile vbFile = getVBFile(fileNumber);
462                         return vbFile.getLength();
463                 }
464
465                 public static void Input(int fileNumber, ref Object value)
466                 {
467                         VBFile vbFile = getVBFile(fileNumber);
468                         if (value != null)
469                         {
470                                 Type type = null;
471
472                                 if (value is bool) {
473                                         bool tmp;
474                                         vbFile.Input(out tmp);
475                                         value = tmp;
476                                 }
477                                 else if (value is byte) {
478                                         byte tmp;
479                                         vbFile.Input(out tmp);
480                                         value = tmp;
481                                 }
482                                 else if (value is char) {
483                                         char tmp;
484                                         vbFile.Input(out tmp);
485                                         value = tmp;
486                                 }
487                                 else if (value is double) {
488                                         double tmp;
489                                         vbFile.Input(out tmp);
490                                         value = tmp;
491                                 }
492                                 else if (value is short) {
493                                         short tmp;
494                                         vbFile.Input(out tmp);
495                                         value = tmp;
496                                 }
497                                 else if (value is int) {
498                                         int tmp;
499                                         vbFile.Input(out tmp);
500                                         value = tmp;
501                                 }
502                                 else if (value is long) {
503                                         long tmp;
504                                         vbFile.Input(out tmp);
505                                         value = tmp;
506                                 }
507                                 else if (value is float) {
508                                         float tmp;
509                                         vbFile.Input(out tmp);
510                                         value = tmp;
511                                 }
512                                 else if (value is Decimal) {
513                                         Decimal tmp;
514                                         vbFile.Input(out tmp);
515                                         value = tmp;
516                                 }
517                                 else if (value is string)
518                                         vbFile.Input((string)value);
519                                 // Come back to it later
520                                 //                      else if (type.get_IsByRef())
521                                 //                              vbFile.Input((ObjectRefWrapper)value[i],false);
522
523                         }
524                 }
525
526                 public static String InputString(int fileNumber, int count)
527                 {
528                         if (count < 0)
529                                 throw (ArgumentException)ExceptionUtils.VbMakeException(VBErrors.IllegalFuncCall);
530                         VBFile vbFile = getVBFile(fileNumber);
531                         if (vbFile.getLength()- vbFile.getPosition() < count)
532                                 throw (EndOfStreamException)ExceptionUtils.VbMakeException(VBErrors.EndOfFile);
533                         return vbFile.InputString(count);
534                 }
535
536                 public static String LineInput(int fileNumber)
537                 {
538                         VBFile vbFile = getVBFile(fileNumber);
539
540                         if (EOF(fileNumber))
541                                 throw new EndOfStreamException("Input past end of file.");
542
543                         return vbFile.readLine();
544                 }
545
546                 public static void Print(int fileNumber, Object[] output)
547                 {
548                         VBFile vbFile = getVBFile(fileNumber);
549                         vbFile.print(output);
550                 }
551
552                 public static void PrintLine(int fileNumber)
553                 {
554                         VBFile vbFile = getVBFile(fileNumber);
555                         vbFile.printLine(null);
556                 }
557
558                 public static void PrintLine(int fileNumber, Object[] output)
559                 {
560                         VBFile vbFile = getVBFile(fileNumber);
561                         vbFile.printLine(output);
562                 }
563
564                 public static void Write(int fileNumber, Object[] output)
565                 {
566                         VBFile vbFile = getVBFile(fileNumber);
567                         vbFile.write(output);
568                 }
569
570                 public static void WriteLine(int fileNumber, Object[] output)
571                 {
572                         VBFile vbFile = getVBFile(fileNumber);
573                         vbFile.writeLine(output);
574                 }
575
576                 public static void Rename(String oldPath, String newPath)
577                 {
578                         FileInfo file = new FileInfo(newPath);
579                         if (file.Exists)
580                                 throw (IOException) ExceptionUtils.VbMakeException(
581                                                                                    VBErrors.FileAlreadyExists);
582                         try
583                         {
584                                 Directory.Move(oldPath, newPath);
585                         }catch (DirectoryNotFoundException e){
586                                 throw (ArgumentException)ExceptionUtils.VbMakeException(VBErrors.IllegalFuncCall);
587                         }
588                 }
589
590                 public static void FileCopy(String source, String destination)
591                 {
592                         DirectoryInfo dir;
593
594                         if ((source == null) || (source.Length == 0))
595                         {
596                                 ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
597                                 throw new ArgumentException(
598                                                             Utils.GetResourceString("Argument_PathNullOrEmpty"));
599                         }
600
601                         if ((destination == null) || (destination.Length == 0))
602                         {
603                                 ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
604                                 throw new ArgumentException(
605                                                             Utils.GetResourceString("Argument_PathNullOrEmpty"));
606                         }
607
608                         FileInfo f = new FileInfo(source);
609                         if (!f.Exists)
610                                 throw (FileNotFoundException) ExceptionUtils.VbMakeException(
611                                                                                              VBErrors.FileNotFound);
612                         if (_fileNameIdMap[source] != null)
613                                 throw (IOException) ExceptionUtils.VbMakeException(
614                                                                                    VBErrors.FileAlreadyOpen);
615                         int lastIndex = destination.LastIndexOf('/');
616
617                         if(lastIndex == -1)
618                                 dir = new DirectoryInfo(".");
619                         else
620                                 dir = new DirectoryInfo(destination.Substring(0,lastIndex));
621
622                         if (!dir.Exists)
623                         {
624                                 ExceptionUtils.VbMakeException(VBErrors.FileAlreadyOpen);
625                                 throw new DirectoryNotFoundException();
626                         }
627
628                         // the file name length is 0
629                         if (destination.Length == lastIndex +1)
630                         {
631                                 throw (IOException)ExceptionUtils.VbMakeException(VBErrors.FileAlreadyOpen);
632
633                         }
634
635                         f = new FileInfo(destination);
636                         if (f.Exists)
637                                 throw (IOException) ExceptionUtils.VbMakeException(
638                                                                                    VBErrors.FileAlreadyExists);
639                         File.Copy(source, destination);
640                 }
641
642                 public static void MkDir(String path)
643                 {
644                         if ((path == null) || (path.Length == 0))
645                         {
646                                 ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
647                                 throw new ArgumentException(
648                                                             Utils.GetResourceString("Argument_PathNullOrEmpty"));
649                         }
650                         if (Directory.Exists(path))
651                                 throw (IOException) ExceptionUtils.VbMakeException(
652                                                                                    VBErrors.PathFileAccess);
653
654                         Directory.CreateDirectory(path);
655                 }
656
657                 public static void Kill(String pathName)
658                 {
659                         if (_fileNameIdMap[pathName] != null)
660                                 throw (IOException) ExceptionUtils.VbMakeException(
661                                                                                    VBErrors.FileAlreadyOpen);
662                         if (!File.Exists(pathName))
663                                 throw (IOException) ExceptionUtils.VbMakeException(
664                                                                                    VBErrors.FileNotFound);
665                         File.Delete(pathName);
666                 }
667
668                 public static void RmDir(String pathName)
669                 {
670                         if (pathName == null || pathName.Length == 0 )
671                         {
672                                 ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
673                                 throw new ArgumentException(pathName);
674                         }
675                         DirectoryInfo dir = new DirectoryInfo(pathName);
676                         if (!dir.Exists)
677                         {
678                                 ExceptionUtils.VbMakeException(VBErrors.PathNotFound);
679                                 throw new DirectoryNotFoundException();
680                         }
681                         if (dir.GetFiles().Length != 0)
682                                 throw (IOException) ExceptionUtils.VbMakeException(
683                                                                                    VBErrors.PathFileAccess);
684                         Directory.Delete(pathName);
685                 }
686
687                 public static FileAttribute  GetAttr(String pathName)
688                 {
689                         if (pathName == null || pathName.Length == 0 ||
690                             pathName.IndexOf('*') != -1 || pathName.IndexOf('?') != -1)
691                         {
692                                 throw (IOException)ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
693                         }
694                         //              File f = new File(pathName);
695                         //              if (!f.exists())
696                         //                      throw (FileNotFoundException)
697                         //                              ExceptionUtils.VbMakeException(VBErrors.FileNotFound);
698                         return (FileAttribute) File.GetAttributes(pathName);
699                 }
700
701                 public static void SetAttr(String pathName, FileAttribute fileAttr)
702                 {
703                         if (pathName == null || pathName.Length == 0 ||
704                             pathName.IndexOf('*') != -1 || pathName.IndexOf('?') != -1)
705                         {
706                                 throw (ArgumentException)ExceptionUtils.VbMakeException(VBErrors.IllegalFuncCall);
707                         }
708                         FileInfo f = new FileInfo(pathName);
709                         if (!f.Directory.Exists)
710                         {
711                                 ExceptionUtils.VbMakeException(VBErrors.PathNotFound);
712                                 throw new DirectoryNotFoundException();
713                         }
714                         if (!f.Exists)
715                         {
716                                 throw (FileNotFoundException)
717                                         ExceptionUtils.VbMakeException(VBErrors.FileNotFound);
718                         }
719
720                         try
721                         {
722                                 File.SetAttributes(pathName, (FileAttributes)fileAttr);
723                         }
724                         catch (ArgumentException e)
725                         {
726                                 throw (ArgumentException) ExceptionUtils.VbMakeException(
727                                                                                          VBErrors.IllegalFuncCall);
728                         }
729                         catch (DirectoryNotFoundException ex)
730                         {
731                                 ExceptionUtils.VbMakeException(VBErrors.PathNotFound);
732                                 throw ex;
733                         }
734                         catch (FileNotFoundException ex)
735                         {
736                                 throw (FileNotFoundException)
737                                         ExceptionUtils.VbMakeException(VBErrors.FileNotFound);
738                         }
739
740                 }
741
742
743                 public static /*synchronized*/ String Dir(String pathName)
744                 {
745                         return Dir(pathName, 0);
746                 }
747
748                 public static /*synchronized*/ String Dir(String pathName, 
749                                                           [System.Runtime.InteropServices.Optional] 
750                                                           [System.ComponentModel.DefaultValue(0)] 
751                                                           FileAttribute fileAttribute)
752                 {
753                         _fileIndex = 0;
754                         _files = null;
755                         _pattern = null;
756
757                         _fileAttrs = (int)fileAttribute;
758
759                         if (pathName == null || pathName.Equals(""))
760                         {
761                                 return "";
762                         }
763
764                         if (FileAttribute.Volume == fileAttribute)
765                                 return "";
766
767
768                         int lastBabkSlashInx = pathName.LastIndexOf('\\');
769                         int lastSlashInx = pathName.LastIndexOf('/');
770                         int maxIndex = (lastSlashInx>lastBabkSlashInx)?lastSlashInx:lastBabkSlashInx; 
771                         String dir = pathName.Substring(0, maxIndex + 1);
772                         String fileName = pathName.Substring(1 + maxIndex);
773                         if (fileName == null || fileName.Length == 0)
774                                 fileName = "*";
775
776                         //        int astricsInx = fileName.indexOf('*');
777                         //        int questionInx = fileName.indexOf('?');
778
779                         //        String pattern;
780                         DirectoryInfo directory = new DirectoryInfo(dir);
781                         //      java.io.File directory = new java.io.File(dir);
782                         //              java.io.File file;
783                         if (!directory.Exists)
784                         {
785                                 // path not found - return empty string
786                                 return "";
787                         }
788
789                         //        if (astricsInx == -1 && questionInx == -1)
790                         //        {
791                         //            pattern = fileName;
792                         //        }
793                         //        else
794                         //        {
795                         //            pattern = Strings.Replace(fileName, ".", "\\.", 1, -1, CompareMethod.Binary);
796                         //            pattern = Strings.Replace(pattern, "*", ".*", 1, -1, CompareMethod.Binary);
797                         //            pattern = Strings.Replace(pattern, "?", ".?", 1, -1, CompareMethod.Binary);
798                         //        }
799
800                         _pattern = fileName;
801                         //        _pattern = Pattern.compile(pattern, Pattern.CASE_INSENSITIVE);
802
803                         _files = directory.GetFiles(_pattern);
804                         String answer;
805                         if (_files == null || _files.Length == 0)
806                         {
807                                 DirectoryInfo[] dirs = directory.GetDirectories(_pattern);
808                                 if (dirs == null || dirs.Length == 0)
809                                 {
810                                         return "";
811                                 }
812                                 answer = dirs[0].Name;            
813                         }
814                         else
815                         {   
816                                 answer = _files[0].Name;
817                         }   
818
819                         _fileIndex++;
820                         _isEndOfFiles = false;
821
822
823                         return answer;
824
825                 }
826
827                 public static /*synchronized*/ String Dir()
828                 {
829                         String name;
830                         if (_files == null || _isEndOfFiles)
831                                 throw new /*Illegal*/ArgumentException("no path has been initiated");
832
833                         if (_fileIndex < _files.Length)
834                         {
835                                 name = _files[_fileIndex].Name;
836                                 _fileIndex++;
837                         }
838                         else
839                         {
840                                 _isEndOfFiles = true;
841                                 name = "";
842                         }
843
844                         return name;
845                 }
846
847                 public static DateTime FileDateTime(String pathName)
848                 {
849                         if (pathName == null || pathName.Length == 0 ||
850                             pathName.IndexOf('*') != -1 || pathName.IndexOf('?') != -1)
851                         {
852                                 ExceptionUtils.VbMakeException(VBErrors.BadFileNameOrNumber);
853                                 throw new ArgumentException(
854                                                             VBUtils.GetResourceString(
855                                                                                       "Argument_InvalidValue1",
856                                                                                       "PathName"));
857                         }
858                         FileInfo f = new FileInfo(pathName);
859                         if (!f.Exists)
860                         {
861                                 DirectoryInfo d = new DirectoryInfo(pathName);
862                                 if (!d.Exists)  
863                                         throw (FileNotFoundException)
864                                                 ExceptionUtils.VbMakeException(VBErrors.FileNotFound);
865                                 return d.LastWriteTime;
866                         }
867                         return f.LastWriteTime;
868                 }
869
870                 public static long FileLen(String pathName)
871                 {
872                         FileInfo f = new FileInfo(pathName);
873                         if (!f.Exists)
874                                 throw new FileNotFoundException(
875                                                                 "file not exists: " + pathName);
876
877                         return f.Length;
878                 }
879
880
881                 internal static String SPC(int count)
882                 {
883                         StringBuilder sb = new StringBuilder(count);
884                         for (int i = 0; i < count; i++)
885                                 sb.Append(' ');
886
887                         return sb.ToString();
888                 }
889
890                 public static int FreeFile()
891                 {
892                         ICollection s = _openFilesMap.Keys;
893
894                         if (s.Count == 0)
895                                 return 1;
896
897                         int [] keyArr = new int[s.Count];
898
899                         s.CopyTo(keyArr, 0);
900
901                         Array.Sort(keyArr);
902                         int i = 0;
903                         for (; i < keyArr.Length - 1; i++)
904                         {
905                                 if ((keyArr[i]+ 1) < keyArr[i + 1])
906                                         break;
907                         }
908
909                         int retVal = keyArr[i]+ 1;
910
911                         if (retVal > 255)
912                         {
913                                 String message = VBUtils.GetResourceString(67);
914                                 throw (IOException)VBUtils.VBException(
915                                                                        new IOException(message),
916                                                                        67);
917                         }
918
919                         return retVal;
920
921                 }
922
923                 public static bool EOF(int fileNumber)
924                 {
925                         bool  retVal = false;
926                         VBFile vbFile = getVBFile(fileNumber);
927                         return vbFile.isEndOfFile();
928                 }
929
930                 // check if a specific number is free
931                 private static bool isFileNumberFree(int fileNumber)
932                 {
933                         return !_openFilesMap.ContainsKey(fileNumber);
934                 }
935
936                 [MonoTODO("If path is another drive, it should change the default folder for that drive, but not switch to it.")]
937                 public static void ChDir (string Path) 
938                 {
939                         if ((Path=="") || (Path==null))
940                                 throw new ArgumentException (Utils.GetResourceString ("Argument_PathNullOrEmpty")); 
941                         try {
942                                 Environment.CurrentDirectory = Path;
943                         }
944                         catch { 
945                                 throw new FileNotFoundException (Utils.GetResourceString ("FileSystem_PathNotFound1", Path));
946                         }
947                 }
948
949
950                 public static void ChDrive(char Drive)
951                 {
952                         Drive = char.ToUpper(Drive, CultureInfo.InvariantCulture);
953                         if ((Drive < 65) || (Drive > 90))
954                         {
955                                 throw new ArgumentException(
956                                                             Utils.GetResourceString("Argument_InvalidValue1", "Drive"));
957                         }
958                         Directory.SetCurrentDirectory(String.Concat(StringType.FromChar(Drive), StringType.FromChar(Path.VolumeSeparatorChar)));
959                 }
960
961                 public static void ChDrive(String Drive)
962                 {
963                         if (Drive != null && Drive.Length != 0)
964                                 FileSystem.ChDrive(Drive[0]);
965                 }
966
967                 public static String CurDir()
968                 {
969                         return Environment.CurrentDirectory;
970                 }
971
972                 public static String CurDir(char Drive)
973                 {
974                         return Directory.GetCurrentDirectory();
975                 }
976
977                 public static void FileGetObject(int fileNumber,
978                                                  ref object value,
979                                                  [System.Runtime.InteropServices.Optional] 
980                                                  [System.ComponentModel.DefaultValue(-1)] long recordNumber) 
981
982
983                 {
984                         checkRecordNumber(recordNumber,true);
985                         VBFile vbFile = getVBFile(fileNumber);
986
987                         Type type = value.GetType();
988
989                         if (type == null || value is string) {
990                                 string tmp = null;
991                                 vbFile.get(ref tmp, recordNumber, false);
992                                 value = tmp;
993                         }
994                         else if ( value is bool) {
995                                 bool tmp;
996                                 vbFile.get(out tmp,recordNumber);
997                                 value = tmp;
998                         }
999                         else if ( value is char) {
1000                                 char tmp;
1001                                 vbFile.get(out tmp,recordNumber);
1002                                 value = tmp;
1003                         }
1004                         else if ( value is byte) {
1005                                 byte tmp;
1006                                 vbFile.get(out tmp,recordNumber);
1007                                 value = tmp;
1008                         }
1009                         else if ( value is short) {
1010                                 short tmp;
1011                                 vbFile.get(out tmp,recordNumber);
1012                                 value = tmp;
1013                         }
1014                         else if ( value is int) {
1015                                 int tmp;
1016                                 vbFile.get(out tmp,recordNumber);
1017                                 value = tmp;
1018                         }
1019                         else if ( value is long) {
1020                                 long tmp;
1021                                 vbFile.get(out tmp,recordNumber);
1022                                 value = tmp;
1023                         }
1024                         else if ( value is float) {
1025                                 float tmp;
1026                                 vbFile.get(out tmp,recordNumber);
1027                                 value = tmp;
1028                         }
1029                         else if ( value is double) {
1030                                 double tmp;
1031                                 vbFile.get(out tmp,recordNumber);
1032                                 value = tmp;
1033                         }
1034                         else if ( value is Decimal) {
1035                                 Decimal tmp;
1036                                 vbFile.get(out tmp,recordNumber);
1037                                 value = tmp;
1038                         }
1039                         else if ( value is DateTime) {
1040                                 DateTime tmp;
1041                                 vbFile.get(out tmp,recordNumber);
1042                                 value = tmp;
1043                         }
1044                         else if (type.IsArray) {
1045                                 // need to figure out how to convert from Object& to Array&
1046                                 // vbFile.get(out value, recordNumber,true,false);
1047                                 // value = tmp;
1048                                 throw new NotImplementedException();
1049                         }
1050                         else
1051                                 throw new NotSupportedException();
1052                 }
1053
1054                 public static void FileGet(int fileNumber,
1055                                            ref DateTime value,
1056                                            [System.Runtime.InteropServices.Optional]
1057                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber)
1058
1059                 {
1060                         checkRecordNumber(recordNumber,true);
1061                         VBFile vbFile = getVBFile(fileNumber);
1062                         vbFile.get(out value,recordNumber);
1063                 }
1064
1065                 [MonoTODO]
1066                 public static void FileGet(int fileNumber, out ValueType value, long recordNumber) 
1067                 {
1068                         throw new NotImplementedException();
1069                 }
1070
1071                 public static void FileGet(int fileNumber,
1072                                            ref Array value,
1073                                            [System.Runtime.InteropServices.Optional] 
1074                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber, 
1075                                            [System.Runtime.InteropServices.Optional] 
1076                                            [System.ComponentModel.DefaultValue(false)] bool arrayIsDynamic, 
1077                                            [System.Runtime.InteropServices.Optional] 
1078                                            [System.ComponentModel.DefaultValue(false)] bool stringIsFixedLength) 
1079
1080
1081                 {
1082                         checkRecordNumber(recordNumber,true);
1083                         VBFile vbFile = getVBFile(fileNumber);
1084                         vbFile.get(ref value,recordNumber,arrayIsDynamic,stringIsFixedLength);
1085                 }
1086
1087                 public static void FilePutObject(int fileNumber,
1088                                                  Object value,
1089                                                  [System.Runtime.InteropServices.Optional]
1090                                                  [System.ComponentModel.DefaultValue(-1)] long recordNumber)
1091
1092                 {
1093                         checkRecordNumber(recordNumber,true);
1094                         VBFile vbFile = getVBFile(fileNumber);
1095                         Type type = value.GetType();
1096                         if(value is string || value == null)
1097                                 vbFile.put((String)value,recordNumber,false);
1098                         else if( value is bool) {
1099                                 vbFile.put((bool)value, recordNumber);
1100                         }
1101                         else if( value is char) {
1102                                 vbFile.put((char)value,recordNumber);
1103                         }
1104                         else if( value is byte) {
1105                                 vbFile.put((byte)value, recordNumber);
1106                         }
1107                         else if( value is short) {
1108                                 vbFile.put((short)value, recordNumber);
1109                         }
1110                         else if( value is int) {
1111                                 vbFile.put((int)value, recordNumber);
1112                         }
1113                         else if( value is long) {
1114                                 vbFile.put((long)value, recordNumber);
1115                         }
1116                         else if( value is float) {
1117                                 vbFile.put((float)value, recordNumber);
1118                         }
1119                         else if( value is double) {
1120                                 vbFile.put((double)value, recordNumber);
1121                         }
1122                         else if( value is Decimal) {
1123                                 vbFile.put((Decimal)value,recordNumber);
1124                         }
1125                         else if( value is DateTime) {
1126                                 vbFile.put((DateTime)value, recordNumber);
1127                         }
1128                         else if(type.IsArray) {
1129                                 vbFile.put(value,recordNumber,true,false);
1130                         }
1131                         else {
1132                                 throw new NotSupportedException();
1133                         }
1134
1135                 }
1136
1137                 private const string obsoleteMsg1 = "Use FilePutObject to write Object types, or";
1138                 private const string obsoleteMsg2 = "coerce FileNumber and RecordNumber to Integer for writing non-Object types";
1139                 private const string obsoleteMsg = obsoleteMsg1 + obsoleteMsg2; 
1140
1141                 [System.ObsoleteAttribute(obsoleteMsg, false)] 
1142                 public static void FilePut(Object FileNumber,
1143                                            Object Value,
1144                                            [System.Runtime.InteropServices.Optional]
1145                                            [System.ComponentModel.DefaultValue(-1)] System.Object RecordNumber)
1146                 {
1147                         throw new ArgumentException(Utils.GetResourceString("UseFilePutObject"));
1148                 }
1149
1150                 [MonoTODO]
1151                 public static void FilePut(int FileNumber,
1152                                            ValueType Value,
1153                                            [System.Runtime.InteropServices.Optional]
1154                                            [System.ComponentModel.DefaultValue(-1)] System.Int64 RecordNumber)
1155
1156                 {
1157                         throw new NotImplementedException();
1158                 }
1159
1160                 public static void FilePut(int fileNumber,
1161                                            Array value,
1162                                            [System.Runtime.InteropServices.Optional]
1163                                            [System.ComponentModel.DefaultValue(-1)] long recordNumber,
1164                                            [System.Runtime.InteropServices.Optional]
1165                                            [System.ComponentModel.DefaultValue(false)] bool arrayIsDynamic,
1166                                            [System.Runtime.InteropServices.Optional]
1167                                            [System.ComponentModel.DefaultValue(false)] bool stringIsFixedLength)
1168                 {
1169                         checkRecordNumber(recordNumber,true);
1170                         VBFile vbFile = getVBFile(fileNumber);
1171                         vbFile.put(value,recordNumber,arrayIsDynamic,stringIsFixedLength);
1172                 }
1173
1174                 public static void FilePut(int fileNumber,
1175                                            Decimal value,
1176                                            [System.Runtime.InteropServices.Optional]
1177                                            [System.ComponentModel.DefaultValue(-1)] long  recordNumber)
1178                                            
1179                 {
1180                         checkRecordNumber(recordNumber,true);
1181                         VBFile vbFile = getVBFile(fileNumber);
1182                         vbFile.put(value,recordNumber);
1183                 }
1184
1185                 public static void Input(int fileNumber, ref bool Value)
1186                 {
1187
1188                         VBFile vbFile = getVBFile(fileNumber);
1189                         vbFile.Input(out Value);
1190                 }
1191
1192                 public static void Input(int fileNumber, ref byte Value)
1193                 {
1194                         VBFile vbFile = getVBFile(fileNumber);
1195                         vbFile.Input(out Value);
1196                 }
1197
1198                 public static void Input(int fileNumber, ref short Value)
1199                 {
1200                         VBFile vbFile = getVBFile(fileNumber);
1201                         vbFile.Input(out Value);
1202                 }
1203
1204                 public static void Input(int fileNumber, ref int Value)
1205                 {
1206                         VBFile vbFile = getVBFile(fileNumber);
1207                         vbFile.Input(out Value);
1208                 }
1209
1210                 public static void Input(int fileNumber, ref long Value)
1211                 {
1212                         VBFile vbFile = getVBFile(fileNumber);
1213                         vbFile.Input(out Value);
1214                 }
1215
1216                 public static void Input(int fileNumber, ref char Value)
1217                 {
1218                         VBFile vbFile = getVBFile(fileNumber);
1219                         vbFile.Input(out Value);
1220                 }
1221
1222                 public static void Input(int fileNumber, ref float Value)
1223                 {
1224                         VBFile vbFile = getVBFile(fileNumber);
1225                         vbFile.Input(out Value);
1226                 }
1227
1228                 public static void Input(int fileNumber, ref double Value)
1229                 {
1230                         VBFile vbFile = getVBFile(fileNumber);
1231                         vbFile.Input(out Value);
1232                 }
1233
1234                 public static void Input(int fileNumber, ref Decimal Value)
1235                 {
1236                         VBFile vbFile = getVBFile(fileNumber);
1237                         vbFile.Input(out Value);
1238                 }
1239
1240                 public static void Input(int fileNumber, ref DateTime Value)
1241                 {
1242                         VBFile vbFile = getVBFile(fileNumber);
1243                         vbFile.Input(out Value);
1244                 }
1245
1246                 public static void Input(int fileNumber, ref string Value)
1247                 {
1248                         VBFile vbFile = getVBFile(fileNumber);
1249                         vbFile.Input(out Value);
1250                 }
1251
1252
1253                 //      public static void Input$V$FileSystem$ILSystem_Object$$$(int fileNumber, ObjectRefWrapper Value)
1254                 //      {
1255                 //              VBFile vbFile = getVBFile(fileNumber);
1256                 //              vbFile.Input(Value,false);
1257                 //      }
1258
1259                 [MonoTODO]
1260                 public static void Lock(int fileNumber) 
1261                 {
1262                         throw new NotImplementedException("The method Lock in class FileSystem is not supported");
1263                 }
1264
1265                 [MonoTODO]
1266                 public static void Lock(int FileNumber, long Record) 
1267                 {
1268                         throw new NotImplementedException("The method Lock in class FileSystem is not supported");
1269                 }
1270
1271                 [MonoTODO]
1272                 public static void Lock(int FileNumber, long FromRecord, long ToRecord) 
1273                 {
1274                         throw new NotImplementedException("The method Lock in class FileSystem is not supported");
1275                 }
1276
1277                 [MonoTODO]
1278                 public static void Unlock(int FileNumber) 
1279                 {
1280                         throw new NotImplementedException("The method Unlock in class FileSystem is not supported");
1281                 }
1282
1283                 [MonoTODO]
1284                 public static void Unlock(int FileNumber, long Record) 
1285                 {
1286                         throw new NotImplementedException("The method Unlock in class FileSystem is not supported");
1287                 }
1288
1289                 [MonoTODO]
1290                 public static void Unlock(int FileNumber, long FromRecord, long ToRecord) 
1291                 {
1292                         throw new NotImplementedException("The method Unlock in class FileSystem is not supported");
1293                 }
1294
1295                 public static void FileWidth(int fileNumber, int RecordWidth)
1296                 {
1297                         VBFile vbFile = getVBFile(fileNumber);
1298                         vbFile.width(fileNumber,RecordWidth);
1299                 }
1300
1301                 public static TabInfo TAB()
1302                 {
1303                         return new TabInfo((short) - 1);
1304                 }
1305
1306                 public static TabInfo TAB(short Column)
1307                 {
1308                         return new TabInfo(Column);
1309                 }
1310
1311                 public static SpcInfo SPC(short Count)
1312                 {
1313                         return new SpcInfo(Count);
1314                 }
1315
1316                 public static OpenMode FileAttr(int fileNumber)
1317                 {
1318                         VBFile vbFile = getVBFile(fileNumber);
1319                         return (OpenMode) vbFile.getMode();
1320                 }
1321         }
1322
1323         class VBStreamWriter : StreamWriter
1324         {
1325                 int _currentColumn;
1326                 int _width;
1327
1328                 public VBStreamWriter(string fileName):base(fileName)
1329                 {
1330                 }
1331
1332                 public VBStreamWriter(string fileName, bool append):base(fileName, append)
1333                 {
1334                 }
1335         }
1336
1337         //TODO: FileFilters from Mainsoft code
1338
1339 }