2005-01-31 Zoltan Varga <vargaz@freemail.hu>
[mono.git] / mcs / class / Microsoft.VisualBasic / Microsoft.VisualBasic / RandomVBFile.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 using System;
25 using System.Text;
26 using System.IO;
27 using Microsoft.VisualBasic;
28 using Microsoft.VisualBasic.CompilerServices;
29
30
31 /**
32  * @author along
33  */
34 public class RandomVBFile : BaseVBFile
35 {
36         protected BinaryWriter _binaryWrite;
37         protected BinaryReader _binaryReader;
38         protected Encoding _encoding;
39         private int _width;
40     
41         public RandomVBFile(String fileName, OpenMode mode, OpenAccess access,int recordLength)
42                 : base(fileName, mode, 
43                        (access == OpenAccess.Default) ? OpenAccess.ReadWrite : (OpenAccess) access, recordLength)
44         {
45                 
46                 if (access != OpenAccess.Read)    
47                         _binaryWrite = new BinaryWriter(_fileStream);
48                 if (access != OpenAccess.Write) 
49                         _binaryReader = new BinaryReader(_fileStream);
50                 _encoding = new UTF8Encoding(false, true);
51         }
52     
53         protected bool getBoolean(long recordNumber,bool isSetRecord)
54         {
55                 if (isSetRecord)
56                         setRecord(recordNumber);
57                 bool tmp = _binaryReader.ReadBoolean();
58                 return tmp;
59         }
60         /* (non-Javadoc)
61          * @see Microsoft.VisualBasic.VBFile#getChar(long)
62          */
63         protected char getChar(long recordNumber,bool isSetRecord)
64         {
65                 if (isSetRecord)
66                         setRecord(recordNumber);
67                 char tmp = _binaryReader.ReadChar();
68                 return tmp;        
69         }
70         /* (non-Javadoc)
71          * @see Microsoft.VisualBasic.VBFile#getByte(long)
72          */
73         protected byte getByte(long recordNumber,bool isSetRecord)
74         {
75                 if (isSetRecord)
76                         setRecord(recordNumber);
77                 int tmp = _binaryReader.ReadByte();
78                 return (byte)tmp; 
79         }
80         /* (non-Javadoc)
81          * @see Microsoft.VisualBasic.VBFile#getShort(long)
82          */
83         protected short getShort(long recordNumber,bool isSetRecord)
84         {
85                 if (isSetRecord)
86                         setRecord(recordNumber);
87                 short tmp = _binaryReader.ReadInt16();
88                 return tmp;
89         }
90         /* (non-Javadoc)
91          * @see Microsoft.VisualBasic.VBFile#getInt(long)
92          */
93         protected int getInt(long recordNumber,bool isSetRecord)
94         {
95                 if (isSetRecord)
96                         setRecord(recordNumber);
97                 int tmp = _binaryReader.ReadInt32();
98                 return tmp;
99         }
100         /* (non-Javadoc)
101          * @see Microsoft.VisualBasic.VBFile#getLong(long)
102          */
103         protected long getLong(long recordNumber,bool isSetRecord)
104         {
105                 if (isSetRecord)
106                         setRecord(recordNumber);
107                 long tmp = _binaryReader.ReadInt64();
108                 return tmp;
109         }
110         /* (non-Javadoc)
111          * @see Microsoft.VisualBasic.VBFile#getFloat(long)
112          */
113         protected float getFloat(long recordNumber,bool isSetRecord)
114         {
115                 if (isSetRecord)
116                         setRecord(recordNumber);
117                 float tmp = _binaryReader.ReadSingle();
118                 return tmp;
119         }
120         /* (non-Javadoc)
121          * @see Microsoft.VisualBasic.VBFile#getDouble(long)
122          */
123         protected double getDouble(long recordNumber,bool isSetRecord)
124         {
125                 if (isSetRecord)
126                         setRecord(recordNumber);
127                 double tmp = _binaryReader.ReadDouble();
128                 return tmp;
129         }
130
131         protected Decimal getDecimal(long recordNumber,bool isSetRecord)
132         {
133                 if (isSetRecord)
134                         setRecord(recordNumber);
135                 Decimal tmp = _binaryReader.ReadDecimal();
136                 return tmp;
137         }
138
139         protected DateTime getDateTime(long recordNumber,bool isSetRecord)
140         {
141                 if (isSetRecord)
142                         setRecord(recordNumber);
143
144                 double tmp = _binaryReader.ReadDouble();       
145                 return DateTime.FromOADate(tmp);
146         }
147    
148         public override void get(out bool value,long recordNumber)
149         {
150                 checkReadPermision();
151                 value = getBoolean(recordNumber,true)? true : false;        
152         } 
153
154         public override void get(out byte value,long recordNumber)
155         {
156                 checkReadPermision();
157                 value = getByte(recordNumber,true);
158         }
159
160         public override void get(out short value,long recordNumber)
161         {
162                 checkReadPermision();
163                 value = getShort(recordNumber,true);
164         }
165
166         public override void get(out char value,long recordNumber)
167         {
168                 checkReadPermision();
169                 value = getChar(recordNumber,true);
170         }
171
172         public override void get(out int value, long recordNumber)
173         {
174                 checkReadPermision();
175                 value = getInt(recordNumber,true);
176         }
177
178         public override void get(out long value, long recordNumber)
179         {
180                 checkReadPermision();
181                 value = getLong(recordNumber,true);
182         }
183
184         public override void get(out float value,long recordNumber)
185         {
186                 checkReadPermision();
187                 value = getFloat(recordNumber,true);
188         }
189
190         public override void get(out double value,long recordNumber)
191         {
192                 checkReadPermision();
193                 value = getDouble(recordNumber,true);
194         }
195     
196         public override void get(out DateTime value,long recordNumber)
197         {
198                 checkReadPermision();
199                 value = getDateTime(recordNumber,true);
200         }
201     
202         public override void get(out Decimal value,long recordNumber)
203         {
204                 checkReadPermision();
205                 Decimal tmp = getDecimal(recordNumber,true);       
206                 value = tmp;
207         }
208
209         public override void get(ref string str, long recordNumber, bool bIgnored)
210         {
211                 checkReadPermision();
212                 int strLen = 0;
213                 if (str == null || str.Length == 0)
214                         strLen = _binaryReader.ReadInt16();
215                 else
216                         strLen = str.Length;   
217                 str = new String(_binaryReader.ReadChars(strLen));
218         } 
219
220         public override void get(ref object value,long recordNumber)
221         {
222                 checkReadPermision();
223                 if (value.GetType().IsArray) {
224                         // need to figure out how to convert from Object& to Array &
225                         // get(value,recordNumber,false,false); 
226                         throw new NotImplementedException();
227                 }
228                 else
229                 {        
230                         setRecord(recordNumber);           
231                         value = _binaryReader.ReadString();
232                 }        
233         }
234     
235         public override void get(ref Array value, long recordNum, bool arrIsDynamic, bool strIsFixedLen)
236         {
237                 checkReadPermision();
238                 Object arr = value;
239
240                 Type type = arr.GetType().GetElementType();
241                 int  rank = (arr as Array).Rank;
242                 if (rank == 0 || rank > 2)
243                         throw new ArgumentException(Utils.GetResourceString("Argument_UnsupportedArrayDimensions"));
244
245                 if (getPosition() >= getLength())
246                 {
247                         return;
248                 }
249                 base.setRecord(recordNum);
250                 int strLen = 0;
251                 Object obj;
252                 if (strIsFixedLen && (type == typeof(string)))
253                 {
254                         if (rank == 1)
255                                 obj = (arr as Array).GetValue(0);
256                         else             
257                                 obj = (arr as Array).GetValue(0, 0);
258                         if (obj != null)
259                                 strLen = ((String) obj).Length;
260                         if (strLen == 0)
261                                 throw new ArgumentException(
262                                                             Utils.GetResourceString(
263                                                                                     "Argument_InvalidFixedLengthString"));            
264                 }      
265                 int len1 = (arr as Array).GetLength(0);
266                 int len2 = (rank == 2) ? (arr as Array).GetLength(1):0;
267                 String val = "";
268
269                 if (rank == 1)
270                 {
271                         for (int i = 0 ; i < len1 ; i++)
272                         {
273                                 if (strIsFixedLen)
274                                         val = new String(_binaryReader.ReadChars(strLen));                
275                                 else
276                                 {                    
277                                         strLen = _binaryReader.ReadInt16();
278                                         val = new String(_binaryReader.ReadChars(strLen));
279                                 }
280                                 (arr as Array).SetValue(val,i);                                
281                         }
282                 }
283                 else
284                 {
285                         for (int i = 0 ; i < len1 ; i++)
286                         {
287                                 for (int j = 0 ; j < len2 ; j++)
288                                 {                
289                                         val = this._binaryReader.ReadString();                
290                                         if (strIsFixedLen && val.Length != strLen)
291                                                 throw new ArgumentException(
292                                                                             Utils.GetResourceString(
293                                                                                                     "Argument_InvalidFixedLengthString"));
294                                         (arr as Array).SetValue(val,i,j);
295                                 }                                 
296                         }
297                 }       
298         }     
299
300     
301         public override void put(bool val, long recordNumber)
302         {
303                 checkWritePermision();
304                 putBoolean(val,recordNumber,true);        
305         }
306         /* (non-Javadoc)
307          * @see Microsoft.VisualBasic.VBFile#putChar(char, long)
308          */
309         public override void put(byte value, long recordNumber)
310         {
311                 checkWritePermision();
312                 putByte(value,recordNumber,true);   
313         }
314
315         public override void put(short value, long recordNumber)
316         {
317                 checkWritePermision();
318                 putShort(value,recordNumber,true); 
319         }
320     
321
322         public override void put( char value, long recordNumber)
323         {
324                 checkWritePermision();
325                 putChar(value,recordNumber,true); 
326         }
327     
328
329         public override void put(int value, long recordNumber)
330         {
331                 checkWritePermision();
332                 putInt(value,recordNumber,true); 
333         }
334
335         public override void put(long value, long recordNumber)
336         {
337                 checkWritePermision();
338                 putLong(value,recordNumber,true); 
339         }
340
341         public override void put(float value, long recordNumber)
342         {
343                 checkWritePermision();
344                 putSingle(value,recordNumber,true); 
345         }
346
347         public override void put(double value, long recordNumber)
348         {
349                 checkWritePermision();
350                 putDouble(value,recordNumber,true); 
351         }
352     
353         public override void put(Decimal value, long recordNumber)
354         {
355                 checkWritePermision();
356                 putDecimal(value,recordNumber,true); 
357         } 
358
359         public override void put(String value,long recordNumber,bool stringIsFixedLength)
360         {
361                 checkWritePermision();
362                 if (value.IndexOf('\"') == -1)
363                         putString(value,recordNumber,stringIsFixedLength,true);
364                 else
365                 {
366                         for (int i = 0 ; i < value.Length;i++)
367                                 _binaryWrite.Write(value[i]); 
368                     
369                 }
370         }
371     
372         public override void put(Object arr,long recordNum,
373                                  bool arrIsDynamic,bool strIsFixedLen)
374         {
375                 checkWritePermision();
376                 if (arr == null)
377                 {
378                         throw new ArgumentException(
379                                                     Utils.GetResourceString("Argument_ArrayNotInitialized"));
380                 }
381                 Type type = arr.GetType().GetElementType();
382                 int  rank = (arr as Array).Rank;
383                 if (rank == 0 || rank > 2)
384                         throw new ArgumentException(
385                                                     Utils.GetResourceString("Argument_UnsupportedArrayDimensions"));
386                 base.setRecord(recordNum);
387                 int strLen = 0;
388                 Object obj;             
389                 if (strIsFixedLen && (type == typeof(string)))
390                 {
391                         if (rank == 1)
392                                 obj = (arr as Array).GetValue(0);
393                         else             
394                                 obj = (arr as Array).GetValue(0, 0);
395                         if (obj != null)
396                                 strLen = ((String) obj).Length;
397                         if (strLen == 0)
398                                 throw new ArgumentException(
399                                                             Utils.GetResourceString(
400                                                                                     "Argument_InvalidFixedLengthString"));            
401                 }      
402                 int len1 = (arr as Array).GetLength(0);
403                 int len2 = (rank == 2) ? (arr as Array).GetLength(1) : 0;
404                 if (rank == 1)
405                 {
406                         for (int i = 0 ; i < len1 ; i++)
407                         {                
408                                 putObject((arr as Array).GetValue(i), recordNum , type,strIsFixedLen);                                 
409                         }
410                 }
411                 else
412                 {
413                         for (int i = 0 ; i < len1 ; i++)
414                         {
415                                 for (int j = 0 ; j < len2 ; j++)
416                                 {                
417                                         putObject((arr as Array).GetValue(i), recordNum , type,strIsFixedLen);                                 
418                                 }                                 
419                         }
420                 }           
421         }
422     
423         private void putObject(Object obj ,long recordNumber ,Type type,bool strIsFixedLen)
424         {
425                 if (obj is string)
426                         putString((string)obj,recordNumber,strIsFixedLen,false);
427                 else if (obj is bool)
428                         putBoolean((bool)obj, recordNumber,false);
429                 else if (obj is char)
430                         putChar((char)obj, recordNumber,false);
431                 else if (obj is byte)
432                         putByte((byte)obj, recordNumber,false);
433                 else if (obj is short)
434                         putShort((short)obj,recordNumber,false);
435                 else if (obj is int)
436                         putInt((int)obj, recordNumber,false);
437                 else if (obj is long)
438                         putLong((long)obj, recordNumber,false);
439                 else if (obj is double)
440                         putDouble((double)obj,recordNumber,false);
441                 else if (obj is float)
442                         putSingle((float)obj, recordNumber,false);
443                 else if (obj is DateTime)
444                         putDatetime((DateTime)obj,recordNumber,false);        
445           
446         }
447
448         public override void put(DateTime value,long recordNumber)
449         {
450                 checkWritePermision();
451                 putDatetime(value,recordNumber,true);          
452         }
453     
454         protected void putBoolean(bool val, long recordNumber,bool isSetRecord)
455         {
456                 if (isSetRecord)
457                         setRecord(recordNumber);
458                 checkLength(2);
459                 if (val)
460                         _binaryWrite.Write(val);
461                 else
462                         _binaryWrite.Write(val);
463                 //  setPosition(getPosition()+2);
464         }
465         /* (non-Javadoc)
466          * @see Microsoft.VisualBasic.VBFile#putChar(char, long)
467          */
468         protected void putChar(char val, long recordNumber,bool isSetRecord)
469         {
470                 if (isSetRecord)
471                         setRecord(recordNumber);
472                 this.checkLength(2);
473                 _binaryWrite.Write(val);        
474                 //  setPosition(getPosition()+2);
475         }
476     
477         /* (non-Javadoc)
478          * @see Microsoft.VisualBasic.VBFile#putShort(short, long)
479          */
480         protected void putShort(short val, long recordNumber,bool isSetRecord)
481         {
482                 if (isSetRecord)
483                         setRecord(recordNumber);
484                 this.checkLength(2);
485                 _binaryWrite.Write(val);        
486                 //  setPosition(getPosition()+2);
487         }
488     
489         protected void putByte(byte val, long recordNumber,bool isSetRecord)
490         {
491                 if (isSetRecord)
492                         setRecord(recordNumber);
493                 this.checkLength(2);
494                 _binaryWrite.Write(val);        
495                 //   setPosition(getPosition()+2);
496         }
497         /* (non-Javadoc)
498          * @see Microsoft.VisualBasic.VBFile#putInt(int, long)
499          */
500         protected void putInt(int val, long recordNumber,bool isSetRecord)
501         {
502                 if (isSetRecord)
503                         setRecord(recordNumber);
504                 this.checkLength(4);
505                 _binaryWrite.Write(val);        
506                 //  setPosition(getPosition()+4);
507         }
508         /* (non-Javadoc)
509          * @see Microsoft.VisualBasic.VBFile#putLong(long, long)
510          */
511         protected void putLong(long val, long recordNumber,bool isSetRecord)
512         {
513                 if (isSetRecord)
514                         setRecord(recordNumber);
515                 this.checkLength(8);
516                 _binaryWrite.Write(val);        
517                 //  setPosition(getPosition()+8);
518         }
519         /* (non-Javadoc)
520          * @see Microsoft.VisualBasic.VBFile#putFloat(float, long)
521          */
522         protected void putSingle(float val, long recordNumber,bool isSetRecord)
523         {
524                 if (isSetRecord)
525                         setRecord(recordNumber);
526                 this.checkLength(4);
527                 _binaryWrite.Write(val);        
528                 // setPosition(getPosition()+4);
529         }
530         /* (non-Javadoc)
531          * @see Microsoft.VisualBasic.VBFile#putDouble(double, long)
532          */
533         protected void putDouble(double val, long recordNumber,bool isSetRecord)
534         {
535                 if (isSetRecord)
536                         setRecord(recordNumber);
537                 this.checkLength(8);
538                 _binaryWrite.Write(val);        
539                 //  setPosition(getPosition()+8);
540         }
541     
542         protected void putDecimal(Decimal val, long recordNumber,bool isSetRecord)
543         {
544                 if (isSetRecord)
545                         setRecord(recordNumber);
546                 this.checkLength(8);
547                 _binaryWrite.Write(val);        
548                 //  setPosition(getPosition()+8);
549         }
550     
551         protected void putDatetime(DateTime val, long recordNumber,bool isSetRecord)
552         {
553                 if (isSetRecord)
554                         setRecord(recordNumber);
555                 this.checkLength(8);
556                 _binaryWrite.Write(val.ToOADate());        
557                 //  setPosition(getPosition()+8);
558         }  
559     
560         public void putString(
561                               String value,
562                               long recordNumber,
563                               bool stringIsFixedLength,bool isSetRecord)
564         {
565                 if (value == null)
566                         value = "";
567                 int byteCount = _encoding.GetByteCount(value);
568                 if (isSetRecord)
569                         setRecord(recordNumber);
570                 if (stringIsFixedLength)
571                         checkLength(byteCount);
572                 else
573                 {
574                         checkLength(byteCount+2);
575                         _binaryWrite.Write((short)byteCount);
576                 }
577                 if (byteCount != 0)
578                         for (int i = 0 ; i < byteCount ; i++)
579                                 _binaryWrite.Write(value[i]);
580                 //  setPosition(getPosition()+((stringIsFixedLength) ? byteCount :byteCount+2));
581         }
582     
583         public override long seek()
584         {
585                 if (_recordLen == 0)
586                         throw ExceptionUtils.VbMakeException(VBErrors.InternalError);
587                 return ((getPosition() + _recordLen - 1) / _recordLen);
588         }
589     
590         public override void seek(long position)
591         {
592                 _fileStream.Position = position;
593         }
594     
595         public override bool isEndOfFile()
596         {
597                 return (this._fileStream.Length == this._fileStream.Position);
598         }
599     
600         public override void width(int fileNumber, int RecordWidth)
601         {
602                 if (RecordWidth < 0 || RecordWidth > 255)
603                         throw (ArgumentException) ExceptionUtils.VbMakeException(
604                                                                                  VBErrors.IllegalFuncCall);
605                 _width = RecordWidth;
606         }    
607    
608 }