Example #1
0
bool StringData::isInteger() const {
    if (m_hash < 0) return false;
    int64_t lval;
    double dval;
    DataType ret = isNumericWithVal(lval, dval, 0);
    switch (ret) {
    case KindOfNull:
    case KindOfDouble:
        return false;
    case KindOfInt64:
        return true;
    case KindOfUninit:
    case KindOfBoolean:
    case KindOfPersistentString:
    case KindOfString:
    case KindOfPersistentArray:
    case KindOfArray:
    case KindOfObject:
    case KindOfResource:
    case KindOfRef:
    case KindOfClass:
        break;
    }
    not_reached();
}
Example #2
0
int StringData::numericCompare(const StringData *v2) const {
  ASSERT(v2);

  int64 lval1, lval2;
  double dval1, dval2;
  DataType ret1, ret2;
  if ((ret1 = isNumericWithVal(lval1, dval1, 0)) == KindOfNull ||
      (ret1 == KindOfDouble && !finite(dval1)) ||
      (ret2 = v2->isNumericWithVal(lval2, dval2, 0)) == KindOfNull ||
      (ret2 == KindOfDouble && !finite(dval2))) {
    return -2;
  }
  if (ret1 == KindOfInt64 && ret2 == KindOfInt64) {
    if (lval1 > lval2) return 1;
    if (lval1 == lval2) return 0;
    return -1;
  }
  if (ret1 == KindOfDouble && ret2 == KindOfDouble) {
    if (dval1 > dval2) return 1;
    if (dval1 == dval2) return 0;
    return -1;
  }
  if (ret1 == KindOfDouble) {
    ASSERT(ret2 == KindOfInt64);
    dval2 = (double)lval2;
  } else {
    ASSERT(ret1 == KindOfInt64);
    ASSERT(ret2 == KindOfDouble);
    dval1 = (double)lval1;
  }

  if (dval1 > dval2) return 1;
  if (dval1 == dval2) return 0;
  return -1;
}
Example #3
0
void StringData::setStatic() const {
  _count = (1 << 30);
  ASSERT(!isShared()); // because we are gonna reuse the space!
  m_hash = hash_string(data(), size());
  ASSERT(m_hash >= 0);
  int64 lval; double dval;
  if (isNumericWithVal(lval, dval, 1) == KindOfNull) {
    m_hash |= (1ull << 63);
  }
}
Example #4
0
void StringData::preCompute() const {
  assert(!isShared()); // because we are gonna reuse the space!
  StringSlice s = slice();
  m_hash = hash_string(s.ptr, s.len);
  assert(m_hash >= 0);
  int64_t lval; double dval;
  if (isNumericWithVal(lval, dval, 1) == KindOfNull) {
    m_hash |= STRHASH_MSB;
  }
}
Example #5
0
void StringData::preCompute() const {
  ASSERT(!isShared()); // because we are gonna reuse the space!
  // We don't want to collect taint for a hash
  StringSlice s = slice();
  m_hash = hash_string(s.ptr, s.len);
  ASSERT(m_hash >= 0);
  int64 lval; double dval;
  if (isNumericWithVal(lval, dval, 1) == KindOfNull) {
    m_hash |= STRHASH_MSB;
  }
}
Example #6
0
bool StringData::isInteger() const {
  if (m_hash < 0) return false;
  int64 lval; double dval;
  DataType ret = isNumericWithVal(lval, dval, 0);
  switch (ret) {
  case KindOfNull:   return false;
  case KindOfInt64:  return true;
  case KindOfDouble: return false;
  default:
    ASSERT(false);
    break;
  }
  return false;
}
Example #7
0
int64 StringData::hashForIntSwitch(int64 firstNonZero, int64 noMatch) const {
  int64 lval; double dval;
  DataType ret = isNumericWithVal(lval, dval, 1);
  switch (ret) {
  case KindOfNull:
    // if the string is not a number, it matches 0
    return 0;
  case KindOfInt64:
    return lval;
  case KindOfDouble:
    return Variant::DoubleHashForIntSwitch(dval, noMatch);
  default:
    break;
  }
  ASSERT(false);
  return 0;
}
Example #8
0
int StringData::numericCompare(const StringData *v2) const {
  assert(v2);

  int oflow1, oflow2;
  int64_t lval1, lval2;
  double dval1, dval2;
  DataType ret1, ret2;
  if ((ret1 = isNumericWithVal(lval1, dval1, 0, &oflow1)) == KindOfNull ||
      (ret1 == KindOfDouble && !finite(dval1)) ||
      (ret2 = v2->isNumericWithVal(lval2, dval2, 0, &oflow2)) == KindOfNull ||
      (ret2 == KindOfDouble && !finite(dval2))) {
    return -2;
  }
  if (oflow1 && oflow1 == oflow2 && dval1 == dval2) {
    return -2; // overflow in same direction, comparison will be inaccurate
  }
  if (ret1 == KindOfInt64 && ret2 == KindOfInt64) {
    if (lval1 > lval2) return 1;
    if (lval1 == lval2) return 0;
    return -1;
  }
  if (ret1 == KindOfDouble && ret2 == KindOfDouble) {
    if (dval1 > dval2) return 1;
    if (dval1 == dval2) return 0;
    return -1;
  }
  if (ret1 == KindOfDouble) {
    assert(ret2 == KindOfInt64);
    if (oflow1) {
      return oflow1;
    }
    dval2 = (double)lval2;
  } else {
    assert(ret1 == KindOfInt64);
    assert(ret2 == KindOfDouble);
    if (oflow2) {
      return -oflow2;
    }
    dval1 = (double)lval1;
  }

  if (dval1 > dval2) return 1;
  if (dval1 == dval2) return 0;
  return -1;
}
Example #9
0
int64 StringData::hashForStringSwitch(
    int64 firstTrueCaseHash,
    int64 firstNullCaseHash,
    int64 firstFalseCaseHash,
    int64 firstZeroCaseHash,
    int64 firstHash,
    int64 noMatchHash,
    bool &needsOrder) const {
  int64 lval; double dval;
  DataType ret = isNumericWithVal(lval, dval, 1);
  needsOrder = false;
  switch (ret) {
  case KindOfNull:
    return empty() ? firstNullCaseHash : hash();
  case KindOfInt64:
    return lval;
  case KindOfDouble:
    return (int64) dval;
  default:
    break;
  }
  ASSERT(false);
  return 0;
}
Example #10
0
DataType StringData::toNumeric(int64_t &lval, double &dval) const {
  if (m_hash < 0) return KindOfString;
  DataType ret = isNumericWithVal(lval, dval, 0);
  if (ret == KindOfInt64 || ret == KindOfDouble) return ret;
  return KindOfString;
}