github.com/igggame/nebulas-go@v2.1.0+incompatible/nf/nvm/v8/samples/memory_modules.cc (about) 1 // Copyright (C) 2017 go-nebulas authors 2 // 3 // This file is part of the go-nebulas library. 4 // 5 // the go-nebulas library is free software: you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // the go-nebulas library is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with the go-nebulas library. If not, see 17 // <http://www.gnu.org/licenses/>. 18 // 19 20 #include "memory_modules.h" 21 #include "../lib/logger.h" 22 23 #include <atomic> 24 #include <mutex> 25 #include <sstream> 26 #include <string> 27 #include <unordered_map> 28 #include <vector> 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <string.h> 33 34 using namespace std; 35 36 typedef struct { 37 string source; 38 int lineOffset; 39 } SourceInfo; 40 41 static std::mutex m; 42 static std::unordered_map<string, SourceInfo> modules; 43 44 void reformatModuleId(char *dst, const char *src) { 45 string s = src; 46 string delimiter = "/"; 47 48 vector<string> paths; 49 50 size_t pos = 0; 51 while ((pos = s.find(delimiter)) != std::string::npos) { 52 string p = s.substr(0, pos); 53 s.erase(0, pos + delimiter.length()); 54 55 if (p.length() == 0 || p.compare(".") == 0) { 56 continue; 57 } 58 59 if (p.compare("..") == 0) { 60 if (paths.size() > 0) { 61 paths.pop_back(); 62 continue; 63 } 64 } 65 paths.push_back(p); 66 } 67 paths.push_back(s); 68 69 std::stringstream ss; 70 for (size_t i = 0; i < paths.size(); ++i) { 71 if (i != 0) 72 ss << "/"; 73 ss << paths[i]; 74 } 75 76 strcpy(dst, ss.str().c_str()); 77 } 78 79 char *RequireDelegateFunc(void *handler, const char *filepath, 80 size_t *lineOffset) { 81 // LogInfof("RequireDelegateFunc: %s -> %s", "", filepath); 82 83 char id[128]; 84 sprintf(id, "%zu:%s", (uintptr_t)handler, filepath); 85 86 char *ret = NULL; 87 *lineOffset = 0; 88 89 m.lock(); 90 auto it = modules.find(string(id)); 91 if (it != modules.end()) { 92 SourceInfo &srcInfo = it->second; 93 ret = (char *)calloc(srcInfo.source.length() + 1, sizeof(char)); 94 strncpy(ret, srcInfo.source.c_str(), srcInfo.source.length()); 95 *lineOffset = srcInfo.lineOffset; 96 } 97 m.unlock(); 98 99 return ret; 100 } 101 102 char *AttachLibVersionDelegateFunc(void *handler, const char *libname) { 103 char *path = (char *)calloc(128, sizeof(char)); 104 if (strncmp(libname, "lib/", 4) == 0) { 105 sprintf(path, "lib/1.0.0/%s", libname + 4); 106 } else { 107 sprintf(path, "1.0.0/%s", libname); 108 } 109 LogDebugf("AttachLibVersion: %s -> %s", libname, path); 110 return path; 111 } 112 113 void AddModule(void *handler, const char *filename, const char *source, 114 int lineOffset) { 115 char filepath[128]; 116 if (strncmp(filename, "/", 1) != 0 && strncmp(filename, "./", 2) != 0 && 117 strncmp(filename, "../", 3) != 0) { 118 sprintf(filepath, "lib/%s", filename); 119 reformatModuleId(filepath, filepath); 120 } else { 121 reformatModuleId(filepath, filename); 122 } 123 LogDebugf("AddModule: %s -> %s %d", filename, filepath, lineOffset); 124 125 char id[128]; 126 sprintf(id, "%zu:%s", (uintptr_t)handler, filepath); 127 128 m.lock(); 129 SourceInfo srcInfo; 130 srcInfo.lineOffset = lineOffset; 131 srcInfo.source = source; 132 modules[string(id)] = srcInfo; 133 m.unlock(); 134 } 135 136 char *GetModuleSource(void *handler, const char *filename) { 137 char filepath[128]; 138 if (strncmp(filename, "/", 1) != 0 && strncmp(filename, "./", 2) != 0 && 139 strncmp(filename, "../", 3) != 0) { 140 sprintf(filepath, "lib/%s", filename); 141 reformatModuleId(filepath, filepath); 142 } else { 143 reformatModuleId(filepath, filename); 144 } 145 // LogInfof("GetModule: %s -> %s", filename, filepath); 146 147 size_t size = 0; 148 return RequireDelegateFunc(handler, filepath, &size); 149 }