Hexa bindings: first commit.

This commit is contained in:
Philippe PITTOLI 2024-06-21 13:28:45 +02:00
commit c829cfcd59
10 changed files with 171 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
/docs/
/lib/
/bin/
/.shards/
/examples/example
*.dwarf
# Libraries don't need dependency lock
# Dependencies will be locked in applications that use them
/shard.lock

37
README.md Normal file
View File

@ -0,0 +1,37 @@
# hexa
Bindings to `libhexa` to produce hexadecimal dumps of arbitrary input bytes.
This prints debug info in a pretty way.
## Installation
1. Add the dependency to your `shard.yml`:
```yaml
dependencies:
hexa:
branch: master
git: https://git.baguette.netlib.re/Baguette/hexa.cr.git
```
2. Run `shards install`
## Usage
```crystal
require "hexa"
h = Hexa.new 5_000 # Size of the output buffer.
# First, an hexadecimal dump of a small text.
text = "hello this is some text" # could be Bytes
puts h.dump text
# With a centered title on the first line.
title = "itz mai title lul"
puts h.dump title, text
```
## Contributors
- [Philippe PITTOLI](https://github.com/your-github-user) - creator and maintainer

12
examples/example.cr Normal file
View File

@ -0,0 +1,12 @@
require "../src/hexa.cr"
h = Hexa.new 2_000
text = "hello this is some text I want to show"
puts h.dump text
puts ""
puts "with a title:"
title = "some text"
puts h.dump title, text

13
examples/makefile Normal file
View File

@ -0,0 +1,13 @@
all: build
include makefile.local
SOURCE_FILES = ../src/bindings.cr ../src/hexa.cr ../src/high-level-bindings.cr
example: $(SOURCE_FILES) example.cr
crystal build --progress $(LD_FLAGS) example.cr
build: example
run: build
$(LIB_PATH) ./example

9
examples/makefile.local Normal file
View File

@ -0,0 +1,9 @@
ifdef DEV
# Use ABSOLUTE paths for linker parameters (-L path) to avoid errors.
LIB_HEXA_REPOS ?= /tmp/prog/libhexa/zig-out/lib
LIB_PATH = LD_LIBRARY_PATH=$(LIB_HEXA_REPOS)
endif
ifdef LIB_HEXA_REPOS
# This is an example on how to use link flags with Crystal.
LD_FLAGS ?= --link-flags "-L$(LIB_HEXA_REPOS)"
endif

11
makefile Normal file
View File

@ -0,0 +1,11 @@
SOURCE_FILES = src/bindings.cr src/hexa.cr src/high-level-bindings.cr
doc:
crystal docs $(SOURCE_FILES)
HTTPD_ACCESS_LOGS ?= /tmp/access-hexa.cr-docs.log
HTTPD_ADDR ?= 127.0.0.1
HTTPD_PORT ?= 9002
DIR ?= docs
serve-doc:
darkhttpd $(DIR) --addr $(HTTPD_ADDR) --port $(HTTPD_PORT) --log $(HTTPD_ACCESS_LOGS)

15
shard.yml Normal file
View File

@ -0,0 +1,15 @@
name: hexa
version: 0.1.0
authors:
- Philippe PITTOLI <karchnu@karchnu.fr>
description: |
High-level Crystal bindings to libhexa.
crystal: '>= 1.12.2'
libraries:
libhexa: ">= 0.1.0"
license: ISC

5
src/bindings.cr Normal file
View File

@ -0,0 +1,5 @@
@[Link("hexa")]
lib LibHexa
# title & title_len, input & input len, buffer & pointer on buffer len -> int
fun dump = hexdump(LibC::Char*, UInt32, LibC::Char*, UInt32, LibC::Char*, UInt32*) : LibC::Int
end

2
src/hexa.cr Normal file
View File

@ -0,0 +1,2 @@
require "./bindings.cr"
require "./high-level-bindings.cr"

View File

@ -0,0 +1,57 @@
# The `Hexa` class is a high-level binding to `libhexa`, producing hexadecimal dumps of arbitrary input bytes.
# Used to print debug info in a pretty way.
#
# This library can be used with either raw Bytes or strings for the input buffer.
# A title can be given to the dump.
#
# ```
# require "hexa"
#
# h = Hexa.new 2_000 # Size of the output buffer.
#
# text = "hello this is some text I want to show"
# puts h.dump text
#
# puts ""
# puts "same thing with a title:"
#
# title = "some text"
# puts h.dump title, text
# ```
class Hexa
property buffer_size : UInt32 = 200_000
def initialize(buffer_size : UInt32?)
@buffer_size = buffer_size if buffer_size
@output_buffer = Array(UInt8).new @buffer_size
end
# Hexdump with a title and an input string.
def dump(title : String, buffer : String) : String
dump title, buffer.to_slice
end
# Hexdump with a title and raw bytes as input.
def dump(title : String, buffer : Bytes) : String
buflen : UInt32 = @buffer_size
ret = LibHexa.dump title, title.size, buffer.to_unsafe, buffer.size, @output_buffer.to_unsafe, pointerof(buflen)
if ret != 0
raise "oh noes, 'dump' iz brkn"
end
String.new @output_buffer.to_unsafe.to_slice(buflen)
end
# Hexdump a string (no title).
def dump(buffer : String) : String
dump buffer.to_slice
end
# Hexdump raw bytes (no title).
def dump(buffer : Bytes) : String
buflen : UInt32 = @buffer_size
ret = LibHexa.dump "", 0, buffer.to_unsafe, buffer.size, @output_buffer.to_unsafe, pointerof(buflen)
if ret != 0
raise "oh noes, 'dump' iz brkn"
end
String.new @output_buffer.to_unsafe.to_slice(buflen)
end
end