TypedValue HHVM_FUNCTION(substr_compare,
                         const String& main_str,
                         const String& str,
                         int offset,
                         int length /* = INT_MAX */,
                         bool case_insensitivity /* = false */) {
  int s1_len = main_str.size();
  int s2_len = str.size();

  if (length <= 0) {
    raise_warning("The length must be greater than zero");
    return make_tv<KindOfBoolean>(false);
  }

  if (offset < 0) {
    offset = s1_len + offset;
    if (offset < 0) offset = 0;
  }

  if (offset >= s1_len) {
    raise_warning("The start position cannot exceed initial string length");
    return make_tv<KindOfBoolean>(false);
  }

  int cmp_len = s1_len - offset;
  if (cmp_len < s2_len) cmp_len = s2_len;
  if (cmp_len > length) cmp_len = length;

  const char *s1 = main_str.data();
  if (case_insensitivity) {
    return tvReturn(bstrcasecmp(s1 + offset, cmp_len, str.data(), cmp_len));
  }
  return tvReturn(string_ncmp(s1 + offset, str.data(), cmp_len));
}