diff --git a/bsputil/decompile.cpp b/bsputil/decompile.cpp index ebad86b9..98a4481c 100644 --- a/bsputil/decompile.cpp +++ b/bsputil/decompile.cpp @@ -1033,7 +1033,7 @@ static void DecompileEntity( continue; } else if (modelNum > 0 && keyValue.first == "origin") { auto &value = keyValue.second; - parser_t parser(value.data(), value.data() + value.size()); + parser_t parser(value); qvec3d vec; parser.parse_token(); vec[0] = stof(parser.token); diff --git a/common/entdata.cc b/common/entdata.cc index 61eab9e3..42351fa7 100644 --- a/common/entdata.cc +++ b/common/entdata.cc @@ -117,7 +117,7 @@ keyvalues_t::iterator entdict_t::end() std::vector EntData_Parse(const std::string &entdata) { std::vector result; - parser_t parser(entdata.data(), entdata.data() + entdata.size()); + parser_t parser(entdata); /* go through all the entities */ while (1) { diff --git a/include/common/parser.hh b/include/common/parser.hh index ca5232bc..e1c9a5c8 100644 --- a/include/common/parser.hh +++ b/include/common/parser.hh @@ -47,7 +47,15 @@ struct parser_t uint32_t linenum = 1; std::string token; - parser_t(const char *data, const char *in_end) : pos(data), end(in_end) { } + // base constructor; accept raw start & length + parser_t(const void *start, size_t length) : pos(reinterpret_cast(start)), end(reinterpret_cast(start) + length) { } + + // pull from string_view; note that the string view must live for the entire + // duration of the parser's life time + parser_t(const std::string_view &view) : parser_t(&view.front(), view.size()) { } + + // pull from C string; made explicit because this is error-prone + explicit parser_t(const char *str) : parser_t(str, strlen(str)) { } bool parse_token(parseflags flags = PARSE_NORMAL); diff --git a/light/entities.cc b/light/entities.cc index d8c4a946..8e6de47d 100644 --- a/light/entities.cc +++ b/light/entities.cc @@ -1404,7 +1404,7 @@ bool ParseLightsFile(const std::filesystem::path &fname) while (!f.eof()) { std::getline(f, buf); - parser_t parser(buf.data(), buf.data() + buf.size()); + parser_t parser(buf); if (!parser.parse_token()) continue; diff --git a/qbsp/map.cc b/qbsp/map.cc index 75b70a52..c150042f 100644 --- a/qbsp/map.cc +++ b/qbsp/map.cc @@ -1847,8 +1847,7 @@ mapentity_t LoadExternalMap(const char *filename) FError("Couldn't load external map file \"{}.\"\n", filename); } - const char *begin = reinterpret_cast(file->data()); - parser_t parser(begin, begin + file->size()); + parser_t parser(file->data(), file->size()); // parse the worldspawn if (!ParseEntity(parser, &dest)) { @@ -1896,8 +1895,7 @@ void LoadMapFile(void) return; } - const char *begin = reinterpret_cast(file->data()); - parser_t parser(begin, begin + file->size()); + parser_t parser(file->data(), file->size()); for (int i = 0;; i++) { mapentity_t &entity = map.entities.emplace_back(); diff --git a/qbsp/test_qbsp.cc b/qbsp/test_qbsp.cc index ddc752e1..33822e46 100644 --- a/qbsp/test_qbsp.cc +++ b/qbsp/test_qbsp.cc @@ -32,7 +32,7 @@ static mapentity_t LoadMap(const char *map) options.target_version = &bspver_q1; options.target_game = options.target_version->game; - parser_t parser(map, map + strlen(map)); + parser_t parser(map); mapentity_t worldspawn; // FIXME: adds the brush to the global map...