从数组的中间组成一个Buffy缓冲区,并找出它消耗了多少



我想使用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-typestring-type已经将其readerIndex移动了6,但遗憾的是,事实并非如此:

user> (.readerIndex buf)
0

这是因为buffy/decompose对流进行了某种浅拷贝以供其内部使用,所以外部bufreaderIndex没有更新吗?还是我误解了readerIndex应该是什么?

如何实现我最初的目标,即在给定的偏移量上将(byte-array)传递给Buffy,并了解它消耗了多少字节?

Buffy使用的是getXXX方法的绝对版本,该方法不会修改缓冲区的位置,因此无法使用.readerIndex.

我看到了两种可能的选择,这取决于你试图实现的目标:

  1. 使用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])
    
  2. 像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])
    

相关内容

  • 没有找到相关文章

最新更新