Merge pull request #6 from hardkrash/feature/osx_32bit_num_iokit

Feature/osx 32bit num iokit
diff --git a/serial/rfc2217.py b/serial/rfc2217.py
index 8776f09..9c5d68b 100644
--- a/serial/rfc2217.py
+++ b/serial/rfc2217.py
@@ -706,9 +706,7 @@
                         self.logger.debug("socket error in reader thread: %s" % (e,))
                     break
                 if not data: break # lost connection
-                #~ for byte in data:    # fails for python3 as it returns ints instead of b''
-                for x in range(len(data)):
-                    byte = data[x:x+1]
+                for byte in iterbytes(data):
                     if mode == M_NORMAL:
                         # interpret as command or as data
                         if byte == IAC:
@@ -1031,9 +1029,7 @@
 
         (socket error handling code left as exercise for the reader)
         """
-        #~ for byte in data:    # XXX fails for python3 as it returns ints instead of bytes
-        for x in range(len(data)):
-            byte = data[x:x+1]
+        for byte in iterbytes(data):
             if self.mode == M_NORMAL:
                 # interpret as command or as data
                 if byte == IAC:
diff --git a/serial/serialutil.py b/serial/serialutil.py
index a71bd37..e20196d 100644
--- a/serial/serialutil.py
+++ b/serial/serialutil.py
@@ -22,6 +22,16 @@
         pass
 
 
+# "for byte in data" fails for python3 as it returns ints instead of bytes
+def iterbytes(b):
+    """Iterate over bytes, returning bytes instead of ints (python3)"""
+    x = 0
+    a = True
+    while a:
+        a = b[x:x+1]
+        x += 1
+        yield a
+        
 # all Python versions prior 3.x convert ``str([17])`` to '[17]' instead of '\x11'
 # so a simple ``bytes(sequence)`` doesn't work for all versions
 def to_bytes(seq):
diff --git a/serial/tools/miniterm.py b/serial/tools/miniterm.py
index 7814c84..ca48b94 100644
--- a/serial/tools/miniterm.py
+++ b/serial/tools/miniterm.py
@@ -116,6 +116,23 @@
     import msvcrt
     import ctypes
     class Console(ConsoleBase):
+        def __init__(self):
+            super(Console, self).__init__()
+            ctypes.windll.kernel32.SetConsoleOutputCP(65001)
+            ctypes.windll.kernel32.SetConsoleCP(65001)
+            if sys.version_info < (3, 0):
+                class Out:
+                    def __init__(self):
+                        self.fd = sys.stdout.fileno()
+                    def flush(self):
+                        pass
+                    def write(self, s):
+                        os.write(self.fd, s)
+                self.output = codecs.getwriter('UTF-8')(Out(), 'replace')
+                self.byte_output = Out()
+            else:
+                self.output = codecs.getwriter('UTF-8')(sys.stdout.buffer, 'replace')
+
         def getkey(self):
             while True:
                 z = msvcrt.getwch()
@@ -125,21 +142,6 @@
                     msvcrt.getwch()
                 else:
                     return z
-        
-        def write(self, s):
-            # works, kind of.. can't print unicode
-            self.byte_output.write(s.encode(sys.stdout.encoding, 'replace'))
-            #~ sys.stdout.write(s) # fails with encoding errors
-            #~ for byte in data:    # fails for python3 as it returns ints instead of b''
-            #~ for x in range(len(s)):
-                #~ byte = s[x:x+1]
-                #~ msvcrt.putwch(byte)     # blocks?!? non-overlapped win io?
-        
-        def write_bytes(self, data):
-            #~ for byte in data:    # fails for python3 as it returns ints instead of b''
-            for x in range(len(data)):
-                byte = data[x:x+1]
-                msvcrt.putch(byte)
 
 elif os.name == 'posix':
     import atexit
@@ -178,6 +180,7 @@
 # codecs.IncrementalEncoder would be a good choice
 
 class Transform(object):
+    """do-nothing: forward all data unchanged"""
     def input(self, text):
         """text received from serial port"""
         return text
@@ -281,6 +284,7 @@
         'crlf': CRLF,
         'cr': CR,
         'lf': LF,
+        'direct': Transform,    # no transformation
         'default': NoTerminal,
         'nocontrol': NoControls,
         'printable': Printable,
diff --git a/serial/urlhandler/protocol_loop.py b/serial/urlhandler/protocol_loop.py
index 02f30df..02167e5 100644
--- a/serial/urlhandler/protocol_loop.py
+++ b/serial/urlhandler/protocol_loop.py
@@ -174,9 +174,7 @@
         if self._writeTimeout is not None and time_used_to_send > self._writeTimeout:
             time.sleep(self._writeTimeout) # must wait so that unit test succeeds
             raise writeTimeoutError
-        #~ for byte in data:    # fails for python3 as it returns ints instead of b''
-        for x in range(len(data)):
-            byte = data[x:x+1]
+        for byte in iterbytes(data):
             self.queue.put(byte, timeout=self._writeTimeout)
         return len(data)