Esempio n. 1
0
Variant f_gzencode(CStrRef data, int level /* = -1 */,
                   int encoding_mode /* = k_FORCE_GZIP */) {
  int len = data.size();
  char *ret = gzencode(data.data(), len, level, encoding_mode);
  if (ret == NULL) {
    return false;
  }
  return String(ret, len, AttachString);
}
Esempio n. 2
0
void FileCache::write(const char *name, const char *fullpath) {
  assert(name && *name);
  assert(fullpath && *fullpath);
  assert(!exists(name));

  struct stat sb;
  if (stat(fullpath, &sb) != 0) {
    throw Exception("Unable to stat %s: %s", fullpath,
                    Util::safe_strerror(errno).c_str());
  }
  int len = sb.st_size;
  Buffer &buffer = m_files[name];
  buffer.len = len; // static file
  buffer.data = nullptr;
  buffer.clen = -1;
  buffer.cdata = nullptr;

  if (len) {
    FILE *f = fopen(fullpath, "r");
    if (f == nullptr) {
      throw Exception("Unable to open %s: %s", fullpath,
                      Util::safe_strerror(errno).c_str());
    }

    char *buf = buffer.data = (char *)malloc(len);
    if (!read_bytes(f, buf, len)) {
      throw Exception("Unable to read all bytes from %s", fullpath);
    }
    fclose(f);

    if (is_compressible_file(name)) {
      int new_len = buffer.len;
      char *compressed = gzencode(buffer.data, new_len, 9, CODING_GZIP);
      if (compressed && new_len < ((buffer.len * 3) / 4)) {
        buffer.clen = new_len;
        buffer.cdata = compressed;
      } else {
        free(compressed);
      }
    }
  }

  writeDirectories(name);
}
void DynamicContentCache::store(const std::string &name, const char *data,
                                int size) {
  assert(!name.empty());
  assert(size > 0);

  ResourceFilePtr f(new ResourceFile());
  CstrBufferPtr sb(new CstrBuffer(size));
  sb->append(data, size); // makes a copy
  f->file = sb;
  int len = sb->size();
  char *compressed = gzencode(sb->data(), len, 9, CODING_GZIP);
  if (compressed) {
    if (unsigned(len) < sb->size()) {
      f->compressed = CstrBufferPtr(new CstrBuffer(compressed, len));
    } else {
      free(compressed);
    }
  }

  WriteLock lock(m_mutex);
  if (m_files.find(name) == m_files.end()) {
    m_files[name] = f;
  }
}
void DynamicContentCache::store(const std::string &name, const char *data,
                                int size) {
  assert(!name.empty());
  assert(size > 0);

  auto const f = std::make_shared<ResourceFile>();
  auto const sb = std::make_shared<CstrBuffer>(size);
  sb->append(StringSlice{data, static_cast<uint32_t>(size)}); // makes a copy
  f->file = sb;
  int len = sb->size();
  char *compressed = gzencode(sb->data(), len, 9, CODING_GZIP);
  if (compressed) {
    if (unsigned(len) < sb->size()) {
      f->compressed = std::make_shared<CstrBuffer>(compressed, len);
    } else {
      free(compressed);
    }
  }

  WriteLock lock(m_mutex);
  if (m_files.find(name) == m_files.end()) {
    m_files[name] = f;
  }
}
void StaticContentCache::load() {
  Timer timer(Timer::WallTime, "loading static content");

  if (!RuntimeOption::FileCache.empty()) {
    TheFileCache = FileCachePtr(new FileCache());
    TheFileCache->load(RuntimeOption::FileCache.c_str());
    Logger::Info("loaded file cache from %s",
                 RuntimeOption::FileCache.c_str());
    return;
  }

  int rootSize = RuntimeOption::SourceRoot.size();
  if (rootSize == 0) return;

  // get a list of all files, one for each extension
  Logger::Info("searching all files under source root...");
  int count = 0;
  map<string, vector<string> > ext2files;
  {
    const char *argv[] = {"", (char*)RuntimeOption::SourceRoot.c_str(),
                          "-type", "f", NULL};
    string files;
    vector<string> out;
    Process::Exec("find", argv, NULL, files);
    Util::split('\n', files.c_str(), out, true);
    for (unsigned int i = 0; i < out.size(); i++) {
      const string &name = out[i];
      size_t pos = name.rfind('.');
      if (pos != string::npos) {
        ext2files[name.substr(pos+1)].push_back(name);
        ++count;
      }
    }
  }

  Logger::Info("analyzing %d files under source root...", count);
  for (map<string, string>::const_iterator iter =
         RuntimeOption::StaticFileExtensions.begin();
       iter != RuntimeOption::StaticFileExtensions.end(); ++iter) {
    if (ext2files.find(iter->first) == ext2files.end()) {
      continue;
    }
    const vector<string> &out = ext2files[iter->first];

    int total = 0;
    for (unsigned int i = 0; i < out.size(); i++) {
      ResourceFilePtr f(new ResourceFile());

      StringBufferPtr sb(new StringBuffer(out[i].c_str()));
      if (sb->valid() && sb->size() > 0) {
        string url = out[i].substr(rootSize + 1);
        f->file = sb;
        m_files[url] = f;

        // prepare gzipped content, skipping image and swf files
        if (iter->second.find("image/") != 0 && iter->first != "swf") {
          int len = sb->size();
          char *data = gzencode(sb->data(), len, 9, CODING_GZIP);
          if (data) {
            if (len < sb->size()) {
              f->compressed = StringBufferPtr(new StringBuffer(data, len));
            } else {
              free(data);
            }
          }
        }

        total += sb->size();
      }
    }
    Logger::Info("..loaded %d bytes of %s files", total, iter->first.c_str());
    m_totalSize += total;
  }
  Logger::Info("loaded %d bytes of static content in total", m_totalSize);
}