заполнение ленивых последовательностей двоичного блока - PullRequest
4 голосов
/ 23 июня 2009

У меня есть функция Clojure, которая берет последовательность чисел, делит ее на соответствующее количество битов и возвращает ленивую последовательность фрагментов (сначала младшие биты). Он дополняет старшие биты последнего блока, чтобы заполнить размер блока, и мне нужен совет по «лучшему способу (tm)», чтобы записать количество заполнения, сохраняя его ленивым и функциональным?

Слова мудрости очень ценятся.

(defn block-seq
  ([block-size bytes]
    "reads a byte-seq into a sequence of block-size bits."
    (block-seq 8 block-size bytes))
  ([in-block-size out-block-size bytes]
    "converts a seq from in-block-size to out-block-size"
  ...

Параметры:

  • in-block-size - количество значащих бит в каждом числе во входной последовательности
  • out-block-size - это число значащих битов в каждом из чисел в ленивом seq, которое возвращается.
  • байт - это ленивая последовательность чисел, из которой можно извлечь биты

Вот пример, который берет последовательность из трех байтов и разбивает ее на последовательность из двух двадцати битных чисел (а затем печатает ее в виде двоичной строки).

user> (map #(java.lang.Integer/toBinaryString %) (block-seq 20 [0xAA 0xAA 0xAA]))
("10101010101010101010" "1010")
user> 

Второе число в последовательности 20-битных чисел имеет только четыре значащих бита и имеет добавленные эффективные 16 нулей. Если я затем передал эту последовательность другой функции, которая хотела бы что-то сделать с последовательностью и отправить ее по сети; код на принимающей стороне должен знать, чтобы не печатать / хранить / и т.д. последние 16 бит.

PS: они могут быть связаны. (block-seq 20 15 (block-seq 8 20 (чтение байтов из файла)))

1 Ответ

1 голос
/ 23 сентября 2009

До сих пор не совсем ясно, что вы хотите сделать, но, похоже, вы хотите знать, как block-seq возвращает количество дополняемых битов в последнем фрагменте. Конечно, это невозможно заранее, если вы хотите быть ленивым, поэтому номер нужно будет вернуть с последним фрагментом или после него.

Без использования метаданных вы можете просто вернуть список, как

(1 2 3 :pad 12)

Используя метаданные, вы можете добавить эту дополнительную информацию к последним минусам (Clojure не может добавить метаданные к целым числам), поэтому последние минусы будут эквивалентны

(with-meta '(3) {:pad 12})

Чтобы цепочка работала, двоичный блок должен был знать об этой информации заполнения, в обоих случаях, чтобы иметь возможность развернуть, а затем повторно дополнить последний фрагмент.

Как передать информацию о прокладке по проводам, это другой вопрос.

...