Revision 52e20f9e

b/host/include/uhd/convert.hpp
19 19
#define INCLUDED_UHD_CONVERT_HPP
20 20

  
21 21
#include <uhd/config.hpp>
22
#include <uhd/types/io_type.hpp>
23
#include <uhd/types/otw_type.hpp>
24 22
#include <uhd/types/ref_vector.hpp>
25 23
#include <boost/function.hpp>
24
#include <boost/operators.hpp>
26 25
#include <string>
27 26

  
28 27
namespace uhd{ namespace convert{
29 28

  
30 29
    typedef uhd::ref_vector<void *> output_type;
31 30
    typedef uhd::ref_vector<const void *> input_type;
32
    typedef boost::function<void(const input_type&, const output_type&, size_t, double)> function_type;
31

  
32
    //! input vectors, output vectors, num samples, scale factor
33
    typedef boost::function<void(const input_type&, const output_type&, const size_t, const double)> function_type;
33 34

  
34 35
    /*!
35 36
     * Describe the priority of a converter function.
......
45 46
        PRIORITY_EMPTY = -1,
46 47
    };
47 48

  
49
    //! Identify a conversion routine in the registry
50
    struct id_type : boost::equality_comparable<id_type>{
51
        std::string input_markup;
52
        size_t num_inputs;
53
        std::string output_markup;
54
        size_t num_outputs;
55
        std::string args;
56
        std::string to_pp_string(void) const;
57
    };
58

  
59
    //! Implement equality_comparable interface
60
    UHD_API bool operator==(const id_type &, const id_type &);
61

  
48 62
    /*!
49
     * Register a converter function that converts cpu type to/from otw type.
50
     * \param markup representing the signature
63
     * Register a converter function.
64
     * \param id identify the conversion
51 65
     * \param fcn a pointer to the converter
52 66
     * \param prio the function priority
53 67
     */
54 68
    UHD_API void register_converter(
55
        const std::string &markup,
69
        const id_type &id,
56 70
        function_type fcn,
57 71
        priority_type prio
58 72
    );
59 73

  
60 74
    /*!
61
     * Get a converter function that converts cpu to otw.
62
     * \param io_type the type of the input samples
63
     * \param otw_type the type of the output samples
64
     * \param num_input_buffs the number of inputs
65
     * \param num_output_buffs the number of outputs
75
     * Get a converter function.
76
     * \param id identify the conversion
77
     * \return the converter function
66 78
     */
67
    UHD_API const function_type &get_converter_cpu_to_otw(
68
        const io_type_t &io_type,
69
        const otw_type_t &otw_type,
70
        size_t num_input_buffs,
71
        size_t num_output_buffs
72
    );
79
    UHD_API function_type get_converter(const id_type &id);
73 80

  
74 81
    /*!
75
     * Get a converter function that converts otw to cpu.
76
     * \param io_type the type of the input samples
77
     * \param otw_type the type of the output samples
78
     * \param num_input_buffs the number of inputs
79
     * \param num_output_buffs the number of outputs
82
     * Register the size of a particular item.
83
     * \param markup the item markup
84
     * \param size the size in bytes
80 85
     */
81
    UHD_API const function_type &get_converter_otw_to_cpu(
82
        const io_type_t &io_type,
83
        const otw_type_t &otw_type,
84
        size_t num_input_buffs,
85
        size_t num_output_buffs
86
    UHD_API void register_bytes_per_item(
87
        const std::string &markup, const size_t size
86 88
    );
87 89

  
90
    //! Convert an item markup to a size in bytes
91
    UHD_API size_t get_bytes_per_item(const std::string &markup);
92

  
88 93
}} //namespace
89 94

  
90 95
#endif /* INCLUDED_UHD_CONVERT_HPP */
b/host/lib/convert/CMakeLists.txt
112 112
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
113 113

  
114 114
LIBUHD_PYTHON_GEN_SOURCE(
115
    ${CMAKE_CURRENT_SOURCE_DIR}/gen_convert_pred.py
116
    ${CMAKE_CURRENT_BINARY_DIR}/convert_pred.hpp
117
)
118

  
119
INCLUDE(AddFileDependencies)
120
ADD_FILE_DEPENDENCIES(
121
    ${CMAKE_CURRENT_SOURCE_DIR}/convert_impl.cpp
122
    ${CMAKE_CURRENT_BINARY_DIR}/convert_pred.hpp
123
)
124

  
125
LIBUHD_PYTHON_GEN_SOURCE(
126 115
    ${CMAKE_CURRENT_SOURCE_DIR}/gen_convert_general.py
127 116
    ${CMAKE_CURRENT_BINARY_DIR}/convert_general.cpp
128 117
)
b/host/lib/convert/convert_common.hpp
23 23
#include <boost/cstdint.hpp>
24 24
#include <complex>
25 25

  
26
#define DECLARE_CONVERTER(fcn, prio) \
26
#define _DECLARE_CONVERTER(fcn, in_mark, num_in, out_mark, num_out, prio) \
27 27
    static void fcn( \
28 28
        const uhd::convert::input_type &inputs, \
29 29
        const uhd::convert::output_type &outputs, \
30
        size_t nsamps, double scale_factor \
30
        const size_t nsamps, \
31
        const double scale_factor \
31 32
    ); \
32
    UHD_STATIC_BLOCK(register_##fcn##_##prio){ \
33
        uhd::convert::register_converter(#fcn, fcn, prio); \
33
    UHD_STATIC_BLOCK(__register_##fcn##_##prio){ \
34
        uhd::convert::id_type id; \
35
        id.input_markup = #in_mark; \
36
        id.num_inputs = num_in; \
37
        id.output_markup = #out_mark; \
38
        id.num_outputs = num_out; \
39
        uhd::convert::register_converter(id, fcn, prio); \
34 40
    } \
35 41
    static void fcn( \
36 42
        const uhd::convert::input_type &inputs, \
37 43
        const uhd::convert::output_type &outputs, \
38
        size_t nsamps, double scale_factor \
44
        const size_t nsamps, \
45
        const double scale_factor \
39 46
    )
40 47

  
48
#define DECLARE_CONVERTER(in_mark, num_in, out_mark, num_out, prio) \
49
    _DECLARE_CONVERTER(__convert_##in_mark##_##num_in##_##out_mark##_##num_out, in_mark, num_in, out_mark, num_out, prio)
50

  
41 51
/***********************************************************************
42 52
 * Typedefs
43 53
 **********************************************************************/
44 54
typedef std::complex<double>         fc64_t;
45 55
typedef std::complex<float>          fc32_t;
56
typedef std::complex<boost::int32_t> sc32_t;
46 57
typedef std::complex<boost::int16_t> sc16_t;
47 58
typedef std::complex<boost::int8_t>  sc8_t;
59
typedef double                       f64_t;
60
typedef float                        f32_t;
61
typedef boost::int32_t               s32_t;
62
typedef boost::int16_t               s16_t;
63
typedef boost::int8_t                s8_t;
64

  
48 65
typedef boost::uint32_t              item32_t;
49 66

  
50 67
/***********************************************************************
b/host/lib/convert/convert_fc32_with_sse2.cpp
21 21

  
22 22
using namespace uhd::convert;
23 23

  
24
DECLARE_CONVERTER(convert_fc32_1_to_item32_1_nswap, PRIORITY_CUSTOM){
24
DECLARE_CONVERTER(fc32, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){
25 25
    const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
26 26
    item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
27 27

  
......
64 64
    }
65 65
}
66 66

  
67
DECLARE_CONVERTER(convert_fc32_1_to_item32_1_bswap, PRIORITY_CUSTOM){
67
DECLARE_CONVERTER(fc32, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){
68 68
    const fc32_t *input = reinterpret_cast<const fc32_t *>(inputs[0]);
69 69
    item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
70 70

  
......
106 106
    }
107 107
}
108 108

  
109
DECLARE_CONVERTER(convert_item32_1_to_fc32_1_nswap, PRIORITY_CUSTOM){
109
DECLARE_CONVERTER(sc16_item32_le, 1, fc32, 1, PRIORITY_CUSTOM){
110 110
    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
111 111
    fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
112 112

  
......
151 151
    }
152 152
}
153 153

  
154
DECLARE_CONVERTER(convert_item32_1_to_fc32_1_bswap, PRIORITY_CUSTOM){
154
DECLARE_CONVERTER(sc16_item32_be, 1, fc32, 1, PRIORITY_CUSTOM){
155 155
    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
156 156
    fc32_t *output = reinterpret_cast<fc32_t *>(outputs[0]);
157 157

  
b/host/lib/convert/convert_fc64_with_sse2.cpp
21 21

  
22 22
using namespace uhd::convert;
23 23

  
24
DECLARE_CONVERTER(convert_fc64_1_to_item32_1_nswap, PRIORITY_CUSTOM){
24
DECLARE_CONVERTER(fc64, 1, sc16_item32_le, 1, PRIORITY_CUSTOM){
25 25
    const fc64_t *input = reinterpret_cast<const fc64_t *>(inputs[0]);
26 26
    item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
27 27

  
......
68 68
    }
69 69
}
70 70

  
71
DECLARE_CONVERTER(convert_fc64_1_to_item32_1_bswap, PRIORITY_CUSTOM){
71
DECLARE_CONVERTER(fc64, 1, sc16_item32_be, 1, PRIORITY_CUSTOM){
72 72
    const fc64_t *input = reinterpret_cast<const fc64_t *>(inputs[0]);
73 73
    item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
74 74

  
......
114 114
    }
115 115
}
116 116

  
117
DECLARE_CONVERTER(convert_item32_1_to_fc64_1_nswap, PRIORITY_CUSTOM){
117
DECLARE_CONVERTER(sc16_item32_le, 1, fc64, 1, PRIORITY_CUSTOM){
118 118
    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
119 119
    fc64_t *output = reinterpret_cast<fc64_t *>(outputs[0]);
120 120

  
......
163 163
    }
164 164
}
165 165

  
166
DECLARE_CONVERTER(convert_item32_1_to_fc64_1_bswap, PRIORITY_CUSTOM){
166
DECLARE_CONVERTER(sc16_item32_be, 1, fc64, 1, PRIORITY_CUSTOM){
167 167
    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
168 168
    fc64_t *output = reinterpret_cast<fc64_t *>(outputs[0]);
169 169

  
b/host/lib/convert/convert_impl.cpp
18 18
#include <uhd/convert.hpp>
19 19
#include <uhd/utils/log.hpp>
20 20
#include <uhd/utils/static.hpp>
21
#include <uhd/types/dict.hpp>
21 22
#include <uhd/exception.hpp>
23
#include <boost/cstdint.hpp>
24
#include <boost/format.hpp>
25
#include <complex>
22 26

  
23 27
using namespace uhd;
24 28

  
25
#include "convert_pred.hpp"
29
bool convert::operator==(const convert::id_type &lhs, const convert::id_type &rhs){
30
    return
31
        (lhs.input_markup == rhs.input_markup) and
32
        (lhs.num_inputs == rhs.num_inputs) and
33
        (lhs.output_markup == rhs.output_markup) and
34
        (lhs.num_outputs == rhs.num_outputs) and
35
        (lhs.args == rhs.args)
36
    ;
37
}
38

  
39
std::string convert::id_type::to_pp_string(void) const{
40
    return str(boost::format(
41
        "conversion ID\n"
42
        "  Input markup: %s\n"
43
        "  Num inputs: %d\n"
44
        "  Output markup: %s\n"
45
        "  Num outputs: %d\n"
46
        "  Optional args: %s\n"
47
    )
48
        % this->input_markup
49
        % this->num_inputs
50
        % this->output_markup
51
        % this->num_outputs
52
        % this->args
53
    );
54
}
26 55

  
27 56
/***********************************************************************
28 57
 * Define types for the function tables
......
30 59
struct fcn_table_entry_type{
31 60
    convert::priority_type prio;
32 61
    convert::function_type fcn;
33
    fcn_table_entry_type(void)
34
    : prio(convert::PRIORITY_EMPTY), fcn(NULL){
35
        /* NOP */
36
    }
37 62
};
38
typedef std::vector<fcn_table_entry_type> fcn_table_type;
39 63

  
40 64
/***********************************************************************
41 65
 * Setup the table registry
42 66
 **********************************************************************/
43
UHD_SINGLETON_FCN(fcn_table_type, get_cpu_to_otw_table);
44
UHD_SINGLETON_FCN(fcn_table_type, get_otw_to_cpu_table);
45

  
46
fcn_table_type &get_table(dir_type dir){
47
    switch(dir){
48
    case DIR_OTW_TO_CPU: return get_otw_to_cpu_table();
49
    case DIR_CPU_TO_OTW: return get_cpu_to_otw_table();
50
    }
51
    UHD_THROW_INVALID_CODE_PATH();
52
}
67
typedef uhd::dict<convert::id_type, fcn_table_entry_type> fcn_table_type;
68
UHD_SINGLETON_FCN(fcn_table_type, get_table);
53 69

  
54 70
/***********************************************************************
55 71
 * The registry functions
56 72
 **********************************************************************/
57 73
void uhd::convert::register_converter(
58
    const std::string &markup,
74
    const id_type &id,
59 75
    function_type fcn,
60 76
    priority_type prio
61 77
){
62
    //extract the predicate and direction from the markup
63
    dir_type dir;
64
    pred_type pred = make_pred(markup, dir);
65

  
66 78
    //get a reference to the function table
67
    fcn_table_type &table = get_table(dir);
68

  
69
    //resize the table so that its at least pred+1
70
    if (table.size() <= pred) table.resize(pred+1);
79
    fcn_table_type &table = get_table();
71 80

  
72 81
    //register the function if higher priority
73
    if (table[pred].prio < prio){
74
        table[pred].fcn = fcn;
75
        table[pred].prio = prio;
82
    if (not table.has_key(id) or table[id].prio < prio){
83
        table[id].fcn = fcn;
84
        table[id].prio = prio;
76 85
    }
77 86

  
78 87
    //----------------------------------------------------------------//
79
    UHD_LOGV(always) << "register_converter: " << markup << std::endl
88
    UHD_LOGV(always) << "register_converter: " << id.to_pp_string() << std::endl
80 89
        << "    prio: " << prio << std::endl
81
        << "    pred: " << pred << std::endl
82
        << "    dir: " << dir << std::endl
83 90
        << std::endl
84 91
    ;
85 92
    //----------------------------------------------------------------//
......
88 95
/***********************************************************************
89 96
 * The converter functions
90 97
 **********************************************************************/
91
const convert::function_type &convert::get_converter_cpu_to_otw(
92
    const io_type_t &io_type,
93
    const otw_type_t &otw_type,
94
    size_t num_input_buffs,
95
    size_t num_output_buffs
96
){
97
    pred_type pred = make_pred(io_type, otw_type, num_input_buffs, num_output_buffs);
98
    return get_cpu_to_otw_table().at(pred).fcn;
98
convert::function_type convert::get_converter(const id_type &id){
99
    if (get_table().has_key(id)) return get_table()[id].fcn;
100
    throw uhd::key_error("Cannot find a conversion routine for " + id.to_pp_string());
99 101
}
100 102

  
101
const convert::function_type &convert::get_converter_otw_to_cpu(
102
    const io_type_t &io_type,
103
    const otw_type_t &otw_type,
104
    size_t num_input_buffs,
105
    size_t num_output_buffs
103
/***********************************************************************
104
 * Mappings for item markup to byte size for all items we can
105
 **********************************************************************/
106
typedef uhd::dict<std::string, size_t> item_size_type;
107
UHD_SINGLETON_FCN(item_size_type, get_item_size_table);
108

  
109
void register_bytes_per_item(
110
    const std::string &markup, const size_t size
106 111
){
107
    pred_type pred = make_pred(io_type, otw_type, num_input_buffs, num_output_buffs);
108
    return get_otw_to_cpu_table().at(pred).fcn;
112
    get_item_size_table()[markup] = size;
113
}
114

  
115
size_t convert::get_bytes_per_item(const std::string &markup){
116
    if (get_item_size_table().has_key(markup)) return get_item_size_table()[markup];
117
    throw uhd::key_error("Cannot find an item size " + markup);
118
}
119

  
120
UHD_STATIC_BLOCK(convert_register_item_sizes){
121
    //register standard complex types
122
    get_item_size_table()["fc64"] = sizeof(std::complex<double>);
123
    get_item_size_table()["fc32"] = sizeof(std::complex<float>);
124
    get_item_size_table()["sc32"] = sizeof(std::complex<boost::int32_t>);
125
    get_item_size_table()["sc16"] = sizeof(std::complex<boost::int16_t>);
126
    get_item_size_table()["sc8"] = sizeof(std::complex<boost::int8_t>);
127

  
128
    //register standard real types
129
    get_item_size_table()["f64"] = sizeof(double);
130
    get_item_size_table()["f32"] = sizeof(float);
131
    get_item_size_table()["s32"] = sizeof(boost::int32_t);
132
    get_item_size_table()["s16"] = sizeof(boost::int16_t);
133
    get_item_size_table()["s8"] = sizeof(boost::int8_t);
109 134
}
b/host/lib/convert/gen_convert_general.py
29 29
"""
30 30

  
31 31
TMPL_CONV_TO_FROM_ITEM32_1 = """
32
DECLARE_CONVERTER(convert_$(cpu_type)_1_to_item32_1_$(swap), PRIORITY_GENERAL){
32
DECLARE_CONVERTER($(cpu_type), 1, sc16_item32_$(end), 1, PRIORITY_GENERAL){
33 33
    const $(cpu_type)_t *input = reinterpret_cast<const $(cpu_type)_t *>(inputs[0]);
34 34
    item32_t *output = reinterpret_cast<item32_t *>(outputs[0]);
35 35

  
36 36
    for (size_t i = 0; i < nsamps; i++){
37
        output[i] = $(swap_fcn)($(cpu_type)_to_item32(input[i], float(scale_factor)));
37
        output[i] = $(to_wire)($(cpu_type)_to_item32(input[i], float(scale_factor)));
38 38
    }
39 39
}
40 40

  
41
DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_1_$(swap), PRIORITY_GENERAL){
41
DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), 1, PRIORITY_GENERAL){
42 42
    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
43 43
    $(cpu_type)_t *output = reinterpret_cast<$(cpu_type)_t *>(outputs[0]);
44 44

  
45 45
    for (size_t i = 0; i < nsamps; i++){
46
        output[i] = item32_to_$(cpu_type)($(swap_fcn)(input[i]), float(scale_factor));
46
        output[i] = item32_to_$(cpu_type)($(to_host)(input[i]), float(scale_factor));
47 47
    }
48 48
}
49 49
"""
50 50
TMPL_CONV_TO_FROM_ITEM32_X = """
51
DECLARE_CONVERTER(convert_$(cpu_type)_$(width)_to_item32_1_$(swap), PRIORITY_GENERAL){
51
DECLARE_CONVERTER($(cpu_type), $(width), sc16_item32_$(end), 1, PRIORITY_GENERAL){
52 52
    #for $w in range($width)
53 53
    const $(cpu_type)_t *input$(w) = reinterpret_cast<const $(cpu_type)_t *>(inputs[$(w)]);
54 54
    #end for
......
56 56

  
57 57
    for (size_t i = 0, j = 0; i < nsamps; i++){
58 58
        #for $w in range($width)
59
        output[j++] = $(swap_fcn)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
59
        output[j++] = $(to_wire)($(cpu_type)_to_item32(input$(w)[i], float(scale_factor)));
60 60
        #end for
61 61
    }
62 62
}
63 63

  
64
DECLARE_CONVERTER(convert_item32_1_to_$(cpu_type)_$(width)_$(swap), PRIORITY_GENERAL){
64
DECLARE_CONVERTER(sc16_item32_$(end), 1, $(cpu_type), $(width), PRIORITY_GENERAL){
65 65
    const item32_t *input = reinterpret_cast<const item32_t *>(inputs[0]);
66 66
    #for $w in range($width)
67 67
    $(cpu_type)_t *output$(w) = reinterpret_cast<$(cpu_type)_t *>(outputs[$(w)]);
......
69 69

  
70 70
    for (size_t i = 0, j = 0; i < nsamps; i++){
71 71
        #for $w in range($width)
72
        output$(w)[i] = item32_to_$(cpu_type)($(swap_fcn)(input[j++]), float(scale_factor));
72
        output$(w)[i] = item32_to_$(cpu_type)($(to_host)(input[j++]), float(scale_factor));
73 73
        #end for
74 74
    }
75 75
}
......
84 84
    file = os.path.basename(__file__)
85 85
    output = parse_tmpl(TMPL_HEADER, file=file)
86 86
    for width in 1, 2, 3, 4:
87
        for swap, swap_fcn in (('nswap', ''), ('bswap', 'uhd::byteswap')):
87
        for end, to_host, to_wire in (
88
            ('be', 'uhd::ntohx', 'uhd::htonx'),
89
            ('le', 'uhd::wtohx', 'uhd::htowx'),
90
        ):
88 91
            for cpu_type in 'fc64', 'fc32', 'sc16':
89 92
                output += parse_tmpl(
90 93
                    TMPL_CONV_TO_FROM_ITEM32_1 if width == 1 else TMPL_CONV_TO_FROM_ITEM32_X,
91
                    width=width, swap=swap, swap_fcn=swap_fcn, cpu_type=cpu_type
94
                    width=width, end=end, to_host=to_host, to_wire=to_wire, cpu_type=cpu_type
92 95
                )
93 96
    open(sys.argv[1], 'w').write(output)
/dev/null
1
#!/usr/bin/env python
2
#
3
# Copyright 2011-2011 Ettus Research LLC
4
#
5
# This program is free software: you can redistribute it and/or modify
6
# it under the terms of the GNU General Public License as published by
7
# the Free Software Foundation, either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# This program is distributed in the hope that it will be useful,
11
# but WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
#
18

  
19
TMPL_TEXT = """
20
#import time
21
/***********************************************************************
22
 * This file was generated by $file on $time.strftime("%c")
23
 **********************************************************************/
24
\#include <uhd/exception.hpp>
25
\#include <boost/tokenizer.hpp>
26
\#include <boost/lexical_cast.hpp>
27
\#include <boost/detail/endian.hpp>
28
\#include <boost/cstdint.hpp>
29
\#include <string>
30
\#include <vector>
31

  
32
typedef size_t pred_type;
33
typedef std::vector<pred_type> pred_vector_type;
34

  
35
enum dir_type{
36
    DIR_OTW_TO_CPU = 0,
37
    DIR_CPU_TO_OTW = 1
38
};
39

  
40
struct pred_error : uhd::value_error{
41
    pred_error(const std::string &what):
42
        uhd::value_error("convert::make_pred: " + what)
43
    {
44
        /* NOP */
45
    }
46
};
47

  
48
pred_type make_pred(const std::string &markup, dir_type &dir){
49
    pred_type pred = 0;
50

  
51
    try{
52
        boost::tokenizer<boost::char_separator<char> > tokenizer(markup, boost::char_separator<char>("_"));
53
        std::vector<std::string> tokens(tokenizer.begin(), tokenizer.end());
54
        //token 0 is <convert>
55
        std::string inp_type = tokens.at(1);
56
        std::string num_inps = tokens.at(2);
57
        //token 3 is <to>
58
        std::string out_type = tokens.at(4);
59
        std::string num_outs = tokens.at(5);
60
        std::string swap_type = tokens.at(6);
61

  
62
        std::string cpu_type, otw_type;
63
        if (inp_type.find("item") == std::string::npos){
64
            cpu_type = inp_type;
65
            otw_type = out_type;
66
            dir = DIR_CPU_TO_OTW;
67
        }
68
        else{
69
            cpu_type = out_type;
70
            otw_type = inp_type;
71
            dir = DIR_OTW_TO_CPU;
72
        }
73

  
74
        if      (cpu_type == "fc64") pred |= $ph.fc64_p;
75
        else if (cpu_type == "fc32") pred |= $ph.fc32_p;
76
        else if (cpu_type == "sc16") pred |= $ph.sc16_p;
77
        else if (cpu_type == "sc8")  pred |= $ph.sc8_p;
78
        else throw pred_error("unhandled io type " + cpu_type);
79

  
80
        if (otw_type == "item32") pred |= $ph.item32_p;
81
        else throw pred_error("unhandled otw type " + otw_type);
82

  
83
        int num_inputs = boost::lexical_cast<int>(num_inps);
84
        int num_outputs = boost::lexical_cast<int>(num_outs);
85

  
86
        switch(num_inputs*num_outputs){ //FIXME treated as one value
87
        case 1: pred |= $ph.chan1_p; break;
88
        case 2: pred |= $ph.chan2_p; break;
89
        case 3: pred |= $ph.chan3_p; break;
90
        case 4: pred |= $ph.chan4_p; break;
91
        default: throw pred_error("unhandled number of channels");
92
        }
93

  
94
        if      (swap_type == "bswap") pred |= $ph.bswap_p;
95
        else if (swap_type == "nswap") pred |= $ph.nswap_p;
96
        else throw pred_error("unhandled swap type");
97

  
98
    }
99
    catch(...){
100
        throw pred_error("could not parse markup: " + markup);
101
    }
102

  
103
    return pred;
104
}
105

  
106
#define pred_table_wildcard pred_type(~0)
107
#define pred_table_max_size size_t(128)
108
#define pred_table_index(e) (pred_type(e) & 0x7f)
109

  
110
static pred_vector_type get_pred_byte_order_table(void){
111
    pred_vector_type table(pred_table_max_size, pred_table_wildcard);
112
    \#ifdef BOOST_BIG_ENDIAN
113
    table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)]    = $ph.nswap_p;
114
    table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.bswap_p;
115
    \#else
116
    table[pred_table_index(otw_type_t::BO_BIG_ENDIAN)]    = $ph.bswap_p;
117
    table[pred_table_index(otw_type_t::BO_LITTLE_ENDIAN)] = $ph.nswap_p;
118
    \#endif
119
    table[pred_table_index(otw_type_t::BO_NATIVE)]        = $ph.nswap_p;
120
    return table;
121
}
122

  
123
static pred_vector_type get_pred_io_type_table(void){
124
    pred_vector_type table(pred_table_max_size, pred_table_wildcard);
125
    table[pred_table_index(io_type_t::COMPLEX_FLOAT64)]    = $ph.fc64_p;
126
    table[pred_table_index(io_type_t::COMPLEX_FLOAT32)]    = $ph.fc32_p;
127
    table[pred_table_index(io_type_t::COMPLEX_INT16)]      = $ph.sc16_p;
128
    return table;
129
}
130

  
131
static pred_vector_type get_pred_num_io_table(void){
132
    pred_vector_type table(pred_table_max_size, pred_table_wildcard);
133
    table[1] = $ph.chan1_p;
134
    table[2] = $ph.chan2_p;
135
    table[3] = $ph.chan3_p;
136
    table[4] = $ph.chan4_p;
137
    return table;
138
}
139

  
140
UHD_INLINE pred_type make_pred(
141
    const io_type_t &io_type,
142
    const otw_type_t &otw_type,
143
    size_t num_inputs,
144
    size_t num_outputs
145
){
146
    pred_type pred = $ph.item32_p; //only item32 supported as of now
147

  
148
    static const pred_vector_type pred_byte_order_table(get_pred_byte_order_table());
149
    pred |= pred_byte_order_table[pred_table_index(otw_type.byteorder)];
150

  
151
    static const pred_vector_type pred_io_type_table(get_pred_io_type_table());
152
    pred |= pred_io_type_table[pred_table_index(io_type.tid)];
153

  
154
    static const pred_vector_type pred_num_io_table(get_pred_num_io_table());
155
    pred |= pred_num_io_table[pred_table_index(num_inputs*num_outputs)];
156

  
157
    if (pred == pred_table_wildcard) throw pred_error(
158
        "unhanded input combination for make_pred()"
159
    );
160

  
161
    return pred;
162
}
163
"""
164

  
165
def parse_tmpl(_tmpl_text, **kwargs):
166
    from Cheetah.Template import Template
167
    return str(Template(_tmpl_text, kwargs))
168

  
169
class ph:
170
    bswap_p  = 0b00001
171
    nswap_p  = 0b00000
172
    item32_p = 0b00000
173
    sc8_p    = 0b00000
174
    sc16_p   = 0b00010
175
    fc32_p   = 0b00100
176
    fc64_p   = 0b00110
177
    chan1_p  = 0b00000
178
    chan2_p  = 0b01000
179
    chan3_p  = 0b10000
180
    chan4_p  = 0b11000
181

  
182
if __name__ == '__main__':
183
    import sys, os
184
    file = os.path.basename(__file__)
185
    open(sys.argv[1], 'w').write(parse_tmpl(TMPL_TEXT, file=file, ph=ph))

Also available in: Unified diff