def make_callbacks():
    signature_str = {
    'en':  """
 .. code-block:: php

  void callback({0})
""",
    'de':  """
 .. code-block:: php

  void callback({0})
"""
    }

    cbs = ''
    func_start = '.. php:member:: int '
    cls = device.get_category() + device.get_camel_case_name()
    for packet in device.get_packets('callback'):
        params = php_common.make_parameter_list(packet, True)
        if len(params) > 0:
            params += " [, mixed $userData]"
        else:
            params += "[mixed $userData]"
        desc = format_doc(packet)
        signature = common.select_lang(signature_str).format(params)
        func = '{0}{1}::CALLBACK_{2}\n{3}{4}'.format(func_start,
                                                     cls,
                                                     packet.get_upper_case_name(),
                                                     signature,
                                                     desc)
        cbs += func + '\n'

    return cbs
def make_methods(typ):
    methods = ''
    func_start = '.. php:function:: '
    cls = device.get_category() + device.get_camel_case_name()
    for packet in device.get_packets('function'):
        if packet.get_doc()[0] != typ:
            continue

        ret_type = php_common.get_return_type(packet)
        name = packet.get_headless_camel_case_name()
        params = php_common.make_parameter_list(packet, True)
        desc = format_doc(packet)
        obj_desc = make_object_desc(packet)
        func = '{0}{1} {2}::{3}({4})\n{5}{6}'.format(func_start,
                                                     ret_type,
                                                     cls,
                                                     name,
                                                     params,
                                                     desc,
                                                     obj_desc)
        methods += func + '\n'

    return methods
def make_methods():
    methods = ''
    method_multi = """
    /**
     * {6}
     */
    public function {0}({1})
    {{
        $result = array();

        $payload = '';
{2}

{3}

{4}

{5}

        return $result;
    }}
"""
    method_single = """
    /**
     * {6}
     */
    public function {0}({1})
    {{
        $payload = '';
{2}

{3}

{4}

{5}
    }}
"""

    for packet in device.get_packets('function'):
        name_lower = packet.get_headless_camel_case_name()
        parameter = php_common.make_parameter_list(packet)
        pack = []
        for element in packet.get_elements('in'):
            if element[1] == 'bool':
                if element[2] > 1:
                    pack.append('        for ($i = 0; $i < {0}; $i++) {{'.format(element[2]))
                    pack.append('            $payload .= pack(\'{0}\', intval((bool)${1}[$i]));\n        }}'.format(get_pack_type(element), element[0]))
                else:
                    pack.append('        $payload .= pack(\'{0}\', intval((bool)${1}));'.format(get_pack_type(element), element[0]))
            elif element[1] == 'string':
                if element[2] > 1:
                    pack.append('        for ($i = 0; $i < strlen(${0}) && $i < {1}; $i++) {{'.format(element[0], element[2]))
                    pack.append('            $payload .= pack(\'{0}\', ord(${1}[$i]));\n        }}'.format(get_pack_type(element), element[0]))
                    pack.append('        for ($i = strlen(${0}); $i < {1}; $i++) {{'.format(element[0], element[2]))
                    pack.append('            $payload .= pack(\'{0}\', 0);\n        }}'.format(get_pack_type(element)))
                else:
                    pack.append('        $payload .= pack(\'{0}\', ord(${1}));'.format(get_pack_type(element), element[0]))
            elif element[1] == 'char':
                if element[2] > 1:
                    pack.append('        for ($i = 0; $i < count(${0}) && $i < {1}; $i++) {{'.format(element[0], element[2]))
                    pack.append('            $payload .= pack(\'{0}\', ord(${1}[$i]));\n        }}'.format(get_pack_type(element), element[0]))
                    pack.append('        for ($i = count(${0}); $i < {1}; $i++) {{'.format(element[0], element[2]))
                    pack.append('            $payload .= pack(\'{0}\', 0);\n        }}'.format(get_pack_type(element)))
                else:
                    pack.append('        $payload .= pack(\'{0}\', ord(${1}));'.format(get_pack_type(element), element[0]))
            else:
                if element[2] > 1:
                    pack.append('        for ($i = 0; $i < {0}; $i++) {{'.format(element[2]))
                    pack.append('            $payload .= pack(\'{0}\', ${1}[$i]);\n        }}'.format(get_pack_type(element), element[0]))
                else:
                    pack.append('        $payload .= pack(\'{0}\', ${1});'.format(get_pack_type(element), element[0]))

        has_multi_return_value = len(packet.get_elements('out')) > 1
        unpack_format = []
        collect = []

        for element in packet.get_elements('out'):
            unpack_format.append('{0}{1}{2}'.format(get_unpack_type(element), element[2], element[0]))

            unpack_fix = get_unpack_fix(element)

            if has_multi_return_value:
                if element[2] > 1:
                    collect.append('        $result[\'{0}\'] = {2}$payload, \'{0}\', {1}{3};'.format(element[0], element[2], unpack_fix[0], unpack_fix[1]))
                else:
                    collect.append('        $result[\'{0}\'] = {1}$payload[\'{0}\']{2};'.format(element[0], unpack_fix[0], unpack_fix[1]))
            else:
                if element[2] > 1:
                    collect.append('        return {2}$payload, \'{0}\', {1}{3};'.format(element[0], element[2], unpack_fix[0], unpack_fix[1]))
                else:
                    collect.append('        return {1}$payload[\'{0}\']{2};'.format(element[0], unpack_fix[0], unpack_fix[1]))

        if len(unpack_format) > 0:
            send = '        $data = $this->sendRequest(self::FUNCTION_{0}, $payload);\n'.format(packet.get_upper_case_name())
        else:
            send = '        $this->sendRequest(self::FUNCTION_{0}, $payload);\n'.format(packet.get_upper_case_name())

        final_unpack = ''

        if len(unpack_format) > 0:
            final_unpack = '        $payload = unpack(\'{0}\', $data);'.format('/'.join(unpack_format))

        doc = format_doc(packet, [''] + make_parameter_doc(packet).split('\n'))

        if has_multi_return_value:
            method = method_multi.format(name_lower,
                                         parameter,
                                         '\n'.join(pack),
                                         send,
                                         final_unpack,
                                         '\n'.join(collect),
                                         doc)
        else:
            method = method_single.format(name_lower,
                                          parameter,
                                          '\n'.join(pack),
                                          send,
                                          final_unpack,
                                          '\n'.join(collect),
                                          doc)

        prev = method
        method = method.replace('\n\n\n', '\n\n').replace('\n\n    }', '\n    }')
        while prev != method:
            prev = method
            method = method.replace('\n\n\n', '\n\n').replace('\n\n    }', '\n    }')

        methods += method

    return """
    /**
     * @internal
     * @param string $header
     * @param string $data
     */
    public function handleCallback($header, $data)
    {
        call_user_func(array($this, $this->callbackWrappers[$header['functionID']]), $data);
    }
""" + methods