예제 #1
0
const GzipHeaderCodec::ZlibContext* GzipHeaderCodec::getZlibContext(
    SPDYVersionSettings versionSettings, int compressionLevel) {
  static folly::ThreadLocal<ZlibContextMap> zlibContexts_;
  ZlibConfig zlibConfig(versionSettings.version, compressionLevel);
  auto match = zlibContexts_->find(zlibConfig);
  if (match != zlibContexts_->end()) {
    return match->second.get();
  } else {
    // This is the first request for the specified SPDY version and compression
    // level in this thread, so we need to construct the initial compressor and
    // decompressor contexts.
    auto newContext = folly::make_unique<ZlibContext>();
    newContext->deflater.zalloc = Z_NULL;
    newContext->deflater.zfree = Z_NULL;
    newContext->deflater.opaque = Z_NULL;
    newContext->deflater.avail_in = 0;
    newContext->deflater.next_in = Z_NULL;
    int windowBits  = (compressionLevel == Z_NO_COMPRESSION) ? 8 : 11;
    int r = deflateInit2(
        &(newContext->deflater),
        compressionLevel,
        Z_DEFLATED, // compression method
        windowBits, // log2 of the compression window size, negative value
                    // means raw deflate output format w/o libz header
        1,          // memory size for internal compression state, 1-9
        Z_DEFAULT_STRATEGY);
    CHECK(r == Z_OK);
    if (compressionLevel != Z_NO_COMPRESSION) {
      r = deflateSetDictionary(&(newContext->deflater), versionSettings.dict,
                               versionSettings.dictSize);
      CHECK(r == Z_OK);
    }

    newContext->inflater.zalloc = Z_NULL;
    newContext->inflater.zfree = Z_NULL;
    newContext->inflater.opaque = Z_NULL;
    newContext->inflater.avail_in = 0;
    newContext->inflater.next_in = Z_NULL;
    r = inflateInit(&(newContext->inflater));
    CHECK(r == Z_OK);

    auto result = newContext.get();
    zlibContexts_->emplace(zlibConfig, std::move(newContext));
    return result;
  }
}
예제 #2
0
bool SPDYUtil::hasGzipAndDeflate(const std::string& value, bool& hasGzip,
                                 bool& hasDeflate) {
  static folly::ThreadLocal<std::vector<RFC2616::TokenQPair>> output;
  output->clear();
  hasGzip = false;
  hasDeflate = false;
  RFC2616::parseQvalues(value, *output);
  for (const auto& encodingQ: *output) {
    std::string lower(encodingQ.first.str());
    std::transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
    // RFC says 3 sig figs
    if (lower == "gzip" && encodingQ.second >= 0.001) {
      hasGzip = true;
    } else if (lower == "deflate" && encodingQ.second >= 0.001) {
      hasDeflate = true;
    }
  }
  return hasGzip && hasDeflate;
}
예제 #3
0
bool parseQvalues(folly::StringPiece value, std::vector<TokenQPair> &output) {
  bool result = true;
  static folly::ThreadLocal<std::vector<folly::StringPiece>> tokens;
  tokens->clear();
  folly::split(",", value, *tokens, true /*ignore empty*/);
  for (auto& token: *tokens) {
    auto pos = token.find(';');
    double qvalue = 1.0;
    if (pos != std::string::npos) {
      auto qpos = token.find("q=", pos);
      if (qpos != std::string::npos) {
        folly::StringPiece qvalueStr(token.data() + qpos + 2,
                                     token.size() - (qpos + 2));
        try {
          qvalue = folly::to<double>(&qvalueStr);
        } catch (const std::range_error&) {
          // q=<some garbage>
          result = false;
        }
        // we could validate that the remainder of qvalueStr was all whitespace,
        // for now we just discard it
      } else {
        // ; but no q=
        result = false;
      }
      token.reset(token.start(), pos);
    }
    // strip leading whitespace
    while (token.size() > 0 && isspace(token[0])) {
      token.reset(token.start() + 1, token.size() - 1);
    }
    if (token.size() == 0) {
      // empty token
      result = false;
    } else {
      output.emplace_back(token, qvalue);
    }
  }
  return result && output.size() > 0;
}
void QueuedImmediateExecutor::addStatic(Func callback) {
    static folly::ThreadLocal<std::queue<Func>> q_;

    if (q_->empty()) {
        q_->push(std::move(callback));
        while (!q_->empty()) {
            q_->front()();
            q_->pop();
        }
    } else {
        q_->push(callback);
    }
}
예제 #5
0
파일: Random.cpp 프로젝트: 1Hgm/folly
ThreadLocalPRNG::ThreadLocalPRNG() {
  static folly::ThreadLocal<ThreadLocalPRNG::LocalInstancePRNG> localInstance;
  local_ = localInstance.get();
}
예제 #6
0
void useA() {
  a->use();
}