@@ -43,94 +43,98 @@ Public Class ConvertLineEndings
4343 ''' <returns>Exit code.</returns>
4444 Private Shared Async Function ReplaceLineEndings(originalFile As String , newFile As String ,
4545 convertMode As TextConvertMode) As Task( Of Integer )
46- Const cr As Char = ChrW( 13 )
47- Const lf As Char = ChrW( 10 )
48-
49- ' Attempt to detect encoding
50- Dim fileEncoding As Encoding = GetEncoding(originalFile)
51- If fileEncoding Is Nothing Then Return 4
52- Debug.Print(fileEncoding.ToString())
5346
54- Dim convertedText As New StringBuilder
55- Dim oldFileStream As FileStream = Nothing
5647 Try
57- oldFileStream = New FileStream(originalFile, FileMode.Open)
58- Using oldFile As New StreamReader(oldFileStream, fileEncoding, True )
59- Do Until oldFile.EndOfStream ' Read through the whole file
60- Dim readBuffer( 0 ) As Char
61- Dim readChars As Integer = Await oldFile.ReadAsync(readBuffer, 0 , 1 )
62- If readChars < 1 Then Exit Do ' Short circuit
63- Select Case convertMode
64- Case TextConvertMode.Dos2Ux
65- If readBuffer( 0 ) = cr AndAlso oldFile.Peek() = 10 Then
66- ' Strip out CR chars if followed by LF
67- Await oldFile.ReadAsync(readBuffer, 0 , 1 )
68- End If
69- Case TextConvertMode.Ux2Dos
70- If readBuffer( 0 ) = cr AndAlso oldFile.Peek() = 10 Then
71- ReDim Preserve readBuffer( 1 )
72- ' This is a DOS line ending, keep it.
73- Dim tempBuffer( 1 ) As Char
74- Await oldFile.ReadAsync(tempBuffer, 0 , 1 )
75- readBuffer( 1 ) = tempBuffer( 0 )
76- ElseIf readBuffer( 0 ) = lf Then
77- ReDim readBuffer( 1 )
78- ' Add preceeding CR
79- readBuffer( 0 ) = cr
80- readBuffer( 1 ) = lf
81- End If
82- Case Else
83- Debug.Print( "Unimplemented text conversion mode" )
84- Return - 1
85- End Select
48+ Using oldFileStream As New FileStream(originalFile, FileMode.Open)
49+ ' Attempt to detect encoding
50+ Dim fileEncoding As Encoding = GetEncoding(oldFileStream)
51+ If fileEncoding Is Nothing Then Return 4
52+ Debug.Print(fileEncoding.ToString())
8653
87- convertedText.Append(readBuffer)
88- Loop
54+ 'Write the result out to a new file
55+ File.WriteAllText(newFile, Await GetConvertedText(oldFileStream, fileEncoding, convertMode), fileEncoding)
8956 End Using
90-
91- oldFileStream = Nothing
9257 Catch ex As Exception
9358 Debug.Print( "Error: " & ex.Message & Environment.NewLine & "Number: " & ex.HResult.ToString)
9459 Return ex.HResult
95- Finally
96- If oldFileStream IsNot Nothing Then oldFileStream.Dispose()
9760 End Try
9861
99- 'Write the result out to a new file
62+ Return 0 ' Exit status 0 is a good thing
63+ End Function
64+
65+ Private Shared Async Function GetConvertedText(originalFile As FileStream, fileEncoding As Encoding, convertMode As TextConvertMode) As Task( Of String )
66+ Const cr As Char = ChrW( 13 )
67+ Const lf As Char = ChrW( 10 )
68+
69+ Dim convertedLines As StringBuilder = Nothing
10070 Try
101- File.WriteAllText(newFile, convertedText.ToString(), New UTF8Encoding( False ))
71+ Using oldFile As New StreamReader(originalFile, fileEncoding, True )
72+ Do Until oldFile.EndOfStream ' Read through the whole file
73+ Dim readBuffer( 0 ) As Char
74+ Dim readChars As Integer = Await oldFile.ReadAsync(readBuffer, 0 , 1 )
75+ If readChars >= 1 Then
76+ Select Case convertMode
77+ Case TextConvertMode.Dos2Ux
78+ If readBuffer( 0 ) = cr AndAlso oldFile.Peek() = 10 Then
79+ ' Strip out CR chars if followed by LF
80+ Await oldFile.ReadAsync(readBuffer, 0 , 1 )
81+ End If
82+ Case TextConvertMode.Ux2Dos
83+ If readBuffer( 0 ) = cr AndAlso oldFile.Peek() = 10 Then
84+ ReDim Preserve readBuffer( 1 )
85+ ' This is a DOS line ending, keep it.
86+ Dim tempBuffer( 1 ) As Char
87+ Await oldFile.ReadAsync(tempBuffer, 0 , 1 )
88+ readBuffer( 1 ) = tempBuffer( 0 )
89+ ElseIf readBuffer( 0 ) = lf Then
90+ ReDim readBuffer( 1 )
91+ ' Add preceeding CR
92+ readBuffer( 0 ) = cr
93+ readBuffer( 1 ) = lf
94+ End If
95+ End Select
96+
97+ 'Yield readBuffer
98+ convertedLines.Append(readBuffer)
99+ End If
100+ Loop
101+ End Using
102102 Catch ex As Exception
103103 Debug.Print( "Error: " & ex.Message & Environment.NewLine & "Number: " & ex.HResult.ToString)
104- Return ex.HResult
104+ Return ex.HResult.ToString
105105 End Try
106106
107- Return 0 ' Exit status 0 is a good thing
107+ Return convertedLines.ToString
108108 End Function
109109
110110 ''' <summary>
111111 ''' Attempt to detect the encoding of a file.
112112 ''' </summary>
113113 ''' <param name="filename">The file to get the encoding pattern from.</param>
114114 ''' <returns>Encoding type, defaults to ASCII.</returns>
115- Public Shared Function GetEncoding(filename As String ) As Encoding
115+ Public Shared Function GetEncoding(theFile As FileStream ) As Encoding
116116 Dim bom = New Byte ( 3 ) {}
117117 Try ' to read BOM
118- Using file = New FileStream(filename, FileMode.Open, FileAccess.Read)
119- file.Read(bom, 0 , 4 )
120- End Using
118+ theFile.Read(bom, 0 , 4 )
121119 Catch ex As Exception
122120 Debug.Print( "Error: " & ex.Message & Environment.NewLine & "Number: " & ex.HResult.ToString)
123121 Return Nothing
124122 End Try
125123
126124 ' Detect BOM type
127- If bom( 0 ) = &H2B AndAlso bom( 1 ) = &H2F AndAlso bom( 2 ) = &H76 Then Return Encoding.UTF7
128- If bom( 0 ) = &HEF AndAlso bom( 1 ) = &HBB AndAlso bom( 2 ) = &HBF Then Return Encoding.UTF8
129- If bom( 0 ) = &HFF AndAlso bom( 1 ) = &HFE Then Return Encoding.Unicode
130- If bom( 0 ) = &HFE AndAlso bom( 1 ) = &HFF Then Return Encoding.BigEndianUnicode
131- If bom( 0 ) = 0 AndAlso bom( 1 ) = 0 AndAlso bom( 2 ) = &HFE AndAlso bom( 3 ) = &HFF Then Return Encoding.UTF32
132-
133- ' Default to
134- Return Encoding.ASCII
125+ If bom( 0 ) = &H2B AndAlso bom( 1 ) = &H2F AndAlso bom( 2 ) = &H76 Then
126+ Return Encoding.UTF7
127+ ElseIf bom( 0 ) = &HEF AndAlso bom( 1 ) = &HBB AndAlso bom( 2 ) = &HBF Then
128+ Return Encoding.UTF8
129+ ElseIf bom( 0 ) = &HFF AndAlso bom( 1 ) = &HFE Then
130+ Return Encoding.Unicode
131+ ElseIf bom( 0 ) = &HFE AndAlso bom( 1 ) = &HFF Then
132+ Return Encoding.BigEndianUnicode
133+ ElseIf bom( 0 ) = 0 AndAlso bom( 1 ) = 0 AndAlso bom( 2 ) = &HFE AndAlso bom( 3 ) = &HFF Then
134+ Return Encoding.UTF32
135+ Else
136+ ' Default to
137+ Return Encoding.ASCII
138+ End If
135139 End Function
136140End Class
0 commit comments