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; }
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; }
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'); }
double prettyToDouble(folly::StringPiece prettyString, const PrettyType type){ double result = prettyToDouble(&prettyString, type); detail::enforceWhitespace(prettyString.data(), prettyString.data() + prettyString.size()); return result; }
// 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; }
LuaPrimitiveObject makePrimitive(folly::StringPiece val) { LuaPrimitiveObject pobj; pobj.__isset.stringVal = true; pobj.stringVal.assign(val.data(), val.size()); return pobj; }
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()); }
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; }
uint64_t RendezvousHash::computeHash(folly::StringPiece key) const { return folly::hash::fnv64_buf(key.data(), key.size()); }
LuaObject make(folly::StringPiece val) { LuaObject obj; obj.value.__isset.stringVal = true; obj.value.stringVal.assign(val.data(), val.size()); return obj; }