mirror of
				https://github.com/NotAShelf/hexxy.git
				synced 2025-10-31 19:32:37 +00:00 
			
		
		
		
	[hexxy] add --reverse option and --plain
This commit is contained in:
		
					parent
					
						
							
								f45df01756
							
						
					
				
			
			
				commit
				
					
						6d4d21c621
					
				
			
		
					 2 changed files with 195 additions and 7 deletions
				
			
		
							
								
								
									
										105
									
								
								hexxy.go
									
										
									
									
									
								
							
							
						
						
									
										105
									
								
								hexxy.go
									
										
									
									
									
								
							|  | @ -2,6 +2,7 @@ package main | |||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"encoding/hex" | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
|  | @ -16,6 +17,10 @@ import ( | |||
| var opts struct { | ||||
| 	NoColor      bool   `short:"N" long:"no-color" description:"do not print output with color"` | ||||
| 	OffsetFormat string `short:"t" long:"radix" default:"x" choice:"d" choice:"o" choice:"x" description:"Print offset in [d|o|x] format"` | ||||
| 	Reverse      bool   `short:"r" long:"reverse" description:"re-assemble hexdump output back into binary"` | ||||
| 	Plain        bool   `short:"p" long:"plain" description:"plain output without ascii table and offset row [often used with hexxy -r]"` | ||||
| 	ForceColor   bool   `short:"F" long:"force-color" description:"color is automatically disabled if output is a pipe, this option forces color output"` | ||||
| 	Separator    string `short:"s" long:"separator" default:"|" description:"separator character for the ascii character table"` | ||||
| 	Verbose      bool   `short:"v" long:"verbose" description:"print debugging information and verbose output"` | ||||
| } | ||||
| 
 | ||||
|  | @ -81,6 +86,7 @@ func printOffset(offset uint64) string { | |||
| } | ||||
| 
 | ||||
| func printSeparator(writer io.Writer, newline bool) { | ||||
| 	// WHY??? | ||||
| 	if newline { | ||||
| 		fmt.Fprintln(writer, Separator) | ||||
| 	} else { | ||||
|  | @ -158,19 +164,89 @@ func Hexdump(file *os.File, color *Color) error { | |||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func HexdumpPlain(file *os.File) error { | ||||
| 	// stdout := bufio.NewWriter(os.Stdout) | ||||
| 	// stderr := os.Stderr | ||||
| 	// defer stdout.Flush() | ||||
| 
 | ||||
| 	src, err := io.ReadAll(file) | ||||
| 	if err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	dst := make([]byte, hex.EncodedLen(len(src))) | ||||
| 	hex.Encode(dst, src) | ||||
| 	fmt.Printf("%s\n", dst) | ||||
| 
 | ||||
| 	// reader := bufio.NewReaderSize(file, 10*1024*1024) | ||||
| 
 | ||||
| 	// for { | ||||
| 	// 	b, err := reader.ReadByte() | ||||
| 	// 	if errors.Is(err, io.EOF) { | ||||
| 	// 		break | ||||
| 	// 	} | ||||
| 	// 	if err != nil { | ||||
| 	// 		fmt.Fprintf(stderr, "Failed to read %v: %v\n", file.Name(), err) | ||||
| 	// 		return err | ||||
| 	// 	} | ||||
| 	// 	stdout.WriteString(fmt.Sprintf("%02x", string(b))) | ||||
| 	// } | ||||
| 	return nil | ||||
| } | ||||
| 
 | ||||
| func plain2Binary(file *os.File) error { | ||||
| 
 | ||||
| 	return reverse(os.Stdout, os.Stdin) | ||||
| 	// contents, err := io.ReadAll(file) | ||||
| 	// if err != nil { | ||||
| 	// 	return err | ||||
| 	// } | ||||
| 	// fmt.Println(len(contents)) | ||||
| 	// fmt.Printf("Binary byte representation: %08b\n", contents) | ||||
| 
 | ||||
| 	// _, err = hex.Decode(contents, dst) | ||||
| 	// if err != nil { | ||||
| 	// 	return err | ||||
| 	// } | ||||
| 	// os.Stdout.Write(dst) | ||||
| 
 | ||||
| 	// dest := make([]byte, hex.EncodedLen(len(contents))) | ||||
| 	// hex.Decode(dest, contents) | ||||
| 
 | ||||
| 	// fmt.Printf("%s\n", dest) | ||||
| 
 | ||||
| 	// return nil | ||||
| } | ||||
| 
 | ||||
| func getOffsetFormat() error { | ||||
| 	var prefix string | ||||
| 	var suffix string | ||||
| 	var sep string | ||||
| 
 | ||||
| 	// turn off color if output is a pipe | ||||
| 	// idk if I like this though since I often | ||||
| 	// use hexxy asdf | head -n 10 but I also want to work on --reverse option | ||||
| 
 | ||||
| 	// stat, _ := os.Stdout.Stat() | ||||
| 	// if stat.Mode()&os.ModeCharDevice == 0 && !opts.ForceColor { | ||||
| 	// 	opts.NoColor = true | ||||
| 	// } | ||||
| 
 | ||||
| 	if !opts.NoColor { | ||||
| 		prefix = GREY | ||||
| 		suffix = CLR | ||||
| 		sep = "│" | ||||
| 	} else { | ||||
| 		prefix = "" | ||||
| 		suffix = "" | ||||
| 		sep = "|" | ||||
| 	} | ||||
| 
 | ||||
| 	Separator = prefix + "│" + suffix | ||||
| 	if opts.Separator != "" { | ||||
| 		sep = opts.Separator | ||||
| 	} | ||||
| 
 | ||||
| 	Separator = prefix + sep + suffix | ||||
| 
 | ||||
| 	switch opts.OffsetFormat { | ||||
| 	case "d": | ||||
|  | @ -188,6 +264,10 @@ func getOffsetFormat() error { | |||
| func Hexxy(args []string) error { | ||||
| 	color := &Color{} | ||||
| 
 | ||||
| 	if opts.Reverse { | ||||
| 		return plain2Binary(os.Stdin) | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.NoColor { | ||||
| 		color.disable = true | ||||
| 	} | ||||
|  | @ -197,8 +277,12 @@ func Hexxy(args []string) error { | |||
| 	} | ||||
| 
 | ||||
| 	if len(args) < 1 && stdinOpen() { | ||||
| 		if opts.Plain { | ||||
| 			return HexdumpPlain(os.Stdin) | ||||
| 		} else { | ||||
| 			return Hexdump(os.Stdin, color) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	for _, f := range args { | ||||
| 		file, err := os.Open(f) | ||||
|  | @ -207,10 +291,16 @@ func Hexxy(args []string) error { | |||
| 		} | ||||
| 		defer file.Close() | ||||
| 
 | ||||
| 		if opts.Plain { | ||||
| 			if err := HexdumpPlain(file); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} else { | ||||
| 			if err := Hexdump(file, color); err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
| } | ||||
|  | @ -228,6 +318,19 @@ func main() { | |||
| 		Debug = log.Printf | ||||
| 	} | ||||
| 
 | ||||
| 	if opts.Reverse { | ||||
| 		// f, err := os.Open(args[0]) | ||||
| 		// if err != nil { | ||||
| 		// 	panic(err) | ||||
| 		// } | ||||
| 		// defer f.Close() | ||||
| 		err = plain2Binary(os.Stdin) | ||||
| 		if err != nil { | ||||
| 			log.Fatal(err) | ||||
| 		} | ||||
| 		os.Exit(0) | ||||
| 	} | ||||
| 
 | ||||
| 	err = getOffsetFormat() | ||||
| 	if err != nil { | ||||
| 		log.Fatal(err) | ||||
|  |  | |||
							
								
								
									
										85
									
								
								reverse.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										85
									
								
								reverse.go
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,85 @@ | |||
| package main | ||||
| 
 | ||||
| import ( | ||||
| 	"bufio" | ||||
| 	"fmt" | ||||
| 	"io" | ||||
| 	"os" | ||||
| 	"strconv" | ||||
| 	"strings" | ||||
| ) | ||||
| 
 | ||||
| // func reverse(w io.Writer, path string) error { | ||||
| func reverse(w io.Writer, f *os.File) error { | ||||
| 	// f, err := os.Open(path) | ||||
| 	// if err != nil { | ||||
| 	// 	return err | ||||
| 	// } | ||||
| 	// defer f.Close() | ||||
| 	s := bufio.NewScanner(f) | ||||
| 
 | ||||
| 	star := false | ||||
| 	var prev uint64 | ||||
| 	var data []byte | ||||
| 	var zero [16]byte | ||||
| 
 | ||||
| 	for s.Scan() { | ||||
| 		line := s.Text() | ||||
| 		if line == "*" { | ||||
| 			star = true | ||||
| 			continue | ||||
| 		} | ||||
| 
 | ||||
| 		if len(line) < len("00000000") { | ||||
| 			return fmt.Errorf("invalid line %q, missing address prefix", line) | ||||
| 		} | ||||
| 
 | ||||
| 		part := line[:len("00000000")] | ||||
| 		line = line[len("00000000"):] | ||||
| 
 | ||||
| 		addr, err := strconv.ParseUint(part, 16, 32) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 
 | ||||
| 		if star { | ||||
| 			for i := prev + 16; i < addr; i += 16 { | ||||
| 				data = append(data, zero[:]...) | ||||
| 			} | ||||
| 			star = false | ||||
| 		} | ||||
| 
 | ||||
| 		prev = addr | ||||
| 		pos := strings.IndexByte(line, '|') | ||||
| 
 | ||||
| 		if pos != -1 { | ||||
| 			line = line[:pos] | ||||
| 		} | ||||
| 
 | ||||
| 		for len(line) > 0 { | ||||
| 			line = strings.TrimSpace(line) | ||||
| 			pos := strings.IndexByte(line, ' ') | ||||
| 			if pos == -1 { | ||||
| 				pos = len(line) | ||||
| 			} | ||||
| 
 | ||||
| 			part := line[:pos] | ||||
| 			line = line[pos:] | ||||
| 
 | ||||
| 			b, err := strconv.ParseUint(part, 16, 8) | ||||
| 			if err != nil { | ||||
| 				return err | ||||
| 			} | ||||
| 
 | ||||
| 			data = append(data, byte(b)) | ||||
| 		} | ||||
| 	} | ||||
| 	if err := s.Err(); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 
 | ||||
| 	if _, err := w.Write(data); err != nil { | ||||
| 		return err | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 mizi
				mizi