Hello there again,

I think I fell again on a weird niche issue.

I try to consume some json data generated by another program, before sending 
them to another program after processing (mainly filtering). At the beginning 
every thing was fine… until I discover some missing data. By digging into it, I 
discovered some glitches in the strings I was processing. As I’m not (yet 😉) a 
scheme expert, I didn’t really know how to debug that, but I tried with the 
bytevector module. I discovered that everything is fine for ascii chars, but 
once one of the parsed string contains any non-ascii chars, problems begins. 
Not only complicated utf8 stuff like emojis. But also accentuated letters…

I write a simple script bellow to test what happen. Everything is 
self-contained: the script generates a very simple json file, then try to parse 
it either directly (through with-input-from-file) or from a process call (by 
calling cat on it). As you will see the direct parsing works, but not the 
process output parsing. So my guess would be that it is more a process-port 
than a json module issue… but as far as I can tell, both port report utf8 as 
encoding.

If someone has an idea of what can be the issue there?

Here is the result of the script on my machine:

test-data1: "🤫 ascii — éè"
test-data2: "🤫 ascii — éè"
test-data3: "🤫 ascii — éè"
test-data1 == test-data2: #t
test-data1 == test-data3: #f
test-data1 string->utf8: #u8(240 159 164 171             32 97 115 99 105 105 
32 226 128 148         32 195 169     195 168)
test-data3 string->utf8: #u8(240 159 164 171 159 164 171 32 97 115 99 105 105 
32 226 128 148 128 148 32 195 169 169 195 168 168)

(as you can see, some bytes (159 164 171) seems to be duplicated in test-data3 
before the first space (32) and again later around the –, plus the final double 
168. I don’t know from where they come.

As the script is a bit long, I say thank you in advance now,

Have a good day,

Étienne

Here is the script:

(import (scheme base)
        (chicken format)
        (chicken process)
        json)

;; Test string with utf8 chars
(define test-data1 "🤫 ascii — éè")

;; Create json file
(with-output-to-file "test.json"
  (lambda ()
    (fprintf (current-output-port)
             "{\"test\": \"~A\"}"
             test-data1)))

;; Reading it directly as a file
(define test-data2
  (cdr
   (vector-ref
    (with-input-from-file "test.json" json-read)
    0)))

;; Reading it from a process output
(define test-data3
  (let* ((proc (process "cat" '("test.json")))
         (stdout (process-output-port proc)))
    (close-output-port (process-input-port proc))
    (let ((output (json-read stdout)))
      (close-input-port stdout)
      (receive (process-wait proc))
      (cdr (vector-ref output 0)))))

(printf "test-data1: ~S~N" test-data1)
(printf "test-data2: ~S~N" test-data2)
(printf "test-data3: ~S~N" test-data3)

(printf "test-data1 == test-data2: ~S~N" (equal? test-data1 test-data2)) ;; #t
(printf "test-data1 == test-data3: ~S~N" (equal? test-data1 test-data3)) ;; #f 
<-- error

(printf "test-data1 string->utf8: ~S~N" (string->utf8 test-data1))
(printf "test-data3 string->utf8: ~S~N" (string->utf8 test-data3))





Reply via email to