File: //proc/self/root/usr/include/hphp/runtime/base/zend-string.h
/*
+----------------------------------------------------------------------+
| HipHop for PHP |
+----------------------------------------------------------------------+
| Copyright (c) 2010-present Facebook, Inc. (http://www.facebook.com) |
| Copyright (c) 1998-2010 Zend Technologies Ltd. (http://www.zend.com) |
+----------------------------------------------------------------------+
| This source file is subject to version 2.00 of the Zend license, |
| that is bundled with this package in the file LICENSE, and is |
| available through the world-wide-web at the following url: |
| http://www.zend.com/license/2_00.txt. |
| If you did not receive a copy of the Zend license and are unable to |
| obtain it through the world-wide-web, please send a note to |
| license@zend.com so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
*/
#ifndef incl_HPHP_ZEND_STRING_H_
#define incl_HPHP_ZEND_STRING_H_
#include "hphp/zend/zend-string.h"
#include "hphp/runtime/base/type-string.h"
namespace HPHP {
///////////////////////////////////////////////////////////////////////////////
/**
* Low-level string functions PHP uses.
*
* 1. If a function returns a char *, it has malloc-ed a new string and it's
* caller's responsibility to free it.
*
* 2. If a function takes "int &len" right after the 1st string parameter, it
* is input string's length, and in return, it's return string's length.
*
* 3. All functions work with binary strings and all returned strings are
* NULL terminated, regardless of whether it's a binary string.
*/
/*
* Copy src to string dst of size siz. At most siz-1 characters
* will be copied. Always NUL terminates (unless siz == 0).
* Returns strlen(src); if retval >= siz, truncation occurred.
*/
int string_copy(char *dst, const char *src, int siz);
/**
* Compare two binary strings.
*/
inline int string_strcmp(const char *s1, int len1, const char *s2, int len2) {
int minlen = len1 < len2 ? len1 : len2;
int retval;
retval = memcmp(s1, s2, minlen);
if (!retval) {
return (len1 - len2);
}
return (retval > 0) - (retval < 0);
}
/**
* Compare two binary strings of the first n bytes.
*/
inline int string_strncmp(const char *s1, int len1, const char *s2, int len2,
int len) {
int minlen = len1 < len2 ? len1 : len2;
int retval;
if (len < minlen) {
if (UNLIKELY(len < 0)) len = 0;
minlen = len;
}
retval = memcmp(s1, s2, minlen);
if (!retval) {
return (len < len1 ? len : len1) - (len < len2 ? len : len2);
} else {
return retval;
}
}
/**
* Compare two binary strings of the first n bytes, ignore case.
*/
inline int string_strncasecmp(const char *s1, int len1,
const char *s2, int len2, int len) {
int minlen = len1 < len2 ? len1 : len2;
int c1, c2;
if (len < minlen) {
if (UNLIKELY(len < 0)) len = 0;
minlen = len;
}
while (minlen--) {
c1 = tolower((int)*(unsigned char *)s1++);
c2 = tolower((int)*(unsigned char *)s2++);
if (c1 != c2) {
return c1 - c2;
}
}
return (len < len1 ? len : len1) - (len < len2 ? len : len2);
}
/**
* Compare strings.
*/
int string_ncmp(const char *s1, const char *s2, int len);
int string_natural_cmp(char const *a, size_t a_len,
char const *b, size_t b_len, int fold_case);
/**
* Changing string's cases in place. Return's length is always the same
* as "len".
*/
void string_to_case(String& s, int (*tocase)(int));
// Use lambdas wrapping the ctype.h functions because of linker weirdness on
// OS X Mavericks.
#define string_to_upper(s) \
string_to_case((s), [] (int i) -> int { return toupper(i); })
/**
* Pad a string with pad_string to pad_length. "len" is
* input string's length, and in return, it's trimmed string's length. pad_type
* can be k_STR_PAD_RIGHT, k_STR_PAD_LEFT or k_STR_PAD_BOTH.
*/
String string_pad(const char *input, int len, int pad_length,
const char *pad_string, int pad_str_len, int pad_type);
/**
* Find a character or substring and return it's position (or -1 if not found).
*/
int string_find(const char *input, int len, char ch, int pos,
bool case_sensitive);
int string_rfind(const char *input, int len, char ch, int pos,
bool case_sensitive);
int string_find(const char *input, int len, const char *s, int s_len,
int pos, bool case_sensitive);
int string_rfind(const char *input, int len, const char *s, int s_len,
int pos, bool case_sensitive);
const char *string_memnstr(const char *haystack, const char *needle,
int needle_len, const char *end);
/**
* Replace specified substring or search string with specified replacement.
*/
String string_replace(const char *s, int len, int start, int length,
const char *replacement, int len_repl);
String string_replace(const char *input, int len,
const char *search, int len_search,
const char *replacement, int len_replace,
int &count, bool case_sensitive);
/**
* Replace a substr with another and return replaced one. Note, read
* http://www.php.net/substr about meanings of negative start or length.
*
* The form that takes a "count" reference will still replace all occurrences
* and return total replaced count in the out parameter. It does NOT mean
* it will replace at most that many occurrences, so count's input value
* is never checked.
*/
inline String string_replace(const String& str, int start, int length,
const String& repl) {
return string_replace(str.data(), str.size(), start, length,
repl.data(), repl.size());
}
inline String string_replace(const String& str, const String& search,
const String& replacement,
int &count, bool caseSensitive) {
count = 0;
if (!search.empty() && !str.empty()) {
auto ret = string_replace(str.data(), str.size(),
search.data(), search.size(),
replacement.data(), replacement.size(),
count, caseSensitive);
if (!ret.isNull()) {
return ret;
}
}
return str;
}
inline String string_replace(const String& str, const String& search,
const String& replacement) {
int count;
return string_replace(str, search, replacement, count, true);
}
/**
* Reverse, repeat or shuffle a string.
*/
String string_chunk_split(const char *src, int srclen, const char *end,
int endlen, int chunklen);
/**
* Strip HTML and PHP tags.
*/
String string_strip_tags(const char *s, int len, const char *allow,
int allow_len, bool allow_tag_spaces);
/**
* Encoding/decoding strings according to certain formats.
*/
String string_quoted_printable_encode(const char *input, int len);
String string_quoted_printable_decode(const char *input, int len, bool is_q);
String string_uuencode(const char *src, int src_len);
String string_uudecode(const char *src, int src_len);
String string_base64_encode(const char *input, int len);
String string_base64_decode(const char *input, int len, bool strict);
String string_escape_shell_arg(const char *str);
String string_escape_shell_cmd(const char *str);
std::string base64_encode(const char *input, int len);
std::string base64_decode(const char *input, int len, bool strict);
/**
* Convert between strings and numbers.
*/
inline bool string_validate_base(int base) {
return (2 <= base && base <= 36);
}
Variant string_base_to_numeric(const char *s, int len, int base);
String string_long_to_base(unsigned long value, int base);
String string_numeric_to_base(const Variant& value, int base);
/**
* Translates characters in str_from into characters in str_to one by one,
* assuming str_from and str_to have the same length of "trlen".
*/
void string_translate(char *str, int len, const char *str_from,
const char *str_to, int trlen);
/**
* Formatting.
*/
String string_money_format(const char *format, double value);
String string_number_format(double d, int dec,
const String& dec_point,
const String& thousand_sep);
/**
* Similarity and other properties of strings.
*/
int string_levenshtein(const char *s1, int l1, const char *s2, int l2,
int cost_ins, int cost_rep, int cost_del);
int string_similar_text(const char *t1, int len1,
const char *t2, int len2, float *percent);
String string_soundex(const String& str);
String string_metaphone(const char *input, int word_len, long max_phonemes,
int traditional);
/**
* Locale strings.
*/
String string_convert_cyrillic_string(const String& input, char from, char to);
String string_convert_hebrew_string(const String& str, int max_chars_per_line,
int convert_newlines);
///////////////////////////////////////////////////////////////////////////////
// helpers
/**
* Fills a 256-byte bytemask with input. You can specify a range like 'a..z',
* it needs to be incrementing. This function determines how "charlist"
* parameters are interpreted in varies functions that take a list of
* characters.
*/
void string_charmask(const char *input, int len, char *mask);
///////////////////////////////////////////////////////////////////////////////
}
#endif // incl_HPHP_ZEND_STRING_H_