Decode takes a single chunk of data and decodes it. Chunk expected to be validated (see Validate) before.
(chunk string)
| 41 | // Decode takes a single chunk of data and decodes it. |
| 42 | // Chunk expected to be validated (see Validate) before. |
| 43 | func (d *Decoder) Decode(chunk string) error { |
| 44 | idx := strings.IndexByte(chunk, '|') // expected to be validated before |
| 45 | if idx == -1 { |
| 46 | return fmt.Errorf("invalid frame: \"%s\"", chunk) |
| 47 | } |
| 48 | |
| 49 | header := chunk[:idx] |
| 50 | // continuous QR reading often sends the same chunk in a row, skip it |
| 51 | if d.isCached(header) { |
| 52 | return nil |
| 53 | } |
| 54 | |
| 55 | var ( |
| 56 | blockCode int64 |
| 57 | chunkLen, total int |
| 58 | ) |
| 59 | _, err := fmt.Sscanf(header, "%d/%d/%d", &blockCode, &chunkLen, &total) |
| 60 | if err != nil { |
| 61 | return fmt.Errorf("invalid header: %v (%s)", err, header) |
| 62 | } |
| 63 | |
| 64 | payload := chunk[idx+1:] |
| 65 | lubyBlock := fountain.LTBlock{ |
| 66 | BlockCode: blockCode, |
| 67 | Data: []byte(payload), |
| 68 | } |
| 69 | |
| 70 | if d.fd == nil { |
| 71 | d.total = total |
| 72 | d.chunkLen = chunkLen |
| 73 | numChunks := numberOfChunks(d.total, d.chunkLen) |
| 74 | d.codec = fountain.NewLubyCodec(numChunks, rand.New(fountain.NewMersenneTwister(200)), solitonDistribution(numChunks)) |
| 75 | d.fd = d.codec.NewDecoder(total) |
| 76 | } |
| 77 | d.completed = d.fd.AddBlocks([]fountain.LTBlock{lubyBlock}) |
| 78 | |
| 79 | return nil |
| 80 | } |
| 81 | |
| 82 | // Validate checks if a given chunk of data is a valid txqr protocol packet. |
| 83 | func (d *Decoder) Validate(chunk string) error { |