X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=laserbrain_demo;a=blobdiff_plain;f=src%2Fdatamap.cc;h=dcbae788b0cc2fe3d7b0ea6f8b0154a701ceab86;hp=bf8854c60cb7e10a8d19bd58241b2077307da5ee;hb=80c04e7a9aa6d42f769dd4fa70c2c3113440cbce;hpb=516e9be0443cfd7f844feb9b8299f909075b7c3c diff --git a/src/datamap.cc b/src/datamap.cc index bf8854c..dcbae78 100644 --- a/src/datamap.cc +++ b/src/datamap.cc @@ -1,44 +1,171 @@ -#include -#include -#include +#include +#include +#include +#include #include "datamap.h" -static std::vector> dmap; -static std::map cache; -static std::string root; +#if defined(WIN32) || defined(__WIN32__) +#include +#else +#include +#endif -void datmap_reset() +static char *clean_line(char *s); + +DataMap::DataMap() +{ + strip_paths = false; +} + +void DataMap::clear() { - root.clear(); dmap.clear(); cache.clear(); } -void datmap_set_path(const char *path) +void DataMap::set_path(const char *path) { root = std::string(path); } -bool datmap_load_map(const char *fname) +void DataMap::set_strip(bool s) +{ + strip_paths = s; +} + +bool DataMap::load_map(const char *fname) { std::string path = root.empty() ? fname : root + std::string("/") + fname; - return false; // TODO cont... + fname = path.c_str(); + + FILE *fp = fopen(fname, "r"); + if(!fp) { + fprintf(stderr, "failed to open data map: %s\n", fname); + return false; + } + + char buf[256]; + if(fread(buf, 1, 8, fp) < 8 || memcmp(buf, "DATAMAP0", 8) != 0) { + fprintf(stderr, "invalid datamap file: %s\n", fname); + fclose(fp); + return false; + } + + clear(); + + char *line; + int nline = 0; + while(fgets(buf, sizeof buf, fp)) { + ++nline; + line = clean_line(buf); + if(!line || !*line) continue; + + char *colon = strchr(line, ':'); + if(!colon) { + goto err; + } + *colon = 0; + + //std::pair pair; + //pair.first = std::regex(line); + std::pair pair; + pair.first = std::string(line); + + char *value = clean_line(colon + 1); + if(!value || !*value) { + goto err; + } + pair.second = std::string(value); + dmap.push_back(pair); + } + fclose(fp); + + printf("loaded datamap %s: %d mappings\n", fname, (int)dmap.size()); + return true; + +err: + fprintf(stderr, "error while parsing %s, invalid line %d: %s\n", fname, nline, line); + clear(); + fclose(fp); + return false; } -void datmap_map(const char *re, const char *path) +void DataMap::map(const char *match, const char *path) { std::pair mapping; - mapping.first = std::string(re); + mapping.first = std::string(match); mapping.second = std::string(path); - dmap.push_back(mapping); + dmap.push_back(std::move(mapping)); } -int datmap_lookup(const char *in, char *buf, int bsz) +int DataMap::lookup(const char *in, char *buf, int bsz) const { - return -1; // TODO + std::string res; + + if(strip_paths) { + const char *ptr = strrchr(in, '/'); + if(ptr) { + in = ptr + 1; + } + } + + char *inbuf = (char*)alloca(strlen(in) + 1); + strcpy(inbuf, in); + in = clean_line(inbuf); + + // first check the cache + std::map::iterator it = cache.find(in); + if(it != cache.end()) { + res = it->second; + } else { + // try matching with the available mappings + res = root.empty() ? std::string(in) : root + "/" + std::string(in); + + int num = dmap.size(); + for(int i=0; i s && isspace(*end)) --end; + if(s == end) return 0; + end[1] = 0; + + // app-specific: convert backslashes + char *c = s; + while(*c) { + if(*c == '\\') *c = '/'; + ++c; + } + + return s; }