Skip to content

Commit

Permalink
feat: Allow NA
Browse files Browse the repository at this point in the history
  • Loading branch information
MEO265 committed May 6, 2024
1 parent d91ba40 commit de318f5
Showing 1 changed file with 56 additions and 10 deletions.
66 changes: 56 additions & 10 deletions src/split_json.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,32 @@
#include <vector>
#include <string>

extern "C" SEXP splitString(SEXP strSEXP) {
extern "C" SEXP split_json(SEXP strSEXP) {
const char* str = CHAR(STRING_ELT(strSEXP, 0));
std::vector<std::string> result;
std::vector<std::string> keys;
std::vector<std::string> values;
std::vector<bool> keysNA;
std::vector<bool> valuesNA;
std::string token;
bool inQuotes = false;
int backslashCount = 0;
bool isKey = true;

Check warning on line 15 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L6-L15

Added lines #L6 - L15 were not covered by tests

for (int i = 0; str[i] != '\0'; ++i) {
int start = 0;
int end = strlen(str) - 1;

Check warning on line 18 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L17-L18

Added lines #L17 - L18 were not covered by tests

// Ignore leading and trailing whitespaces
while (str[start] == ' ') start++;
while (str[end] == ' ') end--;

Check warning on line 22 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L21-L22

Added lines #L21 - L22 were not covered by tests

// Check for '{' and '}' and adjust the boundaries
if (str[start] == '{') start++;
if (str[end] == '}') end--;

Check warning on line 26 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L25-L26

Added lines #L25 - L26 were not covered by tests

for (int i = start; i <= end; ++i) {
char ch = str[i];
if (ch == ' ' && !inQuotes) continue; // Skip spaces outside quotes

Check warning on line 30 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L28-L30

Added lines #L28 - L30 were not covered by tests

if (ch == '\\' && !inQuotes) {
backslashCount++;
token += ch;
Expand All @@ -20,7 +37,19 @@ extern "C" SEXP splitString(SEXP strSEXP) {
token += ch;
backslashCount = 0;
} else if ((ch == ',' || ch == ':') && !inQuotes) {
result.push_back(token);
bool isNA = token == "null";
if (token.front() == '"' && token.back() == '"' && token.size() > 1) {
token = token.substr(1, token.size() - 2); // Remove quotes

Check warning on line 42 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L32-L42

Added lines #L32 - L42 were not covered by tests
}
if (isKey) {
keys.push_back(token);
keysNA.push_back(isNA);
isKey = false; // Next token will be a value

Check warning on line 47 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L44-L47

Added lines #L44 - L47 were not covered by tests
} else {
values.push_back(token);
valuesNA.push_back(isNA);
isKey = true; // Next token will be a key

Check warning on line 51 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L49-L51

Added lines #L49 - L51 were not covered by tests
}
token.clear();
backslashCount = 0;

Check warning on line 54 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L53-L54

Added lines #L53 - L54 were not covered by tests
} else {
Expand All @@ -29,15 +58,32 @@ extern "C" SEXP splitString(SEXP strSEXP) {
}
}

if (!token.empty()) {
result.push_back(token);
// Check the last token
if (!token.empty() && token != "null") {
if (token.front() == '"' && token.back() == '"' && token.size() > 1) {
token = token.substr(1, token.size() - 2); // Remove quotes

Check warning on line 64 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L62-L64

Added lines #L62 - L64 were not covered by tests
}
values.push_back(token);
valuesNA.push_back(token == "null");

Check warning on line 67 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L66-L67

Added lines #L66 - L67 were not covered by tests
} else {
values.push_back("");
valuesNA.push_back(true);

Check warning on line 70 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L69-L70

Added lines #L69 - L70 were not covered by tests
}

SEXP ans = PROTECT(allocVector(STRSXP, result.size()));
for (size_t j = 0; j < result.size(); ++j) {
SET_STRING_ELT(ans, j, mkChar(result[j].c_str()));
SEXP ans = PROTECT(allocVector(VECSXP, 2)); // List with two elements
SEXP keysR = PROTECT(allocVector(STRSXP, keys.size()));
SEXP valuesR = PROTECT(allocVector(STRSXP, values.size()));

Check warning on line 75 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L73-L75

Added lines #L73 - L75 were not covered by tests

for (size_t j = 0; j < keys.size(); ++j) {
SET_STRING_ELT(keysR, j, keysNA[j] ? NA_STRING : mkChar(keys[j].c_str()));

Check warning on line 78 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L77-L78

Added lines #L77 - L78 were not covered by tests
}
for (size_t j = 0; j < values.size(); ++j) {
SET_STRING_ELT(valuesR, j, valuesNA[j] ? NA_STRING : mkChar(values[j].c_str()));

Check warning on line 81 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L80-L81

Added lines #L80 - L81 were not covered by tests
}

SET_VECTOR_ELT(ans, 0, keysR);
SET_VECTOR_ELT(ans, 1, valuesR);

Check warning on line 85 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L84-L85

Added lines #L84 - L85 were not covered by tests

UNPROTECT(1);
UNPROTECT(3);
return ans;

Check warning on line 88 in src/split_json.cpp

View check run for this annotation

Codecov / codecov/patch

src/split_json.cpp#L87-L88

Added lines #L87 - L88 were not covered by tests
}

0 comments on commit de318f5

Please sign in to comment.