我想使用Buffy来解释从数组中间开始的二进制数据。我还需要知道Buffy消耗了数组的多少字节。
假设我有一个像这样的动态缓冲区定义:
(ns foo.core
(:refer-clojure :exclude [read])
(:use [byte-streams])
(:require [clojurewerkz.buffy.core :refer :all]
[clojurewerkz.buffy.frames :refer :all]
[clojurewerkz.buffy.types.protocols :refer :all])
(:import [io.netty.buffer Unpooled ByteBuf]))
(def dynbuf
(let [string-encoder (frame-encoder [value]
length (short-type) (count value)
string (string-type (count value)) value)
string-decoder (frame-decoder [buffer offset]
length (short-type)
string (string-type (read length buffer offset)))]
(dynamic-buffer (frame-type string-encoder string-decoder second))))
我希望我可以使用Netty ByteBuf
来使用dynbuf
解析从偏移量开始的一堆字节
(def buf
(let [bytes (concat [0 0 0 4] (map #(byte %) "Foobar"))
offset 2]
(Unpooled/wrappedBuffer (byte-array bytes) offset (- (count bytes) offset))))
此时,我可以根据dynbuf
:解析buf
user> (decompose dynbuf buf)
["Foob"]
在这一点上,我希望从buf
中读取short-type
和string-type
已经将其readerIndex
移动了6,但遗憾的是,事实并非如此:
user> (.readerIndex buf)
0
这是因为buffy/decompose
对流进行了某种浅拷贝以供其内部使用,所以外部buf
的readerIndex
没有更新吗?还是我误解了readerIndex
应该是什么?
如何实现我最初的目标,即在给定的偏移量上将(byte-array)
传递给Buffy,并了解它消耗了多少字节?
Buffy使用的是getXXX方法的绝对版本,该方法不会修改缓冲区的位置,因此无法使用.readerIndex.
我看到了两种可能的选择,这取决于你试图实现的目标:
-
使用Buffy动态帧。请注意,如果您想知道动态帧需要花费多少时间,
clojurewerkz.buffy.frames
命名空间有一个decoding-size
函数。类似于:(defn read-from-middle [data f-type start-idx] (let [tmp-buf (Unpooled/wrappedBuffer data start-idx (- (alength data) start-idx)) buffy-buffer (dynamic-buffer f-type) total-size (decoding-size f-type tmp-buf 0)] [(decompose buffy-buffer tmp-buf) (+ start-idx total-size)])) (def f-type (let [string-encoder (frame-encoder [value] length (short-type) (count value) string (string-type (count value)) value) string-decoder (frame-decoder [buffer offset] length (short-type) string (string-type (read length buffer offset)))] (frame-type string-encoder string-decoder second))) (let [my-data (byte-array [0 1 0x61 0 2 0x62 0x63 0 1 0x64]) idx 0 [i1 idx] (read-from-middle my-data f-type idx) [i2 idx] (read-from-middle my-data f-type idx) [i3 idx] (read-from-middle my-data f-type idx)] [i1 i2 i3])
-
像Buffy一样计算帧的大小,并手动设置缓冲区中的正确位置。类似于:
(import [io.netty.buffer Unpooled]) (require '[clojurewerkz.buffy.core :as buffy] '[clojurewerkz.buffy.types.protocols :as ptypes]) (defn read-from-middle [data spec start-idx] (let [total-size (reduce + (map ptypes/size (map second spec))) tmp-buf (Unpooled/wrappedBuffer data start-idx (- (alength data) start-idx)) buffy-buffer (buffy/compose-buffer spec :orig-buffer tmp-buf)] [(buffy/decompose buffy-buffer) (+ start-idx total-size)])) (let [my-data (byte-array [0 0 0 1 0 0 0 2 0 0 0 3]) spec (buffy/spec :foo (buffy/int32-type)) idx 0 [i1 idx] (read-from-middle my-data spec idx) [i2 idx] (read-from-middle my-data spec idx) [i3 idx] (read-from-middle my-data spec idx)] [i1 i2 i3])