''' -----------------------------------------------------------------------------
''' Project	 : Scandir
''' Struct	 : TPath
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' Structure fournissant quelques méthodes pour les dossiers
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' 	[nicolas]	23/10/2005	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Structure TPath
    Private mPath As String
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Initialise le nom du chemin
    ''' </summary>
    ''' <param name="pPath">Chemin à controler</param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	23/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New(ByVal pPath As String)
        mPath = pPath
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne ou définit le chemin à controler
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	23/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Property Path() As String
        Get
            Return mPath
        End Get
        Set(ByVal Value As String)
            If Right(Value, 1) <> "\" Then Value += "\"
            mPath = Value
        End Set
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne true si le nom est correctement formé
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	23/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function IsCorrect() As Boolean
        Dim mTmp As String
        Dim i As Integer
        If mPath.Length < 3 Then Return False
        If (mPath Like "\\?*\?*") Then
            'Chemin UNC 
            mTmp = "<>""|?;:/*"
            For i = 1 To mPath.Length
                If mTmp.IndexOf(mPath.Substring(i, 1)) >= 0 Then
                    Return False
                End If
            Next
            If mPath.LastIndexOf("\\") = 0 Then
                Return True
            Else
                Return False
            End If
        ElseIf "abcdefghijklmnopqrstuvwxyz".IndexOf(mPath.Substring(0, 1).ToLower) > -1 And mPath Like "?:\*" Then
            'Chemin local
            mTmp = "<>""|?;:/*"
            For i = 2 To mPath.Length - 1
                If mTmp.IndexOf(mPath.Substring(i, 1)) >= 0 Then
                    Return False
                End If
            Next
            If mPath.LastIndexOf("\\") = -1 Then
                Return True
            Else
                Return False
            End If
        Else
            Return False
        End If
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne true si le dossier existe, false sinon
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	23/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function IsExist() As Boolean
        Dim TmpDir As System.io.DirectoryInfo
        If IsCorrect() Then
            Try
                TmpDir = New System.io.DirectoryInfo(mPath)
                Return TmpDir.Exists
            Catch ex As Exception
                Return False
            End Try
        Else
            Return False
        End If
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne un tableau de directoryinfo représentant les sous-dossiers contenu
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	23/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function GetSubDirs() As IO.DirectoryInfo()
        Dim mObj As IO.DirectoryInfo
        If IsExist() = False Then
            Dim mTmp As IO.DirectoryInfo()
            ReDim mTmp(-1)
            Return mTmp
        End If
        Try
            mObj = New IO.DirectoryInfo(mPath)
            Return mObj.GetDirectories
        Catch ex As Exception
            Dim mTmp As IO.DirectoryInfo()
            ReDim mTmp(-1)
            Return mTmp
        End Try
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne un tableau de fileinfo représentant les fichiers contenus dans le répertoire
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	23/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function GetFiles(Optional ByVal Filter As String = "") As System.io.FileInfo()
        Dim mObj As System.io.DirectoryInfo
        If IsExist() = False Then
            Dim mTmp As System.io.FileInfo()
            ReDim mTmp(-1)
            Return mTmp
        End If
        Try
            mObj = New System.io.DirectoryInfo(mPath)
            If Filter = "" Then
                Return mObj.GetFiles
            Else
                Return mObj.GetFiles(Filter)
            End If
        Catch ex As Exception
            Dim mTmp As System.io.FileInfo()
            ReDim mTmp(-1)
            Return mTmp
        End Try
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne ou définit les attributs d'un dossier
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Property Attributes() As System.IO.FileAttributes
        Get
            If IsExist() Then
                Dim mFile As New System.IO.DirectoryInfo(mPath)
                Return mFile.Attributes
            Else
                Return 0
            End If
        End Get
        Set(ByVal Value As System.IO.FileAttributes)
            If IsExist() Then
                Dim mFile As New System.IO.DirectoryInfo(mPath)
                mFile.Attributes = Value
            End If
        End Set
    End Property
    'Public ReadOnly Property DirName() As String
    '    Get
    '        If IsCorrect() Then

    '        Else
    '            Return ""
    '        End If
    '    End Get
    'End Property
End Structure
''' -----------------------------------------------------------------------------
''' Project	 : Scandir
''' Struct	 : TFile
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' Structure fournissant quelques méthodes pour les fichiers
''' </summary>
''' <remarks>
''' </remarks>
''' <history>
''' 	[nicolas]	24/10/2005	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Structure TFile
    Private mFileName As String
    Private mCrc As Integer
    Private mMD5 As String
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Créé une instance de la structure avec le nom de fichier passé en paramètre
    ''' </summary>
    ''' <param name="pFileName">Nom de fichier</param>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Sub New(ByVal pFileName As String)
        mFileName = pFileName
        mCrc = 0
        mMD5 = ""
    End Sub
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne ou définit le nom du fichier
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Property FileName() As String
        Get
            Return mFileName
        End Get
        Set(ByVal Value As String)
            mFileName = Value
            mCrc = 0
            mMD5 = ""
        End Set
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne true si le nom de fichier est bien formé
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function IsCorrect() As Boolean
        If (New TPath(mFileName)).IsCorrect = False Then Return False
        Dim mFile As String
        mFile = Right(mFileName, mFileName.Length - mFileName.LastIndexOf("\"))
        mFile.Replace("\", "")
        If mFile.IndexOf(".") = -1 Then Return False
        Return True
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne true si le fichier existe
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function IsExist() As Boolean
        If IsCorrect() = False Then Return False
        Dim mFile As System.IO.FileInfo
        Try
            mFile = New System.IO.FileInfo(mFileName)
            If mFile.Exists Then
                Return True
            Else
                Return False
            End If
        Catch ex As Exception
            Return False
        End Try
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne ou définit les atributs du fichier
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Property Attributes() As System.IO.FileAttributes
        Get
            If IsExist() Then
                Dim mFile As New System.IO.FileInfo(mFileName)
                Return mFile.Attributes
            Else
                Return 0
            End If
        End Get
        Set(ByVal Value As System.IO.FileAttributes)
            If IsExist() Then
                Dim mFile As New System.IO.FileInfo(mFileName)
                mFile.Attributes = Value
            End If
        End Set
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne le Crc32 du fichier (0 en cas de non existance)
    ''' </summary>
    ''' <returns></returns>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public Function GetCrc32() As Integer
        If IsExist() = False Then Return 0
        If mCrc <> 0 Then Return mCrc

        ' This is v2 of the VB CRC32 algorithm provided by Paul
        ' (wpsjr1@succeed.net) - much quicker than the nasty
        ' original version I posted.  Excellent work!

        'Code modifié de la source récupérée sur VBaccelerator.com
        'Sous le nom CRC32

        Dim crc32Table() As Integer
        Const BUFFER_SIZE As Integer = 1024

        ' This is the official polynomial used by CRC32 in PKZip.
        ' Often the polynomial is shown reversed (04C11DB7).
        Dim dwPolynomial As Integer = &HEDB88320
        Dim i As Integer, j As Integer

        ReDim crc32Table(256)
        Dim dwCrc As Integer

        For i = 0 To 255
            dwCrc = i
            For j = 8 To 1 Step -1
                If (dwCrc And 1) <> 0 Then
                    dwCrc = CInt(((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF)
                    dwCrc = dwCrc Xor dwPolynomial
                Else
                    dwCrc = CInt(((dwCrc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF)
                End If
            Next j
            crc32Table(i) = dwCrc
        Next i

        Dim stream As System.IO.FileStream = New System.IO.FileStream(mFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read, System.IO.FileShare.Read, 8192)

        Dim crc32Result As Integer
        crc32Result = &HFFFFFFFF

        Dim buffer(BUFFER_SIZE) As Byte
        Dim readSize As Integer = BUFFER_SIZE

        Dim count As Integer = stream.Read(buffer, 0, readSize)
        Dim iLookup As Integer
        Dim tot As Integer = 0
        Do While (count > 0)
            For i = 0 To count - 1
                iLookup = (crc32Result And &HFF) Xor buffer(i)
                crc32Result = ((crc32Result And &HFFFFFF00) \ &H100) And &HFFFFFF   ' nasty shr 8 with vb :/
                crc32Result = crc32Result Xor crc32Table(iLookup)
            Next i
            count = stream.Read(buffer, 0, readSize)
        Loop

        mCrc = Not (crc32Result)
        Return mCrc
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne le hash MD5 du fichier
    ''' </summary>
    ''' <returns></returns>
    ''' -----------------------------------------------------------------------------
    Public Function GetMD5() As String
        If IsExist() = False OrElse Length = 0 Then Return ""
        If mMD5 <> "" Then Return mMD5
        Dim lFic As System.IO.FileStream = Nothing
        Try
            Dim ltData() As Byte
            ReDim ltData(CInt(Length - 1))

            lFic = New System.IO.FileStream(mFileName, IO.FileMode.Open)

            Dim lCrypt As New System.Security.Cryptography.MD5CryptoServiceProvider
            Dim ltByte As Byte() = lCrypt.ComputeHash(lFic)
            mMD5 = ""
            For i As Integer = 0 To ltByte.Length - 1
                If ltByte(i) > 15 Then
                    mMD5 += Hex(ltByte(i))
                Else
                    mMD5 += "0" + Hex(ltByte(i))
                End If
            Next
            lFic.Close()
            Return mMD5
        Catch Ex As Exception
            If Not (lFic Is Nothing) Then lFic.Close()
            mMD5 = ""
            Return ""
        End Try
    End Function
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne la taille du fichier
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public ReadOnly Property Length() As Long
        Get
            If IsExist() Then
                Return ((New System.IO.FileInfo(mFileName)).Length)
            Else
                Return -1
            End If
        End Get
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne l'extension du fichier
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public ReadOnly Property FileExt() As String
        Get
            If IsExist() Then
                Return ((New System.IO.FileInfo(mFileName)).Extension)
            Else
                Return ""
            End If
        End Get
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne le nom du fichier (sans le dossier)
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public ReadOnly Property FileTitle() As String
        Get
            If IsExist() Then
                Return ((New System.IO.FileInfo(mFileName)).Name)
            Else
                Return ""
            End If
        End Get
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne le nom du dossier parent
    ''' </summary>
    ''' <value></value>
    ''' <remarks>
    ''' </remarks>
    ''' <history>
    ''' 	[nicolas]	24/10/2005	Created
    ''' </history>
    ''' -----------------------------------------------------------------------------
    Public ReadOnly Property FilePath() As String
        Get
            If IsExist() Then
                Return ((New System.IO.FileInfo(mFileName)).DirectoryName)
            Else
                Return ""
            End If
        End Get
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne ou définit la date de création du fichier
    ''' </summary>
    ''' <value></value>
    ''' -----------------------------------------------------------------------------
    Public Property CreatedDate() As Date
        Get
            If IsExist() Then
                Return (New IO.FileInfo(mFileName)).CreationTime
            Else
                Return New Date(1, 1, 1)
            End If
        End Get
        Set(ByVal Value As Date)
            Dim lFile As New IO.FileInfo(mFileName)
            lFile.CreationTime = Value
        End Set
    End Property
    ''' -----------------------------------------------------------------------------
    ''' <summary>
    ''' Retourne ou définit la date de modification du fichier
    ''' </summary>
    ''' <value></value>
    ''' -----------------------------------------------------------------------------
    Public Property ModifiedDate() As Date
        Get
            If IsExist() Then
                Return (New IO.FileInfo(mFileName)).LastWriteTime
            Else
                Return New Date(1, 1, 1)
            End If
        End Get
        Set(ByVal Value As Date)
            Dim lFile As New IO.FileInfo(mFileName)
            lFile.LastWriteTime = Value
        End Set
    End Property

End Structure
