def process(data)
      bytes = StringIO.new(String(data)).each_byte
      bytes.each do |byte|
        case byte
        when REPORT_VERSION
          @major_version = bytes.next
          @minor_version = bytes.next

          emit('report_version')

        when ANALOG_MESSAGE_RANGE
          least_significant_byte = bytes.next
          most_significant_byte = bytes.next

          value = least_significant_byte | (most_significant_byte << 7)
          pin = byte & 0x0F

          if analog_pin = analog_pins[pin]
            pins[analog_pin].value = value

            emit('analog-read', pin, value)
            emit("analog-read-#{pin}", value)
          end

        when DIGITAL_MESSAGE_RANGE
          port           = byte & 0x0F
          first_bitmask  = bytes.next
          second_bitmask = bytes.next
          port_value     = first_bitmask | (second_bitmask << 7)

          8.times do |i|
            pin_number = 8 * port + i
            if pin = pins[pin_number] and pin.mode == INPUT
              value = (port_value >> (i & 0x07)) & 0x01
              pin.value = value
              emit('digital-read', pin_number, value)
              emit("digital-read-#{pin_number}", value)
            end
          end

        when START_SYSEX
          current_buffer = [byte]
          begin
            current_buffer.push(bytes.next)
          end until current_buffer.last == END_SYSEX

          command = current_buffer[1]

          case command
          when CAPABILITY_RESPONSE
            supported_modes = 0
            n = 0

            current_buffer.slice(2, current_buffer.length - 3).each do |byte|
              if byte == 127
                modes = []
                # the pin modes
                [ INPUT, OUTPUT, ANALOG, PWM, SERVO ].each do |mode|
                   modes.push(mode) unless (supported_modes & (1 << mode)).zero?
                end

                @pins.push(Pin.new(modes, OUTPUT, 0))

                supported_modes = 0
                n = 0
                next
              end

              supported_modes |= (1 << byte) if n.zero?

              n ^= 1
            end

            emit('capability_query')

          when ANALOG_MAPPING_RESPONSE
            pin_index = 0

            current_buffer.slice(2, current_buffer.length - 3).each do |byte|

              @pins[pin_index].analog_channel = byte

              @analog_pins.push(pin_index) unless byte == 127

              pin_index += 1
            end

            emit('analog_mapping_query')

          when PIN_STATE_RESPONSE
            pin       = pins[current_buffer[2]]
            pin.mode  = current_buffer[3]
            pin.value = current_buffer[4]

            pin.value |= (current_buffer[5] << 7) if current_buffer.size > 6

            pin.value |= (current_buffer[6] << 14) if current_buffer.size > 7

          when FIRMWARE_QUERY
            @firmware_name = current_buffer.slice(4, current_buffer.length - 5).reject { |b| b.zero? }.map(&:chr).join
            emit('firmware_query')

          else
            puts 'bad byte'
          end
        end
      end
    rescue StopIteration
      # do nadda
    end
def process(data)
      bytes = StringIO.new(String(data)).each_byte
      bytes.each do |byte|
        case byte
        when REPORT_VERSION
          @major_version = bytes.next
          @minor_version = bytes.next

          emit('report_version')

        when ANALOG_MESSAGE_RANGE
          least_significant_byte = bytes.next
          most_significant_byte = bytes.next

          value = least_significant_byte | (most_significant_byte << 7)
          pin = byte & 0x0F

          if analog_pin = analog_pins[pin]
            pins[analog_pin].value = value

            emit('analog-read', pin, value)
            emit("analog-read-#{pin}", value)
          end

        when DIGITAL_MESSAGE_RANGE
          port           = byte & 0x0F
          first_bitmask  = bytes.next
          second_bitmask = bytes.next
          port_value     = first_bitmask | (second_bitmask << 7)

          8.times do |i|
            pin_number = 8 * port + i
            if pin = pins[pin_number] and pin.mode == INPUT
              value = (port_value >> (i & 0x07)) & 0x01
              pin.value = value
              emit('digital-read', pin_number, value)
              emit("digital-read-#{pin_number}", value)
            end
          end

        when START_SYSEX
          current_buffer = [byte]
          begin
            current_buffer.push(bytes.next)
          end until current_buffer.last == END_SYSEX

          command = current_buffer[1]

          case command
          when CAPABILITY_RESPONSE
            supported_modes = 0
            n = 0

            current_buffer.slice(2, current_buffer.length - 3).each do |byte|
              if byte == 127
                modes = []
                # the pin modes
                [ INPUT, OUTPUT, ANALOG, PWM, SERVO ].each do |mode|
                   modes.push(mode) unless (supported_modes & (1 << mode)).zero?
                end

                @pins.push(Pin.new(modes, OUTPUT, 0))

                supported_modes = 0
                n = 0
                next
              end

              supported_modes |= (1 << byte) if n.zero?

              n ^= 1
            end

            emit('capability_query')

          when ANALOG_MAPPING_RESPONSE
            pin_index = 0

            current_buffer.slice(2, current_buffer.length - 3).each do |byte|

              @pins[pin_index].analog_channel = byte

              @analog_pins.push(pin_index) unless byte == 127

              pin_index += 1
            end

            emit('analog_mapping_query')

          when PIN_STATE_RESPONSE
            pin       = pins[current_buffer[2]]
            pin.mode  = current_buffer[3]
            pin.value = current_buffer[4]

            pin.value |= (current_buffer[5] << 7) if current_buffer.size > 6

            pin.value |= (current_buffer[6] << 14) if current_buffer.size > 7

          when FIRMWARE_QUERY
            @firmware_name = current_buffer.slice(4, current_buffer.length - 5).reject { |b| b.zero? }.map(&:chr).join
            emit('firmware_query')

          else
            puts 'bad byte'
          end
        end
      end
    rescue StopIteration
      # do nadda
    end
Internal: Process a series of bytes.

 data: The String data to process.

 Returns nothing.