2015-01-17 42 views
0

假設我有一個枚舉[數組[字節]]產生大小可變的字節陣列的塊(比方說POST體在控制器接受)播放Iteratees:重組字節流分成大小可變的塊

我知道這流實際上包含數據的分組,其中每個分組是:

  • 表示整數,表示該分組的車身尺寸的大小以字節大小的
  • 包體4個字節

每個數據包可以有不同的主體大小。

我們如何實現一個Enumeratee,它將初始流轉換爲字節數組流,其中每個數組都是一個數據包體。

與整數簡化的例子(第一配INT表示包體大小):

List(1, 2, 3), List(4, 5), List(6), List(2, 8), List(9) -> List(2) List(4, 5 ,6), List(8, 9)

+0

我能拿出枚舉,重新組合成固定大小的cunks,但這還不夠。 https://gist.github.com/chernetsov/404409350b0011bb4de7 –

+0

我想我找到了一個很好的例子:https://github.com/alpeb/play-iteratees#master –

回答

0

我試圖從HTTP響應流解析JPG頭時遇到的相同問題。

首先,您需要使用Enumerator.mapConcat將流轉換爲Bytes而不是Chunks。 然後,您必須根據第一個字節按組分組您的字節。爲此,有一個函數Enumeratee.grouped,它以Iteratee[From, To]作爲參數,並重復使用它來處理From的傳入流並將其轉換爲To的流。

這是我想出了:

val takeSegment: Iteratee[Byte, List[Byte]] = for { 
    //find segment length (the first four bytes of the segment, assumed unsigned and bigEndian) 
    size <- Enumeratee.take(4) &>> Iteratee.fold[Byte, Int](0){ 
       case (acc, b) => acc * 256 + (b & 0xFF) 
      } 
    //fetch rest of segment 
    rest <- Enumeratee.take(size) &>> Iteratee.getChunks[Byte] 
    } yield rest 

val segmentStream: Enumerator[List[Byte]] = 
        inputStream &> 
        // mapConcat takes an argument of type From => Seq[To] 
        Enumeratee.mapConcat[Array[Byte], Byte](bytes => bytes) &> 
        Enumeratee.grouped[Byte, List[Byte]](takeSegment) 

當然,如果你的整數編碼不同的(我假設的無符號大尾端,但你可能有不同的情況),您需要更改尺寸線相應的理解。