package com.galois.qrstream.qrpipe;

import java.util.BitSet;

/**
 * Used to mark the progress of decoding stream of QR codes.
 */
public class DecodeState {
	
	private final BitSet data;
	private final int capacity;
		
	public DecodeState (int capacity) {
		this.capacity = capacity;
		this.data = new BitSet(capacity);
	}
	
	public State getState () {
		if (data.isEmpty()) {
			return State.Initial;
		} else if (data.cardinality() == this.capacity) {
			return State.Final;
		} else {
			return State.Intermediate;
		}
	}
	
	/**
	 * Get a deep copy of the underlying bitset.
	 * 
	 * @return The bitset underlying the decode state.
	 */
	public BitSet getData() {
		return (BitSet) data.clone();
	}
}

@@ -152,17 +152,16 @@
 State %7B%0A
-%09
 %0A%09privat
@@ -162,22 +162,16 @@
 private 
-final 
 BitSet d
@@ -173,16 +173,23 @@
 Set data
+ = null
 ;%0A%09priva
@@ -195,68 +195,602 @@
 ate 
-final int capacity;%0A%09%09%0A%09public DecodeState (int capacity) %7B%0A
+int capacity = 0;%0A%0A%09/**%0A%09 * Initialize DecodeState with given capacity. After initialization, requests%0A%09 * to change capacity are ignored. This allows external applications to query%0A%09 * status of transmission and QR decoding, in the case that %7B@code Receive%7D%0A%09 * is has not yet received and decoded its first QR code. It needs at least%0A%09 * one QR code to know how many QR codes it should expect to receive.%0A%09 */%0A%09public void setInitialCapacity(int capacity) %7B%0A%09%09if (this.data == null) %7B%0A%09%09%09if (capacity %3C 0) %7B%0A%09%09%09%09throw new IllegalArgumentException(%22DecodeState must have capacity %3E 0%22);%0A%09%09%09%7D%0A%09
 %09%09th
@@ -813,16 +813,17 @@
 pacity;%0A
+%09
 %09%09this.d
@@ -850,20 +850,362 @@
 acity);%0A
+%09
 %09%7D%0A%09
+%7D%0A%0A%09/**%0A%09 * Return the state that a transmission is in. If no QR codes have been%0A%09 * received and decoded, this returns the %7B@code Initial%7D state. When at%0A%09 * least one QR code has been decoded, return %7B@code Intermediate%7D state.%0A%09 * Finally, when all QR codes have been received and decoded, the state%0A%09 * transitions to %7B@code Final%7D.%0A%09 */
 %0A%09public
@@ -1235,16 +1235,32 @@
 if (data
+ == null %7C%7C data
 .isEmpty
@@ -1413,17 +1413,602 @@
 %0A%09%09%7D%0A%09%7D%0A
-%09
+%0A%09/**%0A%09 * Mark progress of data transmission by setting the bit corresponding%0A%09 * to %7B@code chunkId%7D of the underlying bitset to true.%0A%09 *%0A%09 * @throw IndexOutOfBoundsException if %7B@code chunkId%7D is not within bounds%0A%09 * of capacity of underlying bitset.%0A%09 */%0A%09public void markDataReceived (int chunkId) throws IndexOutOfBoundsException %7B%0A%09%09if (data != null) %7B%0A%09%09%09if (chunkId %3C 1 %7C%7C chunkId %3E capacity) %7B%0A%09%09%09%09throw new IndexOutOfBoundsException(%22Cannot mark bit, chunkId: %22 + chunkId +%0A%09%09%09%09                                    %22, is out of bounds%22);%0A%09%09%09%7D%0A%09%09%09data.set(chunkId - 1);%0A%09%09%7D%0A%09%7D%0A
 %0A%09/**%0A%09 
@@ -2054,17 +2054,16 @@
 set.%0A%09 *
- 
 %0A%09 * @re

allow DecodeState to be in Initial state before capacity of bitset is known