Skip to content

Commit 714194d

Browse files
committed
Merge branch 'master' of github.com:syoyo/tinyobjloader
2 parents 9d81c24 + 4998867 commit 714194d

2 files changed

Lines changed: 38 additions & 6 deletions

File tree

‎README.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ Tiny but powerful single file wavefront obj loader written in C++. No dependency
1616

1717
`tinyobjloader` is good for embedding .obj loader to your (global illumination) renderer ;-)
1818

19+
If you are looking for C89 version, please see https://github.com/syoyo/tinyobjloader-c .
20+
1921
Notice!
2022
-------
2123

‎tiny_obj_loader.h‎

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,38 @@ struct obj_shape {
257257
std::vector<float> vt;
258258
};
259259

260+
// See
261+
// http://stackoverflow.com/questions/6089231/getting-std-ifstream-to-handle-lf-cr-and-crlf
262+
static std::istream &safeGetline(std::istream &is, std::string &t) {
263+
t.clear();
264+
265+
// The characters in the stream are read one-by-one using a std::streambuf.
266+
// That is faster than reading them one-by-one using the std::istream.
267+
// Code that uses streambuf this way must be guarded by a sentry object.
268+
// The sentry object performs various tasks,
269+
// such as thread synchronization and updating the stream state.
270+
271+
std::istream::sentry se(is, true);
272+
std::streambuf *sb = is.rdbuf();
273+
274+
for (;;) {
275+
int c = sb->sbumpc();
276+
switch (c) {
277+
case '\n':
278+
return is;
279+
case '\r':
280+
if (sb->sgetc() == '\n') sb->sbumpc();
281+
return is;
282+
case EOF:
283+
// Also handle the case when the last line has no line ending
284+
if (t.empty()) is.setstate(std::ios::eofbit);
285+
return is;
286+
default:
287+
t += static_cast<char>(c);
288+
}
289+
}
290+
}
291+
260292
#define IS_SPACE(x) (((x) == ' ') || ((x) == '\t'))
261293
#define IS_DIGIT(x) \
262294
(static_cast<unsigned int>((x) - '0') < static_cast<unsigned int>(10))
@@ -646,12 +678,10 @@ void LoadMtl(std::map<std::string, int> *material_map,
646678
material_t material;
647679
InitMaterial(&material);
648680

649-
size_t maxchars = 8192; // Alloc enough size.
650-
std::vector<char> buf(maxchars); // Alloc enough size.
651681
while (inStream->peek() != -1) {
652-
inStream->getline(&buf[0], static_cast<std::streamsize>(maxchars));
682+
std::string linebuf;
653683

654-
std::string linebuf(&buf[0]);
684+
safeGetline(*inStream, linebuf);
655685

656686
// Trim trailing whitespace.
657687
if (linebuf.size() > 0) {
@@ -1031,7 +1061,7 @@ bool LoadObj(attrib_t *attrib, std::vector<shape_t> *shapes,
10311061

10321062
while (inStream->peek() != -1) {
10331063
std::string linebuf;
1034-
std::getline((*inStream), linebuf);
1064+
safeGetline(*inStream, linebuf);
10351065

10361066
// Trim newline '\r\n' or '\n'
10371067
if (linebuf.size() > 0) {
@@ -1312,7 +1342,7 @@ bool LoadObjWithCallback(std::istream &inStream, const callback_t &callback,
13121342

13131343
std::string linebuf;
13141344
while (inStream.peek() != -1) {
1315-
std::getline(inStream, linebuf);
1345+
safeGetline(inStream, linebuf);
13161346

13171347
// Trim newline '\r\n' or '\n'
13181348
if (linebuf.size() > 0) {

0 commit comments

Comments
 (0)