IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Qt Discussion :

[Qt 4.4.3] QByteArray - QDataStream; utiliser << ou >> avec un type quelconque


Sujet :

Qt

  1. #1
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut [Qt 4.4.3] QByteArray - QDataStream; utiliser << ou >> avec un type quelconque
    Bonjour,

    j'ai un petit problème :

    Je suis en train de tenter de faire un peu de communication reseau sur mon programme (TCP).

    Dans le protocole déjà défini (puisque je reprends le programme), au début de chaque trame, je dois envoyer un en-tête qui est une structure.

    Ce que j'aurais voulu faire, c'est utiliser l'opérateur << comme je le fais déjà lorsque je veux faire transiter des types connus (quint8, QString ...).

    Par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    QByteArray data;
    QDataStream out(&data, QIODevice::WriteOnly);
    out << (quint16) 0;  // Fonctionne
    out << header;   // Ne fonctionne pas, header ne fait pas partie de la arguments list de QDataStream &operator
    sachant que header est une structure qui ressemble à ça :
    (Note cmdType est de type enum)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    // format d entete des commandes
    typedef struct _cmdHeader
    {
        cmdType     m_stCmd; // valeur de la commande
        quint32       m_dwSize; // taille de la structure de commande
        quint32       m_dwNextCmdOffset; // position de la prochaine commande dans le cas 
                                       //  des protocoles
    } cmdHeader;

    Comment je pourrais faire sachant que de l'autre côté (côté serveur) j'aimerai aussi récupérer cette structure avec l'opérateur réciproque ?

  2. #2
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968

  3. #3
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    euh...c'est typiquement le genre de docs que je n'arrive pas à comprendre

  4. #4
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    il faut que tu définisse les fonctions
    QDataStream &operator<<(QDataStream &out, const MyClass &myObj);
    QDataStream &operator>>(QDataStream &in, MyClass &myObj);
    et que tu enregistre auprès de Qt
    qRegisterMetaTypeStreamOperators<MyClass>("MyClass");
    Du moins c'est ce que je comprend

  5. #5
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    C'est aussi ce que j'ai compris (et donc j'ai compris que ce n'est pas clair ). ça s'utilise uniquement avec des classes ?

    Avec ça, je n'ai encore jamais fait (en fait si mais y'a très longtemps) de surcharge d'opérateur et donc je ne suis pas à mon aise avec ça.

  6. #6
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kestufou Voir le message
    ça s'utilise uniquement avec des classes ?
    En c++,
    struct == classe public
    Citation Envoyé par Kestufou Voir le message
    Avec ça, je n'ai encore jamais fait (en fait si mais y'a très longtemps) de surcharge d'opérateur et donc je ne suis pas à mon aise avec ça.
    Tu peut te baser sur
    http://cpp.developpez.com/faq/cpp/?p..._polymorphique

  7. #7
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    Humm...ok, dans l'immediat j'ai utilisé writeRawData et readRawData et ça fonctionne, mais pour la beauté du geste j'aimerais mieux <<.

  8. #8
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kestufou Voir le message
    Humm...ok, dans l'immediat j'ai utilisé writeRawData et readRawData et ça fonctionne, mais pour la beauté du geste j'aimerais mieux <<.
    /!\
    writeRawData et readRawData ne sera pas portable

  9. #9
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    ah ok, bien, je regarderai ça.

  10. #10
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Voici un exemples

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    #include <QtGui>
     
    struct maStuct
    {
        qint32 val;
        QString nom;
        void ecrireStream(QDataStream &ds) const
        {
            ds<<val<<nom;
        }
     
        void lireStream(QDataStream &ds)
        {
            ds>>val>>nom;
        }
    };
     
    QDataStream &operator<<(QDataStream &out, const maStuct &myObj)
    {
        myObj.ecrireStream(out);
        return out;
    }
    QDataStream &operator>>(QDataStream &in, maStuct &myObj)
    {
        myObj.lireStream(in);
        return in;
    }
     
     
    int main(int argc, char *argv[])
    {
       /* qRegisterMetaTypeStreamOperators<maStuct>("maStuct");*/
     
        QByteArray ba;
        {
            maStuct ms;
            ms.val =10;
            ms.nom ="salut";
            QDataStream stream(&ba,QIODevice::WriteOnly);
            stream<<ms;
        }
     
        maStuct ms;
        ms.val =5;
        ms.nom ="baba";
        QDataStream stream(ba);
        stream>>ms;
     
        return 0;
    }
    je t'ai dit une connerie pour qRegisterMetaTypeStreamOperators<maStuct>("maStuct");
    Ca sert uniquement quand tu met ta class dans QVariant

  11. #11
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    merci bien, ça marche !
    J'avais le linker qui buggait parce que j'avais inclusion du fichier contenant les définitions des opérateurs à plusieurs endroits, du coup y'avait redefinition.

    Je risque de marquer prochainement en non résolu parce que dans le fichier des structures que mon collègue m'a filé, il a fait plein de structures qui héritent d'autres structure et ainsi de suite. Je pense malgré tout que ce qu'il y a ici devrait m'aider.

  12. #12
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    Bon, me voilà à un point plus corsé.

    Je reprécise : mon collègue m'a filé un .h avec plein de structures dont certaines qui heritent d'autres. Le but étant de transmettre ces structures avec l'opérateur de flux sur un QDataStream sur le réseau.

    J'ai fais les tests avec une structure de base (qui n'hérite de personne donc) et les tests sont concluants.

    Voilà ce que j'ai donc (simplifié) :

    header

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    typedef struct _Base
    {
        quint8 A;
        quint32 B;
        quint64 C; 
     
    #ifdef _QT_
    void outputStream(QDataStream &ds) const
    {
         ds << A << B << C;
    }
     
    void inputStream(QDataStream &ds)
    {
         ds >> A >> B >> C;
    }
    #endif
    } Base;
     
    #ifdef _QT_
    QDataStream &operator<<(QDataStream &out, const Base &structure);
    QDataStream &operator>>(QDataStream &in, Base &structure);
    #endif
    code
    QDataStream &operator<<(QDataStream &out, const Base &structure)
    {
    structure.outputStream(out); // envoie sur le flux de sortie des membres de l'objet (la structure ici)
    return out;
    }
    QDataStream &operator>>(QDataStream &in, Base &structure)
    {
    structure.inputStream(in); // lecture des membres des champs de la structure
    return in;
    }

    Maintenant, ce que je veux savoir (peut-être en s'appuyant sur ça :

    J'ai une structure, toujours dans le header qui ressemble à ça :

    header

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    typedef struct _Derivee : public Base
    {
         QString D;
    } cmdIdent;
    Mes questions : (je suis conscient que c'est plus du C++ que du Qt)
    _Je voudrais définir les opérateurs de flux sur la structure dérivée aussi. Mais d'après l'exemple du lien, il faudrait définir une seule fois les operateurs, le deuxième argument permettant de dissocier quelle méthode virtuelle de quelle classe appeler ?

    _Plus clairement, le second argument de operateur doit-il toujours être une référence constante sur un objet de type de la classe de base ?

    _Si oui à la question ci dessus, est-ce que du coup, c'est le compilateur (ou le linker je sais pas) qui va se charger d'appeler la bonne méthode (la méthode virtuelle Print) ?

    _Si oui toujours, est-ce cela implique que dans chacune de mes structures, mes méthodes outputStream et inputStream doivent être virtuelles ?

    _Si oui , alors dans ma classe dérivée, je pourrais faire de la sorte :
    (version simplifiée : uniquement la méthode suivante : )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void outputStream(QDataStream &ds) const
    {
         ds << A << B << C << D;
    }
    Cette méthode pouvant être contraignante, puis-je simplifier son utilisation en simplifiant (ôh que c'est mal dit) ce qui est en rouge < A << B << C ? Ce qui me donnerait quelque chose (dans l'idée) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    void outputStream(QDataStream &ds) const
    {
         ds << Base << D;
    }
    Je vous remercie de m'avoir lu au moins jusqu'au bout, et j'espère que ce topic en aidera certains.

  13. #13
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    En attendant je vais tester quelque chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void outputStream(QDataStream &ds) const
    {
         Base::outputStream(ds);   // appel à celui de base
         ds << D;
    }

  14. #14
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kestufou Voir le message
    _Je voudrais définir les opérateurs de flux sur la structure dérivée aussi. Mais d'après l'exemple du lien, il faudrait définir une seule fois les operateurs, le deuxième argument permettant de dissocier quelle méthode virtuelle de quelle classe appeler ?
    par polymorphisme oui

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    _Plus clairement, le second argument de operateur doit-il toujours être une référence constante sur un objet de type de la classe de base ?
    ca change rien

    _Si oui à la question ci dessus, est-ce que du coup, c'est le compilateur (ou le linker je sais pas) qui va se charger d'appeler la bonne méthode (la méthode virtuelle Print) ?
    c'est à l'execution

    _Si oui toujours, est-ce cela implique que dans chacune de mes structures, mes méthodes outputStream et inputStream doivent être virtuelles ?
    oui

    _Si oui , alors dans ma classe dérivée, je pourrais faire de la sorte :
    oui
    Cette méthode pouvant être contraignante, puis-je simplifier son utilisation en simplifiant (ôh que c'est mal dit) ce qui est en rouge < A << B << C ? Ce qui me donnerait quelque chose (dans l'idée) :
    en appelant classMere::outputStream(ds)

    Pas trop le temps de rentrer dans les détail tout de suite, mais si tu as des questions n'hésite pas

  15. #15
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kestufou Voir le message
    En attendant je vais tester quelque chose :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    void outputStream(QDataStream &ds) const
    {
         Base::outputStream(ds);   // appel à celui de base
         ds << D;
    }
    ha ben tu t'est auto-répondu alors

  16. #16
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    ha ben tu t'est auto-répondu alors
    ouais, je confirme et ça marche. Il faut 'juste' que je regarde plus en détails ce qu'est le polymorphisme, parce que moi ça me perturbe, je comprends pas pourquoi, avec une méthode recevant une référence sur une Base, lorsqu'on lui donne une référence sur une dérivée alors ça appelle les méthodes de l'objet dérivé

    Concrètement, j'appelle la méthode suivante en lui donnant en second parametre un objet Derive.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    QDataStream &operator<<(QDataStream &out, const Base &structure)
    {
         structure.ouputStream(out);
         return out;
    }
    Comment ça se fait que la méthode outputStream appelée est celle de l'objet Derivee ? C'est le compilateur qui est malin et qui a fait ça tout seul ?

  17. #17
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kestufou Voir le message
    Comment ça se fait que la méthode outputStream appelée est celle de l'objet Derivee ? C'est le compilateur qui est malin et qui a fait ça tout seul ?
    ben c'est le polymorphisme...
    Une reference c'est comme un pointeur mais plus restrictif.
    C'est quoi que tu ne comprend pas? comment cela fonctionne?

  18. #18
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    Une reference c'est comme un pointeur mais plus restrictif
    C'est bien là que ça m'intrigue. Vu qu'une référence c'est comme un pointeur, alors le paramètre chope l'adresse de l'objet, jusque là je comprends. Mais lorsqu'il doit accéder à une méthode de cet objet, que fait-il ? il prend un offset sur la valeur de la référence ?
    Si c'est le cas, se décaler d'un offset correpondant à la méthode de l'objet dérivé dans une classe de base, ferait sortir de l'objet (ce qui n'est pas le cas heureusement) ?
    Ou est-ce que tout simplement, le compilateur fait des tests lors de la compilation, pour voir si - dans le cas où l'argument est un objet Derivee - alors peut-être que l'on a définit des méthodes virtuelles dans la base et les derivees pour se servir du polymorphisme et donc de lui même alors il sait quelle méthode appeler ?

  19. #19
    yan
    yan est déconnecté
    Rédacteur
    Avatar de yan
    Homme Profil pro
    Ingénieur expert
    Inscrit en
    Mars 2004
    Messages
    10 033
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations professionnelles :
    Activité : Ingénieur expert
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Mars 2004
    Messages : 10 033
    Points : 13 968
    Points
    13 968
    Par défaut
    Citation Envoyé par Kestufou Voir le message
    Ou est-ce que tout simplement, le compilateur fait des tests lors de la compilation, pour voir si - dans le cas où l'argument est un objet Derivee - alors peut-être que l'on a définit des méthodes virtuelles dans la base et les derivees pour se servir du polymorphisme et donc de lui même alors il sait quelle méthode appeler ?
    Tout ceci est dynamique, donc le compilot ne peut pas faire grand chose.
    En simplifiant (ça dépend de ce que font les compilateur) une classe sera constitué de
    1- zone correspondant à la class mère
    2- membre
    3- fonction
    4- pointeur de fonction (méthode virtuel)

    Lors d'un héritage tu modifie donc les pointeurs de fonction (méthode virtuel) dans la class mère.
    Pour plus de précision, cherche dans le forum c++ et/ou poste une question

  20. #20
    Membre averti Avatar de MacPro
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    367
    Détails du profil
    Informations personnelles :
    Âge : 40
    Localisation : France, Rhône (Rhône Alpes)

    Informations forums :
    Inscription : Novembre 2007
    Messages : 367
    Points : 344
    Points
    344
    Par défaut
    Je pense que toute la réponse se situe dans l'utilisation du dynamic_cast dont on peut trouver des infos ici ou dans le forum C++.

    Si ça se trouve, lorsque la méthode ayant en argument une référence sur un objet de Base reçoit un objet Derivee, alors une conversion de type s'effectue à notre insu ce qui expliqueait le bins.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. équivalent du couple QByteArray/QDataStream
    Par stardeath dans le forum C++
    Réponses: 7
    Dernier message: 27/07/2011, 14h53
  2. Impossible d'utiliser DISTINCT avec des types image et ntext
    Par azlinch dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 17/08/2005, 18h43
  3. Réponses: 6
    Dernier message: 21/07/2005, 17h56
  4. utilisation de "LIKE" avec un type datetime dans r
    Par ericmart dans le forum Langage SQL
    Réponses: 8
    Dernier message: 06/11/2003, 15h58

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo