2017-08-28 2 views
0

Je suis nouveau à Racket Lang et auparavant j'ai écrit des milliers de lignes de code en C++, Java et C. J'essaie de comprendre comment faire la tâche suivante:Traitement des données binaires brutes avec Racket

  • donnant un tableau (comme tableau C uint8_t) avec le format suivant:

    • premier octet est utilisé pour indiquer le « format », disons que cela pourrait être 0x0a, 0x0B et ainsi de suite.
    • Les données restantes peuvent inclure des chaînes C sans terminateur nul et des entiers.
  • Ecrivez une fonction qui analyse le tableau et place les valeurs dans certaines variables.

Avant de demander ici, je lisais: https://docs.racket-lang.org/guide et aussi https://docs.racket-lang.org/reference

Mon approche est la suivante:

  • J'utilise une chaîne d'octets, car il semble qu'il peut être utilisé pour imiter les tableaux C++/C.
  • J'utilise la récursion de queue pour traverser le "tableau".

Questions:

1) en C, I utilisent toujours la valeur de retour d'une fonction comme un code d'erreur: 0 est correct et une valeur négative est une erreur. Avec Racket, j'utilise plusieurs valeurs de retour pour indiquer: a) le code de retour, b) la valeur traitée (s), à savoir quelque chose comme:

(valeurs return_code OUT2 OUT1 ...)

Qu'est-ce que tu penses? Recommandez-vous l'utilisation d'exceptions pour le traitement des erreurs?

2) Quelle est la meilleure approche pour traiter des tableaux dans Racket? Je veux dire, le meilleur selon l'offre de Racket et pour réaliser une bonne performance.

Merci!

Edit1: En ce qui concerne ma première question (les codes de retour), je fais appel de nombreuses fonctions et je voudrais revenir un code de sortie qui me permet de savoir s'il y avait une erreur dans la fonction. Ceci est un exemple de code:

#lang racket 

(define (is_valid in) 
    (cond 
    [(and (>= in 10) (<= in 15)) #t] 
    [else #f])) 

(define (copy_values in) 
    (define len (bytes-ref in 2)) 
    ; 3 is where the string "ABCD" begins 
    (define str (subbytes in 3 (+ 3 len))) 
    (define numbers (subbytes in (+ 3 len))) 
    (values str numbers)) 

(define (parse in) 
    (define type (bytes-ref in 0)) 
    (if (is_valid type) 
     (let() 
     (define-values (str numbers) (copy_values in)) 
     (values #t str numbers)) 
     (values #f 0 0))) 

; format:   type strlen 
;      len |-- str --| | -- numbers -- | 
;       
(define input1 (bytes 10 10 4 65 66 67 68 110 120 130 140 150)) 

(define input2 (bytes 1 10 4 65 66 67 68 110 120 130 140 150)) 

(parse input1) 
(parse input2) 

Ceci est la sortie en DrRacket:

Welcome to DrRacket, version 6.7 [3m]. 
Language: racket, with debugging; memory limit: 128 MB. 
#t 
#"ABCD" 
#"nx\202\214\226" 
#f 
0 
0 

Regardez comment j'utiliser les valeurs (...) des choses, est-ce sens?

+0

Qu'est-ce qu'une chaîne C sans terminateur nul? –

+0

Quel code avez-vous essayé? –

+0

@benrudgers une chaîne C est quelque chose comme "abc \ 0" où '\ 0' est le caractère nul. L'entrée que j'analyse est quelque chose comme: 0x0a 3 'a' 'b' 'c'. En ce qui concerne le code que j'ai essayé: juste une fonction qui traverse le tableau et stocke les valeurs dés-codifiées dans un autre tableau. Désolé de ne pas poster ici le code, c'est encore un désordre. – Kumar

Répondre

0

Pour renvoyer une valeur au système d'exploitation, utilisez (exit [v]).. Les autres valeurs devraient probablement aller à la sortie standard et/ou à l'erreur standard. Cela signifie les écrire avant la fin du programme.

En termes d'affectation des valeurs d'un tableau à des variables, il y a plusieurs façons de le faire en fonction de la façon dont la portée lexicale entre en jeu dans la fonction et le module et entre les modules. La sémantique de référence et la sémantique des valeurs sont également des considérations. Enfin, il n'y a pas de raison impérieuse de choisir la récursivité sur une boucle explicite en traitant avec un byte-string. bytes-length est une primitive de bas niveau implémentée en C et retournera la longueur nécessaire pour une boucle sans tester une chaîne d'octets vide.

+0

Sauf que les boucles dans les systèmes Scheme ne sont que du sucre syntaxique pour la récursion, donc vous ajoutez simplement une abstraction. – Sylwester

+0

En ce qui concerne la récursivité vs boucles, merci, je l'ai! – Kumar

+0

@Sylwester Les abstractions décrites dans le centre de la question autour des tableaux. La récursivité + tableaux fonctionnera, mais c'est une combinaison douteuse d'abstractions. Quoi qu'il en soit, sans une pointe de chapeau à l'itération, il n'y a aucune raison d'utiliser la récursivité de la queue sur la récursivité sans queue ... et la tortue au bas de l'architecture de Von Neumann est l'itération et la récursivité est toujours syntactique vient à pousser. –