Advertisement
Guest User

Encoder

a guest
Apr 22nd, 2016
439
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.92 KB | None | 0 0
  1.         // Read an entire standard DBF file into a DataTable
  2.         public static DataTable EncodedDataTable(string dbfFile)
  3.         {
  4.             long start = DateTime.Now.Ticks;
  5.             DataTable dt = new DataTable();
  6.             BinaryReader recReader;
  7.             string number;
  8.             string year;
  9.             string month;
  10.             string day;
  11.             long lDate;
  12.             long lTime;
  13.             DataRow row;
  14.             int fieldIndex;
  15.  
  16.             // If there isn't even a file, just return an empty DataTable
  17.             if ((false == File.Exists(dbfFile)))
  18.             {
  19.                 return dt;
  20.             }
  21.  
  22.             BinaryReader br = null;
  23.             try
  24.             {
  25.                 // Read the header into a buffer
  26.                 br = new BinaryReader(File.OpenRead(dbfFile));
  27.                 byte[] buffer = br.ReadBytes(Marshal.SizeOf(typeof(DBFHeader)));
  28.  
  29.                 // Marshall the header into a DBFHeader structure
  30.                 GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  31.                 DBFHeader header = (DBFHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(DBFHeader));
  32.                 handle.Free();
  33.  
  34.                 // Read in all the field descriptors. Per the spec, 13 (0D) marks the end of the field descriptors
  35.                 ArrayList fields = new ArrayList();
  36.                 while ((13 != br.PeekChar()))
  37.                 {
  38.                     buffer = br.ReadBytes(Marshal.SizeOf(typeof(FieldDescriptor)));
  39.                     handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
  40.                     fields.Add((FieldDescriptor)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(FieldDescriptor)));
  41.                     handle.Free();
  42.                 }
  43.  
  44.                 // Read in the first row of records, we need this to help determine column types below
  45.                 ((FileStream)br.BaseStream).Seek(header.headerLen + 1, SeekOrigin.Begin);
  46.                 buffer = br.ReadBytes(header.recordLen);
  47.                 recReader = new BinaryReader(new MemoryStream(buffer));
  48.  
  49.                 // Usput generiramo strukturu
  50.                 Struktura = new DataTable();
  51.                 Struktura.Columns.Add("NAME", typeof(string));
  52.                 Struktura.Columns.Add("TYPE", typeof(string));
  53.                 Struktura.Columns.Add("WIDTH", typeof(long));
  54.                 Struktura.Columns.Add("DECIMAL", typeof(long));
  55.  
  56.                 // Create the columns in our new DataTable
  57.  
  58.                 DataColumn col = null;
  59.                 foreach (FieldDescriptor field in fields)
  60.                 {
  61.                     number = Encoding.ASCII.GetString(recReader.ReadBytes(field.fieldLen));
  62.  
  63.                     switch (field.fieldType)
  64.                     {
  65.                         case 'N':
  66.                             if (number.IndexOf(".") > -1)
  67.                             {
  68.                                 col = new DataColumn(field.fieldName, typeof(decimal));
  69.                             }
  70.                             else
  71.                             {
  72.                                 col = new DataColumn(field.fieldName, typeof(long));
  73.                             }
  74.                             Struktura.Rows.Add(field.fieldName, "N", field.fieldLen, field.count);
  75.                             break;
  76.                         case 'C':
  77.                             col = new DataColumn(field.fieldName, typeof(string));
  78.                             Struktura.Rows.Add(field.fieldName, "C", field.fieldLen, field.count);
  79.                             break;
  80.                         case 'T':
  81.                             // You can uncomment this to see the time component in the grid
  82.                             //col = new DataColumn(field.fieldName, typeof(string));
  83.                             col = new DataColumn(field.fieldName, typeof(DateTime));
  84.                             Struktura.Rows.Add(field.fieldName, "T", field.fieldLen, field.count);
  85.                             break;
  86.                         case 'D':
  87.                             col = new DataColumn(field.fieldName, typeof(DateTime));
  88.                             Struktura.Rows.Add(field.fieldName, "D", field.fieldLen, field.count);
  89.                             break;
  90.                         case 'L':
  91.                             col = new DataColumn(field.fieldName, typeof(bool));
  92.                             Struktura.Rows.Add(field.fieldName, "L", field.fieldLen, field.count);
  93.                             break;
  94.                         case 'F':
  95.                             col = new DataColumn(field.fieldName, typeof(Double));
  96.                             Struktura.Rows.Add(field.fieldName, "F", field.fieldLen, field.count);
  97.                             break;
  98.                     }
  99.                     dt.Columns.Add(col);
  100.                 }
  101.  
  102.                 Struktura.AcceptChanges();
  103.  
  104.                 // Skip past the end of the header.
  105.                 ((FileStream)br.BaseStream).Seek(header.headerLen, SeekOrigin.Begin);
  106.  
  107.                 // Read in all the records
  108.                 for (int counter = 0; counter <= header.numRecords - 1; counter++)
  109.                 {
  110.                     // First we'll read the entire record into a buffer and then read each field from the buffer
  111.                     // This helps account for any extra space at the end of each record and probably performs better
  112.                     buffer = br.ReadBytes(header.recordLen);
  113.                     recReader = new BinaryReader(new MemoryStream(buffer));
  114.  
  115.                     // All dbf field records begin with a deleted flag field. Deleted - 0x2A (asterisk) else 0x20 (space)
  116.                     if (recReader.ReadChar() == '*')
  117.                     {
  118.                         continue;
  119.                     }
  120.  
  121.                     // Loop through each field in a record
  122.                     fieldIndex = 0;
  123.                     row = dt.NewRow();
  124.                     foreach (FieldDescriptor field in fields)
  125.                     {
  126.                         switch (field.fieldType)
  127.                         {
  128.                             case 'N':  // Number
  129.                                 // If you port this to .NET 2.0, use the Decimal.TryParse method
  130.                                 number = Encoding.ASCII.GetString(recReader.ReadBytes(field.fieldLen));
  131.                                 if (IsNumber(number))
  132.                                 {
  133.                                     var decimalCount = field.count; //<- Added this
  134.                                     //REPLACED THIS: if (number.IndexOf(".") > -1) FOR:
  135.                                     if (number.IndexOf(".") > -1 || decimalCount > 0)
  136.                                     {
  137.                                         //REPLACED THIS: row[fieldIndex] = decimal.Parse(number); FOR:
  138.                                         row[fieldIndex] = decimal.Parse(number, System.Globalization.CultureInfo.InvariantCulture);
  139.                                     }
  140.                                     else
  141.                                     {
  142.                                         row[fieldIndex] = Convert.ToInt64(number);
  143.                                     }
  144.                                 }
  145.                                 else
  146.                                 {
  147.                                     row[fieldIndex] = 0;
  148.                                 }
  149.                                 break;
  150.  
  151.                             case 'C': // String *** Enkodirano 437 u 852
  152.                                 row[fieldIndex] = EncodeString(Encoding.GetEncoding(852).GetString(recReader.ReadBytes(field.fieldLen)));
  153.                                 //row[fieldIndex] = Encoding.ASCII.GetString(recReader.ReadBytes(field.fieldLen));
  154.                                 break;
  155.  
  156.                             case 'D': // Date (YYYYMMDD)
  157.                                 year = Encoding.ASCII.GetString(recReader.ReadBytes(4));
  158.                                 month = Encoding.ASCII.GetString(recReader.ReadBytes(2));
  159.                                 day = Encoding.ASCII.GetString(recReader.ReadBytes(2));
  160.                                 row[fieldIndex] = System.DBNull.Value;
  161.                                 try
  162.                                 {
  163.                                     if (IsNumber(year) && IsNumber(month) && IsNumber(day))
  164.                                     {
  165.                                         if ((Int32.Parse(year) > 1900))
  166.                                         {
  167.                                             row[fieldIndex] = new DateTime(Int32.Parse(year), Int32.Parse(month), Int32.Parse(day));
  168.                                         }
  169.                                     }
  170.                                 }
  171.                                 catch
  172.                                 { }
  173.  
  174.                                 break;
  175.  
  176.                             case 'T': // Timestamp, 8 bytes - two integers, first for date, second for time
  177.                                 // Date is the number of days since 01/01/4713 BC (Julian Days)
  178.                                 // Time is hours * 3600000L + minutes * 60000L + Seconds * 1000L (Milliseconds since midnight)
  179.                                 lDate = recReader.ReadInt32();
  180.                                 lTime = recReader.ReadInt32() * 10000L;
  181.                                 row[fieldIndex] = JulianToDateTime(lDate).AddTicks(lTime);
  182.                                 break;
  183.  
  184.                             case 'L': // Boolean (Y/N)
  185.                                 if ('Y' == recReader.ReadByte())
  186.                                 {
  187.                                     row[fieldIndex] = true;
  188.                                 }
  189.                                 else
  190.                                 {
  191.                                     row[fieldIndex] = false;
  192.                                 }
  193.  
  194.                                 break;
  195.  
  196.                             case 'F':
  197.                                 number = Encoding.ASCII.GetString(recReader.ReadBytes(field.fieldLen));
  198.                                 if (IsNumber(number))
  199.                                 {
  200.                                     row[fieldIndex] = double.Parse(number);
  201.                                 }
  202.                                 else
  203.                                 {
  204.                                     row[fieldIndex] = 0.0F;
  205.                                 }
  206.                                 break;
  207.                         }
  208.                         fieldIndex++;
  209.                     }
  210.  
  211.                     recReader.Close();
  212.                     dt.Rows.Add(row);
  213.                 }
  214.             }
  215.  
  216.             catch
  217.             {
  218.                 throw;
  219.             }
  220.             finally
  221.             {
  222.                 if (null != br)
  223.                 {
  224.                     br.Close();
  225.                 }
  226.             }
  227.  
  228.             long count = DateTime.Now.Ticks - start;
  229.  
  230.             return dt;
  231.         }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement