Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/boost_1_33_1/libs/program_options/test/test_convert.cpp @ 20

Last change on this file since 20 was 12, checked in by landauf, 18 years ago

added boost

File size: 3.9 KB
Line 
1// Copyright Vladimir Prus 2002-2004.
2// Distributed under the Boost Software License, Version 1.0.
3// (See accompanying file LICENSE_1_0.txt
4// or copy at http://www.boost.org/LICENSE_1_0.txt)
5
6#include <string>
7#include <fstream>
8#include <sstream>
9#include <iostream>
10#include <cassert>
11#include <boost/progress.hpp>
12#include <boost/bind.hpp>
13#include <boost/ref.hpp>
14
15#include <boost/program_options/detail/convert.hpp>
16#include <boost/program_options/detail/utf8_codecvt_facet.hpp>
17
18using namespace std;
19
20string file_content(const string& filename)
21{
22    ifstream ifs(filename.c_str());
23    assert(ifs);
24   
25    stringstream ss;
26    ss << ifs.rdbuf();
27   
28    return ss.str();
29}
30
31// A version of from_8_bit which does not use functional object, for
32// performance comparison.
33std::wstring from_8_bit_2(const std::string& s, 
34                          const codecvt<wchar_t, char, mbstate_t>& cvt)
35{
36    std::wstring result;
37
38
39    std::mbstate_t state = {0};
40
41    const char* from = s.data();
42    const char* from_end = s.data() + s.size();
43    // The interace of cvt is not really iterator-like, and it's
44    // not possible the tell the required output size without the conversion.
45    // All we can is convert data by pieces.
46    while(from != from_end) {
47           
48        // std::basic_string does not provide non-const pointers to the data,
49        // so converting directly into string is not possible.
50        wchar_t buffer[32];
51           
52        wchar_t* to_next = buffer;
53        // Try to convert remaining input.
54        std::codecvt_base::result r = 
55            cvt.in(state, from, from_end, from, buffer, buffer + 32, to_next);
56       
57        if (r == std::codecvt_base::error)
58            throw logic_error("character conversion failed");
59        // 'partial' is not an error, it just means not all source characters
60        // we converted. However, we need to check that at least one new target
61        // character was produced. If not, it means the source data is
62        // incomplete, and since we don't have extra data to add to source, it's
63        // error.
64        if (to_next == buffer)
65            throw logic_error("character conversion failed");
66
67        // Add converted characters
68        result.append(buffer, to_next);
69    }
70
71    return result;       
72}
73
74
75void test_convert(const std::string& input, 
76                  const std::string& expected_output)
77{
78    boost::program_options::detail::utf8_codecvt_facet<wchar_t, char> facet;
79   
80    std::wstring output;
81    { 
82        boost::progress_timer t;
83        for (int i = 0; i < 10000; ++i)
84            output = boost::from_8_bit(
85                input,
86                facet);
87    }
88
89    {
90        boost::progress_timer t;
91        for (int i = 0; i < 10000; ++i)
92            output = from_8_bit_2(
93                input,
94                facet);
95    }
96
97    assert(output.size()*2 == expected_output.size());
98
99    for(unsigned i = 0; i < output.size(); ++i) {
100
101        {
102            unsigned low = output[i];
103            low &= 0xFF;
104            unsigned low2 = expected_output[2*i];
105            low2 &= 0xFF;
106            assert(low == low2);
107        }
108        {       
109            unsigned high = output[i];
110            high >>= 8;
111            high &= 0xFF;
112            unsigned high2 = expected_output[2*i+1];           
113            assert(high == high2);
114        }
115    }
116
117    string ref = boost::to_8_bit(output, facet);
118
119    assert(ref == input);
120}
121
122int test_main(int ac, char* av[])
123{       
124    std::string input = file_content("utf8.txt");
125    std::string expected = file_content("ucs2.txt");
126
127    test_convert(input, expected);
128   
129    if (ac > 1) {
130        cout << "Trying to convert the command line argument\n";
131   
132        locale::global(locale(""));
133        std::wstring w = boost::from_local_8_bit(av[1]);
134 
135        cout << "Got something, printing decimal code point values\n";
136        for (unsigned i = 0; i < w.size(); ++i) {
137            cout << (unsigned)w[i] << "\n";
138        }
139       
140    }
141   
142    return 0;
143}
Note: See TracBrowser for help on using the repository browser.