Jump to content

Recommended Posts

Posted

Hello again
I want to do something in lisp to read or write binary files at bit level. My intention is to be able to read or write numbers encoded in the IEEE754 standard or any other
I know 'binio.fas' and I know I could use it as a starting point.
But before I decide to write anything I want to know if there is any library that can do this job.

Thanks in advance

Posted

Thanks RLX
Yes: I already knew these LM functions. I also know and use the 'binio.fas' functions
But these functions read or write at the byte level. To encode numbers in the floating point arithmetic standard (IEEE 754) it is necessary to obtain the list of bits for each byte.
This can be done in lisp but if there is some already compiled library that allows this, it would save me the work of having to write it and it would also work faster.

Posted (edited)

think I still have the original (pre-Lee) functions somewhere but I suspect they are pretty much the same . Last time I used them was probably last century anyway. But it was worth a shot.. 

 

the code I mentioned :

 

;;; CodeHimBelonga MP fromTheSwamp
(defun _ReadStream ( path len / fso file stream result )

    ;;  If the file is successful read the data is returned as 
    ;;  a string. Won't be tripped up by nulls, control chars
    ;;  including ctrl z (eof marker). Pretty fast (feel free 
    ;;  to bench mark / compare to alternates).
    ;;
    ;;  If the caller wants the result as a list of byte values 
    ;;  simply use vl-string->list on the result:
    ;;
    ;;      (setq bytes
    ;;          (if (setq stream (_ReadStream path len))
    ;;              (vl-string->list stream)
    ;;          )
    ;;      )            
    ;;
    ;;  Arguments:
    ;;
    ;;      path  <duh>
    ;;      len   Number of bytes to read. If non numeric, less 
    ;;            than 1 or greater than the number of bytes in 
    ;;            the file everything is returned.
    
    (vl-catch-all-apply
       '(lambda ( / iomode format size )
            (setq 
                iomode   1 ;; 1 = read, 2 = write, 8 = append
                format   0 ;; 0 = ascii, -1 = unicode, -2 = system default
                fso      (vlax-create-object "Scripting.FileSystemObject")
                file     (vlax-invoke fso 'GetFile path)
                stream   (vlax-invoke fso 'OpenTextFile path iomode format)
                size     (vlax-get file 'Size)
                len      (if (and (numberp len) (< 0 len size)) (fix len) size)
                result   (vlax-invoke stream 'read len)
            )
            (vlax-invoke stream 'Close)
        )
    )
    
    (if stream (vlax-release-object stream))
    (if file (vlax-release-object file))
    (if fso (vlax-release-object fso))
    
    result

)



;;; CodeHimBelonga MP fromTheSwamp
(defun _WriteStream ( path text mode / fso stream file result )

    ;;  Return the file size if the file is successfully written 
    ;;  to, otherwise nil. Will write all ascii chars to file
    ;;  including nulls. If the caller wants to pass a list of
    ;;  byte values to the function just call it like so:
    ;;
    ;;      (_WriteStream 
    ;;          path 
    ;;          (vl-list->string '(87 111 111 116 33)) 
    ;;          mode
    ;;      ) 
    ;;
    ;;  Arguments:
    ;;
    ;;      path  <duh>
    ;;      text  <duh>
    ;;      mode  "a" to create/append, 
    ;;            "w" to create/overwrite (default)
    
    (setq mode (if (member mode '("a" "A")) "a" "w"))
    
    (vl-catch-all-apply
       '(lambda ( / format )
            (setq fso (vlax-create-object "Scripting.FileSystemObject"))
            (cond
                (   (or (null (findfile path)) (eq "w" mode))
                    (setq stream
                        (vlax-invoke 
                            fso
                           'CreateTextFile 
                            path 
                           -1 ;; 0 (false) = don't overwrite , -1 (true) = overwrite
                            0 ;; 0 (false) = ascii, -1 (true) = unicode 
                        )
                    )
                    (setq file (vlax-invoke fso 'GetFile path))
                )
                (   (setq file (vlax-invoke fso 'GetFile path))
                    (setq stream
                        (vlax-invoke 
                            file
                           'OpenAsTextStream 
                            8 ;; 1 = read, 2 = write, 8 = append
                            0 ;; 0 = ascii, -1 = unicode, -2 system default
                        )
                    )       
                )
            )
            (vlax-invoke stream 'Write text)
            (vlax-invoke stream 'Close)
            (setq result (vlax-get file 'Size))
        )
    )

    (if file (vlax-release-object file))
    (if stream (vlax-release-object stream))
    (if fso (vlax-release-object fso))
    
    result
    
)



(defun c:t3 ( / fn )
  (if (setq fn (getfiled "Any file" "" "" 0))(setq str (vl-string->list (_ReadStream fn 0))))
  (princ)
  (_WriteStream "c:\\temp\\streamtest.txt" (vl-list->string str) "w")
  (princ)
)

(defun c:t4 ( / str fn)
  (setq str '(66 77 6 3 0 0 0 0 0 0 54 0 0 0 40 0 0 0 16 0 0 0 15 0 0 0 1 0 24 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
	      0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0
	      0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 0 0
	      0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255
	      0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255
	      0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255
	      0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0
	      0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255
	      0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255
	      0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0
	      0 0 0 0 0 0 0 0 255 0 0 0 0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255
	      0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255
	      0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255
	      0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0
	      255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0
	      255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0
	      0 255 0 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 0 0 0 0 0 0 255 0 0 255 0 0 0
	      0 0 0 0 0 0 0 0 0 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255
	      0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0 0 255 0))
  (_WriteStream "c:\\temp\\streamtestje.bmp" (vl-list->string str) "w")
  (princ)
)

 

Edited by rlx
Posted

Interesting, there’s no bit type, you will have to read bytes and unpack the bits.

Curious how this would be done efficiently in lisp

easier in C++, depending on endianness just memcpy or a cast

Posted (edited)

Yes: I think the only way to achieve this is by transforming each byte into a list of bits.

I have already done this. Now I am finishing designing the read and write functions to work with single (32 bits) and double (64 bits) precision numbers.

Once I finish this work and test it, I will leave the result in this thread, in case anyone finds it useful.

 

In any case, one thing is clear: in Lisp it cannot be so efficient.

Edited by GLAVCVS
  • Like 1
Posted

Do you have a file? or link to an example file?

I have a read function in C++ that should crush performance wise, just want to test it lol

Posted (edited)
(defun decimal->binario	(num / lst dameBit dif)
  (defun dameBit (num / resto)
    (if	(> (setq resto (rem num 2)) 9)
      (+ 55 resto)
      resto
    )
  )
  (setq	lst (list (dameBit num)))
  (while (>= (setq num (/ num 2)) 2)
    (setq lst (append (list (dameBit num)) lst))
  )
  (append (list (dameBit num)) lst)
)

 

 

Decimal-binario.lsp

Edited by GLAVCVS
Minor correction
Posted

I will post the rest when I finish it. This will not happen before 2-3 days.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...