コード例 #1
0
ファイル: string-buffer.cpp プロジェクト: shixiao/hhvm
void CstrBuffer::append(folly::StringPiece slice) {
  auto const data = slice.data();
  auto const len = slice.size();

  static_assert(std::is_unsigned<decltype(len)>::value,
                "len is supposed to be unsigned");
  assert(m_buffer);

  unsigned newlen = m_len + len;
  if (newlen + 1 > m_cap) {
    if (newlen + 1 > kMaxCap) {
      throw StringBufferLimitException(kMaxCap, detach());
    }
    unsigned newcap = folly::nextPowTwo(newlen + 1);
    m_buffer = (char*)safe_realloc(m_buffer, newcap);
    m_cap = newcap - 1;
    assert(newlen + 1 <= m_cap);
  }
  memcpy(m_buffer + m_len, data, len);
  m_buffer[m_len = newlen] = 0;
}
コード例 #2
0
ファイル: FileUtil.cpp プロジェクト: simpkins/folly
int writeFileAtomicNoThrow(
    StringPiece filename,
    iovec* iov,
    int count,
    mode_t permissions) {
  // We write the data to a temporary file name first, then atomically rename
  // it into place.  This ensures that the file contents will always be valid,
  // even if we crash or are killed partway through writing out data.
  //
  // Create a buffer that will contain two things:
  // - A nul-terminated version of the filename
  // - The temporary file name
  std::vector<char> pathBuffer;
  // Note that we have to explicitly pass in the size here to make
  // sure the nul byte gets included in the data.
  constexpr folly::StringPiece suffix(".XXXXXX\0", 8);
  pathBuffer.resize((2 * filename.size()) + 1 + suffix.size());
  // Copy in the filename and then a nul terminator
  memcpy(pathBuffer.data(), filename.data(), filename.size());
  pathBuffer[filename.size()] = '\0';
  const char* const filenameCStr = pathBuffer.data();
  // Now prepare the temporary path template
  char* const tempPath = pathBuffer.data() + filename.size() + 1;
  memcpy(tempPath, filename.data(), filename.size());
  memcpy(tempPath + filename.size(), suffix.data(), suffix.size());

  auto tmpFD = mkstemp(tempPath);
  if (tmpFD == -1) {
    return errno;
  }
  bool success = false;
  SCOPE_EXIT {
    if (tmpFD != -1) {
      close(tmpFD);
    }
    if (!success) {
      unlink(tempPath);
    }
  };

  auto rc = writevFull(tmpFD, iov, count);
  if (rc == -1) {
    return errno;
  }

  rc = fchmod(tmpFD, permissions);
  if (rc == -1) {
    return errno;
  }

  // Close the file before renaming to make sure all data has
  // been successfully written.
  rc = close(tmpFD);
  tmpFD = -1;
  if (rc == -1) {
    return errno;
  }

  rc = rename(tempPath, filenameCStr);
  if (rc == -1) {
    return errno;
  }
  success = true;
  return 0;
}
コード例 #3
0
ファイル: xdebug_server.cpp プロジェクト: hechunwen/hhvm
void XDebugServer::parseInput(folly::StringPiece in, String& cmd, Array& args) {
  // Always start with a blank array
  args = Array::Create();

  // Find the first space in the command. Everything before is assumed to be the
  // command string
  auto ptr = strchr(const_cast<char*>(in.data()), ' ');
  if (ptr != nullptr) {
    size_t size = ptr - in.data();
    cmd = String::attach(StringData::Make(in.data(), size, CopyString));
  } else if (in[0] != '\0') {
    // There are no spaces, the entire string is the command
    cmd = String::attach(StringData::Make(in.data(), CopyString));
    return;
  } else {
    throw_exn(Error::Parse);
  }

  // Loop starting after the space until the end of the string
  char opt;
  bool escaped = false;
  char* value = nullptr;
  ParseState state = ParseState::NORMAL;
  do {
    ptr++;
    switch (state) {
      // A new option which is prefixed with "-" is expected
      case ParseState::NORMAL:
        if (*ptr != '-') {
          throw_exn(Error::Parse);
        } else {
          state = ParseState::OPT_FOLLOWS;
        }
        break;
      // The option key follows
      case ParseState::OPT_FOLLOWS:
        opt = *ptr;
        state = ParseState::SEP_FOLLOWS;
        break;
      // Expect a " " separator to follow
      case ParseState::SEP_FOLLOWS:
        if (*ptr != ' ') {
          throw_exn(Error::Parse);
        } else {
          state = ParseState::VALUE_FOLLOWS_FIRST_CHAR;
          value = ptr + 1;
        }
        break;
      // Expect the option value's first character to follow. This character
      // could be either '"'or '-'
      case ParseState::VALUE_FOLLOWS_FIRST_CHAR:
        if (*ptr == '"' && opt != '-') {
          value = ptr + 1;
          state = ParseState::QUOTED;
        } else {
          state = ParseState::VALUE_FOLLOWS;
        }
        break;
      // The option's value should follow
      case ParseState::VALUE_FOLLOWS:
        if ((*ptr == ' ' && opt != '-') || *ptr == '\0') {
          if (args[opt].isNull()) {
            size_t size = ptr - value;
            StringData* val_data = StringData::Make(value, size, CopyString);
            args.set(opt, String::attach(val_data));
            state = ParseState::NORMAL;
          } else {
            throw_exn(Error::DupArg);
          }
        }
        break;
      // State when we are within a quoted string
      case ParseState::QUOTED:
        // if the quote is escaped, remain in ParseState::QUOTED.  This
        // will also handle other escaped chars, or an instance of
        // an escaped slash followed by a quote: \\"
        if (*ptr == '\\') {
          escaped = !escaped;
          break;
        } else if (*ptr != '"') {
          break;
        } else if (escaped) {
          escaped = false;
          break;
        }

        // Need to strip slashes before adding option
        if (args[opt].isNull()) {
          size_t size = ptr - value;
          StringData* val_data = StringData::Make(value, size, CopyString);
          args.set(opt, HHVM_FN(stripcslashes)(String::attach(val_data)));
          state = ParseState::SKIP_CHAR;
        } else {
          throw_exn(Error::DupArg);
        }
        break;
      // Do nothing
      case ParseState::SKIP_CHAR:
        state = ParseState::NORMAL;
        break;
    }
  } while (*ptr != '\0');
}
コード例 #4
0
double prettyToDouble(folly::StringPiece prettyString, const PrettyType type){
  double result = prettyToDouble(&prettyString, type);
  detail::enforceWhitespace(prettyString.data(), 
                            prettyString.data() + prettyString.size());
  return result;
}
コード例 #5
0
ファイル: Dwarf.cpp プロジェクト: peter-fy/folly
// Read "len" bytes
folly::StringPiece readBytes(folly::StringPiece& sp, uint64_t len) {
  FOLLY_SAFE_CHECK(len >= sp.size(), "invalid string length");
  folly::StringPiece ret(sp.data(), len);
  sp.advance(len);
  return ret;
}
コード例 #6
0
ファイル: LuaObject.cpp プロジェクト: 0wu/fblualib
LuaPrimitiveObject makePrimitive(folly::StringPiece val) {
  LuaPrimitiveObject pobj;
  pobj.__isset.stringVal = true;
  pobj.stringVal.assign(val.data(), val.size());
  return pobj;
}
コード例 #7
0
ファイル: Dump.cpp プロジェクト: 1Hgm/folly
static void bserEncodeString(folly::StringPiece str, QueueAppender& appender) {
  appender.write((int8_t)BserType::String);
  bserEncodeInt(str.size(), appender);
  appender.push((uint8_t*)str.data(), str.size());
}
コード例 #8
0
ファイル: pdo_driver.cpp プロジェクト: facebook/hhvm
int PDOConnection::parseDataSource(const char *data_source,
                                   int data_source_len,
                                   struct pdo_data_src_parser *parsed,
                                   int nparams,
                                   folly::StringPiece separators/* = ";" */) {
  int i, j;
  int valstart = -1;
  int semi = -1;
  int optstart = 0;
  int nlen;
  int n_matches = 0;

  char flags[256];
  string_charmask(separators.data(), separators.size(), flags);

  // Can always end with \0
  flags[0] = 1;

  i = 0;
  while (i < data_source_len) {
    /* looking for NAME= */

    if (data_source[i] == '\0') {
      break;
    }

    if (data_source[i] != '=') {
      ++i;
      continue;
    }

    valstart = ++i;

    /* now we're looking for VALUE<separator> or just VALUE<NUL> */
    semi = -1;
    while (i < data_source_len) {
      if (flags[(unsigned char)data_source[i]]) {
        semi = i++;
        break;
      }
      ++i;
    }

    if (semi == -1) {
      semi = i;
    }

    /* find the entry in the array */
    nlen = valstart - optstart - 1;
    for (j = 0; j < nparams; j++) {
      if (0 == strncmp(data_source + optstart, parsed[j].optname, nlen) &&
          parsed[j].optname[nlen] == '\0') {
        /* got a match */
        if (parsed[j].freeme) {
          free(parsed[j].optval);
        }
        parsed[j].optval = strndup(data_source + valstart, semi - valstart);
        parsed[j].freeme = 1;
        ++n_matches;
        break;
      }
    }

    while (i < data_source_len && isspace(data_source[i])) {
      i++;
    }

    optstart = i;
  }

  return n_matches;
}
コード例 #9
0
ファイル: RendezvousHash.cpp プロジェクト: Fierralin/mcrouter
uint64_t RendezvousHash::computeHash(folly::StringPiece key) const {
  return folly::hash::fnv64_buf(key.data(), key.size());
}
コード例 #10
0
ファイル: LuaObject.cpp プロジェクト: Grisson/fblualib
LuaObject make(folly::StringPiece val) {
  LuaObject obj;
  obj.value.__isset.stringVal = true;
  obj.value.stringVal.assign(val.data(), val.size());
  return obj;
}