-
Notifications
You must be signed in to change notification settings - Fork 50
/
hex_common.py
133 lines (101 loc) · 3.7 KB
/
hex_common.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
"""
Hex Viewer.
Licensed under MIT
Copyright (c) 2011-2020 Isaac Muse <[email protected]>
"""
import sublime
from os.path import basename, splitext
ADDRESS_OFFSET = 11
ASCII_OFFSET = 3
BITS_PER_BYTE = 8
ST_SYNTAX = "sublime-syntax"
def is_enabled(current_view=None):
"""Check if hex commands should be enabled."""
window = sublime.active_window()
if window is None:
return False
view = window.active_view()
if view is None:
return False
# Check not only if active main view is hex,
# check if current view is the main active view
if current_view is not None and current_view.id() != view.id():
return False
syntax = view.settings().get('syntax')
language = splitext(basename(syntax))[0].lower() if syntax is not None else "plain text"
return bool(language == "hexviewer")
def clear_edits(view):
"""Clear edit highlights."""
view.add_regions(
"hex_edit",
[],
""
)
def use_hex_lowercase():
"""Check if lowercase hex format should be used."""
return hv_settings('use_lowercase_hex', True)
def is_hex_dirty(view):
"""Check if hex view is dirty."""
return True if len(view.get_regions("hex_edit")) != 0 else False
def get_hex_char_range(group_size, bytes_wide):
"""Get the hex char range."""
return int((group_size * 2) * bytes_wide / (group_size) + bytes_wide / (group_size)) - 1
def get_byte_count(start, end, group_size):
"""Get the byte count."""
return (
int((end - start - 1) / (group_size * 2 + 1)) * int(group_size) +
int(((end - start - 1) % (group_size * 2 + 1)) / 2 + 1)
)
def ascii_to_hex_col(index, group_size):
"""
Convert ASCII selection to the column in the hex data.
Calculate byte number Account for address
current_char wanted_byte
------------ = ----------- => wanted_byte + offset = start_column
total_chars total_bytes
"""
start_column = int(
ADDRESS_OFFSET + (group_size * 2) * index / (group_size) +
index / (group_size)
)
# Convert byte column position to test point
return start_column
def adjust_hex_sel(view, start, end, group_size):
"""Adjust the hex selection."""
num_bytes = 0
size = end - start
if view.score_selector(start, 'raw.nibble.upper') == 0:
if view.score_selector(start, 'raw.nibble.lower'):
start -= 1
elif view.score_selector(start + 1, 'raw.nibble.upper') and size > 0:
start += 1
else:
start = None
# Adjust ending of selection to end of last selected byte
if size == 0 and start is not None:
end = start + 1
num_bytes = 1
elif view.score_selector(end, 'raw.nibble.lower') == 0:
if view.score_selector(end - 1, 'raw.nibble.lower'):
end -= 1
else:
end -= 2
if start is not None and end is not None:
num_bytes = get_byte_count(start, end, group_size)
return start, end, num_bytes
def underline(selected_bytes):
"""Convert to empty regions to simulate underline."""
new_regions = []
for region in selected_bytes:
start = region.begin()
end = region.end()
while start < end:
new_regions.append(sublime.Region(start))
start += 1
return new_regions
def hv_settings(key=None, default=None):
"""Get the settings."""
if key is not None:
return sublime.load_settings('hex_viewer.sublime-settings').get(key, default)
else:
return sublime.load_settings('hex_viewer.sublime-settings')