Attribute VB_Name = "Unicode"
Public Const CP_ACP = 0
Public Const CP_UTF8 = 65001

Private Declare Function MultiByteToWideChar Lib "Kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long) As Long
Private Declare Function WideCharToMultiByte Lib "Kernel32" (ByVal CodePage As Long, ByVal dwFlags As Long, ByVal lpWideCharStr As Long, ByVal cchWideChar As Long, ByVal lpMultiByteStr As Long, ByVal cchMultiByte As Long, ByVal lpDefaultChar As Long, lpUsedDefaultChar As Long) As Long


Public Function ANSIToUnicode(Text As String, ByVal CharSet As Long) As String
  If UTF8on = 2 Then
    Data = ANSIToUnicode(DataIn, 204)
  ElseIf UTF8on = 3 Then
    Data = DecodeUTF8(DataIn)
  ElseIf IsUTF8(DataIn) Then
    Data = DecodeUTF8(DataIn)
  Else
    Data = ANSIToUnicode(DataIn, 204)
  End If
End Function

Public Function ANSIToUnicode(Text As String, ByVal CharSet As Long) As String
  Dim stBuffer As String
  Dim cwch As Long
  Dim pwz As Long
  Dim pwzBuffer As Long
  Dim lpUsedDefaultChar As Long
  Dim tempBuff As String
  
  If Len(Text) Then
    tempBuff = UTF8helper(Text, CP_ACP)
    pwz = StrPtr(tempBuff)
    cwch = MultiByteToWideChar(CharSet, 0, pwz, -1, 0&, 0&)
    stBuffer = String(cwch + 1, vbNullChar)
    pwzBuffer = StrPtr(stBuffer)
    cwch = MultiByteToWideChar(CharSet, 0, pwz, -1, pwzBuffer, Len(stBuffer))
    If cwch > 0 Then ANSIToUnicode = Left(stBuffer, cwch - 1)
  End If
End Function

Public Function IsUTF8(Text As String) As Boolean
  Dim I As Integer
  Dim I2 As Integer
  Dim uftFound As Boolean
  Dim CharVal As Byte
  Dim Divider As Byte
  
  Divider = 128
  For I = 1 To Len(Text)
    CharVal = Asc(Mid(Text, I, 1))
    If I2 = 0 Then
      Do While CharVal \ Divider
        CharVal = CharVal - Divider
        Divider = Divider \ 2
        I2 = I2 + 1
        If I2 > 4 Then Exit Function
      Loop
      If I2 > 0 Then
        If I2 = 1 Then Exit Function
        I2 = I2 - 1
        Divider = 128
      End If
    Else
      I2 = I2 - 1
      If CharVal \ 128 = 0 Or (CharVal - 128) \ 64 > 0 Then
        Exit Function
      End If
      uftFound = True
    End If
  Next
  IsUTF8 = uftFound And I2 = 0
End Function

Public Function EncodeUTF8(Text As String) As String
  Dim I As Integer
  Dim stBuffer As String
  
  If Len(Text) Then
    stBuffer = StrConv(UTF8helper(Text, CP_UTF8), vbUnicode)
    I = InStr(1, stBuffer, Chr(0)) - 1
    If I < 0 Then I = Len(stBuffer)
    EncodeUTF8 = Left(stBuffer, I)
  End If
End Function

Public Function DecodeUTF8(ByVal Text As String) As String
  Dim stBuffer As String
  Dim cwch As Long
  Dim pwz As Long
  Dim pwzBuffer As Long
  Dim lpUsedDefaultChar As Long
  Dim tempBuff As String
  
  If Len(Text) Then
    tempBuff = UTF8helper(Text, CP_ACP)
    pwz = StrPtr(tempBuff)
    cwch = MultiByteToWideChar(CP_UTF8, 0, pwz, -1, 0&, 0&)
    stBuffer = String(cwch + 1, vbNullChar)
    pwzBuffer = StrPtr(stBuffer)
    cwch = MultiByteToWideChar(CP_UTF8, 0, pwz, -1, pwzBuffer, Len(stBuffer))
    If cwch > 0 Then DecodeUTF8 = Left(stBuffer, cwch - 1)
  End If
End Function

Private Function UTF8helper(ByVal Text As String, Optional CodePage As Long) As String
  Dim stBuffer As String
  Dim cwch As Long
  Dim pwz As Long
  Dim pwzBuffer As Long
  
  pwz = StrPtr(Text)
  cwch = WideCharToMultiByte(CodePage, 0, pwz, -1, 0&, 0&, ByVal 0&, ByVal 0&)
  stBuffer = String(cwch + 1, vbNullChar)
  pwzBuffer = StrPtr(stBuffer)
  cwch = WideCharToMultiByte(CodePage, 0, pwz, -1, pwzBuffer, Len(stBuffer), ByVal 0&, ByVal 0&)
  If cwch > 0 Then UTF8helper = Left(stBuffer, cwch - 1)
End Function
