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); }
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); }