@@ -183,30 +183,7 @@ namespace csv {
183183 template <typename TStream,
184184 csv::enable_if_t <std::is_base_of<std::istream, TStream>::value, int > = 0 >
185185 CSVReader (TStream &source, CSVFormat format = CSVFormat::guess_csv()) : _format(format) {
186- auto head = internals::get_csv_head (source);
187- using Parser = internals::StreamParser<TStream>;
188-
189- // Apply chunk size from format before any reading occurs
190- this ->_chunk_size = format.get_chunk_size ();
191-
192- if (format.guess_delim ()) {
193- auto guess_result = internals::_guess_format (head, format.possible_delimiters );
194- format.delimiter (guess_result.delim );
195- // Only override header if user hasn't explicitly called no_header()
196- // Note: column_names() also sets header=-1, but it populates col_names,
197- // so we can distinguish: no_header() means header=-1 && col_names.empty()
198- if (format.header != -1 || !format.col_names .empty ()) {
199- format.header = guess_result.header_row ;
200- }
201- this ->_format = format;
202- }
203-
204- if (!format.col_names .empty ())
205- this ->set_col_names (format.col_names );
206-
207- this ->parser = std::unique_ptr<Parser>(
208- new Parser (source, format, col_names)); // For C++11
209- this ->initial_read ();
186+ this ->init_from_stream (source, format);
210187 }
211188 // /@}
212189
@@ -283,8 +260,10 @@ namespace csv {
283260 /* * Queue of parsed CSV rows */
284261 std::unique_ptr<RowCollection> records{new RowCollection (100 )};
285262
286- /* * Owned file stream used for stream-based filename parsing on targets without mmap. */
263+ #if defined(__EMSCRIPTEN__)
264+ /* * Owned file stream used by filename constructor fallback to stream parsing. */
287265 std::unique_ptr<std::ifstream> owned_file_stream = nullptr ;
266+ #endif
288267
289268 size_t n_cols = 0 ; /* *< The number of columns in this CSV */
290269 size_t _n_rows = 0 ; /* *< How many rows (minus header) have been read so far */
@@ -337,6 +316,36 @@ namespace csv {
337316 }
338317 }
339318
319+ template <typename TStream,
320+ csv::enable_if_t <std::is_base_of<std::istream, TStream>::value, int > = 0 >
321+ void init_from_stream (TStream& source, CSVFormat format) {
322+ auto head = internals::get_csv_head (source);
323+ using Parser = internals::StreamParser<TStream>;
324+
325+ // Apply chunk size from format before any reading occurs
326+ this ->_chunk_size = format.get_chunk_size ();
327+
328+ if (format.guess_delim ()) {
329+ auto guess_result = internals::_guess_format (head, format.possible_delimiters );
330+ format.delimiter (guess_result.delim );
331+ // Only override header if user hasn't explicitly called no_header()
332+ // Note: column_names() also sets header=-1, but it populates col_names,
333+ // so we can distinguish: no_header() means header=-1 && col_names.empty()
334+ if (format.header != -1 || !format.col_names .empty ()) {
335+ format.header = guess_result.header_row ;
336+ }
337+ this ->_format = format;
338+ }
339+
340+ if (!format.col_names .empty ()) {
341+ this ->set_col_names (format.col_names );
342+ }
343+
344+ this ->parser = std::unique_ptr<Parser>(
345+ new Parser (source, format, col_names)); // For C++11
346+ this ->initial_read ();
347+ }
348+
340349 /* * Read initial chunk to get metadata */
341350 void initial_read () {
342351#if CSV_ENABLE_THREADS
0 commit comments