'Decode HyBi style WebSocket packets.
Returns:
{\'fin\'          : 0_or_1,
\'opcode\'       : number,
\'mask\'         : 32_bit_number,
\'hlen\'         : header_bytes_number,
\'length\'       : payload_bytes_number,
\'payload\'      : decoded_buffer,
\'left\'         : bytes_left_number,
\'close_code\'   : number,
\'close_reason\' : string}'

@staticmethod
def decode_hybi(buf, base64=False):

    f = {'fin': 0, 'opcode': 0, 'mask': 0, 'hlen': 2, 'length': 0, 'payload': None, 'left': 0, 'close_code': None, 'close_reason': None}
    blen = len(buf)
    f['left'] = blen
    if (blen < f['hlen']):
        return f
    (b1, b2) = struct.unpack_from('>BB', buf)
    f['opcode'] = (b1 & 15)
    f['fin'] = ((b1 & 128) >> 7)
    has_mask = ((b2 & 128) >> 7)
    f['length'] = (b2 & 127)
    if (f['length'] == 126):
        f['hlen'] = 4
        if (blen < f['hlen']):
            return f
        (f['length'],) = struct.unpack_from('>xxH', buf)
    elif (f['length'] == 127):
        f['hlen'] = 10
        if (blen < f['hlen']):
            return f
        (f['length'],) = struct.unpack_from('>xxQ', buf)
    full_len = ((f['hlen'] + (has_mask * 4)) + f['length'])
    if (blen < full_len):
        return f
    f['left'] = (blen - full_len)
    if has_mask:
        f['mask'] = buf[f['hlen']:(f['hlen'] + 4)]
        b = c = ''
        if (f['length'] >= 4):
            data = struct.unpack('<I', buf[f['hlen']:(f['hlen'] + 4)])[0]
            of1 = (f['hlen'] + 4)
            b = ''
            for i in xrange(0, int((f['length'] / 4))):
                mask = struct.unpack('<I', buf[(of1 + (4 * i)):(of1 + (4 * (i + 1)))])[0]
                b += struct.pack('I', (data ^ mask))
        if (f['length'] % 4):
            l = (f['length'] % 4)
            of1 = f['hlen']
            of2 = (full_len - l)
            c = ''
            for i in range(0, l):
                mask = struct.unpack('B', buf[(of1 + i)])[0]
                data = struct.unpack('B', buf[(of2 + i)])[0]
                c += chr((data ^ mask))
        f['payload'] = (b + c)
    else:
        print ('Unmasked    frame:    %s' % repr(buf))
        f['payload'] = buf[(f['hlen'] + (has_mask * 4)):full_len]
    if (base64 and (f['opcode'] in [1, 2])):
        try:
            f['payload'] = b64decode(f['payload'])
        except:
            print ('Exception    while    b64decoding    buffer:    %s' % repr(buf))
            raise
    if (f['opcode'] == 8):
        if (f['length'] >= 2):
            f['close_code'] = struct.unpack_from('>H', f['payload'])
        if (f['length'] > 3):
            f['close_reason'] = f['payload'][2:]
    return f
