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