Start implementing LoadPersistent.

Switch to using fstream instead of stdio.

Change-Id: I600a8748a0b3dcf24740d63cc296df000abc388d
This commit is contained in:
Peter Johnson
2015-06-27 09:56:43 -07:00
parent 69e91244f4
commit 05e084364a
2 changed files with 163 additions and 126 deletions

View File

@@ -7,7 +7,9 @@
#include "ntcore.h"
#include <cstdio>
#include <fstream>
#include <string>
#include <tuple>
#include "llvm/StringExtras.h"
#include "base64.h"
@@ -15,48 +17,45 @@
using namespace ntimpl;
static void WriteString(FILE* f, llvm::StringRef str) {
fputc('"', f);
for (unsigned int i = 0, e = str.size(); i != e; ++i) {
unsigned char c = str[i];
static void WriteString(std::ostream& os, llvm::StringRef str) {
os << '"';
for (auto c : str) {
switch (c) {
case '\\':
fputs("\\\\", f);
os << "\\\\";
break;
case '\t':
fputs("\\t", f);
os << "\\t";
break;
case '\n':
fputs("\\n", f);
os << "\\n";
break;
case '"':
fputs("\\\"", f);
os << "\\\"";
break;
default:
if (std::isprint(c)) {
fputc(c, f);
os << c;
break;
}
// Write out the escaped representation.
fputs("\\x", f);
fputc(llvm::hexdigit((c >> 4 & 0xF)), f);
fputc(llvm::hexdigit((c >> 0) & 0xF), f);
os << "\\x";
os << llvm::hexdigit((c >> 4) & 0xF);
os << llvm::hexdigit((c >> 0) & 0xF);
}
}
fputc('"', f);
os << '"';
}
const char* NT_SavePersistent(const char* filename) {
FILE* f = fopen(filename, "wt");
if (!f) return "could not open file";
std::ofstream os(filename);
if (!os) return "could not open file";
fputs("[NetworkTables Storage 3.0]\n", f);
os << "[NetworkTables Storage 3.0]\n";
Storage& storage = Storage::GetInstance();
for (Storage::EntriesMap::const_iterator i = storage.entries.begin(),
end = storage.entries.end();
const Storage& storage = Storage::GetInstance();
for (auto i = storage.entries.begin(), end = storage.entries.end();
i != end; ++i) {
const StorageEntry& entry = i->getValue();
// only write persistent-flagged values
@@ -66,72 +65,75 @@ const char* NT_SavePersistent(const char* filename) {
const NT_Value& v = entry.value;
switch (v.type) {
case NT_BOOLEAN:
fputs("boolean ", f);
os << "boolean ";
break;
case NT_DOUBLE:
fputs("double ", f);
os << "double ";
break;
case NT_STRING:
fputs("string ", f);
os << "string ";
break;
case NT_RAW:
fputs("raw ", f);
os << "raw ";
break;
case NT_BOOLEAN_ARRAY:
fputs("array boolean ", f);
os << "array boolean ";
break;
case NT_DOUBLE_ARRAY:
fputs("array double ", f);
os << "array double ";
break;
case NT_STRING_ARRAY:
fputs("array string ", f);
os << "array string ";
break;
default:
continue;
}
// name
WriteString(f, i->getKey());
WriteString(os, i->getKey());
// =
fputc('=', f);
os << '=';
// value
switch (v.type) {
case NT_BOOLEAN:
fputs(v.data.v_boolean ? "true" : "false", f);
os << (v.data.v_boolean ? "true" : "false");
break;
case NT_DOUBLE:
fprintf(f, "%g", v.data.v_double);
os << v.data.v_double;
break;
case NT_STRING:
WriteString(f, MakeStringRef(v.data.v_string));
WriteString(os, MakeStringRef(v.data.v_string));
break;
case NT_RAW: {
char* buf = new char[Base64EncodeLen(v.data.v_raw.len)];
Base64Encode(buf,
reinterpret_cast<const unsigned char*>(v.data.v_raw.str),
v.data.v_raw.len);
fputs(buf, f);
os << buf;
delete[] buf;
break;
}
case NT_BOOLEAN_ARRAY:
for (size_t i = 0; i < v.data.arr_boolean.size; ++i) {
fputs(v.data.arr_boolean.arr[i] ? "true" : "false", f);
if (i != (v.data.arr_boolean.size - 1)) fputc(',', f);
os << (v.data.arr_boolean.arr[i] ? "true" : "false");
if (i != (v.data.arr_boolean.size - 1))
os << ',';
}
break;
case NT_DOUBLE_ARRAY:
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
fprintf(f, "%g", v.data.arr_double.arr[i]);
if (i != (v.data.arr_double.size - 1)) fputc(',', f);
os << v.data.arr_double.arr[i];
if (i != (v.data.arr_double.size - 1))
os << ',';
}
break;
case NT_STRING_ARRAY:
for (size_t i = 0; i < v.data.arr_double.size; ++i) {
WriteString(f, MakeStringRef(v.data.arr_string.arr[i]));
if (i != (v.data.arr_double.size - 1)) fputc(',', f);
WriteString(os, MakeStringRef(v.data.arr_string.arr[i]));
if (i != (v.data.arr_double.size - 1))
os << ',';
}
break;
default:
@@ -139,17 +141,48 @@ const char* NT_SavePersistent(const char* filename) {
}
// eol
fputc('\n', f);
os << '\n';
}
fclose(f);
os.close();
return 0;
}
const char* NT_LoadPersistent(const char* filename) {
FILE* f = fopen(filename, "rt");
const char* NT_LoadPersistent(const char* filename,
void (*warn)(size_t line, const char* msg)) {
std::ifstream f(filename);
if (!f) return "could not open file";
fclose(f);
std::string line_str;
std::size_t line_num = 0;
while (std::getline(f, line_str)) {
llvm::StringRef line(line_str);
++line_num;
// type
llvm::StringRef type_str;
std::tie(type_str, line) = line.split(' ');
NT_Type type = NT_UNASSIGNED;
if (type_str == "boolean") type = NT_BOOLEAN;
else if (type_str == "double") type = NT_DOUBLE;
else if (type_str == "string") type = NT_STRING;
else if (type_str == "raw") type = NT_RAW;
else if (type_str == "array") {
llvm::StringRef array_str;
std::tie(array_str, line) = line.split(' ');
if (array_str == "boolean") type = NT_BOOLEAN_ARRAY;
else if (array_str == "double") type = NT_DOUBLE_ARRAY;
else if (array_str == "string") type = NT_STRING_ARRAY;
}
if (type == NT_UNASSIGNED) {
if (warn) warn(line_num, "unrecognized type");
continue;
}
// name
}
f.close();
return 0;
}