@@ -81,7 +81,7 @@ protected function __construct($size)
8181 }
8282
8383 /**
84- * Clone a bitarray
84+ * Clone a BitArray
8585 *
8686 * @return void
8787 *
@@ -235,9 +235,9 @@ public function count()
235235 {
236236 $ count = 0 ;
237237
238- for ($ i = 0 , $ length = strlen ($ this ->data ); $ i < $ length ; $ i ++)
238+ for ($ index = 0 , $ length = strlen ($ this ->data ); $ index < $ length ; $ index ++)
239239 {
240- $ count += self ::$ count [ord ($ this ->data [$ i ])];
240+ $ count += self ::$ count [ord ($ this ->data [$ index ])];
241241 }
242242
243243 return $ count ;
@@ -254,9 +254,9 @@ public function toArray()
254254 {
255255 $ array = [];
256256
257- for ($ offset = 0 ; $ offset < $ this ->size ; $ offset ++)
257+ for ($ index = 0 ; $ index < $ this ->size ; $ index ++)
258258 {
259- $ array [] = (bool ) (ord ($ this ->data [(int ) ($ offset / 8 )]) & (1 << $ offset % 8 ));
259+ $ array [] = (bool ) (ord ($ this ->data [(int ) ($ index / 8 )]) & (1 << $ index % 8 ));
260260 }
261261
262262 return $ array ;
@@ -298,10 +298,150 @@ public function size()
298298 return $ this ->size ;
299299 }
300300
301+ /**
302+ * Copy bits directly from a BitArray
303+ *
304+ * @param BitArray $bits A BitArray to copy
305+ * @param int $index Starting index for destination
306+ * @param int $offset Starting index for copying
307+ * @param int $size Copy size
308+ *
309+ * @return BitArray This object for chaining
310+ *
311+ * @throw \OutOfRangeException Argument index must be an positive integer lesser than the size
312+ *
313+ * @since 1.1.0
314+ */
315+ public function directCopy (BitArray $ bits , $ index = 0 , $ offset = 0 , $ size = 0 )
316+ {
317+ if ($ offset > $ index )
318+ {
319+ for ($ i = 0 ; $ i < $ size ; $ i ++)
320+ {
321+ $ this [$ i + $ index ] = $ bits [$ i + $ offset ];
322+ }
323+ }
324+ else
325+ {
326+ for ($ i = $ size - 1 ; $ i >= 0 ; $ i --)
327+ {
328+ $ this [$ i + $ index ] = $ bits [$ i + $ offset ];
329+ }
330+ }
331+
332+ return $ this ;
333+ }
334+
335+ /**
336+ * Copy bits from a BitArray
337+ *
338+ * @param BitArray $bits A BitArray to copy
339+ * @param int $index Starting index for destination.
340+ * If index is non-negative, the index parameter is used as it is, keeping its real value between 0 and size-1.
341+ * If index is negative, the index parameter starts from the end, keeping its real value between 0 and size-1.
342+ * @param int $offset Starting index for copying.
343+ * If offset is non-negative, the offset parameter is used as it is, keeping its positive value between 0 and size-1.
344+ * If offset is negative, the offset parameter starts from the end, keeping its real value between 0 and size-1.
345+ * @param mixed $size Copy size.
346+ * If size is given and is positive, then the copy will copy size elements.
347+ * If the bits argument is shorter than the size, then only the available elements will be copied.
348+ * If size is given and is negative then the copy starts from the end.
349+ * If it is omitted, then the copy will have everything from offset up until the end of the bits argument.
350+ *
351+ * @return BitArray This object for chaining
352+ *
353+ * @since 1.1.0
354+ */
355+ public function copy (BitArray $ bits , $ index = 0 , $ offset = 0 , $ size = null )
356+ {
357+ $ index = $ this ->getRealOffset ($ index );
358+ $ offset = $ bits ->getRealOffset ($ offset );
359+ $ size = $ bits ->getRealSize ($ offset , $ size );
360+
361+ if ($ size > $ this ->size - $ index )
362+ {
363+ $ size = $ this ->size - $ index ;
364+ }
365+
366+ return $ this ->directCopy ($ bits , $ index , $ offset , $ size );
367+ }
368+
369+ /**
370+ * Get the real offset using a positive or negative offset
371+ *
372+ * @param int $offset If offset is non-negative, the offset parameter is used as it is, keeping its real value between 0 and size-1.
373+ * If offset is negative, the offset parameter starts from the end, keeping its real value between 0 and size-1.
374+ *
375+ * @return int The real offset
376+ *
377+ * @since 1.1.0
378+ */
379+ protected function getRealOffset ($ offset )
380+ {
381+ $ offset = (int ) $ offset ;
382+
383+ if ($ offset < 0 )
384+ {
385+ // Start from the end
386+ $ offset = $ this ->size + $ offset ;
387+
388+ if ($ offset < 0 )
389+ {
390+ $ offset = 0 ;
391+ }
392+ }
393+ elseif ($ offset > $ this ->size )
394+ {
395+ $ offset = $ this ->size ;
396+ }
397+
398+ return $ offset ;
399+ }
400+
401+ /**
402+ * Get the real offset using a positive or negative offset
403+ *
404+ * @param int $offset The real offset.
405+ * @param mixed $size If size is given and is positive, then the real size will be between 0 and the current size-1.
406+ * If size is given and is negative then the real size starts from the end.
407+ * If it is omitted, then the size goes until the end of the BitArray.
408+ *
409+ * @return int The real size
410+ *
411+ * @since 1.1.0
412+ */
413+ protected function getRealSize ($ offset , $ size )
414+ {
415+ if ($ size === null )
416+ {
417+ $ size = $ this ->size - $ offset ;
418+ }
419+ else
420+ {
421+ $ size = (int ) $ size ;
422+
423+ if ($ size < 0 )
424+ {
425+ $ size = $ this ->size + $ size - $ offset ;
426+
427+ if ($ size < 0 )
428+ {
429+ $ size = 0 ;
430+ }
431+ }
432+ elseif ($ size > $ this ->size - $ offset )
433+ {
434+ $ size = $ this ->size - $ offset ;
435+ }
436+ }
437+
438+ return $ size ;
439+ }
440+
301441 /**
302442 * Create a new BitArray from an integer
303443 *
304- * @param integer $size Size of the bitarray
444+ * @param integer $size Size of the BitArray
305445 *
306446 * @return BitArray A new BitArray
307447 *
@@ -404,9 +544,9 @@ public static function fromJson($json)
404544 /**
405545 * Create a new BitArray using a slice
406546 *
407- * @param BitArray $bits A bitarray to get the slice
547+ * @param BitArray $bits A BitArray to get the slice
408548 * @param int $offset If offset is non-negative, the slice will start at that offset in the bits argument.
409- * If offset is negative, the slice will start that far from the end of the bits argument.
549+ * If offset is negative, the slice will start from the end of the bits argument.
410550 * @param mixed $size If size is given and is positive, then the slice will have up to that many elements in it.
411551 * If the bits argument is shorter than the size, then only the available elements will be present.
412552 * If size is given and is negative then the slice will stop that many elements from the end of the bits argument.
@@ -418,61 +558,18 @@ public static function fromJson($json)
418558 */
419559 public static function fromSlice (BitArray $ bits , $ offset = 0 , $ size = null )
420560 {
421- $ offset = (int ) $ offset ;
422-
423- if ($ offset < 0 )
424- {
425- // Start from the end
426- $ offset = $ bits ->size + $ offset ;
427-
428- if ($ offset < 0 )
429- {
430- $ offset = 0 ;
431- }
432- }
433- elseif ($ offset > $ bits ->size )
434- {
435- $ offset = $ bits ->size ;
436- }
437-
438- if ($ size === null )
439- {
440- $ size = $ bits ->size - $ offset ;
441- }
442- else
443- {
444- $ size = (int ) $ size ;
445-
446- if ($ size < 0 )
447- {
448- $ size = $ bits ->size + $ size - $ offset ;
449-
450- if ($ size < 0 )
451- {
452- $ size = 0 ;
453- }
454- }
455- elseif ($ size > $ bits ->size - $ offset )
456- {
457- $ size = $ bits ->size - $ offset ;
458- }
459- }
460-
561+ $ offset = $ bits ->getRealOffset ($ offset );
562+ $ size = $ bits ->getRealSize ($ offset , $ size );
461563 $ slice = new BitArray ($ size );
462564
463- for ($ i = 0 ; $ i < $ size ; $ i ++)
464- {
465- $ slice [$ i ] = $ bits [$ i + $ offset ];
466- }
467-
468- return $ slice ;
565+ return $ slice ->directCopy ($ bits , 0 , $ offset , $ size );
469566 }
470567
471568 /**
472569 * Create a new BitArray using the concat operation
473570 *
474- * @param BitArray $bits1 A bitarray
475- * @param BitArray $bits2 A bitarray
571+ * @param BitArray $bits1 A BitArray
572+ * @param BitArray $bits2 A BitArray
476573 *
477574 * @return BitArray A new BitArray
478575 *
@@ -482,16 +579,8 @@ public static function fromConcat(BitArray $bits1, BitArray $bits2)
482579 {
483580 $ size = $ bits1 ->size + $ bits2 ->size ;
484581 $ concat = new BitArray ($ size );
485-
486- for ($ i = 0 ; $ i < $ bits1 ->size ; $ i ++)
487- {
488- $ concat [$ i ] = $ bits1 [$ i ];
489- }
490-
491- for ($ i = 0 ; $ i < $ bits2 ->size ; $ i ++)
492- {
493- $ concat [$ i + $ bits1 ->size ] = $ bits2 [$ i ];
494- }
582+ $ concat ->directCopy ($ bits1 , 0 , 0 , $ bits1 ->size );
583+ $ concat ->directCopy ($ bits2 , $ bits1 ->size , 0 , $ bits2 ->size );
495584
496585 return $ concat ;
497586 }
@@ -507,9 +596,9 @@ public function applyComplement()
507596 {
508597 $ length = strlen ($ this ->data );
509598
510- for ($ i = 0 ; $ i < $ length ; $ i ++)
599+ for ($ index = 0 ; $ index < $ length ; $ index ++)
511600 {
512- $ this ->data [$ i ] = chr (~ ord ($ this ->data [$ i ]));
601+ $ this ->data [$ index ] = chr (~ ord ($ this ->data [$ index ]));
513602 }
514603
515604 // Remove useless bits
@@ -538,9 +627,9 @@ public function applyOr(BitArray $bits)
538627 {
539628 $ length = strlen ($ this ->data );
540629
541- for ($ i = 0 ; $ i < $ length ; $ i ++)
630+ for ($ index = 0 ; $ index < $ length ; $ index ++)
542631 {
543- $ this ->data [$ i ] = chr (ord ($ this ->data [$ i ]) | ord ($ bits ->data [$ i ]));
632+ $ this ->data [$ index ] = chr (ord ($ this ->data [$ index ]) | ord ($ bits ->data [$ index ]));
544633 }
545634
546635 return $ this ;
@@ -568,9 +657,9 @@ public function applyAnd(BitArray $bits)
568657 {
569658 $ length = strlen ($ this ->data );
570659
571- for ($ i = 0 ; $ i < $ length ; $ i ++)
660+ for ($ index = 0 ; $ index < $ length ; $ index ++)
572661 {
573- $ this ->data [$ i ] = chr (ord ($ this ->data [$ i ]) & ord ($ bits ->data [$ i ]));
662+ $ this ->data [$ index ] = chr (ord ($ this ->data [$ index ]) & ord ($ bits ->data [$ index ]));
574663 }
575664
576665 return $ this ;
@@ -598,9 +687,9 @@ public function applyXor(BitArray $bits)
598687 {
599688 $ length = strlen ($ this ->data );
600689
601- for ($ i = 0 ; $ i < $ length ; $ i ++)
690+ for ($ index = 0 ; $ index < $ length ; $ index ++)
602691 {
603- $ this ->data [$ i ] = chr (ord ($ this ->data [$ i ]) ^ ord ($ bits ->data [$ i ]));
692+ $ this ->data [$ index ] = chr (ord ($ this ->data [$ index ]) ^ ord ($ bits ->data [$ index ]));
604693 }
605694
606695 return $ this ;
0 commit comments