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  }