#include "bititer.h"

int BitIterator::Next()
{
       extern int *first_ones;
       const uint64 *mask = not_mask;
       int retVal;
       __asm
       {
          ALIGN 4
          mov esi,DWORD PTR [this]     ; this ptr
          mov ecx,DWORD PTR [esi+8]    ; count
          ALIGN 4
       next_word:
          cmp ecx,3
          jle more_bytes
          mov DWORD PTR [esi+8],ecx    ; save count value
          mov retVal,0x7f                 ; invalid
          jmp do_ret
          ALIGN 4
        more_bytes:
          xor eax,eax
          mov ax,WORD ptr [esi+ecx*2]  ; fetch the current word
          and eax,eax                  ; set flags
          jnz have_data
          inc ecx                      ; advance to next word
          jmp next_word
          ALIGN 4
        have_data:
          mov DWORD PTR [esi+8],ecx    ; save count value
          mov ebx,ecx                  ; in register too
          mov edx, first_ones           ; address of first ones table
          mov ecx,DWORD ptr [edx+eax*4] ; fetch first_ones[data word]
          shl ebx,4
          add ecx,ebx
          ; clear bit we just returned
          mov edx,mask                  ; fetch not mask
          mov eax,[edx+ecx*8]
          and DWORD PTR [esi],eax       ; first byte of data
          mov eax,[edx+ecx*8+4]
          and DWORD PTR [esi+4],eax     ; second byte of data
          mov retVal,ecx                ; return value is in ecx
       do_ret:
       }
       return retVal;
}
/**
int BitIterator::Next()
{
   extern int *first_ones;
   register int retVal;
   const register unsigned short *pData = (unsigned short*)&data;
   register unsigned short s;
   for (;;)
   {
       if (n>3) return 127; // invalid
       if ((s = pData[n]) != 0) break;
       ++n;
   }
   retVal = first_ones[s]+n*16;
   clear(retVal);
   return retVal;
}
**/

