def on_load(self, view): """Determine if anything needs to be done with the loaded file.""" # Logic for direct open files if common.hv_settings( "auto_open", AUTO_OPEN) and not view.settings().get('is_widget'): window = view.window() is_preview = window and view.file_name() not in [ file.file_name() for file in window.views() ] if window and not is_preview and view.settings().get( "hex_view_postpone_hexview", True): self.auto_load(view, window, is_preview) temp_file = view.settings().get("hex_viewer_temp_file", None) if temp_file is not None: if exists(temp_file): remove(temp_file) view.set_name( basename(view.settings().get("hex_viewer_file_name")) + ".hex") view.sel().clear() # Offset past address to first byte view.sel().add( sublime.Region(common.ADDRESS_OFFSET, common.ADDRESS_OFFSET)) if common.hv_settings("inspector", False) and common.hv_settings( "inspector_auto_show", False): window = view.window() if window is not None: view.window().run_command("hex_show_inspector")
def buffer_init(self, bits, byte_array): """Initialize info for the hex buffer.""" self.view = self.window.active_view() file_name = None if self.view is not None: # Get font settings self.font = common.hv_settings('custom_font', 'none') self.font_size = common.hv_settings('custom_font_size', 0) # Get file name file_name = self.view.settings().get("hex_viewer_file_name", self.view.file_name()) # Get current bit and byte settings from view # Or try and get them from settings file # If none are found, use default current_bits = self.view.settings().get( 'hex_viewer_bits', common.hv_settings('group_bytes_by_bits', DEFAULT_BIT_GROUP) ) current_bytes = self.view.settings().get( 'hex_viewer_bytes', common.hv_settings('bytes_per_line', DEFAULT_BYTES_WIDE) ) # Use passed in bit and byte settings if available self.bits = bits if bits is not None else int(current_bits) self.bytes = byte_array if byte_array is not None else int(current_bytes) self.set_format() return file_name
def init(self): """Initialize.""" init_status = False # Get highlight settings self.highlight_scope = common.hv_settings("highlight_edit_scope", HIGHLIGHT_EDIT_SCOPE) self.highlight_icon = common.hv_settings("highlight_edit_icon", HIGHLIGHT_EDIT_ICON) style = common.hv_settings("highlight_edit_style", HIGHLIGHT_EDIT_STYLE) # No icon? if self.highlight_icon == "none": self.highlight_icon = "" # Process highlight style self.highlight_style = 0 if style == "outline": self.highlight_style = sublime.DRAW_OUTLINED elif style == "none": self.highlight_style = sublime.HIDDEN elif style == "underline": self.highlight_style = sublime.DRAW_EMPTY_AS_OVERWRITE # Get Seetings from settings file group_size = self.view.settings().get("hex_viewer_bits", None) self.bytes_wide = self.view.settings().get("hex_viewer_actual_bytes", None) # Process hex grouping if group_size is not None and self.bytes_wide is not None: self.group_size = group_size / common.BITS_PER_BYTE init_status = True return init_status
def is_bin_file(self, file_path, encoding): """Determine if view is a bin file.""" match = False if not common.hv_settings("disable_auto_open_hex_encoding", False) and encoding == "Hexadecimal": match = True else: patterns = common.hv_settings("auto_open_patterns", []) for pattern in patterns: match |= fnmatch(file_path, pattern) if match: break return match
def init(self): """Initialize.""" init_status = False self.address_done = False self.total_bytes = 0 self.address = [] self.selected_bytes = [] self.hex_lower = common.use_hex_lowercase() # Get Seetings from settings file group_size = self.view.settings().get("hex_viewer_bits", None) self.inspector_enabled = common.hv_settings("inspector", False) self.throttle = common.hv_settings("highlight_throttle", THROTTLING) self.max_highlight = common.hv_settings("highlight_max_bytes", MAX_HIGHIGHT) self.bytes_wide = self.view.settings().get("hex_viewer_actual_bytes", None) self.highlight_scope = common.hv_settings("highlight_scope", HIGHLIGHT_SCOPE) self.highlight_icon = common.hv_settings("highlight_icon", HIGHLIGHT_ICON) self.enable_fake_hex = common.hv_settings("enable_fake_hex_file", True) style = common.hv_settings("highlight_style", HIGHLIGHT_STYLE) if (group_size is None or self.bytes_wide is None) and self.enable_fake_hex: m = re.match(r'([\da-z]{8}):[\s]{2}((?:[\da-z]+[\s]{1})*)\s*\:[\w\W]*', self.view.substr(self.view.line(0))) if m is not None: starting_address = int(m.group(1), 16) hex_chars = m.group(2).split(' ') group_size = (len(hex_chars[0]) / 2) * 8 self.bytes_wide = (len(hex_chars[0]) / 2) * (len(hex_chars) - 1) self.view.settings().set("hex_viewer_bits", group_size) self.view.settings().set("hex_viewer_actual_bytes", self.bytes_wide) self.view.settings().set("hex_viewer_fake", True) self.view.settings().set("hex_viewer_starting_address", starting_address) self.view.set_read_only(True) self.view.set_scratch(True) if common.hv_settings("inspector", False) and common.hv_settings("inspector_auto_show", False): self.view.window().run_command("hex_show_inspector") # No icon? if self.highlight_icon == "none": self.highlight_icon = "" # Process highlight style self.highlight_style = 0 if style == "outline": self.highlight_style = sublime.DRAW_OUTLINED elif style == "none": self.highlight_style = sublime.HIDDEN elif style == "underline": self.highlight_style = sublime.DRAW_EMPTY_AS_OVERWRITE # Process hex grouping if group_size is not None and self.bytes_wide is not None: self.group_size = group_size / common.BITS_PER_BYTE self.hex_char_range = common.get_hex_char_range(self.group_size, self.bytes_wide) init_status = True return init_status
def is_file_too_big(self): """Check if file is too big and display prompt if desired.""" file_size = float(self.thread.file_size) * 0.001 max_file_size = float(common.hv_settings("max_file_size_kb", DEFAULT_MAX_FILE_SIZE)) too_big = file_size > max_file_size if too_big and common.hv_settings("prompt_on_file_too_big", False): if sublime.ok_cancel_dialog( 'File you\'re trying to open is larger than allowed (in settings). Open anyway?\n\n' 'Skipping opening will fall back to the default action ' '(open in external viewer if available or terminate operation).', 'Open' ): too_big = False return too_big
def is_file_too_big(self): """Check if file is too big and display prompt if desired.""" file_size = float(self.thread.file_size) * 0.001 max_file_size = float( common.hv_settings("max_file_size_kb", DEFAULT_MAX_FILE_SIZE)) too_big = file_size > max_file_size if too_big and common.hv_settings("prompt_on_file_too_big", False): if sublime.ok_cancel_dialog( 'File you\'re trying to open is larger than allowed (in settings). Open anyway?\n\n' 'Skipping opening will fall back to the default action ' '(open in external viewer if available or terminate operation).', 'Open'): too_big = False return too_big
def run(self, edit): """Run command.""" viewer = common.hv_settings("external_viewer", {}).get("viewer", "") if not exists(viewer): error("Can't find the external hex viewer!") return file_name = self.view.file_name() if file_name is not None and exists(file_name): cmd = [viewer] + common.hv_settings("external_viewer", {}).get("args", []) for x in range(0, len(cmd)): cmd[x] = cmd[x].replace("${FILE}", file_name) subprocess.Popen(cmd)
def on_activated(self, view): """Logic for preview windows.""" if common.hv_settings("auto_open", AUTO_OPEN) and not view.settings().get('is_widget'): window = view.window() is_preview = window and view.file_name() not in [file.file_name() for file in window.views()] if view.settings().get("hex_view_postpone_hexview", True) and not view.is_loading(): self.auto_load(view, window, is_preview)
def __init__(self, hash_algorithm=None, data=b""): """Initialize.""" if hash_algorithm is None or hash_algorithm not in VALID_HASH: hash_algorithm = common.hv_settings("hash_algorithm", DEFAULT_CHECKSUM) if hash_algorithm not in VALID_HASH: hash_algorithm = DEFAULT_CHECKSUM self.hash = getattr(hashlib, hash_algorithm)(data) self.name = hash_algorithm
def read_file(self, file_name): """Read the file.""" if common.hv_settings("inspector", False): self.window.run_command("hex_hide_inspector") view = self.window.open_file(file_name) view.settings().set("hex_no_auto_open", True) self.window.focus_view(self.view) self.window.run_command("close_file") self.window.focus_view(view)
def read_bin(self, file_name): """Read the binary file.""" global active_thread self.abort = False self.current_view = self.view self.thread = ReadBin(file_name, self.bytes_wide, self.group_size, self.starting_address) file_size = float(self.thread.file_size) * 0.001 max_file_size = float(common.hv_settings("max_file_size_kb", DEFAULT_MAX_FILE_SIZE)) if file_size > max_file_size: viewer = common.hv_settings("external_viewer", {}).get("viewer", "") if exists(viewer): self.view.run_command("hex_external_viewer") else: error("File size exceeded HexViewers configured max limit of %s KB" % str(max_file_size)) self.reset_thread() else: self.thread.start() self.handle_thread() active_thread = self.thread
def on_load(self, view): """Determine if anything needs to be done with the loaded file.""" # Logic for direct open files if common.hv_settings("auto_open", AUTO_OPEN) and not view.settings().get('is_widget'): window = view.window() is_preview = window and view.file_name() not in [file.file_name() for file in window.views()] if window and not is_preview and view.settings().get("hex_view_postpone_hexview", True): self.auto_load(view, window, is_preview) temp_file = view.settings().get("hex_viewer_temp_file", None) if temp_file is not None: if exists(temp_file): remove(temp_file) view.set_name(basename(view.settings().get("hex_viewer_file_name")) + ".hex") view.sel().clear() # Offset past address to first byte view.sel().add(sublime.Region(common.ADDRESS_OFFSET, common.ADDRESS_OFFSET)) if common.hv_settings("inspector", False) and common.hv_settings("inspector_auto_show", False): window = view.window() if window is not None: view.window().run_command("hex_show_inspector")
def run(self, option): """Run command.""" self.view = self.window.active_view() file_name = self.view.settings().get("hex_viewer_file_name", self.view.file_name()) self.valid_bytes = common.hv_settings("valid_bytes_per_line", VALID_BYTES) if file_name is not None: if self.view.settings().has("hex_viewer_file_name"): option_list = [] if option == "bits": for bits in VALID_BITS: option_list.append(str(bits) + " bits") self.window.show_quick_panel(option_list, self.set_bits) elif option == "bytes": for byte_array in self.valid_bytes: option_list.append(str(byte_array) + " bytes") self.window.show_quick_panel(option_list, self.set_bytes)
def finish_export(self): """Post export event.""" if common.hv_settings("checksum_on_save", USE_CHECKSUM_ON_SAVE): hex_hash = Checksum() self.hex_buffer.seek(0) # Checksum will be threaded and will show the result when done sublime.set_timeout(lambda: sublime.status_message("Checksumming..."), 0) hex_hash.threaded_update(self.hex_buffer, parse_view_data, self.row) # Update the tab name self.view.set_name(common.basename(self.export_path) + ".hex") # Update the internal path self.view.settings().set("hex_viewer_file_name", self.export_path) # Tie it to a real view if not already self.view.settings().set("hex_viewer_fake", False) # Clear the marked edits common.clear_edits(self.view) # Reset class self.reset()
def set_format(self): """Set the hex view format.""" self.group_size = DEFAULT_BIT_GROUP / common.BITS_PER_BYTE self.bytes_wide = DEFAULT_BYTES_WIDE # Set grouping if self.bits in VALID_BITS: self.group_size = self.bits / common.BITS_PER_BYTE # Set bytes per line if self.bytes in common.hv_settings("valid_bytes_per_line", VALID_BYTES): self.bytes_wide = self.bytes # Check if grouping and bytes per line do not align # Round to nearest bytes offset = self.bytes_wide % self.group_size if offset == self.bytes_wide: self.bytes_wide = self.bits / common.BITS_PER_BYTE elif offset != 0: self.bytes_wide -= offset
def is_enabled(self): """Check if command is enabled.""" return bool(common.is_enabled() and common.hv_settings("inspector", False))
def is_enabled(self): """Check if command is enabled.""" file_name = self.window.extract_variables().get('file') viewer = common.hv_settings("external_viewer", {}).get("viewer", "") return exists(viewer) and file_name is not None
def restore(self, value): """Restore.""" window = sublime.active_window() view = None if value.strip().lower() == "yes" and self.fail_safe_view is not None: # Quit if cannot find window if window is None: self.reset() return # Get new view if one was created if self.handshake != -1: for v in window.views(): if self.handshake == v.id(): view = v # Reset handshake so view won't be closed self.handshake = -1 if view is None: view = window.new_file() # Restore view if view is not None: # Get highlight settings highlight_scope = common.hv_settings("highlight_edit_scope", HIGHLIGHT_EDIT_SCOPE) highlight_icon = common.hv_settings("highlight_edit_icon", HIGHLIGHT_EDIT_ICON) style = common.hv_settings("highlight_edit_style", HIGHLIGHT_EDIT_STYLE) # No icon? if highlight_icon == "none": highlight_icon = "" # Process highlight style if style == "outline": style = sublime.DRAW_OUTLINED elif style == "none": style = sublime.HIDDEN elif style == "underline": style = sublime.DRAW_EMPTY_AS_OVERWRITE else: style = 0 # Setup view with saved settings view.set_name(basename(self.fail_safe_view["name"]) + ".hex") view.settings().set("hex_viewer_bits", self.fail_safe_view["bits"]) view.settings().set("hex_viewer_bytes", self.fail_safe_view["bytes"]) view.settings().set("hex_viewer_actual_bytes", self.fail_safe_view["actual"]) view.settings().set("hex_viewer_file_name", self.fail_safe_view["name"]) view.settings().set("font_face", self.fail_safe_view["font_face"]) view.settings().set("font_size", self.fail_safe_view["font_size"]) view.set_syntax_file("Packages/HexViewer/Hex.%s" % common.ST_SYNTAX) view.sel().clear() HexEditGlobal.bfr = self.fail_safe_view["buffer"] HexEditGlobal.region = sublime.Region(0, view.size()) view.run_command("hex_edit_apply") HexEditGlobal.clear() view.set_scratch(True) view.set_read_only(True) view.sel().add(sublime.Region(common.ADDRESS_OFFSET, common.ADDRESS_OFFSET)) view.add_regions( "hex_edit", self.fail_safe_view["edits"], highlight_scope, highlight_icon, style ) self.reset()
def display(self, view, byte8, bytes16, bytes32, bytes64): """Display hex inspector data.""" item_dec = common.hv_settings("inspector_integer_format", "%-12s: %-14d") item_str = common.hv_settings("inspector_missing/bad_format", "%-12s: %-14s") item_float = common.hv_settings("insepctor_float_format", "%-12s: %-14e") item_double = common.hv_settings("inspector_double_format", "%-12s: %-14e") item_bin = common.hv_settings("inspector_binary_format", "%-12s: %-14s") nl = "\n" endian = ">" if self.endian == "big" else "<" i_buffer = "%28s:%-28s" % ("Hex Inspector ", (" Big Endian" if self.endian == "big" else " Little Endian")) + nl if byte8 is not None: i_buffer += item_dec * 2 % ( "byte", unpack(endian + "B", unhexlify(byte8))[0], "short", unpack(endian + "b", unhexlify(byte8))[0] ) + nl else: i_buffer += item_str * 2 % ( "byte", "--", "short", "--" ) + nl if bytes16 is not None: i_buffer += item_dec * 2 % ( "word", unpack(endian + "H", unhexlify(bytes16))[0], "int", unpack(endian + "h", unhexlify(bytes16))[0] ) + nl else: i_buffer += item_str * 2 % ( "word", "--", "int", "--" ) + nl if bytes32 is not None: i_buffer += item_dec * 2 % ( "dword", unpack(endian + "I", unhexlify(bytes32))[0], "longint", unpack(endian + "i", unhexlify(bytes32))[0] ) + nl else: i_buffer += item_str * 2 % ( "dword", "--", "longint", "--" ) + nl if bytes64 is not None: i_buffer += item_dec * 2 % ( "qword", unpack(endian + "Q", unhexlify(bytes64))[0], "longlongint", unpack(endian + "q", unhexlify(bytes64))[0] ) + nl else: i_buffer += item_str * 2 % ( "qword", "--", "longlongint", "--" ) + nl if bytes32 is not None: s_float = unpack(endian + "f", unhexlify(bytes32))[0] if math.isnan(s_float): i_buffer += item_str % ("float", "NaN") else: i_buffer += item_float % ( "float", s_float ) else: i_buffer += item_str % ("float", "--") if bytes64 is not None: d_float = unpack(endian + "d", unhexlify(bytes64))[0] if math.isnan(d_float): i_buffer += item_str % ("double", "NaN") + nl else: i_buffer += item_double % ( "double", d_float ) + nl else: i_buffer += item_str % ("double", "--") + nl if byte8 is not None: i_buffer += item_bin % ("binary", '{0:08b}'.format(unpack(endian + "B", unhexlify(byte8))[0])) + nl else: i_buffer += item_str % ("binary", "--") + nl # Update content view.set_read_only(False) HexInspectGlobal.bfr = i_buffer HexInspectGlobal.region = sublime.Region(0, view.size()) view.run_command("hex_inspector_apply") HexInspectGlobal.clear() view.set_read_only(True) view.sel().clear()
def plugin_loaded(): """Setup plugin.""" global hv_endianness hv_endianness = common.hv_settings("inspector_endian", "little")
def restore(self, value): """Restore.""" window = sublime.active_window() view = None if value.strip().lower() == "yes" and self.fail_safe_view is not None: # Quit if cannot find window if window is None: self.reset() return # Get new view if one was created if self.handshake != -1: for v in window.views(): if self.handshake == v.id(): view = v # Reset handshake so view won't be closed self.handshake = -1 if view is None: view = window.new_file() # Restore view if view is not None: # Get highlight settings highlight_scope = common.hv_settings("highlight_edit_scope", HIGHLIGHT_EDIT_SCOPE) highlight_icon = common.hv_settings("highlight_edit_icon", HIGHLIGHT_EDIT_ICON) style = common.hv_settings("highlight_edit_style", HIGHLIGHT_EDIT_STYLE) # No icon? if highlight_icon == "none": highlight_icon = "" # Process highlight style if style == "outline": style = sublime.DRAW_OUTLINED elif style == "none": style = sublime.HIDDEN elif style == "underline": style = sublime.DRAW_EMPTY_AS_OVERWRITE else: style = 0 # Setup view with saved settings view.set_name(basename(self.fail_safe_view["name"]) + ".hex") view.settings().set("hex_viewer_bits", self.fail_safe_view["bits"]) view.settings().set("hex_viewer_bytes", self.fail_safe_view["bytes"]) view.settings().set("hex_viewer_actual_bytes", self.fail_safe_view["actual"]) view.settings().set("hex_viewer_file_name", self.fail_safe_view["name"]) view.settings().set("font_face", self.fail_safe_view["font_face"]) view.settings().set("font_size", self.fail_safe_view["font_size"]) view.set_syntax_file("Packages/HexViewer/Hex.%s" % common.ST_SYNTAX) view.sel().clear() HexEditGlobal.bfr = self.fail_safe_view["buffer"] HexEditGlobal.region = sublime.Region(0, view.size()) view.run_command("hex_edit_apply") HexEditGlobal.clear() view.set_scratch(True) view.set_read_only(True) view.sel().add( sublime.Region(common.ADDRESS_OFFSET, common.ADDRESS_OFFSET)) view.add_regions("hex_edit", self.fail_safe_view["edits"], highlight_scope, highlight_icon, style) self.reset()
def is_enabled(self): """Check if command is enabled.""" viewer = common.hv_settings("external_viewer", {}).get("viewer", "") return exists(viewer) and self.view.file_name() is not None
def display(self, view, byte8, bytes16, bytes32, bytes64): """Display hex inspector data.""" item_dec = common.hv_settings("inspector_integer_format", "%-12s: %-14d") item_str = common.hv_settings("inspector_missing/bad_format", "%-12s: %-14s") item_float = common.hv_settings("inspector_float_format", "%-12s: %-14e") item_double = common.hv_settings("inspector_double_format", "%-12s: %-14e") item_bin = common.hv_settings("inspector_binary_format", "%-12s: %-14s") nl = "\n" endian = ">" if self.endian == "big" else "<" i_buffer = "%28s:%-28s" % ("Hex Inspector ", (" Big Endian" if self.endian == "big" else " Little Endian")) + nl if byte8 is not None: i_buffer += item_dec * 2 % ( "byte", unpack(endian + "B", unhexlify(byte8))[0], "short", unpack(endian + "b", unhexlify(byte8))[0]) + nl else: i_buffer += item_str * 2 % ("byte", "--", "short", "--") + nl if bytes16 is not None: i_buffer += item_dec * 2 % ( "word", unpack(endian + "H", unhexlify(bytes16))[0], "int", unpack(endian + "h", unhexlify(bytes16))[0]) + nl else: i_buffer += item_str * 2 % ("word", "--", "int", "--") + nl if bytes32 is not None: i_buffer += item_dec * 2 % ( "dword", unpack(endian + "I", unhexlify(bytes32))[0], "longint", unpack(endian + "i", unhexlify(bytes32))[0]) + nl else: i_buffer += item_str * 2 % ("dword", "--", "longint", "--") + nl if bytes64 is not None: i_buffer += item_dec * 2 % ( "qword", unpack(endian + "Q", unhexlify(bytes64))[0], "longlongint", unpack(endian + "q", unhexlify(bytes64))[0]) + nl else: i_buffer += item_str * 2 % ("qword", "--", "longlongint", "--") + nl if bytes32 is not None: s_float = unpack(endian + "f", unhexlify(bytes32))[0] if math.isnan(s_float): i_buffer += item_str % ("float", "NaN") else: i_buffer += item_float % ("float", s_float) else: i_buffer += item_str % ("float", "--") if bytes64 is not None: d_float = unpack(endian + "d", unhexlify(bytes64))[0] if math.isnan(d_float): i_buffer += item_str % ("double", "NaN") + nl else: i_buffer += item_double % ("double", d_float) + nl else: i_buffer += item_str % ("double", "--") + nl if byte8 is not None: i_buffer += item_bin % ("binary", '{0:08b}'.format( unpack(endian + "B", unhexlify(byte8))[0])) + nl else: i_buffer += item_str % ("binary", "--") + nl # Update content view.set_read_only(False) HexInspectGlobal.bfr = i_buffer HexInspectGlobal.region = sublime.Region(0, view.size()) view.run_command("hex_inspector_apply") HexInspectGlobal.clear() view.set_read_only(True) view.sel().clear()