lib/idnx/windows.rb in idnx-0.0.1 vs lib/idnx/windows.rb in idnx-0.1.0
- old
+ new
@@ -43,59 +43,62 @@
# LPSTR lpMultiByteStr,
# int cbMultiByte,
# LPCCH lpDefaultChar,
# LPBOOL lpUsedDefaultChar
# );
- attach_function :IdnToAscii, [:uint, :pointer, :int, :pointer, :int], :int
- attach_function :MultiByteToWideChar, [:uint, :uint, :string, :int, :pointer, :int], :int
- attach_function :WideCharToMultiByte, [:uint, :uint, :pointer, :int, :pointer, :int, :pointer, :pointer], :int
+ attach_function :IdnToAscii, %i[uint pointer int pointer int], :int
+ attach_function :MultiByteToWideChar, %i[uint uint string int pointer int], :int
+ attach_function :WideCharToMultiByte, %i[uint uint pointer int pointer int pointer pointer], :int
module_function
def lookup(hostname)
# turn to wchar
wchar_len = MultiByteToWideChar(WIN32OLE::CP_UTF8, MB_ERR_INVALID_CHARS, hostname, -1, nil, 0)
raise Error, "Failed to convert \"#{hostname}\" to wchar" if wchar_len.zero?
+
wchar_ptr = FFI::MemoryPointer.new(:wchar_t, wchar_len)
wchar_len = MultiByteToWideChar(WIN32OLE::CP_UTF8, 0, hostname, -1, wchar_ptr, wchar_len)
raise Error, "Failed to convert \"#{hostname}\" to wchar" if wchar_len.zero?
# translate to punycode
punycode = FFI::MemoryPointer.new(:wchar_t, IDN_MAX_LENGTH)
punycode_len = IdnToAscii(0, wchar_ptr, -1, punycode, IDN_MAX_LENGTH)
wchar_ptr.free
- if punycode_len == 0
+ if punycode_len.zero?
last_error = FFI::LastError.error
# operation completed successfully, hostname is not an IDN
# return hostname if last_error == 0
message = case last_error
- when ERROR_INSUFFICIENT_BUFFER
- "The supplied buffer size was not large enough, or it was incorrectly set to NULL"
- when ERROR_INVALID_FLAGS
- "The values supplied for flags were not valid"
- when ERROR_INVALID_NAME
- "An invalid name was supplied to the function"
- when ERROR_INVALID_PARAMETER
- "Any of the parameter values was invalid"
- when ERROR_NO_UNICODE_TRANSLATION
- "An invalid Unicode was found in a string"
- else
- "Failed to convert \"#{hostname}\"; (error: #{last_error})" \
- "\n\nhttps://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes-1"
- end
+ when ERROR_INSUFFICIENT_BUFFER
+ "The supplied buffer size was not large enough, or it was incorrectly set to NULL"
+ when ERROR_INVALID_FLAGS
+ "The values supplied for flags were not valid"
+ when ERROR_INVALID_NAME
+ "An invalid name was supplied to the function"
+ when ERROR_INVALID_PARAMETER
+ "Any of the parameter values was invalid"
+ when ERROR_NO_UNICODE_TRANSLATION
+ "An invalid Unicode was found in a string"
+ else
+ "Failed to convert \"#{hostname}\"; (error: #{last_error})" \
+ "\n\nhttps://docs.microsoft.com/en-us/windows/win32/debug/system-error-codes#system-error-codes-1"
+ end
punycode.free
raise Error, message
end
# turn to unicode
unicode_len = WideCharToMultiByte(WIN32OLE::CP_UTF8, 0, punycode, -1, nil, 0, nil, nil)
raise Error, "Failed to convert \"#{hostname}\" to utf8" if unicode_len.zero?
+
utf8_ptr = FFI::MemoryPointer.new(:char, unicode_len)
unicode_len = WideCharToMultiByte(WIN32OLE::CP_UTF8, 0, punycode, -1, utf8_ptr, unicode_len, nil, nil)
raise Error, "Failed to convert \"#{hostname}\" to utf8" if unicode_len.zero?
+
unicode = utf8_ptr.read_string(utf8_ptr.size)
unicode.strip! # remove null-byte
end
end
end