1import binascii
2import six
3
4if six.PY2:
5    import commands
6    get_command_output = commands.getoutput
7    get_command_status_output = commands.getstatusoutput
8
9    cmp_ = cmp
10else:
11    def get_command_status_output(command):
12        try:
13            import subprocess
14            return (
15                0,
16                subprocess.check_output(
17                    command,
18                    shell=True,
19                    universal_newlines=True).rstrip())
20        except subprocess.CalledProcessError as e:
21            return (e.returncode, e.output)
22
23    def get_command_output(command):
24        return get_command_status_output(command)[1]
25
26    cmp_ = lambda x, y: (x > y) - (x < y)
27
28def bitcast_to_string(b):
29    """
30    Take a string(PY2) or a bytes(PY3) object and return a string. The returned
31    string contains the exact same bytes as the input object (latin1 <-> unicode
32    transformation is an identity operation for the first 256 code points).
33    """
34    return b if six.PY2 else b.decode("latin1")
35
36def bitcast_to_bytes(s):
37    """
38    Take a string and return a string(PY2) or a bytes(PY3) object. The returned
39    object contains the exact same bytes as the input string. (latin1 <->
40    unicode transformation is an identity operation for the first 256 code
41    points).
42    """
43    return s if six.PY2 else s.encode("latin1")
44
45def unhexlify(hexstr):
46    """Hex-decode a string. The result is always a string."""
47    return bitcast_to_string(binascii.unhexlify(hexstr))
48
49def hexlify(data):
50    """Hex-encode string data. The result if always a string."""
51    return bitcast_to_string(binascii.hexlify(bitcast_to_bytes(data)))
52