cudreg-saml2/App_Code/Shared/CsvParser.vb
2025-06-08 16:22:20 +07:00

217 lines
7.4 KiB
VB.net

Imports System
Imports System.Data
Imports System.Configuration
Imports System.ComponentModel
Imports System.Web
Imports System.Web.Security
Imports System.Web.UI
Imports System.Web.UI.WebControls
Imports System.Web.UI.WebControls.WebParts
Imports System.Web.UI.HtmlControls
Imports System.Text
Imports System.IO
Imports System.Collections
Namespace Persons.UI
''' <summary>
''' Summary description for CsvParser: Parses CSV file and returns one row at a time.
''' Since the code is the same for CSV or TAB, this class is used for parsing both types of files.
''' </summary>
Public Class CsvParser
Inherits Parser
Private sr As StreamReader = Nothing
Private csvStrm As CsvStream = Nothing
Private fileName As String = Nothing
Private separator As Char = System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ListSeparator(0)
Public Sub New(ByVal fName As String)
MyBase.New
'
' Add constructor logic here
'
fileName = fName
separator = System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ListSeparator(0)
Reset()
End Sub
Public Sub New(ByVal fName As String, ByVal fSeparator As Char)
MyBase.New()
'
' Add constructor logic here
'
fileName = fName
separator = fSeparator
Reset()
End Sub
' Resets resourses
Public Overrides Sub Reset()
If (Not (fileName) Is Nothing) Then
sr = New StreamReader(fileName)
csvStrm = New CsvStream(sr, separator)
End If
End Sub
' Gets one row at a time.
Public Overrides Function GetNextRow() As String()
Return csvStrm.GetNextRow
End Function
Public Overrides Sub Close()
csvStrm.Close()
End Sub
' CsvStream is the helper class which parses the file.
Private Class CsvStream
Implements IDisposable
Private stream As TextReader
Private EOS As Boolean = False
Private EOL As Boolean = False
Private buffer() As Char = New Char((4096) - 1) {}
Private pos As Integer = 0
Private length As Integer = 0
Private separator As Char = System.Globalization.CultureInfo.CurrentUICulture.TextInfo.ListSeparator(0)
Public Sub New(ByVal s As TextReader, ByVal fSeparator As Char)
MyBase.New()
stream = s
separator = fSeparator
End Sub
Public Function GetNextRow() As String()
Dim row As ArrayList = New ArrayList
While True
Dim item As String = GetNextItem
If (item Is Nothing) Then
If (row.Count = 0) Then
Return Nothing
Else
If (row(row.Count - 1).ToString = "") Then
row.RemoveAt((row.Count - 1))
End If
If (row.Count <> 0) Then
Return CType(row.ToArray(GetType(System.String)), String())
End If
End If
Else
row.Add(item)
End If
End While
Return Nothing
End Function
Public Sub Close()
If stream IsNot Nothing Then
Me.Dispose()
End If
End Sub
Public Function GetNextItem() As String
If EOL Then
' previous item was last in line, start new line
EOL = False
Return Nothing
End If
Dim quoted As Boolean = False
Dim predata As Boolean = True
Dim postdata As Boolean = False
Dim item As New StringBuilder()
While True
Dim c As Char = GetNextChar(True)
If EOS Then
Return IIf(item.Length > 0, item.ToString(), Nothing)
End If
If (postdata OrElse Not quoted) AndAlso c = separator Then
Return item.ToString()
' end of item, return
End If
If (predata OrElse postdata OrElse Not quoted) AndAlso (c = Chr(10) OrElse c = Chr(13)) Then
' we are at the end of the line, eat newline characters and exit
EOL = True
If c = Chr(13) AndAlso GetNextChar(False) = Chr(10) Then
GetNextChar(True)
' new line sequence is 0D0A
End If
Return item.ToString()
End If
If predata AndAlso c = " "c Then
Continue While
' whitespace preceeding data, discard
End If
If predata AndAlso (c = """"c OrElse c = "'"c) Then
' quoted data is starting
quoted = True
predata = False
Continue While
End If
If predata Then
' data is starting without quotes
predata = False
item.Append(c)
Continue While
End If
If (c = """"c OrElse c = "'"c) AndAlso quoted Then
If GetNextChar(False) = """"c Then
item.Append(GetNextChar(True))
Else
postdata = True
' double quotes within quoted string means add a quote
' end-quote reached
End If
Continue While
End If
' all cases covered, character must be data
item.Append(c)
End While
Return Nothing
End Function
Public Function GetNextChar(ByVal eat As Boolean) As Char
If (pos >= length) Then
length = stream.ReadBlock(buffer, 0, buffer.Length)
If (length = 0) Then
EOS = True
Return Microsoft.VisualBasic.ChrW(92)
End If
pos = 0
End If
If eat Then
pos = pos + 1
Return buffer(pos - 1)
Else
Return buffer(pos)
End If
End Function
Public Sub Dispose() Implements IDisposable.Dispose
If stream IsNot Nothing Then
stream.Close()
stream.Dispose()
stream = Nothing
End If
End Sub
End Class
End Class
End Namespace