Is there a string to 32 bit integer coding system in elisp?

Viewed 69

Is there a coding system such that (encode-coding-string msg '??? t) would convert my message into a list of 32 bit integers?

The binary coding system converts well the message to 8 bit data, and I am aware that I could post-process it to convert the result into 32 bits. I'm just wondering if there is already a coding system that does this... :) #lazy

1 Answers

Ok, attempt number two.

I wrote a test generator snippet in python:

def make_test_2():
    with open('test2.bin', 'wb') as f:
        args = [1867, 1982]
        
        for a in args:
            f.write((a).to_bytes(4, byteorder='little'))

This is a pretty hacky (a couple of reverse calls etc). But, its only meant to be a quick and dirty prototype.

(defun read-int-list2 (filename)
  (let ((result '())
        (accumulator '())
        (accum-count 0)
        (accum-max 4))
    (with-temp-buffer
      (set-buffer-multibyte nil)
      (setq buffer-file-coding-system 'binary) ;; find a way to set temporarily? not sure
      (insert-file-contents-literally filename)
      (while (< (point) (point-max))

        (if (< accum-count accum-max)
            (progn
              (setq accumulator (cons (aref (buffer-substring-no-properties (point) (1+ (point))) 0) accumulator))
              (setq accum-count (1+ accum-count))))

        (if (>= accum-count accum-max) ;; four bytes accumulated, lets bundle
            (progn
              (let* ((s (reverse accumulator))
                     (e1 (elt s 0))
                     (e2 (elt s 1))
                     (e3 (elt s 2))
                     (e4 (elt s 3))
                     (val (logior (lsh e4 24) (lsh e3 16) (lsh e2 8) e1))) ;; assume little endian (intel, ARM)
                ;; (message (format "%x %x %x %x -> %d" e1 e2 e3 e4 val))
                (setq result (cons val result))
                (setq accum-count 0)
                (setq accumulator '()))))

        (forward-char)))

    (reverse result)))

(read-int-list2 "test2.bin") ;; (1867 1982)

I only did the one test. So that needs improvement. In words:

  1. accumulate 8 byte chars from the special temp buffer (special because binary/literal load)
  2. once the bytes per integer count has been reached, merge the accumulated bytes into an integer by bit shifting (be aware some machines are big endian, I assume here little endian) the bytes into place.
  3. dump merged into result list
  4. reset the accumulator
  5. go to step 1

i have no doubt there are many improvements, my lisp is rusty.

Related