static void TestIntervals(void)
{
    PRStatus rv;
    PRUint32 delta;
    PRInt32 seconds;
    PRUint64 elapsed, thousand;
    PRTime timein, timeout;
    PRLock *ml = PR_NewLock();
    PRCondVar *cv = PR_NewCondVar(ml);
    for (seconds = 0; seconds < 10; ++seconds)
    {
        PRIntervalTime ticks = PR_SecondsToInterval(seconds);
        PR_Lock(ml);
        timein = PR_Now();
        rv = PR_WaitCondVar(cv, ticks);
        timeout = PR_Now();
        PR_Unlock(ml);
        LL_SUB(elapsed, timeout, timein);
        LL_I2L(thousand, 1000);
        LL_DIV(elapsed, elapsed, thousand);
        LL_L2UI(delta, elapsed);
        if (debug_mode) PR_fprintf(output, 
            "TestIntervals: %swaiting %ld seconds took %ld msecs\n",
            ((rv == PR_SUCCESS) ? "" : "FAILED "), seconds, delta);
    }
    PR_DestroyCondVar(cv);
    PR_DestroyLock(ml);
    if (debug_mode) PR_fprintf(output, "\n");
}  /* TestIntervals */
Beispiel #2
0
PRMJ_ToExtendedTime(PRInt32 time)
{
    PRInt64 exttime;
    PRInt64 g1970GMTMicroSeconds;
    PRInt64 low;
    time_t diff;
    PRInt64  tmp;
    PRInt64  tmp1;

    diff = PRMJ_LocalGMTDifference();
    LL_UI2L(tmp, PRMJ_USEC_PER_SEC);
    LL_I2L(tmp1,diff);
    LL_MUL(tmp,tmp,tmp1);

    LL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI);
    LL_UI2L(low,G1970GMTMICROLOW);
#ifndef HAVE_LONG_LONG
    LL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
    LL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
#else
    LL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);
#endif
    LL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low);

    LL_I2L(exttime,time);
    LL_ADD(exttime,exttime,g1970GMTMicroSeconds);
    LL_SUB(exttime,exttime,tmp);
    return exttime;
}
Beispiel #3
0
static SECCertTimeValidity _NSSCPY_CheckCrlTimes(CERTCrl *crl, PRTime t)
{
	PRTime notBefore, notAfter, llPendingSlop, tmp1;
	SECStatus rv;
	PRInt32 pSlop = CERT_GetSlopTime();

	rv = _NSSCPY_GetCrlTimes(crl, &notBefore, &notAfter);
	if (rv) {
		return(secCertTimeExpired);
	}
	LL_I2L(llPendingSlop, pSlop);
	/* convert to micro seconds */
	LL_I2L(tmp1, PR_USEC_PER_SEC);
	LL_MUL(llPendingSlop, llPendingSlop, tmp1);
	LL_SUB(notBefore, notBefore, llPendingSlop);
	if ( LL_CMP( t, <, notBefore ) ) {
		return(secCertTimeNotValidYet);
	}
	/* If next update is omitted and the test for notBefore passes, then
	 * we assume that the crl is up to date.
	 */
	if ( LL_IS_ZERO(notAfter) ) {
		return(secCertTimeValid);
	}
	if ( LL_CMP( t, >, notAfter) ) {
		return(secCertTimeExpired);
	}
	return(secCertTimeValid);
}
Beispiel #4
0
void nsTimelineServiceTimer::stop(PRTime now)
{
    TIMER_CHECK_OWNER();
    mRunning--;
    if (mRunning == 0) {
        PRTime delta, accum;
        LL_SUB(delta, now, mStart);
        LL_ADD(accum, mAccum, delta);
        mAccum = accum;
    }
}
Beispiel #5
0
PRUint32
deltaMicroSeconds(PRTime aStartTime, PRTime aEndTime)
{
  PRUint32 delta;
  PRUint64 loadTime64;

  LL_SUB(loadTime64, aEndTime, aStartTime);
  LL_L2UI(delta, loadTime64);

  return delta;
}
Beispiel #6
0
PRTime nsTimelineServiceTimer::getAccum(PRTime now)
{
    TIMER_CHECK_OWNER();
    PRTime accum;

    if (!mRunning) {
        accum = mAccum;
    } else {
        PRTime delta;
        LL_SUB(delta, now, mStart);
        LL_ADD(accum, mAccum, delta);
    }
    return accum;
}
Beispiel #7
0
/*
 * Make this public if we need it.
 */
static nsresult NS_TimelineMarkV(const char *text, va_list args)
{
    PRTime elapsed,tmp;

    PR_CallOnce(&initonce, TimelineInit);

    TimelineThreadData *thread = GetThisThreadData();

    tmp = Now();
    LL_SUB(elapsed, tmp, thread->initTime);

    PrintTime(elapsed, text, args);

    return NS_OK;
}
Beispiel #8
0
static PRInt64 PR_CALLBACK FileAvailable64(PRFileDesc *fd)
{
    PRInt64 result, cur, end;
    PRInt64 minus_one;

    LL_I2L(minus_one, -1);
    cur = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_CUR);

    if (LL_GE_ZERO(cur))
    	end = _PR_MD_LSEEK64(fd, LL_ZERO, PR_SEEK_END);

    if (!LL_GE_ZERO(cur) || !LL_GE_ZERO(end)) return minus_one;

    LL_SUB(result, end, cur);
    (void)_PR_MD_LSEEK64(fd, cur, PR_SEEK_SET);

    return result;
}
static void TestNowOverhead(void)
{
    PRTime timeout, timein;
    PRInt32 overhead, loops = 1000000;
    PRInt64 elapsed, per_call, ten23rd, ten26th;

    LL_I2L(ten23rd, 1000);
    LL_I2L(ten26th, 1000000);

    timein = PR_Now();
    while (--loops > 0)
        timeout = PR_Now();

    LL_SUB(elapsed, timeout, timein);
    LL_MUL(elapsed, elapsed, ten23rd);
    LL_DIV(per_call, elapsed, ten26th);
    LL_L2I(overhead, per_call);
    PR_fprintf(
        output, "Overhead of 'PR_Now()' is %u nsecs\n\n", overhead);
}  /* TestNowOverhead */
Beispiel #10
0
PRMJ_ToBaseTime(PRInt64 time)
{
    PRInt64 g1970GMTMicroSeconds;
    PRInt64 g2037GMTMicroSeconds;
    PRInt64 low;
    PRInt32 result;

    LL_UI2L(g1970GMTMicroSeconds,G1970GMTMICROHI);
    LL_UI2L(low,G1970GMTMICROLOW);
#ifndef HAVE_LONG_LONG
    LL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
    LL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,16);
#else
    LL_SHL(g1970GMTMicroSeconds,g1970GMTMicroSeconds,32);
#endif
    LL_ADD(g1970GMTMicroSeconds,g1970GMTMicroSeconds,low);

    LL_UI2L(g2037GMTMicroSeconds,G2037GMTMICROHI);
    LL_UI2L(low,G2037GMTMICROLOW);
#ifndef HAVE_LONG_LONG
    LL_SHL(g2037GMTMicroSeconds,g2037GMTMicroSeconds,16);
    LL_SHL(g2037GMTMicroSeconds,g2037GMTMicroSeconds,16);
#else
    LL_SHL(g2037GMTMicroSeconds,g2037GMTMicroSeconds,32);
#endif

    LL_ADD(g2037GMTMicroSeconds,g2037GMTMicroSeconds,low);


    if(LL_CMP(time, <, g1970GMTMicroSeconds) ||
       LL_CMP(time, >, g2037GMTMicroSeconds)){
	return -1;
    }

    LL_SUB(time,time,g1970GMTMicroSeconds);
    LL_L2I(result,time);
    return result;
}
Beispiel #11
0
/** Returns a timestamp string containing the local time, if at least
 * deltaSec seconds have elapsed since the last timestamp. Otherwise,
 * a null string is returned.
 * @param deltaSec minimum elapsed seconds since last timestamp (>=0)
 * @param lastTime in/out parameter containing time of last timestamp
 * @param aTimeStamp  returned timestamp string
 * @return NS_OK on success
 */
NS_IMETHODIMP mozXMLTermUtils::TimeStamp(PRInt32 deltaSec, PRTime& lastTime,
                                     nsString& aTimeStamp)
{
  static const PRInt32 DATE_LEN = 19;
  PRTime deltaTime ;
  char dateStr[DATE_LEN+1];
  PRTime curTime, difTime;

  curTime = PR_Now();
  LL_SUB(difTime, curTime, lastTime);

  LL_I2L(deltaTime, deltaSec*1000000);
  if (LL_CMP(difTime, <, deltaTime)) {
    // Not enough time has elapsed for a new time stamp
    aTimeStamp.SetLength(0);
    return NS_OK;
  }

  lastTime = curTime;

  // Current local time
  PRExplodedTime localTime;
  PR_ExplodeTime(curTime, PR_LocalTimeParameters, &localTime);

  PRInt32 nWritten = PR_snprintf(dateStr, DATE_LEN+1,
                     "%02d:%02d:%02d %02d/%02d/%04d", // XXX i18n!
                   localTime.tm_hour, localTime.tm_min, localTime.tm_sec,
                   localTime.tm_mday, localTime.tm_month+1, localTime.tm_year);

  if (nWritten != DATE_LEN)
    return NS_ERROR_FAILURE;

  XMLT_LOG(mozXMLTermUtils::LocalTime,99,("localTime=%s\n", dateStr));

  aTimeStamp.AssignASCII(dateStr);
  return NS_OK;
}
Beispiel #12
0
int main(int argc, char** argv)
{
  FILE* fp = fopen("words.txt", "r");
  if (nsnull == fp) {
    printf("can't open words.txt\n");
    return -1;
  }

  PRInt32 count = 0;
  PRUnichar** strings = new PRUnichar*[60000];
  nsIAtom** ids = new nsIAtom*[60000];
  nsAutoString s1, s2;
  PRTime start = PR_Now();
  PRInt32 i;
  for (i = 0; i < 60000; i++) {
    char buf[1000];
    char* s = fgets(buf, sizeof(buf), fp);
    if (nsnull == s) {
      break;
    }
    nsCAutoString sb;
    sb.Assign(buf);
    strings[count++] = ToNewUnicode(sb);
    ToUpperCase(sb);
    strings[count++] = ToNewUnicode(sb);
  }
  PRTime end0 = PR_Now();

  // Find and create idents
  for (i = 0; i < count; i++) {
    ids[i] = NS_NewAtom(strings[i]);
  }
  PRUnichar qqs[1]; qqs[0] = 0;
  nsIAtom* qq = NS_NewAtom(qqs);
  PRTime end1 = PR_Now();

  // Now make sure we can find all the idents we just made
  for (i = 0; i < count; i++) {
    const char *utf8String;
    ids[i]->GetUTF8String(&utf8String);
    nsIAtom* id = NS_NewAtom(utf8String);
    if (id != ids[i]) {
      id->ToString(s1);
      ids[i]->ToString(s2);
      printf("find failed: id='%s' ids[%d]='%s'\n",
             NS_LossyConvertUTF16toASCII(s1).get(), i, NS_LossyConvertUTF16toASCII(s2).get());
      return -1;
    }
    NS_RELEASE(id);
  }
  PRTime end2 = PR_Now();

  // Destroy all the atoms we just made
  NS_RELEASE(qq);
  for (i = 0; i < count; i++) {
    NS_RELEASE(ids[i]);
  }

  // Print out timings
  PRTime end3 = PR_Now();
  PRTime creates, finds, lookups, dtor, ustoms;
  LL_I2L(ustoms, 1000);
  LL_SUB(creates, end0, start);
  LL_DIV(creates, creates, ustoms);
  LL_SUB(finds, end1, end0);
  LL_DIV(finds, finds, ustoms);
  LL_SUB(lookups, end2, end1);
  LL_DIV(lookups, lookups, ustoms);
  LL_SUB(dtor, end3, end2);
  char buf[500];
  PR_snprintf(buf, sizeof(buf), "making %d ident strings took %lldms",
              count, creates);
  puts(buf);
  PR_snprintf(buf, sizeof(buf), "%d new idents took %lldms",
              count, finds);
  puts(buf);
  PR_snprintf(buf, sizeof(buf), "%d ident lookups took %lldms",
              count, lookups);
  puts(buf);
  PR_snprintf(buf, sizeof(buf), "dtor took %lldusec", dtor);
  puts(buf);

  printf("%d live atoms\n", NS_GetNumberOfAtoms());
  NS_POSTCONDITION(0 == NS_GetNumberOfAtoms(), "dangling atoms");

  return 0;
}
nsresult nsMsgSearchAdapter::EncodeImapTerm (nsIMsgSearchTerm *term, bool reallyDredd, const PRUnichar *srcCharset, const PRUnichar *destCharset, char **ppOutTerm)
{
  NS_ENSURE_ARG_POINTER(term);
  NS_ENSURE_ARG_POINTER(ppOutTerm);

  nsresult err = NS_OK;
  bool useNot = false;
  bool useQuotes = false;
  bool ignoreValue = false;
  nsCAutoString arbitraryHeader;
  const char *whichMnemonic = nsnull;
  const char *orHeaderMnemonic = nsnull;

  *ppOutTerm = nsnull;

  nsCOMPtr <nsIMsgSearchValue> searchValue;
  nsresult rv = term->GetValue(getter_AddRefs(searchValue));

  NS_ENSURE_SUCCESS(rv,rv);

  nsMsgSearchOpValue op;
  term->GetOp(&op);

  if (op == nsMsgSearchOp::DoesntContain || op == nsMsgSearchOp::Isnt)
    useNot = true;

  nsMsgSearchAttribValue attrib;
  term->GetAttrib(&attrib);

  switch (attrib)
  {
  case nsMsgSearchAttrib::ToOrCC:
    orHeaderMnemonic = m_kImapCC;
    // fall through to case nsMsgSearchAttrib::To:
  case nsMsgSearchAttrib::To:
    whichMnemonic = m_kImapTo;
    break;
  case nsMsgSearchAttrib::CC:
    whichMnemonic = m_kImapCC;
    break;
  case nsMsgSearchAttrib::Sender:
    whichMnemonic = m_kImapFrom;
    break;
  case nsMsgSearchAttrib::Subject:
    whichMnemonic = m_kImapSubject;
    break;
  case nsMsgSearchAttrib::Body:
    whichMnemonic = m_kImapBody;
    break;
  case nsMsgSearchAttrib::AgeInDays:  // added for searching online for age in days...
    // for AgeInDays, we are actually going to perform a search by date, so convert the operations for age
    // to the IMAP mnemonics that we would use for date!
    {
      // If we have a future date, the > and < are reversed.
      // e.g. ageInDays > 2 means more than 2 days old ("date before X") whereas
      //      ageInDays > -2 should be more than 2 days in the future ("date after X")
      PRInt32 ageInDays;
      searchValue->GetAge(&ageInDays);
      bool dateInFuture = (ageInDays < 0);
      switch (op)
      {
      case nsMsgSearchOp::IsGreaterThan:
        whichMnemonic = (!dateInFuture) ? m_kImapBefore : m_kImapSince;
        break;
      case nsMsgSearchOp::IsLessThan:
        whichMnemonic = (!dateInFuture) ? m_kImapSince : m_kImapBefore;
        break;
      case nsMsgSearchOp::Is:
        whichMnemonic = m_kImapSentOn;
        break;
      default:
        NS_ASSERTION(false, "invalid search operator");
        return NS_ERROR_INVALID_ARG;
      }
    }
    break;
  case nsMsgSearchAttrib::Size:
    switch (op)
    {
    case nsMsgSearchOp::IsGreaterThan:
      whichMnemonic = m_kImapSizeLarger;
      break;
    case nsMsgSearchOp::IsLessThan:
      whichMnemonic = m_kImapSizeSmaller;
      break;
    default:
      NS_ASSERTION(false, "invalid search operator");
      return NS_ERROR_INVALID_ARG;
    }
    break;
    case nsMsgSearchAttrib::Date:
      switch (op)
      {
      case nsMsgSearchOp::IsBefore:
        whichMnemonic = m_kImapBefore;
        break;
      case nsMsgSearchOp::IsAfter:
        whichMnemonic = m_kImapSince;
        break;
      case nsMsgSearchOp::Isnt:  /* we've already added the "Not" so just process it like it was a date is search */
      case nsMsgSearchOp::Is:
        whichMnemonic = m_kImapSentOn;
        break;
      default:
        NS_ASSERTION(false, "invalid search operator");
        return NS_ERROR_INVALID_ARG;
      }
      break;
    case nsMsgSearchAttrib::AnyText:
      whichMnemonic = m_kImapAnyText;
      break;
    case nsMsgSearchAttrib::Keywords:
      whichMnemonic = m_kImapKeyword;
      break;
    case nsMsgSearchAttrib::MsgStatus:
      useNot = false; // bizarrely, NOT SEEN is wrong, but UNSEEN is right.
      ignoreValue = true; // the mnemonic is all we need
      PRUint32 status;
      searchValue->GetStatus(&status);

      switch (status)
      {
      case nsMsgMessageFlags::Read:
        whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapSeen : m_kImapNotSeen;
        break;
      case nsMsgMessageFlags::Replied:
        whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapAnswered : m_kImapNotAnswered;
        break;
      case nsMsgMessageFlags::New:
        whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapNew : m_kImapNotNew;
        break;
      case nsMsgMessageFlags::Marked:
        whichMnemonic = op == nsMsgSearchOp::Is ? m_kImapFlagged : m_kImapNotFlagged;
        break;
      default:
        NS_ASSERTION(false, "invalid search operator");
        return NS_ERROR_INVALID_ARG;
      }
      break;
    default:
      if ( attrib > nsMsgSearchAttrib::OtherHeader && attrib < nsMsgSearchAttrib::kNumMsgSearchAttributes)
      {
        nsCString arbitraryHeaderTerm;
        term->GetArbitraryHeader(arbitraryHeaderTerm);
        if (!arbitraryHeaderTerm.IsEmpty())
        {
          arbitraryHeader.AssignLiteral(" \"");
          arbitraryHeader.Append(arbitraryHeaderTerm);
          arbitraryHeader.AppendLiteral("\" ");
          whichMnemonic = arbitraryHeader.get();
        }
        else
          return NS_ERROR_FAILURE;
      }
      else
      {
        NS_ASSERTION(false, "invalid search operator");
        return NS_ERROR_INVALID_ARG;
      }
    }

    char *value = nsnull;
    char dateBuf[100];
    dateBuf[0] = '\0';

    bool valueWasAllocated = false;
    if (attrib == nsMsgSearchAttrib::Date)
    {
      // note that there used to be code here that encoded an RFC822 date for imap searches.
      // The IMAP RFC 2060 is misleading to the point that it looks like it requires an RFC822
      // date but really it expects dd-mmm-yyyy, like dredd, and refers to the RFC822 date only in that the
      // dd-mmm-yyyy date will match the RFC822 date within the message.

      PRTime adjustedDate;
      searchValue->GetDate(&adjustedDate);
      if (whichMnemonic == m_kImapSince)
      {
        // it looks like the IMAP server searches on Since includes the date in question...
        // our UI presents Is, IsGreater and IsLessThan. For the IsGreater case (m_kImapSince)
        // we need to adjust the date so we get greater than and not greater than or equal to which
        // is what the IMAP server wants to search on
        // won't work on Mac.
        // ack, is this right? is PRTime seconds or microseconds?
        PRInt64 microSecondsPerSecond, secondsInDay, microSecondsInDay;

        LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
        LL_UI2L(secondsInDay, 60 * 60 * 24);
        LL_MUL(microSecondsInDay, secondsInDay, microSecondsPerSecond);
        LL_ADD(adjustedDate, adjustedDate, microSecondsInDay); // bump up to the day after this one...
      }

      PRExplodedTime exploded;
      PR_ExplodeTime(adjustedDate, PR_LocalTimeParameters, &exploded);
      PR_FormatTimeUSEnglish(dateBuf, sizeof(dateBuf), "%d-%b-%Y", &exploded);
      //    strftime (dateBuf, sizeof(dateBuf), "%d-%b-%Y", localtime (/* &term->m_value.u.date */ &adjustedDate));
      value = dateBuf;
    }
    else
    {
      if (attrib == nsMsgSearchAttrib::AgeInDays)
      {
        // okay, take the current date, subtract off the age in days, then do an appropriate Date search on
        // the resulting day.
        PRInt32 ageInDays;

        searchValue->GetAge(&ageInDays);

        PRTime now = PR_Now();
        PRTime matchDay;

        PRInt64 microSecondsPerSecond, secondsInDays, microSecondsInDay;

        LL_I2L(microSecondsPerSecond, PR_USEC_PER_SEC);
        LL_I2L(secondsInDays, 60 * 60 * 24 * ageInDays);
        LL_MUL(microSecondsInDay, secondsInDays, microSecondsPerSecond);

        LL_SUB(matchDay, now, microSecondsInDay); // = now - term->m_value.u.age * 60 * 60 * 24;
        PRExplodedTime exploded;
        PR_ExplodeTime(matchDay, PR_LocalTimeParameters, &exploded);
        PR_FormatTimeUSEnglish(dateBuf, sizeof(dateBuf), "%d-%b-%Y", &exploded);
        //      strftime (dateBuf, sizeof(dateBuf), "%d-%b-%Y", localtime (&matchDay));
        value = dateBuf;
      }
      else if (attrib == nsMsgSearchAttrib::Size)
      {
        PRUint32 sizeValue;
        nsCAutoString searchTermValue;
        searchValue->GetSize(&sizeValue);

        // Multiply by 1024 to get into kb resolution
        sizeValue *= 1024;

        // Ensure that greater than is really greater than
        // in kb resolution.
        if (op == nsMsgSearchOp::IsGreaterThan)
          sizeValue += 1024;

        searchTermValue.AppendInt(sizeValue);

        value = ToNewCString(searchTermValue);
        valueWasAllocated = true;
      }
      else

      if (IS_STRING_ATTRIBUTE(attrib))
      {
        PRUnichar *convertedValue; // = reallyDredd ? MSG_EscapeSearchUrl (term->m_value.u.string) : msg_EscapeImapSearchProtocol(term->m_value.u.string);
        nsString searchTermValue;
        searchValue->GetStr(searchTermValue);
        // Ugly switch for Korean mail/news charsets.
        // We want to do this here because here is where
        // we know what charset we want to use.
#ifdef DOING_CHARSET
        if (reallyDredd)
          dest_csid = INTL_DefaultNewsCharSetID(dest_csid);
        else
          dest_csid = INTL_DefaultMailCharSetID(dest_csid);
#endif

        // do all sorts of crazy escaping
        convertedValue = reallyDredd ? EscapeSearchUrl (searchTermValue.get()) :
        EscapeImapSearchProtocol(searchTermValue.get());
        useQuotes = ((!reallyDredd ||
                    (nsDependentString(convertedValue).FindChar(PRUnichar(' ')) != -1)) &&
           (attrib != nsMsgSearchAttrib::Keywords));
        // now convert to char* and escape quoted_specials
        nsCAutoString valueStr;
        nsresult rv = ConvertFromUnicode(NS_LossyConvertUTF16toASCII(destCharset).get(),
          nsDependentString(convertedValue), valueStr);
        if (NS_SUCCEEDED(rv))
        {
          const char *vptr = valueStr.get();
          // max escaped length is one extra character for every character in the cmd.
          nsAutoArrayPtr<char> newValue(new char[2*strlen(vptr) + 1]);
          if (newValue)
          {
            char *p = newValue;
            while (1)
            {
              char ch = *vptr++;
              if (!ch)
                break;
              if ((useQuotes ? ch == '"' : 0) || ch == '\\')
                *p++ = '\\';
              *p++ = ch;
            }
            *p = '\0';
            value = strdup(newValue); // realloc down to smaller size
          }
        }
        else
          value = strdup("");
        NS_Free(convertedValue);
        valueWasAllocated = true;

      }
    }

    // this should be rewritten to use nsCString
    int subLen =
      (value ? strlen(value) : 0) +
      (useNot ? strlen(m_kImapNot) : 0) +
      strlen(m_kImapHeader);
    int len = strlen(whichMnemonic) + subLen + (useQuotes ? 2 : 0) +
      (orHeaderMnemonic
       ? (subLen + strlen(m_kImapOr) + strlen(orHeaderMnemonic) + 2 /*""*/)
       : 0) +
      10; // add slough for imap string literals
    char *encoding = new char[len];
    if (encoding)
    {
      encoding[0] = '\0';
      // Remember: if ToOrCC and useNot then the expression becomes NOT To AND Not CC as opposed to (NOT TO) || (NOT CC)
      if (orHeaderMnemonic && !useNot)
        PL_strcat(encoding, m_kImapOr);
      if (useNot)
        PL_strcat (encoding, m_kImapNot);
      if (!arbitraryHeader.IsEmpty())
        PL_strcat (encoding, m_kImapHeader);
      PL_strcat (encoding, whichMnemonic);
      if (!ignoreValue)
        err = EncodeImapValue(encoding, value, useQuotes, reallyDredd);

      if (orHeaderMnemonic)
      {
        if (useNot)
          PL_strcat(encoding, m_kImapNot);

        PL_strcat (encoding, m_kImapHeader);

        PL_strcat (encoding, orHeaderMnemonic);
        if (!ignoreValue)
          err = EncodeImapValue(encoding, value, useQuotes, reallyDredd);
      }

      // kmcentee, don't let the encoding end with whitespace,
      // this throws off later url STRCMP
      if (*encoding && *(encoding + strlen(encoding) - 1) == ' ')
        *(encoding + strlen(encoding) - 1) = '\0';
    }

    if (value && valueWasAllocated)
      NS_Free (value);

    *ppOutTerm = encoding;

    return err;
}
Beispiel #14
0
/*
 * get the difference in seconds between this time zone and UTC (GMT)
 */
PR_IMPLEMENT(time_t) PRMJ_LocalGMTDifference()
{
#if defined(XP_UNIX) || defined(XP_PC)
    struct tm ltime;
    /* get the difference between this time zone and GMT */
    memset((char *)&ltime,0,sizeof(ltime));
    ltime.tm_mday = 2;
    ltime.tm_year = 70;
#ifdef SUNOS4
    ltime.tm_zone = 0;
    ltime.tm_gmtoff = 0;
    return timelocal(&ltime) - (24 * 3600);
#else
    return mktime(&ltime) - (24L * 3600L);
#endif
#endif
#if defined(XP_MAC)
    static time_t    zone = -1L;
    MachineLocation  machineLocation;
    PRUint64	     gmtOffsetSeconds;
    PRUint64	     gmtDelta;
    PRUint64	     dlsOffset;
    PRInt32	     offset;

    /* difference has been set no need to recalculate */
    if(zone != -1)
	return zone;

    /* Get the information about the local machine, including
     * its GMT offset and its daylight savings time info.
     * Convert each into wides that we can add to
     * startupTimeMicroSeconds.
     */

    MyReadLocation(&machineLocation);

    /* Mask off top eight bits of gmtDelta, sign extend lower three. */

    if ((machineLocation.u.gmtDelta & 0x00800000) != 0) {
	gmtOffsetSeconds.lo = (machineLocation.u.gmtDelta & 0x00FFFFFF) | 0xFF000000;
	gmtOffsetSeconds.hi = 0xFFFFFFFF;
	LL_UI2L(gmtDelta,0);
    }
    else {

	gmtOffsetSeconds.lo = (machineLocation.u.gmtDelta & 0x00FFFFFF);
	gmtOffsetSeconds.hi = 0;
	LL_UI2L(gmtDelta,PRMJ_DAY_SECONDS);
    }
    /* normalize time to be positive if you are behind GMT. gmtDelta will always
     * be positive.
     */
    LL_SUB(gmtDelta,gmtDelta,gmtOffsetSeconds);

    /* Is Daylight Savings On?  If so, we need to add an hour to the offset. */
    if (machineLocation.u.dlsDelta != 0) {
	LL_UI2L(dlsOffset, PRMJ_HOUR_SECONDS);
    }
    else
	LL_I2L(dlsOffset, 0);

    LL_ADD(gmtDelta,gmtDelta, dlsOffset);
    LL_L2I(offset,gmtDelta);

    zone = offset;
    return (time_t)offset;
#endif
}
Beispiel #15
0
PRMJ_Now(void)
{
#ifdef XP_PC
    PRInt64 s, us, ms2us, s2us;
    struct timeb b;
#endif /* XP_PC */
#ifdef XP_UNIX
    struct timeval tv;
    PRInt64 s, us, s2us;
#endif /* XP_UNIX */
#ifdef XP_MAC
    UnsignedWide upTime;
    PRInt64	 localTime;
    PRInt64       gmtOffset;
    PRInt64    dstOffset;
    time_t       gmtDiff;
    PRInt64	 s2us;
#endif /* XP_MAC */

#ifdef XP_PC
    ftime(&b);
    LL_UI2L(ms2us, PRMJ_USEC_PER_MSEC);
    LL_UI2L(s2us, PRMJ_USEC_PER_SEC);
    LL_UI2L(s, b.time);
    LL_UI2L(us, b.millitm);
    LL_MUL(us, us, ms2us);
    LL_MUL(s, s, s2us);
    LL_ADD(s, s, us);
    return s;
#endif

#ifdef XP_UNIX
#if defined(SOLARIS)
    gettimeofday(&tv);
#else
    gettimeofday(&tv, 0);
#endif /* SOLARIS */
    LL_UI2L(s2us, PRMJ_USEC_PER_SEC);
    LL_UI2L(s, tv.tv_sec);
    LL_UI2L(us, tv.tv_usec);
    LL_MUL(s, s, s2us);
    LL_ADD(s, s, us);
    return s;
#endif /* XP_UNIX */
#ifdef XP_MAC
    LL_UI2L(localTime,0);
    gmtDiff = PRMJ_LocalGMTDifference();
    LL_I2L(gmtOffset,gmtDiff);
    LL_UI2L(s2us, PRMJ_USEC_PER_SEC);
    LL_MUL(gmtOffset,gmtOffset,s2us);
    LL_UI2L(dstOffset,0);
    dstOffset = PRMJ_DSTOffset(dstOffset);
    LL_SUB(gmtOffset,gmtOffset,dstOffset);
    /* don't adjust for DST since it sets ctime and gmtime off on the MAC */
    Microseconds(&upTime);
    LL_ADD(localTime,localTime,gmtOffset);
    LL_ADD(localTime,localTime, *((PRUint64 *)&dstLocalBaseMicroseconds));
    LL_ADD(localTime,localTime, *((PRUint64 *)&upTime));

    return *((PRUint64 *)&localTime);
#endif /* XP_MAC */
}
Beispiel #16
0
// Set rcvDate to true to get the Received: date instead of the Date: date.
nsresult nsMsgGroupView::GetAgeBucketValue(nsIMsgDBHdr *aMsgHdr, PRUint32 * aAgeBucket, bool rcvDate)
{
  NS_ENSURE_ARG_POINTER(aMsgHdr);
  NS_ENSURE_ARG_POINTER(aAgeBucket);

  PRTime dateOfMsg;
  nsresult rv;
  if (!rcvDate)
    rv = aMsgHdr->GetDate(&dateOfMsg);
  else
  {
    PRUint32 rcvDateSecs;
    rv = aMsgHdr->GetUint32Property("dateReceived", &rcvDateSecs);
    Seconds2PRTime(rcvDateSecs, &dateOfMsg);
  }
  NS_ENSURE_SUCCESS(rv, rv);

  PRTime currentTime = PR_Now();
  PRExplodedTime currentExplodedTime;
  PR_ExplodeTime(currentTime, PR_LocalTimeParameters, &currentExplodedTime);
  PRExplodedTime explodedMsgTime;
  PR_ExplodeTime(dateOfMsg, PR_LocalTimeParameters, &explodedMsgTime);

  if (m_lastCurExplodedTime.tm_mday &&
     m_lastCurExplodedTime.tm_mday != currentExplodedTime.tm_mday)
    m_dayChanged = true; // this will cause us to rebuild the view.

  m_lastCurExplodedTime = currentExplodedTime;
  if (currentExplodedTime.tm_year == explodedMsgTime.tm_year &&
      currentExplodedTime.tm_month == explodedMsgTime.tm_month &&
      currentExplodedTime.tm_mday == explodedMsgTime.tm_mday)
  {
    // same day...
    *aAgeBucket = 1;
  }
  // figure out how many days ago this msg arrived
  else if (LL_CMP(currentTime, >, dateOfMsg))
  {
    // some constants for calculation
    static PRInt64 microSecondsPerSecond;
    static PRInt64 microSecondsPerDay;
    static PRInt64 secondsPerDay;
    static PRInt64 microSecondsPer6Days;
    static PRInt64 microSecondsPer13Days;

    static bool bGotConstants = false;
    if ( !bGotConstants )
    {
      // seeds
      LL_I2L  ( microSecondsPerSecond,  PR_USEC_PER_SEC );
      LL_UI2L ( secondsPerDay,          60 * 60 * 24 );

      // derivees
      LL_MUL( microSecondsPerDay,   secondsPerDay,      microSecondsPerSecond );
      LL_MUL( microSecondsPer6Days, microSecondsPerDay, 6 );
      LL_MUL( microSecondsPer13Days, microSecondsPerDay, 13 );
      bGotConstants = true;
    }

    // setting the time variables to local time
    PRInt64 GMTLocalTimeShift;
    LL_ADD( GMTLocalTimeShift, currentExplodedTime.tm_params.tp_gmt_offset, currentExplodedTime.tm_params.tp_dst_offset );
    LL_MUL( GMTLocalTimeShift, GMTLocalTimeShift, microSecondsPerSecond );
    LL_ADD( currentTime, currentTime, GMTLocalTimeShift );
    LL_ADD( dateOfMsg, dateOfMsg, GMTLocalTimeShift );

    // the most recent midnight, counting from current time
    PRInt64 todaysMicroSeconds, mostRecentMidnight;
    LL_MOD( todaysMicroSeconds, currentTime, microSecondsPerDay );
    LL_SUB( mostRecentMidnight, currentTime, todaysMicroSeconds );
    PRInt64 yesterday;
    LL_SUB( yesterday, mostRecentMidnight, microSecondsPerDay );
    // most recent midnight minus 6 days
    PRInt64 mostRecentWeek;
    LL_SUB( mostRecentWeek, mostRecentMidnight, microSecondsPer6Days );

    // was the message sent yesterday?
    if ( LL_CMP( dateOfMsg, >=, yesterday ) ) // yes ....
      *aAgeBucket = 2;
    else if ( LL_CMP(dateOfMsg, >=, mostRecentWeek) )
      *aAgeBucket = 3;
    else
    {
NS_IMETHODIMP
CVE_2013_1732_firefox12_0_nsBlockFrame::Reflow(nsPresContext*           aPresContext,
                     nsHTMLReflowMetrics&     aMetrics,
                     const nsHTMLReflowState& aReflowState,
                     nsReflowStatus&          aStatus)
{
  DO_GLOBAL_REFLOW_COUNT("nsBlockFrame");
  DISPLAY_REFLOW(aPresContext, this, aReflowState, aMetrics, aStatus);
#ifdef DEBUG
  if (gNoisyReflow) {
    IndentBy(stdout, gNoiseIndent);
    ListTag(stdout);
    printf(": begin reflow availSize=%d,%d computedSize=%d,%d\n",
           aReflowState.availableWidth, aReflowState.availableHeight,
           aReflowState.ComputedWidth(), aReflowState.ComputedHeight());
  }
  AutoNoisyIndenter indent(gNoisy);
  PRTime start = LL_ZERO; // Initialize these variablies to silence the compiler.
  PRInt32 ctc = 0;        // We only use these if they are set (gLameReflowMetrics).
  if (gLameReflowMetrics) {
    start = PR_Now();
    ctc = nsLineBox::GetCtorCount();
  }
#endif

  const nsHTMLReflowState *reflowState = &aReflowState;
  nsAutoPtr<nsHTMLReflowState> mutableReflowState;
  // If we have non-auto height, we're clipping our kids and we fit,
  // make sure our kids fit too.
  if (aReflowState.availableHeight != NS_UNCONSTRAINEDSIZE &&
      aReflowState.ComputedHeight() != NS_AUTOHEIGHT &&
      ApplyOverflowClipping(this, aReflowState.mStyleDisplay)) {
    nsMargin heightExtras = aReflowState.mComputedBorderPadding;
    if (GetSkipSides() & NS_SIDE_TOP) {
      heightExtras.top = 0;
    } else {
      // Bottom margin never causes us to create continuations, so we
      // don't need to worry about whether it fits in its entirety.
      heightExtras.top += aReflowState.mComputedMargin.top;
    }

    if (GetEffectiveComputedHeight(aReflowState) + heightExtras.TopBottom() <=
        aReflowState.availableHeight) {
      mutableReflowState = new nsHTMLReflowState(aReflowState);
      mutableReflowState->availableHeight = NS_UNCONSTRAINEDSIZE;
      reflowState = mutableReflowState;
    }
  }

  // See comment below about oldSize. Use *only* for the
  // abs-pos-containing-block-size-change optimization!
  nsSize oldSize = GetSize();

  // Should we create a float manager?
  nsAutoFloatManager autoFloatManager(const_cast<nsHTMLReflowState&>(*reflowState));

  // XXXldb If we start storing the float manager in the frame rather
  // than keeping it around only during reflow then we should create it
  // only when there are actually floats to manage.  Otherwise things
  // like tables will gain significant bloat.
  bool needFloatManager = nsBlockFrame::BlockNeedsFloatManager(this);
  if (needFloatManager)
    autoFloatManager.CreateFloatManager(aPresContext);

  // OK, some lines may be reflowed. Blow away any saved line cursor
  // because we may invalidate the nondecreasing
  // overflowArea.VisualOverflow().y/yMost invariant, and we may even
  // delete the line with the line cursor.
  ClearLineCursor();

  if (IsFrameTreeTooDeep(*reflowState, aMetrics, aStatus)) {
    return NS_OK;
  }

  bool marginRoot = BlockIsMarginRoot(this);
  nsBlockReflowState state(*reflowState, aPresContext, this, aMetrics,
                           marginRoot, marginRoot, needFloatManager);

#ifdef IBMBIDI
  if (GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION)
    static_cast<nsBlockFrame*>(GetFirstContinuation())->ResolveBidi();
#endif // IBMBIDI

  if (RenumberLists(aPresContext)) {
    AddStateBits(NS_FRAME_HAS_DIRTY_CHILDREN);
  }

  nsresult rv = NS_OK;

  // ALWAYS drain overflow. We never want to leave the previnflow's
  // overflow lines hanging around; block reflow depends on the
  // overflow line lists being cleared out between reflow passes.
  DrainOverflowLines();

  // Handle paginated overflow (see nsContainerFrame.h)
  nsOverflowAreas ocBounds;
  nsReflowStatus ocStatus = NS_FRAME_COMPLETE;
  if (GetPrevInFlow()) {
    ReflowOverflowContainerChildren(aPresContext, *reflowState, ocBounds, 0,
                                    ocStatus);
  }

  // Now that we're done cleaning up our overflow container lists, we can
  // give |state| its nsOverflowContinuationTracker.
  nsOverflowContinuationTracker tracker(aPresContext, this, false);
  state.mOverflowTracker = &tracker;

  // Drain & handle pushed floats
  DrainPushedFloats(state);
  nsOverflowAreas fcBounds;
  nsReflowStatus fcStatus = NS_FRAME_COMPLETE;
  rv = ReflowPushedFloats(state, fcBounds, fcStatus);
  NS_ENSURE_SUCCESS(rv, rv);

  // If we're not dirty (which means we'll mark everything dirty later)
  // and our width has changed, mark the lines dirty that we need to
  // mark dirty for a resize reflow.
  if (reflowState->mFlags.mHResize)
    PrepareResizeReflow(state);

  mState &= ~NS_FRAME_FIRST_REFLOW;

  // Now reflow...
  rv = ReflowDirtyLines(state);
  NS_ASSERTION(NS_SUCCEEDED(rv), "reflow dirty lines failed");
  if (NS_FAILED(rv)) return rv;

  NS_MergeReflowStatusInto(&state.mReflowStatus, ocStatus);
  NS_MergeReflowStatusInto(&state.mReflowStatus, fcStatus);

  // If we end in a BR with clear and affected floats continue,
  // we need to continue, too.
  if (NS_UNCONSTRAINEDSIZE != reflowState->availableHeight &&
      NS_FRAME_IS_COMPLETE(state.mReflowStatus) &&
      state.mFloatManager->ClearContinues(FindTrailingClear())) {
    NS_FRAME_SET_INCOMPLETE(state.mReflowStatus);
  }

  if (!NS_FRAME_IS_FULLY_COMPLETE(state.mReflowStatus)) {
    if (GetOverflowLines() || GetPushedFloats()) {
      state.mReflowStatus |= NS_FRAME_REFLOW_NEXTINFLOW;
    }

#ifdef DEBUG_kipp
    ListTag(stdout); printf(": block is not fully complete\n");
#endif
  }

  CheckFloats(state);

  // Place the "marker" (bullet) frame if it is placed next to a block
  // child.
  //
  // According to the CSS2 spec, section 12.6.1, the "marker" box
  // participates in the height calculation of the list-item box's
  // first line box.
  //
  // There are exactly two places a bullet can be placed: near the
  // first or second line. It's only placed on the second line in a
  // rare case: an empty first line followed by a second line that
  // contains a block (example: <LI>\n<P>... ). This is where
  // the second case can happen.
  if (mBullet && HaveOutsideBullet() && !mLines.empty() &&
      (mLines.front()->IsBlock() ||
       (0 == mLines.front()->mBounds.height &&
        mLines.front() != mLines.back() &&
        mLines.begin().next()->IsBlock()))) {
    // Reflow the bullet
    nsHTMLReflowMetrics metrics;
    // XXX Use the entire line when we fix bug 25888.
    nsLayoutUtils::LinePosition position;
    bool havePosition = nsLayoutUtils::GetFirstLinePosition(this, &position);
    nscoord lineTop = havePosition ? position.mTop
                                   : reflowState->mComputedBorderPadding.top;
    ReflowBullet(state, metrics, lineTop);
    NS_ASSERTION(!BulletIsEmpty() || metrics.height == 0,
                 "empty bullet took up space");

    if (havePosition && !BulletIsEmpty()) {
      // We have some lines to align the bullet with.  

      // Doing the alignment using the baseline will also cater for
      // bullets that are placed next to a child block (bug 92896)
    
      // Tall bullets won't look particularly nice here...
      nsRect bbox = mBullet->GetRect();
      bbox.y = position.mBaseline - metrics.ascent;
      mBullet->SetRect(bbox);
    }
    // Otherwise just leave the bullet where it is, up against our top padding.
  }

  // Compute our final size
  nscoord bottomEdgeOfChildren;
  ComputeFinalSize(*reflowState, state, aMetrics, &bottomEdgeOfChildren);
  nsRect areaBounds = nsRect(0, 0, aMetrics.width, aMetrics.height);
  ComputeOverflowAreas(areaBounds, reflowState->mStyleDisplay,
                       bottomEdgeOfChildren, aMetrics.mOverflowAreas);
  // Factor overflow container child bounds into the overflow area
  aMetrics.mOverflowAreas.UnionWith(ocBounds);
  // Factor pushed float child bounds into the overflow area
  aMetrics.mOverflowAreas.UnionWith(fcBounds);

  // Let the absolutely positioned container reflow any absolutely positioned
  // child frames that need to be reflowed, e.g., elements with a percentage
  // based width/height
  // We want to do this under either of two conditions:
  //  1. If we didn't do the incremental reflow above.
  //  2. If our size changed.
  // Even though it's the padding edge that's the containing block, we
  // can use our rect (the border edge) since if the border style
  // changed, the reflow would have been targeted at us so we'd satisfy
  // condition 1.
  // XXX checking oldSize is bogus, there are various reasons we might have
  // reflowed but our size might not have been changed to what we
  // asked for (e.g., we ended up being pushed to a new page)
  // When WillReflowAgainForClearance is true, we will reflow again without
  // resetting the size. Because of this, we must not reflow our abs-pos children
  // in that situation --- what we think is our "new size"
  // will not be our real new size. This also happens to be more efficient.
  if (HasAbsolutelyPositionedChildren()) {
    nsAbsoluteContainingBlock* absoluteContainer = GetAbsoluteContainingBlock();
    bool haveInterrupt = aPresContext->HasPendingInterrupt();
    if (reflowState->WillReflowAgainForClearance() ||
        haveInterrupt) {
      // Make sure that when we reflow again we'll actually reflow all the abs
      // pos frames that might conceivably depend on our size (or all of them,
      // if we're dirty right now and interrupted; in that case we also need
      // to mark them all with NS_FRAME_IS_DIRTY).  Sadly, we can't do much
      // better than that, because we don't really know what our size will be,
      // and it might in fact not change on the followup reflow!
      if (haveInterrupt && (GetStateBits() & NS_FRAME_IS_DIRTY)) {
        absoluteContainer->MarkAllFramesDirty();
      } else {
        absoluteContainer->MarkSizeDependentFramesDirty();
      }
    } else {
      nsSize containingBlockSize =
        CalculateContainingBlockSizeForAbsolutes(*reflowState,
                                                 nsSize(aMetrics.width,
                                                        aMetrics.height));

      // Mark frames that depend on changes we just made to this frame as dirty:
      // Now we can assume that the padding edge hasn't moved.
      // We need to reflow the absolutes if one of them depends on
      // its placeholder position, or the containing block size in a
      // direction in which the containing block size might have
      // changed.
      bool cbWidthChanged = aMetrics.width != oldSize.width;
      bool isRoot = !GetContent()->GetParent();
      // If isRoot and we have auto height, then we are the initial
      // containing block and the containing block height is the
      // viewport height, which can't change during incremental
      // reflow.
      bool cbHeightChanged =
        !(isRoot && NS_UNCONSTRAINEDSIZE == reflowState->ComputedHeight()) &&
        aMetrics.height != oldSize.height;

      absoluteContainer->Reflow(this, aPresContext, *reflowState,
                                state.mReflowStatus,
                                containingBlockSize.width,
                                containingBlockSize.height, true,
                                cbWidthChanged, cbHeightChanged,
                                &aMetrics.mOverflowAreas);

      //XXXfr Why isn't this rv (and others in this file) checked/returned?
    }
  }

  // Determine if we need to repaint our border, background or outline
  CheckInvalidateSizeChange(aMetrics);

  FinishAndStoreOverflow(&aMetrics);

  // Clear the float manager pointer in the block reflow state so we
  // don't waste time translating the coordinate system back on a dead
  // float manager.
  if (needFloatManager)
    state.mFloatManager = nsnull;

  aStatus = state.mReflowStatus;

#ifdef DEBUG
  // Between when we drain pushed floats and when we complete reflow,
  // we're allowed to have multiple continuations of the same float on
  // our floats list, since a first-in-flow might get pushed to a later
  // continuation of its containing block.  But it's not permitted
  // outside that time.
  nsLayoutUtils::AssertNoDuplicateContinuations(this, mFloats);

  if (gNoisyReflow) {
    IndentBy(stdout, gNoiseIndent);
    ListTag(stdout);
    printf(": status=%x (%scomplete) metrics=%d,%d carriedMargin=%d",
           aStatus, NS_FRAME_IS_COMPLETE(aStatus) ? "" : "not ",
           aMetrics.width, aMetrics.height,
           aMetrics.mCarriedOutBottomMargin.get());
    if (HasOverflowAreas()) {
      printf(" overflow-vis={%d,%d,%d,%d}",
             aMetrics.VisualOverflow().x,
             aMetrics.VisualOverflow().y,
             aMetrics.VisualOverflow().width,
             aMetrics.VisualOverflow().height);
      printf(" overflow-scr={%d,%d,%d,%d}",
             aMetrics.ScrollableOverflow().x,
             aMetrics.ScrollableOverflow().y,
             aMetrics.ScrollableOverflow().width,
             aMetrics.ScrollableOverflow().height);
    }
    printf("\n");
  }

  if (gLameReflowMetrics) {
    PRTime end = PR_Now();

    PRInt32 ectc = nsLineBox::GetCtorCount();
    PRInt32 numLines = mLines.size();
    if (!numLines) numLines = 1;
    PRTime delta, perLineDelta, lines;
    LL_I2L(lines, numLines);
    LL_SUB(delta, end, start);
    LL_DIV(perLineDelta, delta, lines);

    ListTag(stdout);
    char buf[400];
    PR_snprintf(buf, sizeof(buf),
                ": %lld elapsed (%lld per line) (%d lines; %d new lines)",
                delta, perLineDelta, numLines, ectc - ctc);
    printf("%s\n", buf);
  }
#endif

  NS_FRAME_SET_TRUNCATION(aStatus, (*reflowState), aMetrics);
  return rv;
}
nsresult
nsListBoxBodyFrame::DoInternalPositionChanged(bool aUp, PRInt32 aDelta)
{
  if (aDelta == 0)
    return NS_OK;

  nsRefPtr<nsPresContext> presContext(PresContext());
  nsBoxLayoutState state(presContext);

  // begin timing how long it takes to scroll a row
  PRTime start = PR_Now();

  nsWeakFrame weakThis(this);
  mContent->GetDocument()->FlushPendingNotifications(Flush_Layout);
  if (!weakThis.IsAlive()) {
    return NS_OK;
  }

  {
    nsAutoScriptBlocker scriptBlocker;

    PRInt32 visibleRows = 0;
    if (mRowHeight)
      visibleRows = GetAvailableHeight()/mRowHeight;
  
    if (aDelta < visibleRows) {
      PRInt32 loseRows = aDelta;
      if (aUp) {
        // scrolling up, destroy rows from the bottom downwards
        ReverseDestroyRows(loseRows);
        mRowsToPrepend += aDelta;
        mLinkupFrame = nsnull;
      }
      else {
        // scrolling down, destroy rows from the top upwards
        DestroyRows(loseRows);
        mRowsToPrepend = 0;
      }
    }
    else {
      // We have scrolled so much that all of our current frames will
      // go off screen, so blow them all away. Weeee!
      nsIFrame *currBox = mFrames.FirstChild();
      nsCSSFrameConstructor* fc = presContext->PresShell()->FrameConstructor();
      fc->BeginUpdate();
      while (currBox) {
        nsIFrame *nextBox = currBox->GetNextSibling();
        RemoveChildFrame(state, currBox);
        currBox = nextBox;
      }
      fc->EndUpdate();
    }

    // clear frame markers so that CreateRows will re-create
    mTopFrame = mBottomFrame = nsnull; 
  
    mYPosition = mCurrentIndex*mRowHeight;
    mScrolling = true;
    presContext->PresShell()->
      FrameNeedsReflow(this, nsIPresShell::eResize, NS_FRAME_HAS_DIRTY_CHILDREN);
  }
  if (!weakThis.IsAlive()) {
    return NS_OK;
  }
  // Flush calls CreateRows
  // XXXbz there has to be a better way to do this than flushing!
  presContext->PresShell()->FlushPendingNotifications(Flush_Layout);
  if (!weakThis.IsAlive()) {
    return NS_OK;
  }

  mScrolling = false;
  
  VerticalScroll(mYPosition);

  PRTime end = PR_Now();

  PRTime difTime;
  LL_SUB(difTime, end, start);

  PRInt32 newTime;
  LL_L2I(newTime, difTime);
  newTime /= aDelta;

  // average old and new
  mTimePerRow = (newTime + mTimePerRow)/2;
  
  return NS_OK;
}
Beispiel #19
0
int main(int argc, char** argv)
{
  if (3 != argc) {
    printf("usage: CvtURL url utf8\n");
    return -1;
  }

  char* characterSetName = argv[2];
  nsString* cset = ConvertCharacterSetName(characterSetName);
  if (NS_PTR_TO_INT32(cset) < 0) {
    printf("illegal character set name: '%s'\n", characterSetName);
    return -1;
  }

  // Create url object
  char* urlName = argv[1];
  nsIURI* url;
  nsresult rv;
  rv = NS_NewURI(&url, urlName);
  if (NS_OK != rv) {
    printf("invalid URL: '%s'\n", urlName);
    return -1;
  }

  // Get an input stream from the url
  nsresult ec;
  nsIInputStream* in;
  ec = NS_OpenURI(&in, url);
  if (nsnull == in) {
    printf("open of url('%s') failed: error=%x\n", urlName, ec);
    return -1;
  }

  // Translate the input using the argument character set id into
  // unicode
  nsCOMPtr<nsIConverterInputStream> uin =
    do_CreateInstance("@mozilla.org/intl/converter-input-stream;1", &rv);
  if (NS_SUCCEEDED(rv))
    rv = uin->Init(in, cset->get(), 4096);
  if (NS_FAILED(rv)) {
    printf("can't create converter input stream: %d\n", rv);
    return -1;
  }

  // Read the input and write some output
  PRTime start = PR_Now();
  PRInt32 count = 0;
  for (;;) {
    PRUnichar buf[1000];
    PRUint32 nb;
    ec = uin->Read(buf, 0, 1000, &nb);
    if (NS_FAILED(ec)) {
      printf("i/o error: %d\n", ec);
      break;
    }
    if (nb == 0) break; // EOF
    count += nb;
  }
  PRTime end = PR_Now();
  PRTime conversion, ustoms;
  LL_I2L(ustoms, 1000);
  LL_SUB(conversion, end, start);
  LL_DIV(conversion, conversion, ustoms);
  char buf[500];
  PR_snprintf(buf, sizeof(buf),
              "converting and discarding %d bytes took %lldms",
              count, conversion);
  puts(buf);

  // Release the objects
  in->Release();
  url->Release();

  return 0;
}
Beispiel #20
0
int main(int argc, char** argv)
{
	/* The command line argument: -d is used to determine if the test is being run
	in debug mode. The regress tool requires only one line output:PASS or FAIL.
	All of the printfs associated with this test has been handled with a if (debug_mode)
	test.
	Usage: test_name -d
	*/
	PLOptStatus os;
	PLOptState *opt;
    
    PR_STDIO_INIT();
	opt = PL_CreateOptState(argc, argv, "d");
	while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
    {
		if (PL_OPT_BAD == os) continue;
        switch (opt->option)
        {
        case 'd':  /* debug mode */
			debug_mode = PR_TRUE;
            break;
         default:
            break;
        }
    }
	PL_DestroyOptState(opt);

 /* main test */
	
    PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);

#ifdef XP_MAC
	SetupMacPrintfLog("timetest.log");
	debug_mode = PR_TRUE;
#endif
    /* Testing zero PRTime (the epoch) */
    {
	PRTime t;
	PRExplodedTime et;

	LL_I2L(t, 0);
	if (debug_mode) printf("The NSPR epoch is:\n");
        PR_ExplodeTime(t, PR_LocalTimeParameters, &et);
	printExplodedTime(&et);
	if (debug_mode) printf("\n");
	PR_ExplodeTime(t, PR_GMTParameters, &et);
	printExplodedTime(&et);
	if (debug_mode) printf("\n\n");
	testParseTimeString(t);
    }

    /*
     *************************************************************
     **
     **  Testing PR_Now(), PR_ExplodeTime, and PR_ImplodeTime
     **  on the current time
     **
     *************************************************************
     */

    {
	PRTime t1, t2;
	PRExplodedTime et;

	if (debug_mode) {
	printf("*********************************************\n");
	printf("**                                         **\n");
    printf("** Testing PR_Now(), PR_ExplodeTime, and   **\n");
	printf("** PR_ImplodeTime on the current time      **\n");
	printf("**                                         **\n");
	printf("*********************************************\n\n");
	}
	t1 = PR_Now();

        /* First try converting to UTC */

        PR_ExplodeTime(t1, PR_GMTParameters, &et);
        if (et.tm_params.tp_gmt_offset || et.tm_params.tp_dst_offset) {
	    if (debug_mode) printf("ERROR: UTC has nonzero gmt or dst offset.\n");
		else failed_already=1;
	    return 1;
        }
        if (debug_mode) printf("Current UTC is ");
	printExplodedTime(&et);
	if (debug_mode) printf("\n");

        t2 = PR_ImplodeTime(&et);
        if (LL_NE(t1, t2)) {
	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
		else printf("FAIL\n");
	    return 1;
        }

        /* Next, try converting to local (US Pacific) time */

        PR_ExplodeTime(t1, PR_LocalTimeParameters, &et);
        if (debug_mode) printf("Current local time is ");
	printExplodedTime(&et);
	if (debug_mode) printf("\n");
	if (debug_mode) printf("GMT offset is %ld, DST offset is %ld\n",
		et.tm_params.tp_gmt_offset, et.tm_params.tp_dst_offset);
        t2 = PR_ImplodeTime(&et);
        if (LL_NE(t1, t2)) {
	    if (debug_mode) printf("ERROR: Explode and implode are NOT inverse.\n");
	    return 1;
	}

	if (debug_mode) printf("Please examine the results\n");
	testParseTimeString(t1);
    }


    /*
     *******************************************
     **
     ** Testing PR_NormalizeTime()
     **
     *******************************************
     */

    /* July 4, 2001 is Wednesday */
    {
	PRExplodedTime et;

	if (debug_mode)  {
	printf("\n");
	printf("**********************************\n");
	printf("**                              **\n");
	printf("** Testing PR_NormalizeTime()   **\n");
	printf("**                              **\n");
	printf("**********************************\n\n");
	}
        et.tm_year    = 2001;
        et.tm_month   = 7 - 1;
        et.tm_mday    = 4;
        et.tm_hour    = 0;
        et.tm_min     = 0;
        et.tm_sec     = 0;
	et.tm_usec    = 0;
        et.tm_params  = PR_GMTParameters(&et);

	PR_NormalizeTime(&et, PR_GMTParameters);

	if (debug_mode) printf("July 4, 2001 is %s.\n", dayOfWeek[et.tm_wday]);
	if (et.tm_wday == 3) {
	    if (debug_mode) printf("PASS\n");
        } else {
            if (debug_mode) printf("ERROR: It should be Wednesday\n");
			else failed_already=1;
	    return 1;
	}
	testParseTimeString(PR_ImplodeTime(&et));

        /* June 12, 1997 23:00 PST == June 13, 1997 00:00 PDT */
        et.tm_year    = 1997;
        et.tm_month   = 6 - 1;
        et.tm_mday    = 12;
        et.tm_hour    = 23;
        et.tm_min     = 0;
        et.tm_sec     = 0;
	et.tm_usec    = 0;
        et.tm_params.tp_gmt_offset = -8 * 3600;
	et.tm_params.tp_dst_offset = 0;

	PR_NormalizeTime(&et, PR_USPacificTimeParameters);

	if (debug_mode) {
	    printf("Thu Jun 12, 1997 23:00:00 PST is ");
	}
	printExplodedTime(&et);
	if (debug_mode) printf(".\n");
	if (et.tm_wday == 5) {
	    if (debug_mode) printf("PASS\n");
        } else {
            if (debug_mode) printf("ERROR: It should be Friday\n");
			else failed_already=1;
	    return 1;
	}
	testParseTimeString(PR_ImplodeTime(&et));

        /* Feb 14, 1997 00:00:00 PDT == Feb 13, 1997 23:00:00 PST */
        et.tm_year    = 1997;
        et.tm_month   = 2 - 1;
        et.tm_mday    = 14;
        et.tm_hour    = 0;
        et.tm_min     = 0;
        et.tm_sec     = 0;
	et.tm_usec    = 0;
        et.tm_params.tp_gmt_offset = -8 * 3600;
	et.tm_params.tp_dst_offset = 3600;

	PR_NormalizeTime(&et, PR_USPacificTimeParameters);

	if (debug_mode) {
	    printf("Fri Feb 14, 1997 00:00:00 PDT is ");
	}
	printExplodedTime(&et);
	if (debug_mode) printf(".\n");
	if (et.tm_wday == 4) {
	    if (debug_mode) printf("PASS\n");
        } else {
            if (debug_mode) printf("ERROR: It should be Thursday\n");
			else failed_already=1;
	    return 1;
	}
	testParseTimeString(PR_ImplodeTime(&et));

        /* What time is Nov. 7, 1996, 18:29:23 PDT? */
        et.tm_year    = 1996;
        et.tm_month   = 11 - 1;
        et.tm_mday    = 7;
        et.tm_hour    = 18;
        et.tm_min     = 29;
        et.tm_sec     = 23;
	et.tm_usec    = 0;
        et.tm_params.tp_gmt_offset = -8 * 3600;  /* PDT */
	et.tm_params.tp_dst_offset = 3600; 

	PR_NormalizeTime(&et, PR_LocalTimeParameters);
        if (debug_mode) printf("Nov 7 18:29:23 PDT 1996 is ");
	printExplodedTime(&et);
	if (debug_mode) printf(".\n");
	testParseTimeString(PR_ImplodeTime(&et));

        /* What time is Oct. 7, 1995, 18:29:23 PST? */
        et.tm_year    = 1995;
        et.tm_month   = 10 - 1;
        et.tm_mday    = 7;
        et.tm_hour    = 18;
        et.tm_min     = 29;
        et.tm_sec     = 23;
        et.tm_params.tp_gmt_offset = -8 * 3600;  /* PST */
	et.tm_params.tp_dst_offset = 0;

	PR_NormalizeTime(&et, PR_LocalTimeParameters);
        if (debug_mode) printf("Oct 7 18:29:23 PST 1995 is ");
	printExplodedTime(&et);
	if (debug_mode) printf(".\n");
	testParseTimeString(PR_ImplodeTime(&et));

	if (debug_mode) printf("Please examine the results\n");
    }

    /*
     **************************************************************
     **
     ** Testing range of years
     **
     **************************************************************
     */

    {
	PRExplodedTime et1, et2;
    PRTime  ttt;
	PRTime secs;

	if (debug_mode) {
	printf("\n");
	printf("***************************************\n");
	printf("**                                   **\n");
	printf("**  Testing range of years           **\n");
	printf("**                                   **\n");
	printf("***************************************\n\n");
	}
	/* April 4, 1917 GMT */
	et1.tm_usec = 0;
	et1.tm_sec = 0;
	et1.tm_min = 0;
	et1.tm_hour = 0;
	et1.tm_mday = 4;
	et1.tm_month = 4 - 1;
	et1.tm_year = 1917;
	et1.tm_params = PR_GMTParameters(&et1);
	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
	secs = PR_ImplodeTime(&et1);
	if (LL_GE_ZERO(secs)) {
	    if (debug_mode)
		printf("ERROR: April 4, 1917 GMT returns a nonnegative second count\n");
		failed_already = 1;
	    return 1;
        }
	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
	if (!explodedTimeIsEqual(&et1, &et2)) {
		if (debug_mode)
		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for April 4, 1917 GMT\n");
		failed_already=1;
	    return 1;
        }
    ttt = PR_ImplodeTime(&et1);
	testParseTimeString( ttt );

	if (debug_mode) printf("Test passed for April 4, 1917\n");

	/* July 4, 2050 */
	et1.tm_usec = 0;
	et1.tm_sec = 0;
	et1.tm_min = 0;
	et1.tm_hour = 0;
	et1.tm_mday = 4;
	et1.tm_month = 7 - 1;
	et1.tm_year = 2050;
	et1.tm_params = PR_GMTParameters(&et1);
	PR_NormalizeTime(&et1, PR_LocalTimeParameters);
	secs = PR_ImplodeTime(&et1);
	if (!LL_GE_ZERO(secs)) {
	    if (debug_mode)
			printf("ERROR: July 4, 2050 GMT returns a negative second count\n");
		failed_already = 1;
	    return 1;
        }
	PR_ExplodeTime(secs, PR_LocalTimeParameters, &et2);
	if (!explodedTimeIsEqual(&et1, &et2)) {
	    if (debug_mode)
		printf("ERROR: PR_ImplodeTime and PR_ExplodeTime are not inverse for July 4, 2050 GMT\n");
		failed_already=1;
	    return 1;
        }
	testParseTimeString(PR_ImplodeTime(&et1));

	if (debug_mode) printf("Test passed for July 4, 2050\n");

    }

    /*
     **************************************************************
     **
     **  Stress test
     *
     **      Go through four years, starting from
     **      00:00:00 PST Jan. 1, 1993, incrementing
     **      every 10 minutes.
     **
     **************************************************************
     */

    {
	PRExplodedTime et, et1, et2;
	PRInt64 usecPer10Min;
	int day, hour, min;
	PRTime usecs;
	int dstInEffect = 0;

	if (debug_mode) {
	printf("\n");
	printf("*******************************************************\n");
	printf("**                                                   **\n");
	printf("**                 Stress test                       **\n");
	printf("**  Starting from midnight Jan. 1, 1993 PST,         **\n");
	printf("**  going through four years in 10-minute increment  **\n");
	printf("**                                                   **\n");
	printf("*******************************************************\n\n");
	}
	LL_I2L(usecPer10Min, 600000000L);

	/* 00:00:00 PST Jan. 1, 1993 */
	et.tm_usec = 0;
	et.tm_sec = 0;
	et.tm_min = 0;
	et.tm_hour = 0;
	et.tm_mday = 1;
	et.tm_month = 0;
	et.tm_year = 1993;
	et.tm_params.tp_gmt_offset = -8 * 3600;
	et.tm_params.tp_dst_offset = 0;
	usecs = PR_ImplodeTime(&et);

        for (day = 0; day < 4 * 365 + 1; day++) {
	    for (hour = 0; hour < 24; hour++) {
		for (min = 0; min < 60; min += 10) {
	            LL_ADD(usecs, usecs, usecPer10Min);
		    PR_ExplodeTime(usecs, PR_USPacificTimeParameters, &et1);

		    et2 = et;
		    et2.tm_usec += 600000000L;
		    PR_NormalizeTime(&et2, PR_USPacificTimeParameters);

		    if (!explodedTimeIsEqual(&et1, &et2)) {
		        if (debug_mode) printf("ERROR: componentwise comparison failed\n");
			printExplodedTime(&et1);
			if (debug_mode) printf("\n");
			printExplodedTime(&et2);
			if (debug_mode) printf("\n");
			failed_already=1;
		        return 1;
		    }

		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) { 
                        if (debug_mode)
					printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
			printExplodedTime(&et1);
			if (debug_mode) printf("\n");
			failed_already=1;
		        return 1;
		    }
		    testParseTimeString(usecs);

		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
		        dstInEffect = 1;
		        if (debug_mode) printf("DST changeover from ");
			printExplodedTime(&et);
			if (debug_mode) printf(" to ");
			printExplodedTime(&et1);
			if (debug_mode) printf(".\n");
                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
		        dstInEffect = 0;
			if (debug_mode) printf("DST changeover from ");
			printExplodedTime(&et);
			if (debug_mode) printf(" to ");
			printExplodedTime(&et1);
			if (debug_mode) printf(".\n");
                    }

		    et = et1;
		}
	    }
        }
	if (debug_mode) printf("Test passed\n");
    }


    /* Same stress test, but with PR_LocalTimeParameters */

    {
	PRExplodedTime et, et1, et2;
	PRInt64 usecPer10Min;
	int day, hour, min;
	PRTime usecs;
	int dstInEffect = 0;

	if (debug_mode) {
	printf("\n");
	printf("*******************************************************\n");
	printf("**                                                   **\n");
	printf("**                 Stress test                       **\n");
	printf("**  Starting from midnight Jan. 1, 1993 PST,         **\n");
	printf("**  going through four years in 10-minute increment  **\n");
	printf("**                                                   **\n");
	printf("*******************************************************\n\n");
	}
	
	LL_I2L(usecPer10Min, 600000000L);

	/* 00:00:00 PST Jan. 1, 1993 */
	et.tm_usec = 0;
	et.tm_sec = 0;
	et.tm_min = 0;
	et.tm_hour = 0;
	et.tm_mday = 1;
	et.tm_month = 0;
	et.tm_year = 1993;
	et.tm_params.tp_gmt_offset = -8 * 3600;
	et.tm_params.tp_dst_offset = 0;
	usecs = PR_ImplodeTime(&et);

        for (day = 0; day < 4 * 365 + 1; day++) {
	    for (hour = 0; hour < 24; hour++) {
		for (min = 0; min < 60; min += 10) {
	            LL_ADD(usecs, usecs, usecPer10Min);
		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);

		    et2 = et;
		    et2.tm_usec += 600000000L;
		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);

		    if (!explodedTimeIsEqual(&et1, &et2)) {
		        if (debug_mode) printf("ERROR: componentwise comparison failed\n");
			printExplodedTime(&et1);
			if (debug_mode) printf("\n");
			printExplodedTime(&et2);
			if (debug_mode) printf("\n");
		        return 1;
		    }

		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
                        printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
			printExplodedTime(&et1);
			if (debug_mode) printf("\n");
			failed_already=1;
		        return 1;
		    }
		    testParseTimeString(usecs);

		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
		        dstInEffect = 1;
		        if (debug_mode) printf("DST changeover from ");
			printExplodedTime(&et);
			if (debug_mode) printf(" to ");
			printExplodedTime(&et1);
			if (debug_mode) printf(".\n");
                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
		        dstInEffect = 0;
			if (debug_mode) printf("DST changeover from ");
			printExplodedTime(&et);
			if (debug_mode) printf(" to ");
			printExplodedTime(&et1);
			if (debug_mode) printf(".\n");
                    }

		    et = et1;
		}
	    }
        }
	if (debug_mode) printf("Test passed\n");
    }

    /* Same stress test, but with PR_LocalTimeParameters and going backward */

    {
	PRExplodedTime et, et1, et2;
	PRInt64 usecPer10Min;
	int day, hour, min;
	PRTime usecs;
	int dstInEffect = 0;

	if (debug_mode) {
	printf("\n");
	printf("*******************************************************\n");
	printf("**                                                   **\n");
	printf("**                 Stress test                       **\n");
	printf("**  Starting from midnight Jan. 1, 1997 PST,         **\n");
	printf("**  going back four years in 10-minute increment     **\n");
	printf("**                                                   **\n");
	printf("*******************************************************\n\n");
	}

	LL_I2L(usecPer10Min, 600000000L);

	/* 00:00:00 PST Jan. 1, 1997 */
	et.tm_usec = 0;
	et.tm_sec = 0;
	et.tm_min = 0;
	et.tm_hour = 0;
	et.tm_mday = 1;
	et.tm_month = 0;
	et.tm_year = 1997;
	et.tm_params.tp_gmt_offset = -8 * 3600;
	et.tm_params.tp_dst_offset = 0;
	usecs = PR_ImplodeTime(&et);

        for (day = 0; day < 4 * 365 + 1; day++) {
	    for (hour = 0; hour < 24; hour++) {
		for (min = 0; min < 60; min += 10) {
	            LL_SUB(usecs, usecs, usecPer10Min);
		    PR_ExplodeTime(usecs, PR_LocalTimeParameters, &et1);

		    et2 = et;
		    et2.tm_usec -= 600000000L;
		    PR_NormalizeTime(&et2, PR_LocalTimeParameters);

		    if (!explodedTimeIsEqual(&et1, &et2)) {
		        if (debug_mode) printf("ERROR: componentwise comparison failed\n");
			printExplodedTime(&et1);
			if (debug_mode) printf("\n");
			printExplodedTime(&et2);
			if (debug_mode) printf("\n");
		        return 1;
		    }

		    if (LL_NE(usecs, PR_ImplodeTime(&et1))) {
                   if (debug_mode)
					printf("ERROR: PR_ExplodeTime and PR_ImplodeTime are not inverse\n");
			printExplodedTime(&et1);
			if (debug_mode) printf("\n");
			failed_already=1;
		        return 1;
		    }
		    testParseTimeString(usecs);

		    if (!dstInEffect && et1.tm_params.tp_dst_offset) {
		        dstInEffect = 1;
		        if (debug_mode) printf("DST changeover from ");
			printExplodedTime(&et);
			if (debug_mode) printf(" to ");
			printExplodedTime(&et1);
			if (debug_mode) printf(".\n");
                    } else if (dstInEffect && !et1.tm_params.tp_dst_offset) {
		        dstInEffect = 0;
			if (debug_mode) printf("DST changeover from ");
			printExplodedTime(&et);
			if (debug_mode) printf(" to ");
			printExplodedTime(&et1);
			if (debug_mode) printf(".\n");
                    }

		    et = et1;
		}
	    }
        }
    }

	if (failed_already) return 1;
	else return 0;

}
// This is the function that looks for the first folder to purge. It also
// applies retention settings to any folder that hasn't had retention settings
// applied in mMinDelayBetweenPurges minutes (default, 8 hours).
// However, if we've spent more than .5 seconds in this loop, don't
// apply any more retention settings because it might lock up the UI.
// This might starve folders later on in the hierarchy, since we always
// start at the top, but since we also apply retention settings when you
// open a folder, or when you compact all folders, I think this will do
// for now, until we have a cleanup on shutdown architecture.
nsresult nsMsgPurgeService::PerformPurge()
{
    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("performing purge"));

    nsresult rv;

    nsCOMPtr <nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
    NS_ENSURE_SUCCESS(rv,rv);
    bool keepApplyingRetentionSettings = true;

    nsCOMPtr<nsISupportsArray> allServers;
    rv = accountManager->GetAllServers(getter_AddRefs(allServers));
    if (NS_SUCCEEDED(rv) && allServers)
    {
        PRUint32 numServers;
        rv = allServers->Count(&numServers);
        PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("%d servers", numServers));
        nsCOMPtr<nsIMsgFolder> folderToPurge;
        PRIntervalTime startTime = PR_IntervalNow();
        PRInt32 purgeIntervalToUse;
        PRTime oldestPurgeTime = 0; // we're going to pick the least-recently purged folder

        // apply retention settings to folders that haven't had retention settings
        // applied in mMinDelayBetweenPurges minutes (default 8 hours)
        // Because we get last purge time from the folder cache,
        // this code won't open db's for folders until it decides it needs
        // to apply retention settings, and since nsIMsgFolder::ApplyRetentionSettings
        // will close any db's it opens, this code won't leave db's open.
        for (PRUint32 serverIndex=0; serverIndex < numServers; serverIndex++)
        {
            nsCOMPtr <nsIMsgIncomingServer> server =
                do_QueryElementAt(allServers, serverIndex, &rv);
            if (NS_SUCCEEDED(rv) && server)
            {
                if (keepApplyingRetentionSettings)
                {
                    nsCOMPtr <nsIMsgFolder> rootFolder;
                    rv = server->GetRootFolder(getter_AddRefs(rootFolder));
                    NS_ENSURE_SUCCESS(rv, rv);

                    nsCOMPtr <nsISupportsArray> childFolders = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
                    NS_ENSURE_SUCCESS(rv, rv);
                    rv = rootFolder->ListDescendents(childFolders);

                    PRUint32 cnt = 0;
                    childFolders->Count(&cnt);

                    nsCOMPtr<nsISupports> supports;
                    nsCOMPtr<nsIUrlListener> urlListener;
                    nsCOMPtr<nsIMsgFolder> childFolder;

                    for (PRUint32 index = 0; index < cnt; index++)
                    {
                        childFolder = do_QueryElementAt(childFolders, index);
                        if (childFolder)
                        {
                            PRUint32 folderFlags;
                            (void) childFolder->GetFlags(&folderFlags);
                            if (folderFlags & nsMsgFolderFlags::Virtual)
                                continue;
                            PRTime curFolderLastPurgeTime = 0;
                            nsCString curFolderLastPurgeTimeString, curFolderUri;
                            rv = childFolder->GetStringProperty("LastPurgeTime", curFolderLastPurgeTimeString);
                            if (NS_FAILED(rv))
                                continue; // it is ok to fail, go on to next folder

                            if (!curFolderLastPurgeTimeString.IsEmpty())
                            {
                                PRInt64 theTime;
                                PR_ParseTimeString(curFolderLastPurgeTimeString.get(), PR_FALSE, &theTime);
                                curFolderLastPurgeTime = theTime;
                            }

                            childFolder->GetURI(curFolderUri);
                            PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("%s curFolderLastPurgeTime=%s (if blank, then never)", curFolderUri.get(), curFolderLastPurgeTimeString.get()));

                            // check if this folder is due to purge
                            // has to have been purged at least mMinDelayBetweenPurges minutes ago
                            // we don't want to purge the folders all the time - once a day is good enough
                            PRInt64 minDelayBetweenPurges(mMinDelayBetweenPurges);
                            PRInt64 microSecondsPerMinute(60000000);
                            PRTime nextPurgeTime = curFolderLastPurgeTime + (minDelayBetweenPurges * microSecondsPerMinute);
                            if (nextPurgeTime < PR_Now())
                            {
                                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("purging %s", curFolderUri.get()));
                                childFolder->ApplyRetentionSettings();
                            }
                            PRIntervalTime elapsedTime;
                            LL_SUB(elapsedTime, PR_IntervalNow(), startTime);
                            // check if more than 500 milliseconds have elapsed in this purge process
                            if (PR_IntervalToMilliseconds(elapsedTime) > 500)
                            {
                                keepApplyingRetentionSettings = PR_FALSE;
                                break;
                            }
                        }
                    }
                }
                nsCString type;
                nsresult rv = server->GetType(type);
                NS_ENSURE_SUCCESS(rv, rv);

                nsCAutoString contractid(NS_MSGPROTOCOLINFO_CONTRACTID_PREFIX);
                contractid.Append(type);

                nsCOMPtr<nsIMsgProtocolInfo> protocolInfo =
                    do_GetService(contractid.get(), &rv);
                NS_ENSURE_SUCCESS(rv, PR_FALSE);

                nsCString realHostName;
                server->GetRealHostName(realHostName);
                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s (%s)", serverIndex, realHostName.get(), type.get()));

                nsCOMPtr <nsISpamSettings> spamSettings;
                rv = server->GetSpamSettings(getter_AddRefs(spamSettings));
                NS_ENSURE_SUCCESS(rv, rv);

                PRInt32 spamLevel;
                spamSettings->GetLevel(&spamLevel);
                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] spamLevel=%d (if 0, don't purge)", serverIndex, spamLevel));
                if (!spamLevel)
                    continue;

                // check if we are set up to purge for this server
                // if not, skip it.
                bool purgeSpam;
                spamSettings->GetPurge(&purgeSpam);

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] purgeSpam=%s (if false, don't purge)", serverIndex, purgeSpam ? "true" : "false"));
                if (!purgeSpam)
                    continue;

                // check if the spam folder uri is set for this server
                // if not skip it.
                nsCString junkFolderURI;
                rv = spamSettings->GetSpamFolderURI(getter_Copies(junkFolderURI));
                NS_ENSURE_SUCCESS(rv,rv);

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] junkFolderURI=%s (if empty, don't purge)", serverIndex, junkFolderURI.get()));
                if (junkFolderURI.IsEmpty())
                    continue;

                // if the junk folder doesn't exist
                // because the folder pane isn't built yet, for example
                // skip this account
                nsCOMPtr<nsIMsgFolder> junkFolder;
                GetExistingFolder(junkFolderURI, getter_AddRefs(junkFolder));

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s exists? %s (if doesn't exist, don't purge)", serverIndex, junkFolderURI.get(), junkFolder ? "true" : "false"));
                if (!junkFolder)
                    continue;

                PRTime curJunkFolderLastPurgeTime = 0;
                nsCString curJunkFolderLastPurgeTimeString;
                rv = junkFolder->GetStringProperty("curJunkFolderLastPurgeTime", curJunkFolderLastPurgeTimeString);
                if (NS_FAILED(rv))
                    continue; // it is ok to fail, junk folder may not exist

                if (!curJunkFolderLastPurgeTimeString.IsEmpty())
                {
                    PRInt64 theTime;
                    PR_ParseTimeString(curJunkFolderLastPurgeTimeString.get(), PR_FALSE, &theTime);
                    curJunkFolderLastPurgeTime = theTime;
                }

                PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] %s curJunkFolderLastPurgeTime=%s (if blank, then never)", serverIndex, junkFolderURI.get(), curJunkFolderLastPurgeTimeString.get()));

                // check if this account is due to purge
                // has to have been purged at least mMinDelayBetweenPurges minutes ago
                // we don't want to purge the folders all the time
                PRTime nextPurgeTime = curJunkFolderLastPurgeTime + mMinDelayBetweenPurges * 60000000 /* convert mMinDelayBetweenPurges to into microseconds */;
                if (nextPurgeTime < PR_Now())
                {
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] last purge greater than min delay", serverIndex));

                    nsCOMPtr <nsIMsgIncomingServer> junkFolderServer;
                    rv = junkFolder->GetServer(getter_AddRefs(junkFolderServer));
                    NS_ENSURE_SUCCESS(rv,rv);

                    bool serverBusy = false;
                    bool serverRequiresPassword = true;
                    bool passwordPromptRequired;
                    bool canSearchMessages = false;
                    junkFolderServer->GetPasswordPromptRequired(&passwordPromptRequired);
                    junkFolderServer->GetServerBusy(&serverBusy);
                    junkFolderServer->GetServerRequiresPasswordForBiff(&serverRequiresPassword);
                    junkFolderServer->GetCanSearchMessages(&canSearchMessages);
                    // Make sure we're logged on before doing the search (assuming we need to be)
                    // and make sure the server isn't already in the middle of downloading new messages
                    // and make sure a search isn't already going on
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (search in progress? %s)", serverIndex, mSearchSession ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (server busy? %s)", serverIndex, serverBusy ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (serverRequiresPassword? %s)", serverIndex, serverRequiresPassword ? "true" : "false"));
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] (passwordPromptRequired? %s)", serverIndex, passwordPromptRequired ? "true" : "false"));
                    if (canSearchMessages && !mSearchSession && !serverBusy && (!serverRequiresPassword || !passwordPromptRequired))
                    {
                        PRInt32 purgeInterval;
                        spamSettings->GetPurgeInterval(&purgeInterval);

                        if ((oldestPurgeTime == 0) || (curJunkFolderLastPurgeTime < oldestPurgeTime))
                        {
                            PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] purging! searching for messages older than %d days", serverIndex, purgeInterval));
                            oldestPurgeTime = curJunkFolderLastPurgeTime;
                            purgeIntervalToUse = purgeInterval;
                            folderToPurge = junkFolder;
                            // if we've never purged this folder, do it...
                            if (curJunkFolderLastPurgeTime == 0)
                                break;
                        }
                    }
                    else {
                        NS_ASSERTION(canSearchMessages, "unexpected, you should be able to search");
                        PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] not a good time for this server, try again later", serverIndex));
                    }
                }
                else {
                    PR_LOG(MsgPurgeLogModule, PR_LOG_ALWAYS, ("[%d] last purge too recent", serverIndex));
                }
            }
        }
        if (folderToPurge)
            rv = SearchFolderToPurge(folderToPurge, purgeIntervalToUse);
    }

    // set up timer to check accounts again
    SetupNextPurge();
    return rv;
}
nsresult nsMsgSearchOfflineMail::Search (bool *aDone)
{
  nsresult err = NS_OK;

  NS_ENSURE_ARG(aDone);
  nsresult dbErr = NS_OK;
  nsCOMPtr<nsIMsgDBHdr> msgDBHdr;
  nsMsgSearchBoolExpression *expressionTree = nsnull;

  const PRUint32 kTimeSliceInMS = 200;

  *aDone = false;
  // Try to open the DB lazily. This will set up a parser if one is required
  if (!m_db)
    err = OpenSummaryFile ();
  if (!m_db)  // must be reparsing.
    return err;

  // Reparsing is unnecessary or completed
  if (NS_SUCCEEDED(err))
  {
    if (!m_listContext)
      dbErr = m_db->EnumerateMessages (getter_AddRefs(m_listContext));
    if (NS_SUCCEEDED(dbErr) && m_listContext)
    {
      PRIntervalTime startTime = PR_IntervalNow();
      while (!*aDone)  // we'll break out of the loop after kTimeSliceInMS milliseconds
      {
        nsCOMPtr<nsISupports> currentItem;

        dbErr = m_listContext->GetNext(getter_AddRefs(currentItem));
        if(NS_SUCCEEDED(dbErr))
        {
          msgDBHdr = do_QueryInterface(currentItem, &dbErr);
        }
        if (NS_FAILED(dbErr))
          *aDone = true; //###phil dbErr is dropped on the floor. just note that we did have an error so we'll clean up later
        else
        {
          bool match = false;
          nsAutoString nullCharset, folderCharset;
          GetSearchCharsets(nullCharset, folderCharset);
          NS_ConvertUTF16toUTF8 charset(folderCharset);
          // Is this message a hit?
          err = MatchTermsForSearch (msgDBHdr, m_searchTerms, charset.get(), m_scope, m_db, &expressionTree, &match);
          // Add search hits to the results list
          if (NS_SUCCEEDED(err) && match)
          {
            AddResultElement (msgDBHdr);
          }
          PRIntervalTime elapsedTime;
          LL_SUB(elapsedTime, PR_IntervalNow(), startTime);
          // check if more than kTimeSliceInMS milliseconds have elapsed in this time slice started
          if (PR_IntervalToMilliseconds(elapsedTime) > kTimeSliceInMS)
            break;
        }
      }
    }
  }
  else
    *aDone = true; // we couldn't open up the DB. This is an unrecoverable error so mark the scope as done.

  delete expressionTree;

  // in the past an error here would cause an "infinite" search because the url would continue to run...
  // i.e. if we couldn't open the database, it returns an error code but the caller of this function says, oh,
  // we did not finish so continue...what we really want is to treat this current scope as done
  if (*aDone)
    CleanUpScope(); // Do clean up for end-of-scope processing
  return err;
}