This file is indexed.

/usr/include/xtensor/xcsv.hpp is in xtensor-dev 0.10.11-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/***************************************************************************
* Copyright (c) 2016, Johan Mabille, Sylvain Corlay and Wolf Vollprecht    *
*                                                                          *
* Distributed under the terms of the BSD 3-Clause License.                 *
*                                                                          *
* The full license is in the file LICENSE, distributed with this software. *
****************************************************************************/

#ifndef XCSV_HPP
#define XCSV_HPP

#include <exception>
#include <istream>
#include <iterator>
#include <sstream>
#include <string>
#include <utility>

#include "xtensor.hpp"

namespace xt
{

    /**************************************
     * load_csv and dump_csv declarations *
     **************************************/

    template <class T, class A = std::allocator<T>>
    xtensor_container<std::vector<T, A>, 2> load_csv(std::istream& stream);

    template <class E>
    void dump_csv(std::ostream& stream, const xexpression<E>& e);

    /*****************************************
     * load_csv and dump_csv implementations *
     *****************************************/

    namespace detail
    {
        template <class T>
        inline T lexical_cast(const std::string& cell)
        {
            T res;
            std::istringstream iss(cell);
            iss >> res;
            return res;
        }

        template <>
        inline float lexical_cast<float>(const std::string& cell) { return std::stof(cell); }

        template <>
        inline double lexical_cast<double>(const std::string& cell) { return std::stod(cell); }

        template <>
        inline long double lexical_cast<long double>(const std::string& cell) { return std::stold(cell); }

        template <>
        inline int lexical_cast<int>(const std::string& cell) { return std::stoi(cell); }

        template <>
        inline long lexical_cast<long>(const std::string& cell) { return std::stol(cell); }

        template <>
        inline long long lexical_cast<long long>(const std::string& cell) { return std::stoll(cell); }

        template <>
        inline unsigned int lexical_cast<unsigned int>(const std::string& cell) { return static_cast<unsigned int>(std::stoul(cell)); }

        template <>
        inline unsigned long lexical_cast<unsigned long>(const std::string& cell) { return std::stoul(cell); }

        template <>
        inline unsigned long long lexical_cast<unsigned long long>(const std::string& cell) { return std::stoull(cell); }

        template <class ST, class T, class OI>
        ST load_csv_row(std::istream& row_stream, OI output, std::string cell)
        {
            ST length = 0;
            while (std::getline(row_stream, cell, ','))
            {
                *output++ = lexical_cast<T>(cell);
                ++length;
            }
            return length;
        }
    }

    /**
     * @brief Load tensor from CSV.
     * 
     * Returns an \ref xexpression for the parsed CSV
     * @param stream the input stream containing the CSV encoded values
     */
    template <class T, class A>
    xtensor_container<std::vector<T, A>, 2> load_csv(std::istream& stream)
    {
        using container_type = typename std::vector<T, A>;
        using tensor_type = xtensor_container<container_type, 2>;
        using size_type = typename tensor_type::size_type;
        using inner_shape_type = typename tensor_type::inner_shape_type;
        using inner_strides_type = typename tensor_type::inner_strides_type;
        using output_iterator = std::back_insert_iterator<container_type>;

        container_type data;
        size_type nbrow = 0, nbcol = 0;
        {
            output_iterator output(data);
            std::string row, cell;
            while (std::getline(stream, row))
            {
                std::stringstream row_stream(row);
                nbcol = detail::load_csv_row<size_type, T, output_iterator>(row_stream, output, cell);
                ++nbrow;
            }
        }
        inner_shape_type shape = {nbrow, nbcol};
        inner_strides_type strides;  // no need for initializer list for stack-allocated strides_type
        size_type data_size = compute_strides(shape, layout_type::row_major, strides);
        // Sanity check for data size.
        if (data.size() != data_size)
        {
            throw std::runtime_error("Inconsistent row lengths in CSV");
        }
        return tensor_type(std::move(data), std::move(shape), std::move(strides));
    }

    /**
     * @brief Dump tensor to CSV.
     * 
     * @param stream the output stream to write the CSV encoded values
     * @param e the tensor expression to serialize
     */
    template <class E>
    void dump_csv(std::ostream& stream, const xexpression<E>& e)
    {
        using size_type = typename E::size_type;
        const E& ex = e.derived_cast();
        if (ex.dimension() != 2)
        {
            throw std::runtime_error("Only 2-D expressions can be serialized to CSV");
        }
        size_type nbrows = ex.shape()[0], nbcols = ex.shape()[1];
        auto st = ex.stepper_begin(ex.shape());
        for (size_type r = 0; r != nbrows; ++r)
        {
            for (size_type c = 0; c != nbcols; ++c)
            {
                stream << *st;
                if (c != nbcols - 1)
                {
                    st.step(1);
                    stream << ',';
                }
                else
                {
                    st.reset(1);
                    st.step(0);
                    stream << std::endl;
                }
            }
        }
    }
}

#endif