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

标签 clojure stream netty 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))))

此时,我可以解析每个 dynbufbuf:

user> (decompose dynbuf buf)
["Foob"]

此时,我希望从 buf 读取 short-typestring-type 已经移动了它的 readerIndex 增加了 6,但可惜,事实并非如此:

user> (.readerIndex buf)
0

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

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

最佳答案

巴菲 is using absolute version getXXX方法的,它不会修改缓冲区的位置,因此不能使用.readerIndex。

我看到两种可能的选择,具体取决于您想要实现的目标:

  1. 使用巴菲 dynamic frames 。请注意,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. 计算框架的大小as Buffy is doing并手动设置缓冲区中的正确位置。像这样的东西:

    (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])
    

关于clojure - 从数组的中间组成一个 Buffy 缓冲区并找出它消耗了多少,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34656858/

相关文章:

java - Clojure 原始数组类型元数据

video - 直播视频码率计算公式

c++ - 流出字符串的一部分

java - ChannelId 会改变吗?

clojure - 使用闭包进行数据封装

clojure - 如何使用 clojure 或 jython 修剪数字的小数?

JAVA-生成预定的JSON

websocket - Netty:正确关闭WebSocket

netty - 直接调用 close() 和使用 ChannelFutureListener.CLOSE 的区别

vector - 如何在 Clojure 中展平嵌套向量?