2525 */
2626package xyz .meunier .wav2pzx .blocks ;
2727
28+ import com .google .common .collect .ImmutableList ;
2829import com .google .common .primitives .Bytes ;
2930import xyz .meunier .wav2pzx .pulselist .PulseList ;
3031
3637
3738import static com .google .common .base .Preconditions .checkArgument ;
3839import static com .google .common .base .Preconditions .checkNotNull ;
40+ import static com .google .common .collect .ImmutableList .copyOf ;
41+ import static com .google .common .primitives .Longs .asList ;
42+ import static java .lang .Long .valueOf ;
3943import static xyz .meunier .wav2pzx .blocks .PZXEncodeUtils .*;
4044import static xyz .meunier .wav2pzx .romdecoder .LoaderContext .*;
4145
@@ -76,30 +80,30 @@ public final class PZXDataBlock implements PZXBlock {
7680 private final boolean isHeader ;
7781
7882 // The length of the zero pulse identified in the source file
79- private final short zeroPulseLength ;
83+ private final ImmutableList < Long > zeroPulseLengths ;
8084
8185 // The length of the one pulse identified in the source file
82- private final short onePulseLength ;
86+ private final ImmutableList < Long > onePulseLengths ;
8387
8488 /**
8589 * Constructs a new PZXDataBlock.
8690 * @param newPulses the original tape pulses that have been decoded into this block
87- * @param zeroPulseLength the length of the zero pulses in the block
88- * @param onePulseLength the length of the one pulses in the block
91+ * @param zeroPulseLengths the lengths of the zero pulses in the block
92+ * @param onePulseLengths the lengths of the one pulses in the block
8993 * @param tailLength the length of the tail pulse in the block
9094 * @param numBitsInLastByte the number of bits used in the last byte of the data collection
9195 * @param data the decoded data from the tape image
9296 * @throws NullPointerException if newPulses or data is null
9397 * @throws IllegalArgumentException if data is empty
9498 */
95- public PZXDataBlock (PulseList newPulses , long zeroPulseLength , long onePulseLength , long tailLength ,
99+ public PZXDataBlock (PulseList newPulses , List < Long > zeroPulseLengths , List < Long > onePulseLengths , long tailLength ,
96100 int numBitsInLastByte , Collection <Byte > data ) {
97101 checkNotNull (newPulses , "newPulses must not be null" );
98102 checkNotNull (data , "data must not be null" );
99103 checkArgument (!data .isEmpty (), "data array must not be empty" );
100104 this .pulses = newPulses ;
101- this .zeroPulseLength = ( short ) zeroPulseLength ;
102- this .onePulseLength = ( short ) onePulseLength ;
105+ this .zeroPulseLengths = copyOf ( zeroPulseLengths ) ;
106+ this .onePulseLengths = copyOf ( onePulseLengths ) ;
103107 this .tailLength = (short )tailLength ;
104108 this .numBitsInLastByte = numBitsInLastByte ;
105109 this .data = Bytes .toArray (data );
@@ -118,7 +122,8 @@ public PZXDataBlock(PulseList newPulses, long zeroPulseLength, long onePulseLeng
118122 * @throws IllegalArgumentException if data is empty
119123 */
120124 public PZXDataBlock (PulseList newPulses , int numBitsInLastByte , Collection <Byte > data ) {
121- this (newPulses , ZERO , ONE , TAIL , numBitsInLastByte , data );
125+ this (newPulses , asList (valueOf (ZERO ), valueOf (ZERO )), asList (valueOf (ONE ), valueOf (ONE )), TAIL ,
126+ numBitsInLastByte , data );
122127 }
123128
124129 // Calculates the checksum for the data according to the algorithm in the
@@ -179,23 +184,27 @@ public byte[] getPZXBlockDiskRepresentation() {
179184 // use standard duration tail pulse after last bit of the block if we found one
180185 putUnsignedLittleEndianShort (tailLength == 0 ? 0 : tailLength , output );
181186
182- putUnsignedByte ((byte )2 , output ); // number of pulses encoding bit equal to 0.
183- putUnsignedByte ((byte )2 , output ); // number of pulses encoding bit equal to 1.
187+ putUnsignedByte ((byte )zeroPulseLengths . size () , output ); // number of pulses encoding bit equal to 0.
188+ putUnsignedByte ((byte )onePulseLengths . size () , output ); // number of pulses encoding bit equal to 1.
184189
185190 // sequence of pulse durations encoding bit equal to 0.
186- putUnsignedLittleEndianShort (zeroPulseLength , output );
187- putUnsignedLittleEndianShort (zeroPulseLength , output );
188-
191+ putPulseList (zeroPulseLengths , output );
192+
189193 // sequence of pulse durations encoding bit equal to 1.
190- putUnsignedLittleEndianShort (onePulseLength , output );
191- putUnsignedLittleEndianShort (onePulseLength , output );
192-
194+ putPulseList (onePulseLengths , output );
195+
193196 // data stream
194197 output .addAll (Bytes .asList (data ));
195198
196199 return addPZXBlockHeader ("DATA" , output );
197200 }
198-
201+
202+ private void putPulseList (List <Long > pulseLengths , Collection <Byte > output ) {
203+ for (Long pulseLength : pulseLengths ) {
204+ putUnsignedLittleEndianShort (pulseLength .shortValue (), output );
205+ }
206+ }
207+
199208 @ Override
200209 public String getSummary () {
201210 StringBuilder retval = new StringBuilder ();
@@ -276,8 +285,8 @@ public boolean checkChecksum() {
276285
277286 @ Override
278287 public String toString () {
279- return "PZXDataBlock{" + pulses .toString () + ", zeroPulseLength =" + zeroPulseLength + ", onePulseLength ="
280- + onePulseLength + ", tailLength=" + tailLength + ", numBitsInLastByte=" + numBitsInLastByte
288+ return "PZXDataBlock{" + pulses .toString () + ", zeroPulseLengths =" + zeroPulseLengths + ", onePulseLengths ="
289+ + onePulseLengths + ", tailLength=" + tailLength + ", numBitsInLastByte=" + numBitsInLastByte
281290 + ", calculatedChecksum=" + String .format ("0x%x" , calculatedChecksum ) + ", suppliedChecksum="
282291 + String .format ("0x%x" , suppliedChecksum ) + ", isHeader=" + isHeader + ", data.length="
283292 + data .length + '}' ;
@@ -289,9 +298,11 @@ public int hashCode() {
289298 result = 31 * result + (int ) tailLength ;
290299 result = 31 * result + Arrays .hashCode (data );
291300 result = 31 * result + numBitsInLastByte ;
301+ result = 31 * result + (int ) calculatedChecksum ;
292302 result = 31 * result + (int ) suppliedChecksum ;
293- result = 31 * result + (int ) zeroPulseLength ;
294- result = 31 * result + (int ) onePulseLength ;
303+ result = 31 * result + (isHeader ? 1 : 0 );
304+ result = 31 * result + zeroPulseLengths .hashCode ();
305+ result = 31 * result + onePulseLengths .hashCode ();
295306 return result ;
296307 }
297308
@@ -304,12 +315,13 @@ public boolean equals(Object o) {
304315
305316 if (tailLength != that .tailLength ) return false ;
306317 if (numBitsInLastByte != that .numBitsInLastByte ) return false ;
318+ if (calculatedChecksum != that .calculatedChecksum ) return false ;
307319 if (suppliedChecksum != that .suppliedChecksum ) return false ;
308- if (zeroPulseLength != that .zeroPulseLength ) return false ;
309- if (onePulseLength != that .onePulseLength ) return false ;
320+ if (isHeader != that .isHeader ) return false ;
310321 if (!pulses .equals (that .pulses )) return false ;
311- return Arrays .equals (data , that .data );
312-
322+ if (!Arrays .equals (data , that .data )) return false ;
323+ if (!zeroPulseLengths .equals (that .zeroPulseLengths )) return false ;
324+ return onePulseLengths .equals (that .onePulseLengths );
313325 }
314326
315327 /**
0 commit comments