Skip to content

Commit 9fb0df1

Browse files
committed
merge with upstream 'd99kris' till change-date 26-Jul-2025
2 parents e7d8ca2 + dd79854 commit 9fb0df1

3 files changed

Lines changed: 63 additions & 21 deletions

File tree

include/rapidcsv/rapidcsv.h

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@
1313
* ***********************************************************************************
1414
*
1515
* URL: https://github.com/d99kris/rapidcsv
16-
* Version: 8.84
16+
* Version: 8.88
1717
*
18-
* Copyright (C) 2017-2024 Kristofer Berggren
18+
* Copyright (C) 2017-2025 Kristofer Berggren
1919
* All rights reserved.
2020
*
2121
* rapidcsv is distributed under the BSD 3-Clause license, see LICENSE for details.
@@ -54,7 +54,7 @@ typedef SSIZE_T ssize_t;
5454
#define RAPIDCSV_VERSION_MINOR 0
5555
#define RAPIDCSV_VERSION_PATCH 8
5656

57-
#define UPSTREAM___RAPIDCSV__VERSION 8.87
57+
#define UPSTREAM___RAPIDCSV__VERSION 8.88
5858

5959
// Project path is removed from the __FILE__
6060
// Resulting file-path is relative path from project-root-folder.
@@ -1307,24 +1307,17 @@ namespace rapidcsv
13071307
_mIsUtf16 = true;
13081308
_mIsLE = (bom2b == bomU16le);
13091309

1310-
std::wifstream wstream;
1311-
wstream.exceptions(std::wifstream::failbit | std::wifstream::badbit);
1312-
wstream.open(_mPath, std::ios::binary);
1313-
if (_mIsLE)
1314-
{
1315-
wstream.imbue(std::locale(wstream.getloc(),
1316-
new std::codecvt_utf16<wchar_t, 0x10ffff,
1317-
static_cast<std::codecvt_mode>(std::consume_header |
1318-
std::little_endian)>));
1319-
}
1320-
else
1321-
{
1322-
wstream.imbue(std::locale(wstream.getloc(),
1323-
new std::codecvt_utf16<wchar_t, 0x10ffff,
1324-
std::consume_header>));
1325-
}
1326-
std::wstringstream wss;
1327-
wss << wstream.rdbuf();
1310+
std::vector<char> buffer(static_cast<size_t>(length));
1311+
pStream.read(buffer.data(), length);
1312+
1313+
const std::codecvt_mode mode = (
1314+
(_mIsLE) ?
1315+
(static_cast<std::codecvt_mode>(std::consume_header | std::little_endian)) :
1316+
(static_cast<std::codecvt_mode>(std::consume_header));
1317+
std::wstring_convert<std::codecvt_utf16<wchar_t, 0x10ffff, mode>> utf16conv;
1318+
const std::wstring& utf16 = utf16conv.from_bytes(buffer.data(), buffer.data() + length);
1319+
1320+
std::wstringstream wss(utf16);
13281321
std::string utf8 = _toString(wss.str());
13291322
std::stringstream ss(utf8);
13301323
_parseCsv(ss, static_cast<std::streamsize>(utf8.size()));

tests/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,9 @@ add_unit_test(test097)
209209
add_unit_test(test098)
210210
add_unit_test(test099)
211211
add_unit_test(test100)
212+
if(HAS_CODECVT)
213+
add_unit_test(test101)
214+
endif()
212215

213216

214217
add_unit_test(testView001)

tests/test101.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// test101.cpp - read UTF-16 LE stream
2+
3+
#include <rapidcsv.h>
4+
#include "unittest.h"
5+
6+
int main()
7+
{
8+
int rv = 0;
9+
10+
const unsigned char u16le[] =
11+
{
12+
0xff, 0xfe,
13+
0x2d, 0x00, 0x2c, 0x00, 0x41, 0x00, 0x2c, 0x00, 0x42, 0x00, 0x2c, 0x00,
14+
0x43, 0x00, 0x0a, 0x00, 0x31, 0x00, 0x2c, 0x00, 0x33, 0x00, 0x2c, 0x00,
15+
0x39, 0x00, 0x2c, 0x00, 0x38, 0x00, 0x31, 0x00, 0x0a, 0x00, 0x32, 0x00,
16+
0x2c, 0x00, 0x34, 0x00, 0x2c, 0x00, 0x31, 0x00, 0x36, 0x00, 0x2c, 0x00,
17+
0x32, 0x00, 0x35, 0x00, 0x36, 0x00, 0x0a, 0x00
18+
};
19+
const unsigned int u16le_len = 58;
20+
21+
std::string csv(reinterpret_cast<const char*>(u16le), u16le_len);
22+
// "-,A,B,C\n"
23+
// "1,3,9,81\n"
24+
// "2,4,16,256\n"
25+
26+
try
27+
{
28+
// stream from string
29+
std::istringstream sstream(csv);
30+
rapidcsv::Document doc(sstream, rapidcsv::LabelParams(0, 0));
31+
unittest::ExpectEqual(int, doc.GetCell<int>(0, 0), 3);
32+
unittest::ExpectEqual(int, doc.GetCell<int>(1, 0), 9);
33+
unittest::ExpectEqual(int, doc.GetCell<int>(2, 0), 81);
34+
35+
unittest::ExpectEqual(std::string, doc.GetCell<std::string>("A", "2"), "4");
36+
unittest::ExpectEqual(std::string, doc.GetCell<std::string>("B", "2"), "16");
37+
unittest::ExpectEqual(std::string, doc.GetCell<std::string>("C", "2"), "256");
38+
}
39+
catch (const std::exception& ex)
40+
{
41+
std::cout << ex.what() << std::endl;
42+
rv = 1;
43+
}
44+
45+
return rv;
46+
}

0 commit comments

Comments
 (0)