bool tryParseTimeString()

in velox/type/TimestampConversion.cpp [267:359]


bool tryParseTimeString(
    const char* buf,
    size_t len,
    size_t& pos,
    int64_t& result,
    bool strict) {
  int32_t hour = -1, min = -1, sec = -1, micros = -1;
  pos = 0;

  if (len == 0) {
    return false;
  }

  // Skip leading spaces.
  while (pos < len && characterIsSpace(buf[pos])) {
    pos++;
  }

  if (pos >= len) {
    return false;
  }

  if (!characterIsDigit(buf[pos])) {
    return false;
  }

  if (!parseDoubleDigit(buf, len, pos, hour)) {
    return false;
  }
  if (hour < 0 || hour >= 24) {
    return false;
  }

  if (pos >= len) {
    return false;
  }

  // Fetch the separator.
  int sep = buf[pos++];
  if (sep != ':') {
    // Invalid separator.
    return false;
  }

  if (!parseDoubleDigit(buf, len, pos, min)) {
    return false;
  }
  if (min < 0 || min >= 60) {
    return false;
  }

  if (pos >= len) {
    return false;
  }

  if (buf[pos++] != sep) {
    return false;
  }

  if (!parseDoubleDigit(buf, len, pos, sec)) {
    return false;
  }
  if (sec < 0 || sec > 60) {
    return false;
  }

  micros = 0;
  if (pos < len && buf[pos] == '.') {
    pos++;
    // We expect microseconds.
    int32_t mult = 100000;
    for (; pos < len && characterIsDigit(buf[pos]); pos++, mult /= 10) {
      if (mult > 0) {
        micros += (buf[pos] - '0') * mult;
      }
    }
  }

  // In strict mode, check remaining string for non-space characters.
  if (strict) {
    // Skip trailing spaces.
    while (pos < len && characterIsSpace(buf[pos])) {
      pos++;
    }

    // Check position. If end was not reached, non-space chars remaining.
    if (pos < len) {
      return false;
    }
  }
  result = fromTime(hour, min, sec, micros);
  return true;
}