clojure - Composing a Buffy buffer from the middle of an array and finding out how much it has consumed -
i'd use buffy interpret binary data starting middle of array. need find out how many bytes of array have been consumed buffy.
let's have dynamic buffer definition this:
(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))))
i hoped use netty bytebuf
parse bunch of bytes using dynbuf
starting @ offset:
(def buf (let [bytes (concat [0 0 0 4] (map #(byte %) "foobar")) offset 2] (unpooled/wrappedbuffer (byte-array bytes) offset (- (count bytes) offset))))
at point, can parse buf
per dynbuf
:
user> (decompose dynbuf buf) ["foob"]
at point, hoping reading short-type
, string-type
buf
has moved readerindex
6, alas, not so:
user> (.readerindex buf) 0
is because buffy/decompose
makes kind of shallow copy of stream internal use, readerindex
of outer buf
not updated? or misunderstanding readerindex
supposed be?
how can achieve original goal of passing (byte-array)
@ given offset buffy , learning how many bytes has consumed?
buffy is using absolute version of getxxx method, not modify position of buffer, cannot use .readerindex.
i see 2 possible options, depending on trying achieve:
use buffy dynamic frames. note
clojurewerkz.buffy.frames
namespace hasdecoding-size
function if want know how dynamic frame take. like:(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])
calculate size of frame as buffy doing , manually set correct position in buffer. like:
(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])
Comments
Post a Comment