Chris@0
|
1 """
|
Chris@0
|
2 vis.py
|
Chris@0
|
3 ======
|
Chris@0
|
4
|
Chris@0
|
5 Ctypes based module to access libbsd's strvis & strunvis functions.
|
Chris@0
|
6
|
Chris@0
|
7 The `vis` function is the equivalent of strvis.
|
Chris@0
|
8 The `unvis` function is the equivalent of strunvis.
|
Chris@0
|
9 All functions accept unicode string as input and return a unicode string.
|
Chris@0
|
10
|
Chris@0
|
11 Constants:
|
Chris@0
|
12 ----------
|
Chris@0
|
13
|
Chris@0
|
14 * to select alternate encoding format
|
Chris@0
|
15 `VIS_OCTAL`: use octal \ddd format
|
Chris@0
|
16 `VIS_CSTYLE`: use \[nrft0..] where appropiate
|
Chris@0
|
17
|
Chris@0
|
18 * to alter set of characters encoded
|
Chris@0
|
19 (default is to encode all non-graphic except space, tab, and newline).
|
Chris@0
|
20 `VIS_SP`: also encode space
|
Chris@0
|
21 `VIS_TAB`: also encode tab
|
Chris@0
|
22 `VIS_NL`: also encode newline
|
Chris@0
|
23 `VIS_WHITE`: same as (VIS_SP | VIS_TAB | VIS_NL)
|
Chris@0
|
24 `VIS_SAFE`: only encode "unsafe" characters
|
Chris@0
|
25
|
Chris@0
|
26 * other
|
Chris@0
|
27 `VIS_NOSLASH`: inhibit printing '\'
|
Chris@0
|
28 `VIS_HTTP1808`: http-style escape % hex hex
|
Chris@0
|
29 `VIS_HTTPSTYLE`: http-style escape % hex hex
|
Chris@0
|
30 `VIS_MIMESTYLE`: mime-style escape = HEX HEX
|
Chris@0
|
31 `VIS_HTTP1866`: http-style &#num; or &string;
|
Chris@0
|
32 `VIS_NOESCAPE`: don't decode `\'
|
Chris@0
|
33 `VIS_GLOB`: encode glob(3) magic characters
|
Chris@0
|
34
|
Chris@0
|
35 :Authors:
|
Chris@0
|
36 - ju1ius (http://github.com/ju1ius)
|
Chris@0
|
37 :Version: 1
|
Chris@0
|
38 :Date: 2014-01-05
|
Chris@0
|
39 """
|
Chris@0
|
40 from ctypes import CDLL, c_char_p, c_int
|
Chris@0
|
41 from ctypes.util import find_library
|
Chris@0
|
42
|
Chris@0
|
43
|
Chris@0
|
44 __all__ = [
|
Chris@0
|
45 'vis', 'unvis',
|
Chris@0
|
46 'VIS_OCTAL', 'VIS_CSTYLE',
|
Chris@0
|
47 'VIS_SP', 'VIS_TAB', 'VIS_NL', 'VIS_WHITE', 'VIS_SAFE',
|
Chris@0
|
48 'VIS_NOSLASH', 'VIS_HTTP1808', 'VIS_HTTPSTYLE', 'VIS_MIMESTYLE',
|
Chris@0
|
49 'VIS_HTTP1866', 'VIS_NOESCAPE', 'VIS_GLOB'
|
Chris@0
|
50 ]
|
Chris@0
|
51
|
Chris@0
|
52
|
Chris@0
|
53 #############################################################
|
Chris@0
|
54 # Constants from bsd/vis.h
|
Chris@0
|
55 #############################################################
|
Chris@0
|
56
|
Chris@0
|
57 #to select alternate encoding format
|
Chris@0
|
58 VIS_OCTAL = 0x0001
|
Chris@0
|
59 VIS_CSTYLE = 0x0002
|
Chris@0
|
60 # to alter set of characters encoded
|
Chris@0
|
61 # (default is to encode all non-graphic except space, tab, and newline).
|
Chris@0
|
62 VIS_SP = 0x0004
|
Chris@0
|
63 VIS_TAB = 0x0008
|
Chris@0
|
64 VIS_NL = 0x0010
|
Chris@0
|
65 VIS_WHITE = VIS_SP | VIS_TAB | VIS_NL
|
Chris@0
|
66 VIS_SAFE = 0x0020
|
Chris@0
|
67 # other
|
Chris@0
|
68 VIS_NOSLASH = 0x0040
|
Chris@0
|
69 VIS_HTTP1808 = 0x0080
|
Chris@0
|
70 VIS_HTTPSTYLE = 0x0080
|
Chris@0
|
71 VIS_MIMESTYLE = 0x0100
|
Chris@0
|
72 VIS_HTTP1866 = 0x0200
|
Chris@0
|
73 VIS_NOESCAPE = 0x0400
|
Chris@0
|
74 VIS_GLOB = 0x1000
|
Chris@0
|
75
|
Chris@0
|
76 #############################################################
|
Chris@0
|
77 # Import libbsd/vis functions
|
Chris@0
|
78 #############################################################
|
Chris@0
|
79
|
Chris@0
|
80 _libbsd = CDLL(find_library('bsd'))
|
Chris@0
|
81
|
Chris@0
|
82 _strvis = _libbsd.strvis
|
Chris@0
|
83 _strvis.argtypes = [c_char_p, c_char_p, c_int]
|
Chris@0
|
84 _strvis.restype = c_int
|
Chris@0
|
85
|
Chris@0
|
86 _strunvis = _libbsd.strunvis
|
Chris@0
|
87 _strvis.argtypes = [c_char_p, c_char_p]
|
Chris@0
|
88 _strvis.restype = c_int
|
Chris@0
|
89
|
Chris@0
|
90
|
Chris@0
|
91 def vis(src, flags=VIS_WHITE):
|
Chris@0
|
92 """
|
Chris@0
|
93 Encodes the string `src` into libbsd's vis encoding.
|
Chris@0
|
94 `flags` must be one of the VIS_* constants
|
Chris@0
|
95
|
Chris@0
|
96 C definition:
|
Chris@0
|
97 int strvis(char *dst, char *src, int flags);
|
Chris@0
|
98 """
|
Chris@0
|
99 src = bytes(src, 'utf-8')
|
Chris@0
|
100 dst_p = c_char_p(bytes(len(src) * 4))
|
Chris@0
|
101 src_p = c_char_p(src)
|
Chris@0
|
102 flags = c_int(flags)
|
Chris@0
|
103
|
Chris@0
|
104 bytes_written = _strvis(dst_p, src_p, flags)
|
Chris@0
|
105 if -1 == bytes_written:
|
Chris@0
|
106 raise RuntimeError('vis failed to encode string "{}"'.format(src))
|
Chris@0
|
107
|
Chris@0
|
108 return dst_p.value.decode('utf-8')
|
Chris@0
|
109
|
Chris@0
|
110
|
Chris@0
|
111 def unvis(src):
|
Chris@0
|
112 """
|
Chris@0
|
113 Decodes a string encoded by vis.
|
Chris@0
|
114
|
Chris@0
|
115 C definition:
|
Chris@0
|
116 int strunvis(char *dst, char *src);
|
Chris@0
|
117 """
|
Chris@0
|
118 src = bytes(src, 'utf-8')
|
Chris@0
|
119 dst_p = c_char_p(bytes(len(src)))
|
Chris@0
|
120 src_p = c_char_p(src)
|
Chris@0
|
121
|
Chris@0
|
122 bytes_written = _strunvis(dst_p, src_p)
|
Chris@0
|
123 if -1 == bytes_written:
|
Chris@0
|
124 raise RuntimeError('unvis failed to decode string "{}"'.format(src))
|
Chris@0
|
125
|
Chris@0
|
126 return dst_p.value.decode('utf-8')
|