Russian Qt Forum
Ноябрь 27, 2024, 02:26 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Портирование с qt3 на qt4.6. Замешательство с QPtrList  (Прочитано 6230 раз)
Serewka
Гость
« : Март 11, 2010, 09:46 »

Добрый день! Помогите разобраться в одном моменте.
у QPtrList ест метод take(). В описании метода написано: Takes the current item out of the list without deleting it.
Какой item является current у метода take() без параметров?

Судя по дальнейшему описанию: The item after the removed item becomes the new current list item if the removed item is not the last item in the list. If the last item is removed, the new last item becomes the current item. The current item is set to 0 if the list becomes empty.
Правильно ли я понял, что это - последний элемент?

Вместо QPtrList я использую QList. Каким методом QList заменить QPtrList::take()? QList::takeLast ()?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Март 11, 2010, 10:55 »

Вместо QPtrList я использую QList. Каким методом QList заменить QPtrList::take()? QList::takeLast ()?

QPtrList::take() указывает именно на текущий элемент, а не на последний. Текущий элемент меняется при помощи методов first(), last(), next() и prev(). Так что QPtrList::take() может указывать на любой жлемент листа. Покажи как можно больше кода, который нужно портировать.
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Serewka
Гость
« Ответ #2 : Март 11, 2010, 14:16 »

над данной коллекцией выполняются в основном однотипные операции: append() и clear(), но есть и функции где организуются итераторы посредством first() и next().

привожу места где используется take()

Код:
SipTransaction *SipCall::newRequest( SipCallMember *member, Sip::Method meth,
                                    const QString &body, const MimeContentType &bodytype, const SipUri &referto,
                                    const QString &proxyauthentication, const QString &authentication,int expiresTime, bool shortTr )
{
  SipTransaction *trans = new SipTransaction( lastseq++, member, this );
  if( trans->sendRequest( meth, body, bodytype, referto, shortTr, proxyauthentication, authentication, expiresTime ) ) {
    if(meth == Sip::PRACK)
    {
      transactions.take(); //take out of queue, do NOT delete
    }
    else
    {
      transactions.clear();
    }
    transactions.append( trans );
    if ( meth == Sip::INVITE )
    {
      member->saveinvite = trans;
    }
    // Audit the call
    auditCall();

    // Return the transaction object for tracking
    return trans;
  }
  else
  {
    delete trans;
    return 0;
  }
}

Код:
SipTransaction *SipCall::newPublish(SipCallMember *callMember,const QString state, const QString sipIfMatch, const SipUri &publishserver, int expiresTime, const QString &authentication, const QString &proxyauthentication, const QString &body)
{
  transactions.clear();
  localuri.setTag( QString::null );
  callMember->setUri(localuri);
  SipTransaction *trans = new SipTransaction( lastseq++, callMember, this );
  transactions.append( trans );
  trans->sendPublish(state,
    sipIfMatch,
    publishserver,
    expiresTime,
    authentication,
    proxyauthentication,
    body
    );
  return trans;
}

далее привожу примеры итераторов по коллекции:

Код:
  SipTransaction *curtrans;

  for ( curtrans = transactions.first(); curtrans != 0; curtrans = transactions.next() )
  {
    if (( incominguri == curtrans->getCallMember()->getUri()) &&
      ( seqnum == curtrans->getSeqNum() ) &&
      ( curtrans->getDirection() == SipTransaction::LocalRequest ) )
    {
      SipCallMember *member = getMember( incominguri );
      if( member == NULL )
      {
        if(KStatics::debugLevel>=2)
          cout << "===SipCall::incomingRequest: member null - do nothing\n";
      } else if( message || message->getStatus().getCode() == 202 )
      {
        // Update the Contact for this member
        if( message->getContactList().getListLength() > 0 )
        {
          member->setContactUri( message->getContactList().getHead() );
        }
        // Update the route
        if( message->getRecordRoute().getListLength() > 0 )
        {
          hasroute = true;
          route = message->getRecordRoute();
          route.reverseList();
          if( !route.getHead().uri().contains( ";lr" ) )
          {
            route.addToEnd( member->getContactUri() );
          }
        }
      }
      if( (message->getStatus().getCode() == 200 ) && (calltype == RegisterCall) )
      {
        QString sr = message->getHeaderData( SipHeader::Service_Route);
        if (sr != "")
        {
          KStatics::serviceRoute = sr;
        }
        else
        {
          KStatics::serviceRoute = "";
        }
      }

      curtrans->incomingResponse( message );
      return;
    }
  }

и тут же встает новый вопрос!

правильна ли замена вышепреведенного участка кода следующим?

Код:
  QList<SipTransaction*>::iterator curtrans;

  for (curtrans = transactions.begin(); curtrans != transactions.end(); ++curtrans)
  {
    if (( incominguri == (*curtrans)->getCallMember()->getUri()) &&
      ( seqnum == (*curtrans)->getSeqNum() ) &&
      ( (*curtrans)->getDirection() == SipTransaction::LocalRequest ) )
    {
      SipCallMember *member = getMember( incominguri );
      if( member == NULL )
      {
        if(KStatics::debugLevel>=2)
          cout << "===SipCall::incomingRequest: member null - do nothing\n";
      } else if( message || message->getStatus().getCode() == 202 )
      {
        // Update the Contact for this member
        if( message->getContactList().getListLength() > 0 )
        {
          member->setContactUri( message->getContactList().getHead() );
        }
        // Update the route
        if( message->getRecordRoute().getListLength() > 0 )
        {
          hasroute = true;
          route = message->getRecordRoute();
          route.reverseList();
          if( !route.getHead().uri().contains( ";lr" ) )
          {
            route.addToEnd( member->getContactUri() );
          }
        }
      }
      if( (message->getStatus().getCode() == 200 ) && (calltype == RegisterCall) )
      {
        QString sr = message->getHeaderData( SipHeader::Service_Route);
        if (sr != "")
        {
          KStatics::serviceRoute = sr;
        }
        else
        {
          KStatics::serviceRoute = "";
        }
      }

      (*curtrans)->incomingResponse( message );
      return;
    }
  }
Записан
Serewka
Гость
« Ответ #3 : Март 11, 2010, 14:21 »

еще 2 итератора и их аналоги (под вопросом)

Код:
  SipTransaction *curtrans;

  if( ( message->getMethod() == Sip::ACK ) || ( message->getMethod() == Sip::CANCEL ) )
  {
    for( curtrans = transactions.first(); curtrans != 0; curtrans = transactions.next() )
    {
      if( ( incominguri == curtrans->getCallMember()->getUri() ) &&
        ( seqnum == curtrans->getSeqNum() ) &&
        ( curtrans->getDirection() == SipTransaction::RemoteRequest ) )
      {
        //Request found
        curtrans->incomingRequest( message, true );
        return 0;
      }
    }
    delete message;
    return 0;
  }

  for( curtrans = transactions.first(); curtrans != 0; curtrans = transactions.next() )
  {
    if( ( incominguri == curtrans->getCallMember()->getUri() ) && ( seqnum == curtrans->getSeqNum() ) &&
      ( seqmethod == curtrans->getSeqMethod() ) &&
      ( curtrans->getDirection() == SipTransaction::RemoteRequest ) )
    {
      curtrans->incomingRequestRetransmission( message );
      return 0;
    }
  }


Аналог

Код:
  QList<SipTransaction*>::iterator curtrans;

  if( ( message->getMethod() == Sip::ACK ) || ( message->getMethod() == Sip::CANCEL ) )
  {
    for (curtrans = transactions.begin(); curtrans != transactions.end(); ++curtrans)
    {
      if( ( incominguri == (*curtrans)->getCallMember()->getUri() ) &&
        ( seqnum == (*curtrans)->getSeqNum() ) &&
        ( (*curtrans)->getDirection() == SipTransaction::RemoteRequest ) )
      {
        //Request found
        (*curtrans)->incomingRequest( message, true );
        return 0;
      }
    }
    delete message;
    return 0;
  }

  for (curtrans = transactions.begin(); curtrans != transactions.end(); ++curtrans)
  {
    if( ( incominguri == (*curtrans)->getCallMember()->getUri() ) && ( seqnum == (*curtrans)->getSeqNum() ) &&
      ( seqmethod == (*curtrans)->getSeqMethod() ) &&
      ( (*curtrans)->getDirection() == SipTransaction::RemoteRequest ) )
    {
      (*curtrans)->incomingRequestRetransmission( message );
      return 0;
    }
  }

В остальных случаях над коллекцией выполняется clear() и append(). В совокупности 13 раз. Если того что я предоставил мало, могу скинуть полный код класса.
« Последнее редактирование: Март 11, 2010, 14:24 от Serewka » Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #4 : Март 11, 2010, 15:07 »

А в каком контекстве вызывается newRequest?

По поводу агалога итераторов: вроде все верно. Ты также можешь использовать QMutableListIterator \ QListIterator.

ЗЫ: Взгляни на раздел в ассистанте Porting to Qt 4
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Serewka
Гость
« Ответ #5 : Март 12, 2010, 01:27 »

А в каком контекстве вызывается newRequest?

что имеется ввиду под контекстом?
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #6 : Март 12, 2010, 05:21 »

что имеется ввиду под контекстом?

покажи код как вызывается этот метод
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Serewka
Гость
« Ответ #7 : Март 12, 2010, 10:59 »

Код:
bool SipCallMember::sendRequestInvite( QString username, QString password )
{
  ourUsername=username;
  ourPassword=password;
  if( !username.isEmpty() && !password.isEmpty() &&
    ( authstate == authState_AuthenticationRequired || authstate == authState_AuthenticationRequiredWithNewPassword || SipCallMember::authState_AuthenticationOK ) ) {
      ourUsername=username;
      ourPassword=password;
      proxyauthresponse=QString::null;
      authresponse=QString::null;
      if( authtype == DigestAuthenticationRequired )
      {
        authresponse = Sip::getDigestResponse(
          username, password, "INVITE", getContactUri().theUri(), proxyauthstr,++nonceCounter );
      }
      else if( authtype == ProxyDigestAuthenticationRequired )
      {
        proxyauthresponse = Sip::getDigestResponse(
          username, password, "INVITE", getContactUri().theUri(), proxyauthstr,++nonceCounter );
      } else if( authtype == ProxyBasicAuthenticationRequired )
      {
        proxyauthresponse = Sip::getBasicResponse( username, password );
      }
      local = call->newRequest( this, Sip::INVITE, localsessiondesc, localsessiontype,
        SipUri::null, proxyauthresponse,authresponse, localExpiresTime );
  }
  else
  {
    local = call->newRequest( this, Sip::INVITE, localsessiondesc, localsessiontype,
      SipUri::null, QString::null, QString::null,localExpiresTime );
  }
  if( localExpiresTime > 0 )
  {
    //timer->start( localExpiresTime * 900, TRUE );
    timer->start( localExpiresTime * 900 );
  }
  if( local )
  {
    op = opRequest;
    if( authstate == authState_AuthenticationRequired ||
      authstate == authState_AuthenticationRequiredWithNewPassword )
    {
        authstate = authState_AuthenticationTryingWithPassword;
    } else if( authstate == SipCallMember::authState_AuthenticationOK)
    {
      ;
    }
    else
    {
      authstate = authState_AuthenticationTrying;
    }
    connect( local, SIGNAL( statusUpdated() ), this, SLOT( localStatusUpdated() ) );
  }
  else
  {
    return false;
  }
  return true;
}


Код:
bool  SipCallMember::requestInvite( const QString &body, const MimeContentType &bodytype )
{
  callMemberType = Invite;
  localsessiondesc = body;
  localsessiontype = bodytype;
  state = state_InviteRequested;
  return sendRequestInvite(ourUsername, ourPassword);
}
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #8 : Март 12, 2010, 14:49 »

Как я понял, при помощи transactions организуется очередь FIFO. И как по мне transactions.take(); удаляет первый элемент очереди. Мой совет: подебаж Qt3 код, посмотри на что указаывает итератор при transactions.take(). Если это всеже очередь по принципу FIFO, и удалется первый элемент замени QPtrList на QQueue
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
Serewka
Гость
« Ответ #9 : Март 12, 2010, 16:59 »

Спасибо за наводку! Буду копать!
Записан
Serewka
Гость
« Ответ #10 : Март 12, 2010, 17:15 »

и еще вопрос!
по использованию в QptrList метода setAutoDelete(true);
как быть в случае QList?
Записан
Dendy
Гость
« Ответ #11 : Март 12, 2010, 18:18 »

Самому явно вызывать delete при удалении элемента из списка и/или qDeleteAll() при очистке контейнера.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.399 секунд. Запросов: 23.