File: csv_utils.hpp

package info (click to toggle)
mapnik 2.2.0%2Bds1-7
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 30,288 kB
  • ctags: 18,382
  • sloc: cpp: 115,128; python: 9,298; xml: 5,692; ansic: 3,726; makefile: 160; sh: 159; lisp: 13
file content (86 lines) | stat: -rw-r--r-- 3,581 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_CSV_UTILS_DATASOURCE_HPP
#define MAPNIK_CSV_UTILS_DATASOURCE_HPP


#include <string>
#include <boost/algorithm/string.hpp>

namespace csv_utils
{
    static inline void fix_json_quoting(std::string & csv_line)
    {
        std::string wrapping_char;
        std::string::size_type j_idx = std::string::npos;
        std::string::size_type post_idx = std::string::npos;
        std::string::size_type j_idx_double = csv_line.find("\"{");
        std::string::size_type j_idx_single = csv_line.find("'{");
        if (j_idx_double != std::string::npos)
        {
            wrapping_char = "\"";
            j_idx = j_idx_double;
            post_idx = csv_line.find("}\"");
            
        }
        else if (j_idx_single != std::string::npos)
        {
            wrapping_char = "'";
            j_idx = j_idx_single;
            post_idx = csv_line.find("}'");
        }
        // we are positive it is valid json
        if (!wrapping_char.empty())
        {
            // grab the json chunk
            std::string json_chunk = csv_line.substr(j_idx,post_idx+wrapping_char.size());
            bool does_not_have_escaped_double_quotes = (json_chunk.find("\\\"") == std::string::npos);
            // ignore properly escaped quotes like \" which need no special handling
            if (does_not_have_escaped_double_quotes)
            {
                std::string pre_json = csv_line.substr(0,j_idx);
                std::string post_json = csv_line.substr(post_idx+wrapping_char.size());
                // handle "" in a string wrapped in "
                // http://tools.ietf.org/html/rfc4180#section-2 item 7.
                // e.g. "{""type"":""Point"",""coordinates"":[30.0,10.0]}"
                if (json_chunk.find("\"\"") != std::string::npos)
                {
                    boost::algorithm::replace_all(json_chunk,"\"\"","\\\"");
                    csv_line = pre_json + json_chunk + post_json;
                }
                // handle " in a string wrapped in '
                // e.g. '{"type":"Point","coordinates":[30.0,10.0]}'
                else
                {
                    // escape " because we cannot exchange for single quotes
                    // https://github.com/mapnik/mapnik/issues/1408
                    boost::algorithm::replace_all(json_chunk,"\"","\\\"");
                    boost::algorithm::replace_all(json_chunk,"'","\"");
                    csv_line = pre_json + json_chunk + post_json;
                }
            }
        }    
    }
}

#endif // MAPNIK_CSV_UTILS_DATASOURCE_HPP