<commit_before>#include <iostream>
#include <sstream>

#include "Socket.h"
#include "client.h"
#include "GameState.h"

//Les définitions ci dessous sont toutes les valeurs que peut avoir l'attribut 'status' de la class de base GameState.
//Valeurs générales :
enum STATUS
{
    STATUS_DEFAULT = 0,
    STATUS_BAD_ENTRY = -1,
    STATUS_DISCONNECT = -2,
    STATUS_RETURNMENU = -3,
    STATUS_QUIT = -4
};
//Valeurs pour unlogged :
enum UNLOGGED
{
    UNLOGGED_CONNECTED = 1,
    UNLOGGED_CONNECT = 2,
    UNLOGGED_REGISTER = 3
};
//Valeurs pour menu :
enum MENU
{
    MENU_MANAGEPLAYERS = 1,
    MENU_MANAGEINFRASTRUCTURES = 2,
    MENU_AUCTIONHOUSE = 3,
    MENU_CONNECTEDLIST = 4
};

using namespace std;

GameState::GameState(Client * client)
{
    client_ = client;
    status = STATUS_DEFAULT;
}

GameState::~GameState() {}

void GameState::setNextState(int state)
{
    client_->setNextState(state);
}

IntroState::IntroState(Client * client) : GameState(client)
{
    cout<<"BienvenuS dans le systme !"<<endl;
}
void IntroState::handleEvents() {}
void IntroState::logic()
{
    setNextState(STATE_UNLOGGED);
}
void IntroState::display() {}

//Unlogged-------------------------------------------------------------------------

UnloggedState::UnloggedState(Client * client) : GameState(client)
{
    cout<<"Entrez l'option souhaité avec les paramètres requis délimités par un espace."<<endl;
    cout<<"Exemple : '1 Usr mdp'"<<endl;
    cout<<endl;
    display();
}
void UnloggedState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}

void UnloggedState::logic()
{
    switch (status) {
    case UNLOGGED_CONNECT :
        //envoyer et traiter les données du serveur.
        status = UNLOGGED_CONNECTED;
        setNextState(STATE_MENU);
        break;
    case UNLOGGED_REGISTER :
        //envoyer et traiter les données du serveur.
        break;
    case STATUS_QUIT :
        setNextState(STATE_EXIT);
        break;
    }
}
void UnloggedState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Se connecter : 1 - Nom d'utilisateur - Mot de passe"<<endl;
        cout<<"S'enregistrer : 2 - Nom d'utilisateur - Mot de passe"<<endl;
        cout<<"Quitter : Q"<<endl;
        cout<<endl;
        break;
    case UNLOGGED_CONNECTED :
        cout<<"Connecté."<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }

}

void UnloggedState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                if (inputVec.size() == 3) {
                    nameInput = inputVec[1];
                    passInput = inputVec[2];
                    status = UNLOGGED_CONNECT; //demande de connection
                }
                else {
                    status = STATUS_BAD_ENTRY;
                }
                break;
            case '2' :
                if (inputVec.size() == 3) {
                    nameInput = inputVec[1];
                    passInput = inputVec[2];
                    status = UNLOGGED_REGISTER; //demande d'enregistrement
                }
                else {
                    status = STATUS_BAD_ENTRY;
                }
                break;
            case 'q' :
            case 'Q' :
                status = STATUS_QUIT;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}
//Menu-------------------------------------------------------------------------

MenuState::MenuState(Client * client) : GameState(client)
{
    display();
}
void MenuState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}
void MenuState::logic()
{
    switch (status) {
    case MENU_MANAGEPLAYERS :
        setNextState(STATE_MANAGE_PLAYERS);
        break;
    case MENU_MANAGEINFRASTRUCTURES :
        setNextState(STATE_MANAGE_INFRASTRUCTURES);
        break;
    case MENU_AUCTIONHOUSE :
        setNextState(STATE_AUCTION_HOUSE);
        break;
    case MENU_CONNECTEDLIST :
        setNextState(STATE_CONNECTEDLIST);
        break;
    case STATUS_DISCONNECT : //!! effectuer tout ce qui est nécéssaire pour la déconnection ici
        setNextState(STATE_INTRO);
        break;
    case STATUS_QUIT :
        setNextState(STATE_EXIT);
        break;
    }
}
void MenuState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Gérer votre équipe : 1"<<endl;
        cout<<"Gérer vos infrastructures : 2"<<endl;
        cout<<"Accéder à l'hotel de vente : 3"<<endl;
        cout<<"Voir la liste de connectés. : 4"<<endl;
        cout<<"Se déconnecter : 5"<<endl;
        cout<<"Quitter : Q"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void MenuState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else
        {
            switch (option.c_str()[0]) {
            case '1' :
                status = MENU_MANAGEPLAYERS;
                break;
            case '2' :
                status = MENU_MANAGEINFRASTRUCTURES;
                break;
            case '3' :
                status = MENU_AUCTIONHOUSE;
                break;
            case '4' :
                status = MENU_CONNECTEDLIST;
                break;
            case '5' :
                status = STATUS_DISCONNECT;
                break;
            case 'q' :
            case 'Q' :
                status = STATUS_QUIT;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//ManagePlayer-------------------------------------------------------------------------

ManagePlayerState::ManagePlayerState(Client * client) : GameState(client)
{
    display();
}
void ManagePlayerState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}
void ManagePlayerState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}
void ManagePlayerState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Retourner au menu : 1"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void ManagePlayerState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//ManageInfrastructure-------------------------------------------------------------------------

ManageInfrastructureState::ManageInfrastructureState(Client * client) : GameState(client)
{
    display();
}
void ManageInfrastructureState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}

void ManageInfrastructureState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}

void ManageInfrastructureState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Infrastructures : "<<endl;
        cout<<"Créer une infirmerie. : 1"<<endl; //pour plus tard, spécialiser les messages (créer -> améliorer)
        cout<<"Créer un shop : 2"<<endl;
        cout<<"Revenir au menu : 3"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void ManageInfrastructureState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '3' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//AuctionHouse-------------------------------------------------------------------------

AuctionHouseState::AuctionHouseState(Client * client) : GameState(client)
{
    display();
}
void AuctionHouseState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}

void AuctionHouseState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}

void AuctionHouseState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Hotel des ventes : "<<endl;
        cout<<"Revenir au menu : 1"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void AuctionHouseState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//ConnectedList--------------------------------------------------------------------------

ConnectedListState::ConnectedListState(Client * client) : GameState(client)
{
    display();
}
void ConnectedListState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}
void ConnectedListState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}
void ConnectedListState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Joueurs connectés : "<<endl;
        cout<<"Revenir au menu : 1"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void ConnectedListState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//InGame-------------------------------------------------------------------------

InGameState::InGameState(Client * client) : GameState(client) {}
void InGameState::handleEvents() {}
void InGameState::logic() {}
void InGameState::display() {}

vector<string> &split(const string &s, char delim, vector<string> &elems)
{
    stringstream ss(s);
    string item;
    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }
    return elems;
}

vector<string> split(const string &s, char delim)
{
    vector<string> elems;
    split(s, delim, elems);
    return elems;
}
<commit_msg>[code]Simplified split util function<commit_after>#include <iostream>
#include <sstream>

#include "Socket.h"
#include "client.h"
#include "GameState.h"

//Les définitions ci dessous sont toutes les valeurs que peut avoir l'attribut 'status' de la class de base GameState.
//Valeurs générales :
enum STATUS
{
    STATUS_DEFAULT = 0,
    STATUS_BAD_ENTRY = -1,
    STATUS_DISCONNECT = -2,
    STATUS_RETURNMENU = -3,
    STATUS_QUIT = -4
};

enum UNLOGGED
{
    UNLOGGED_CONNECTED = 1,
    UNLOGGED_CONNECT = 2,
    UNLOGGED_REGISTER = 3
};

enum MENU
{
    MENU_MANAGEPLAYERS = 1,
    MENU_MANAGEINFRASTRUCTURES = 2,
    MENU_AUCTIONHOUSE = 3,
    MENU_CONNECTEDLIST = 4
};

using namespace std;

GameState::GameState(Client * client)
{
    client_ = client;
    status = STATUS_DEFAULT;
}

GameState::~GameState() {}

void GameState::setNextState(int state)
{
    client_->setNextState(state);
}

IntroState::IntroState(Client * client) : GameState(client)
{
    cout<<"BienvenuS dans le systme !"<<endl; //Rework
}
void IntroState::handleEvents() {}
void IntroState::logic()
{
    setNextState(STATE_UNLOGGED);
}
void IntroState::display() {}

//Unlogged-------------------------------------------------------------------------

UnloggedState::UnloggedState(Client * client) : GameState(client)
{
    cout<<"Entrez l'option souhaité avec les paramètres requis délimités par un espace."<<endl;
    cout<<"Exemple : '1 Usr mdp'"<<endl;
    cout<<endl;
    display();
}
void UnloggedState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}

void UnloggedState::logic()
{
    switch (status) {
    case UNLOGGED_CONNECT :
        //envoyer et traiter les données du serveur.
        status = UNLOGGED_CONNECTED;
        setNextState(STATE_MENU);
        break;
    case UNLOGGED_REGISTER :
        //envoyer et traiter les données du serveur.
        break;
    case STATUS_QUIT :
        setNextState(STATE_EXIT);
        break;
    }
}
void UnloggedState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Se connecter : 1 - Nom d'utilisateur - Mot de passe"<<endl;
        cout<<"S'enregistrer : 2 - Nom d'utilisateur - Mot de passe"<<endl;
        cout<<"Quitter : Q"<<endl;
        cout<<endl;
        break;
    case UNLOGGED_CONNECTED :
        cout<<"Connecté."<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }

}

void UnloggedState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                if (inputVec.size() == 3) {
                    nameInput = inputVec[1];
                    passInput = inputVec[2];
                    status = UNLOGGED_CONNECT; //demande de connection
                }
                else {
                    status = STATUS_BAD_ENTRY;
                }
                break;
            case '2' :
                if (inputVec.size() == 3) {
                    nameInput = inputVec[1];
                    passInput = inputVec[2];
                    status = UNLOGGED_REGISTER; //demande d'enregistrement
                }
                else {
                    status = STATUS_BAD_ENTRY;
                }
                break;
            case 'q' :
            case 'Q' :
                status = STATUS_QUIT;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}
//Menu-------------------------------------------------------------------------

MenuState::MenuState(Client * client) : GameState(client)
{
    display();
}
void MenuState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}
void MenuState::logic()
{
    switch (status) {
    case MENU_MANAGEPLAYERS :
        setNextState(STATE_MANAGE_PLAYERS);
        break;
    case MENU_MANAGEINFRASTRUCTURES :
        setNextState(STATE_MANAGE_INFRASTRUCTURES);
        break;
    case MENU_AUCTIONHOUSE :
        setNextState(STATE_AUCTION_HOUSE);
        break;
    case MENU_CONNECTEDLIST :
        setNextState(STATE_CONNECTEDLIST);
        break;
    case STATUS_DISCONNECT : //!! effectuer tout ce qui est nécéssaire pour la déconnection ici
        setNextState(STATE_INTRO);
        break;
    case STATUS_QUIT :
        setNextState(STATE_EXIT);
        break;
    }
}
void MenuState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Gérer votre équipe : 1"<<endl;
        cout<<"Gérer vos infrastructures : 2"<<endl;
        cout<<"Accéder à l'hotel de vente : 3"<<endl;
        cout<<"Voir la liste de connectés. : 4"<<endl;
        cout<<"Se déconnecter : 5"<<endl;
        cout<<"Quitter : Q"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void MenuState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else
        {
            switch (option.c_str()[0]) {
            case '1' :
                status = MENU_MANAGEPLAYERS;
                break;
            case '2' :
                status = MENU_MANAGEINFRASTRUCTURES;
                break;
            case '3' :
                status = MENU_AUCTIONHOUSE;
                break;
            case '4' :
                status = MENU_CONNECTEDLIST;
                break;
            case '5' :
                status = STATUS_DISCONNECT;
                break;
            case 'q' :
            case 'Q' :
                status = STATUS_QUIT;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//ManagePlayer-------------------------------------------------------------------------

ManagePlayerState::ManagePlayerState(Client * client) : GameState(client)
{
    display();
}
void ManagePlayerState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}
void ManagePlayerState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}
void ManagePlayerState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Retourner au menu : 1"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void ManagePlayerState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//ManageInfrastructure-------------------------------------------------------------------------

ManageInfrastructureState::ManageInfrastructureState(Client * client) : GameState(client)
{
    display();
}
void ManageInfrastructureState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}

void ManageInfrastructureState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}

void ManageInfrastructureState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Infrastructures : "<<endl;
        cout<<"Créer une infirmerie. : 1"<<endl; //pour plus tard, spécialiser les messages (créer -> améliorer)
        cout<<"Créer un shop : 2"<<endl;
        cout<<"Revenir au menu : 3"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void ManageInfrastructureState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '3' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//AuctionHouse-------------------------------------------------------------------------

AuctionHouseState::AuctionHouseState(Client * client) : GameState(client)
{
    display();
}
void AuctionHouseState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}

void AuctionHouseState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}

void AuctionHouseState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Hotel des ventes : "<<endl;
        cout<<"Revenir au menu : 1"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void AuctionHouseState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//ConnectedList--------------------------------------------------------------------------

ConnectedListState::ConnectedListState(Client * client) : GameState(client)
{
    display();
}
void ConnectedListState::handleEvents()
{
    string inputString;
    getline(cin, inputString);
    vector<string> inputVec = split(inputString, ' ');
    parse(inputVec);
}
void ConnectedListState::logic()
{
    switch (status) {
    case STATUS_RETURNMENU :
        setNextState(STATE_MENU);
        break;
    }
}
void ConnectedListState::display()
{
    switch (status) {
    case STATUS_DEFAULT :
        cout<<"Joueurs connectés : "<<endl;
        cout<<"Revenir au menu : 1"<<endl;
        cout<<endl;
        break;
    case STATUS_BAD_ENTRY :
        cout<<"Erreur : votre entrée est incorrecte."<<endl;
        cout<<endl;
        break;
    }
}

void ConnectedListState::parse(vector<string> & inputVec)
{
    if (inputVec.empty() == true)
        status = STATUS_BAD_ENTRY;
    else {
        string option = inputVec[0];
        if (option.size() != 1 or inputVec.size() != 1)
            status = STATUS_BAD_ENTRY;
        else {
            switch (option.c_str()[0]) {
            case '1' :
                status = STATUS_RETURNMENU;
                break;
            default :
                status = STATUS_BAD_ENTRY;
                break;
            }
        }
    }
}

//InGame-------------------------------------------------------------------------

InGameState::InGameState(Client * client) : GameState(client) {}
void InGameState::handleEvents() {}
void InGameState::logic() {}
void InGameState::display() {}

//Utilitaire--------------------------------------------------------------------------
vector<string> split(const string &text, char delim)
{
    stringstream ss(text);
    string item;
    vector<string> elems;

    while (getline(ss, item, delim)) {
        elems.push_back(item);
    }

    return elems;
}
<|endoftext|>


<commit_before>// Copyright (c) 2014, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <gflags/gflags.h>

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <stdlib.h>

#include "common/timer.h"
#include "sdk/bfs.h"

DECLARE_string(flagfile);
DECLARE_string(nameserver);
DECLARE_string(nameserver_port);

void print_usage() {
    printf("Use:\nbfs_client <commond> path\n");
    printf("\t commond:\n");
    printf("\t    ls <path> : list the directory\n");
    printf("\t    cat <path> : cat the file\n");
    printf("\t    mkdir <path> : make director\n");
    printf("\t    mv <srcpath> <destpath> : rename director or file\n");
    printf("\t    touchz <path> : create a new file\n");
    printf("\t    rm <path> : remove a file\n");
    printf("\t    get <bfsfile> <localfile> : copy file to local\n");
    printf("\t    put <localfile> <bfsfile> : copy file from local to bfs\n");
    printf("\t    append <localfile> <bfsfile> : append localfile to bfsfile\n");
    printf("\t    rmdir <path> : remove empty directory\n");
    printf("\t    rmr <path> : remove directory recursively\n");
    printf("\t    change_replica_num <bfsfile> <num>: change replica num of <bfsfile> to <num>\n");
    printf("\t    du <path> : count disk usage for path\n");
}

int BfsMkdir(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->CreateDirectory(argv[0]);
    if (!ret) {
        fprintf(stderr, "Create dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsRename(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bool ret = fs->Rename(argv[0], argv[1]);
    if (!ret) {
        fprintf(stderr, "Rename %s to %s fail\n", argv[0], argv[1]);
        return 1;
    }
    return 0;
}

int BfsCat(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    for (int i = 0; i < argc; i++) {
        bfs::File* file;
        if (!fs->OpenFile(argv[i], O_RDONLY, &file)) {
            fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
            return 1;
        }
        char buf[10240];
        int64_t bytes = 0;
        int64_t len = 0;
        while (1) {
            len = file->Read(buf, sizeof(buf));
            if (len <= 0) {
                break;
            }
            bytes += len;
            write(1, buf, len);
        }
        delete file;
    }
    return 0;
}

int BfsGet(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bfs::File* file;
    if (!fs->OpenFile(argv[0], O_RDONLY, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
        return 1;
    }

    FILE* fp = fopen(argv[1], "wb");
    if (fp == NULL) {
        fprintf(stderr, "Open local file %s fail\n", argv[1]);
        delete file;
        return -1;
    }
    char buf[10240];
    int64_t bytes = 0;
    int64_t len = 0;
    while (1) {
        len = file->Read(buf, sizeof(buf));
        if (len <= 0) {
            break;
        }
        bytes += len;
        fwrite(buf, len, 1, fp);
    }
    printf("Read %ld bytes from %s\n", bytes, argv[1]);
    delete file;
    fclose(fp);
    return 0;
}

int BfsPut(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }

    int ret = 0;
    common::timer::AutoTimer at(0, "BfsPut", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_WRONLY | O_TRUNC, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        fclose(fp);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Write fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        ret = 1;
    }
    delete file;
    fclose(fp);
    printf("Put file to bfs %s %ld bytes\n", argv[3], len);
    return ret;
}

int64_t BfsDuRecursive(bfs::FS* fs, const std::string& path) {
    int64_t ret = 0;
    bfs::BfsFileInfo* files = NULL;
    int num = 0;
    fs->ListDirectory(path.c_str(), &files, &num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        if (type & (1<<9)) {
            ret += BfsDuRecursive(fs, files[i].name);
            continue;
        }
        bfs::BfsFileInfo fileinfo;
        if (fs->Stat(files[i].name, &fileinfo)) {
            ret += fileinfo.size;
            printf("%s\t %ld\n", files[i].name, fileinfo.size);
        }
    }
    delete files;
    return ret;
}

int BfsDu(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 1) {
        print_usage();
        return 1;
    }
    int64_t du = BfsDuRecursive(fs, argv[0]);
    printf("Total:\t%ld\n", du);
    return 0;
}

int BfsList(bfs::FS* fs, int argc, char* argv[]) {
    std::string path("/");
    if (argc == 3) {
        path = argv[2];
    }
    bfs::BfsFileInfo* files = NULL;
    int num;
    fs->ListDirectory(path.c_str(), &files, &num);
    printf("Found %d items\n", num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        char statbuf[16] = "drwxrwxrwx";
        for (int j = 0; j < 10; j++) {
            if ((type & (1<<(9-j))) == 0) {
                statbuf[j] = '-';
            }
        }
        char timestr[64];
        struct tm stm;
        time_t ctime = files[i].ctime;
        localtime_r(&ctime, &stm);
        snprintf(timestr, sizeof(timestr), "%4d-%02d-%02d %2d:%02d",
            stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday, stm.tm_hour, stm.tm_min);
        printf("%s\t%s  %s\n", statbuf, timestr, files[i].name);
    }
    delete files;
    return 0;
}

int BfsAppend(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }
    common::timer::AutoTimer at(0, "BfsAppend", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_APPEND, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        fclose(fp);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Append fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        return 1;
    }
    delete file;
    fclose(fp);
    printf("Append to bfs %s %ld bytes\n", argv[3], len);
    return 0;
}

int BfsRmdir(bfs::FS* fs, int argc, char* argv[], bool recursive) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->DeleteDirectory(argv[0], recursive);
    if (!ret) {
        fprintf(stderr, "Remove dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsChangeReplicaNum(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    char* file_name = argv[0];
    int32_t replica_num = atoi(argv[1]);
    bool ret = fs->ChangeReplicaNum(file_name, replica_num);
    if (!ret) {
        fprintf(stderr, "Change %s replica num to %d fail\n", file_name, replica_num);
        return 1;
    }
    return 0;
}

/// bfs client main
int main(int argc, char* argv[]) {
    FLAGS_flagfile = "./bfs.flag";
    ::google::ParseCommandLineFlags(&argc, &argv, false);

    if (argc < 2) {
        print_usage();
        return 0;
    }

    bfs::FS* fs;
    std::string ns_address = FLAGS_nameserver + ":" + FLAGS_nameserver_port;
    if (!bfs::FS::OpenFileSystem(ns_address.c_str(), &fs)) {
        fprintf(stderr, "Open filesytem %s fail\n", ns_address.c_str());
        return 1;
    }

    int ret = 1;
    if (strcmp(argv[1], "touchz") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        bfs::File* file;
        if (!fs->OpenFile(argv[2], O_WRONLY, &file)) {
            fprintf(stderr, "Open %s fail\n", argv[2]);
        } else {
            ret = 0;
        }
    } else if (strcmp(argv[1], "rm") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        if (fs->DeleteFile(argv[2])) {
            printf("%s Removed\n", argv[2]);
            ret = 0;
        } else {
            fprintf(stderr, "Remove file fail: %s\n", argv[2]);
        }
    } else if (strcmp(argv[1], "mkdir") == 0) {
        ret = BfsMkdir(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "mv") == 0) {
        ret = BfsRename(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "put") == 0) {
        ret = BfsPut(fs, argc, argv);
    } else if (strcmp(argv[1], "get") == 0 ) {
        ret = BfsGet(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "cat") == 0) {
        ret = BfsCat(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "ls") == 0) {
        ret = BfsList(fs, argc, argv);
    } else if (strcmp(argv[1], "append") == 0) {
        ret = BfsAppend(fs, argc, argv);
    } else if (strcmp(argv[1], "rmdir") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, false);
    } else if (strcmp(argv[1], "rmr") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, true);
    } else if (strcmp(argv[1], "change_replica_num") == 0) {
        ret = BfsChangeReplicaNum(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "du") == 0) {
        ret = BfsDu(fs, argc - 2, argv + 2);
    } else {
        fprintf(stderr, "Unknow common: %s\n", argv[1]);
    }
    return ret;
}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<commit_msg>Ajust Writebuf for client put<commit_after>// Copyright (c) 2014, Baidu.com, Inc. All Rights Reserved
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// Author: yanshiguang02@baidu.com

#include <gflags/gflags.h>

#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <string>
#include <unistd.h>
#include <stdlib.h>

#include "common/timer.h"
#include "sdk/bfs.h"

DECLARE_string(flagfile);
DECLARE_string(nameserver);
DECLARE_string(nameserver_port);

void print_usage() {
    printf("Use:\nbfs_client <commond> path\n");
    printf("\t commond:\n");
    printf("\t    ls <path> : list the directory\n");
    printf("\t    cat <path> : cat the file\n");
    printf("\t    mkdir <path> : make director\n");
    printf("\t    mv <srcpath> <destpath> : rename director or file\n");
    printf("\t    touchz <path> : create a new file\n");
    printf("\t    rm <path> : remove a file\n");
    printf("\t    get <bfsfile> <localfile> : copy file to local\n");
    printf("\t    put <localfile> <bfsfile> : copy file from local to bfs\n");
    printf("\t    append <localfile> <bfsfile> : append localfile to bfsfile\n");
    printf("\t    rmdir <path> : remove empty directory\n");
    printf("\t    rmr <path> : remove directory recursively\n");
    printf("\t    change_replica_num <bfsfile> <num>: change replica num of <bfsfile> to <num>\n");
    printf("\t    du <path> : count disk usage for path\n");
}

int BfsMkdir(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->CreateDirectory(argv[0]);
    if (!ret) {
        fprintf(stderr, "Create dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsRename(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bool ret = fs->Rename(argv[0], argv[1]);
    if (!ret) {
        fprintf(stderr, "Rename %s to %s fail\n", argv[0], argv[1]);
        return 1;
    }
    return 0;
}

int BfsCat(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    for (int i = 0; i < argc; i++) {
        bfs::File* file;
        if (!fs->OpenFile(argv[i], O_RDONLY, &file)) {
            fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
            return 1;
        }
        char buf[10240];
        int64_t bytes = 0;
        int64_t len = 0;
        while (1) {
            len = file->Read(buf, sizeof(buf));
            if (len <= 0) {
                break;
            }
            bytes += len;
            write(1, buf, len);
        }
        delete file;
    }
    return 0;
}

int BfsGet(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    bfs::File* file;
    if (!fs->OpenFile(argv[0], O_RDONLY, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[0]);
        return 1;
    }

    FILE* fp = fopen(argv[1], "wb");
    if (fp == NULL) {
        fprintf(stderr, "Open local file %s fail\n", argv[1]);
        delete file;
        return -1;
    }
    char buf[10240];
    int64_t bytes = 0;
    int64_t len = 0;
    while (1) {
        len = file->Read(buf, sizeof(buf));
        if (len <= 0) {
            break;
        }
        bytes += len;
        fwrite(buf, len, 1, fp);
    }
    printf("Read %ld bytes from %s\n", bytes, argv[1]);
    delete file;
    fclose(fp);
    return 0;
}

int BfsPut(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }

    int ret = 0;
    common::timer::AutoTimer at(0, "BfsPut", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_WRONLY | O_TRUNC, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        fclose(fp);
        return 1;
    }
    char buf[10240];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Write fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        ret = 1;
    }
    delete file;
    fclose(fp);
    printf("Put file to bfs %s %ld bytes\n", argv[3], len);
    return ret;
}

int64_t BfsDuRecursive(bfs::FS* fs, const std::string& path) {
    int64_t ret = 0;
    bfs::BfsFileInfo* files = NULL;
    int num = 0;
    fs->ListDirectory(path.c_str(), &files, &num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        if (type & (1<<9)) {
            ret += BfsDuRecursive(fs, files[i].name);
            continue;
        }
        bfs::BfsFileInfo fileinfo;
        if (fs->Stat(files[i].name, &fileinfo)) {
            ret += fileinfo.size;
            printf("%s\t %ld\n", files[i].name, fileinfo.size);
        }
    }
    delete files;
    return ret;
}

int BfsDu(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 1) {
        print_usage();
        return 1;
    }
    int64_t du = BfsDuRecursive(fs, argv[0]);
    printf("Total:\t%ld\n", du);
    return 0;
}

int BfsList(bfs::FS* fs, int argc, char* argv[]) {
    std::string path("/");
    if (argc == 3) {
        path = argv[2];
    }
    bfs::BfsFileInfo* files = NULL;
    int num;
    fs->ListDirectory(path.c_str(), &files, &num);
    printf("Found %d items\n", num);
    for (int i = 0; i < num; i++) {
        int32_t type = files[i].mode;
        char statbuf[16] = "drwxrwxrwx";
        for (int j = 0; j < 10; j++) {
            if ((type & (1<<(9-j))) == 0) {
                statbuf[j] = '-';
            }
        }
        char timestr[64];
        struct tm stm;
        time_t ctime = files[i].ctime;
        localtime_r(&ctime, &stm);
        snprintf(timestr, sizeof(timestr), "%4d-%02d-%02d %2d:%02d",
            stm.tm_year+1900, stm.tm_mon+1, stm.tm_mday, stm.tm_hour, stm.tm_min);
        printf("%s\t%s  %s\n", statbuf, timestr, files[i].name);
    }
    delete files;
    return 0;
}

int BfsAppend(bfs::FS* fs, int argc, char* argv[]) {
    if (argc != 4) {
        print_usage();
        return 0;
    }
    common::timer::AutoTimer at(0, "BfsAppend", argv[3]);
    FILE* fp = fopen(argv[2], "rb");
    if (fp == NULL) {
        fprintf(stderr, "Can't open local file %s\n", argv[2]);
        return 1;
    }

    bfs::File* file;
    if (!fs->OpenFile(argv[3], O_APPEND, &file)) {
        fprintf(stderr, "Can't Open bfs file %s\n", argv[3]);
        fclose(fp);
        return 1;
    }
    char buf[1024];
    int64_t len = 0;
    int64_t bytes = 0;
    while ( (bytes = fread(buf, 1, sizeof(buf), fp)) > 0) {
        int64_t write_bytes = file->Write(buf, bytes);
        if (write_bytes < bytes) {
            fprintf(stderr, "Append fail: [%s:%ld]\n", argv[3], len);
            return 1;
        }
        len += bytes;
    }
    if (!fs->CloseFile(file)) {
        fprintf(stderr, "close fail: %s\n", argv[3]);
        return 1;
    }
    delete file;
    fclose(fp);
    printf("Append to bfs %s %ld bytes\n", argv[3], len);
    return 0;
}

int BfsRmdir(bfs::FS* fs, int argc, char* argv[], bool recursive) {
    if (argc < 1) {
        print_usage();
        return 1;
    }
    bool ret = fs->DeleteDirectory(argv[0], recursive);
    if (!ret) {
        fprintf(stderr, "Remove dir %s fail\n", argv[0]);
        return 1;
    }
    return 0;
}

int BfsChangeReplicaNum(bfs::FS* fs, int argc, char* argv[]) {
    if (argc < 2) {
        print_usage();
        return 1;
    }
    char* file_name = argv[0];
    int32_t replica_num = atoi(argv[1]);
    bool ret = fs->ChangeReplicaNum(file_name, replica_num);
    if (!ret) {
        fprintf(stderr, "Change %s replica num to %d fail\n", file_name, replica_num);
        return 1;
    }
    return 0;
}

/// bfs client main
int main(int argc, char* argv[]) {
    FLAGS_flagfile = "./bfs.flag";
    ::google::ParseCommandLineFlags(&argc, &argv, false);

    if (argc < 2) {
        print_usage();
        return 0;
    }

    bfs::FS* fs;
    std::string ns_address = FLAGS_nameserver + ":" + FLAGS_nameserver_port;
    if (!bfs::FS::OpenFileSystem(ns_address.c_str(), &fs)) {
        fprintf(stderr, "Open filesytem %s fail\n", ns_address.c_str());
        return 1;
    }

    int ret = 1;
    if (strcmp(argv[1], "touchz") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        bfs::File* file;
        if (!fs->OpenFile(argv[2], O_WRONLY, &file)) {
            fprintf(stderr, "Open %s fail\n", argv[2]);
        } else {
            ret = 0;
        }
    } else if (strcmp(argv[1], "rm") == 0) {
        if (argc != 3) {
            print_usage();
            return ret;
        }
        if (fs->DeleteFile(argv[2])) {
            printf("%s Removed\n", argv[2]);
            ret = 0;
        } else {
            fprintf(stderr, "Remove file fail: %s\n", argv[2]);
        }
    } else if (strcmp(argv[1], "mkdir") == 0) {
        ret = BfsMkdir(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "mv") == 0) {
        ret = BfsRename(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "put") == 0) {
        ret = BfsPut(fs, argc, argv);
    } else if (strcmp(argv[1], "get") == 0 ) {
        ret = BfsGet(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "cat") == 0) {
        ret = BfsCat(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "ls") == 0) {
        ret = BfsList(fs, argc, argv);
    } else if (strcmp(argv[1], "append") == 0) {
        ret = BfsAppend(fs, argc, argv);
    } else if (strcmp(argv[1], "rmdir") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, false);
    } else if (strcmp(argv[1], "rmr") == 0) {
        ret = BfsRmdir(fs, argc - 2, argv + 2, true);
    } else if (strcmp(argv[1], "change_replica_num") == 0) {
        ret = BfsChangeReplicaNum(fs, argc - 2, argv + 2);
    } else if (strcmp(argv[1], "du") == 0) {
        ret = BfsDu(fs, argc - 2, argv + 2);
    } else {
        fprintf(stderr, "Unknow common: %s\n", argv[1]);
    }
    return ret;
}

/* vim: set expandtab ts=4 sw=4 sts=4 tw=100: */
<|endoftext|>


<commit_before>//
// ulib - a collection of useful classes
// Copyright (C) 2018 Michael Fink
//
/// \file TestCommandLineParser.cpp tests for CommandLineParser class
//

#include "stdafx.h"
#include "CppUnitTest.h"
#include <ulib/CommandLineParser.hpp>
#include <ulib/win32/VersionInfoResource.hpp>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest
{
   /// tests for VersionInfoResource class
   TEST_CLASS(TestVersionInfoResource)
   {
      /// tests loading version info resource
      TEST_METHOD(TestLoadVersionInfo)
      {
         // get module filename
         CString filename;
         GetModuleFileName(NULL, filename.GetBuffer(MAX_PATH), MAX_PATH);
         filename.ReleaseBuffer();

         // version info resource for current file
         Win32::VersionInfoResource vir(filename);
         Assert::IsTrue(vir.IsAvail());

         {
            Win32::FixedFileInfo* pFixedFileInfo = vir.GetFixedFileInfo();
            Assert::IsNotNull(pFixedFileInfo);
            Assert::IsTrue(pFixedFileInfo->dwSignature == 0xFEEF04BD);

            Win32::FixedFileInfo& fixedFileInfo = *pFixedFileInfo;

            // print out all fixed file infos
            ATLTRACE(_T("fileversion=%u.%u.%u.%u productversion=%u.%u.%u.%u structver=%u.%u\n")
               _T("fileflags=%08x mask=%08x os=%08x type=%08x subtype=%08x date=0x%08x%08x\n")
               _T("os=%s type=%s"),
               HIWORD(fixedFileInfo.dwFileVersionMS), LOWORD(fixedFileInfo.dwFileVersionMS),
               HIWORD(fixedFileInfo.dwFileVersionLS), LOWORD(fixedFileInfo.dwFileVersionLS),
               HIWORD(fixedFileInfo.dwProductVersionMS), LOWORD(fixedFileInfo.dwProductVersionMS),
               HIWORD(fixedFileInfo.dwProductVersionLS), LOWORD(fixedFileInfo.dwProductVersionLS),
               HIWORD(fixedFileInfo.dwStrucVersion), LOWORD(fixedFileInfo.dwStrucVersion),
               fixedFileInfo.dwFileFlags,          // e.g. VFF_DEBUG | VFF_PRERELEASE
               fixedFileInfo.dwFileFlagsMask,      // = 0x3F for version "0.42"
               fixedFileInfo.dwFileOS,             // e.g. VOS_DOS_WINDOWS16
               fixedFileInfo.dwFileType,           // e.g. VFT_DRIVER
               fixedFileInfo.dwFileSubtype,        // e.g. VFT2_DRV_KEYBOARD
               fixedFileInfo.dwFileDateMS,         // e.g. 0
               fixedFileInfo.dwFileDateLS,         // e.g. 0
               fixedFileInfo.GetFileOS(),
               fixedFileInfo.GetFileType());
         }

         // show languages and codepages
         {
            std::vector<Win32::LANGANDCODEPAGE> langAndCodepagesList;
            vir.GetLangAndCodepages(langAndCodepagesList);

            Assert::IsTrue(langAndCodepagesList.size() > 0);

            // print out all languages and codepages
            for (size_t i = 0; i < langAndCodepagesList.size(); i++)
            {
               ATLTRACE(_T("language %04x [%d] codepage %04x [%d]"),
                  langAndCodepagesList[i].wLanguage, langAndCodepagesList[i].wLanguage,
                  langAndCodepagesList[i].wCodePage, langAndCodepagesList[i].wCodePage);

               // show all language-dependent strings
               LPCTSTR allNames[] =
               {
                  _T("Comments"),
                  _T("CompanyName"),
                  _T("FileDescription"),
                  _T("FileVersion"),
                  _T("InternalName"),
                  _T("LegalCopyright"),
                  _T("LegalTrademarks"),
                  _T("OriginalFilename"),
                  _T("ProductName"),
                  _T("ProductVersion"),
                  _T("PrivateBuild"),
                  _T("SpecialBuild")
               };

               for (unsigned int j = 0; j < sizeof(allNames) / sizeof(*allNames); j++)
               {
                  ATLTRACE(_T("  name \"%-17s: [%s]"),
                     CString(allNames[j]) + _T("\""),
                     vir.GetStringValue(langAndCodepagesList[i], allNames[j]));
               }
            }
         }
      }
   };

} // namespace UnitTest
<commit_msg>fixed warnings in test for VersionInfoResource<commit_after>//
// ulib - a collection of useful classes
// Copyright (C) 2018 Michael Fink
//
/// \file TestCommandLineParser.cpp tests for CommandLineParser class
//

#include "stdafx.h"
#include "CppUnitTest.h"
#include <ulib/CommandLineParser.hpp>
#include <ulib/win32/VersionInfoResource.hpp>

using namespace Microsoft::VisualStudio::CppUnitTestFramework;

namespace UnitTest
{
   /// tests for VersionInfoResource class
   TEST_CLASS(TestVersionInfoResource)
   {
      /// tests loading version info resource
      TEST_METHOD(TestLoadVersionInfo)
      {
         // get module filename
         CString filename;
         GetModuleFileName(NULL, filename.GetBuffer(MAX_PATH), MAX_PATH);
         filename.ReleaseBuffer();

         // version info resource for current file
         Win32::VersionInfoResource vir(filename);
         Assert::IsTrue(vir.IsAvail());

         {
            Win32::FixedFileInfo* pFixedFileInfo = vir.GetFixedFileInfo();
            Assert::IsNotNull(pFixedFileInfo);
            Assert::IsTrue(pFixedFileInfo->dwSignature == 0xFEEF04BD);

            Win32::FixedFileInfo& fixedFileInfo = *pFixedFileInfo;

            // print out all fixed file infos
            ATLTRACE(_T("fileversion=%u.%u.%u.%u productversion=%u.%u.%u.%u structver=%u.%u\n")
               _T("fileflags=%08x mask=%08x os=%08x type=%08x subtype=%08x date=0x%08x%08x\n")
               _T("os=%s type=%s"),
               HIWORD(fixedFileInfo.dwFileVersionMS), LOWORD(fixedFileInfo.dwFileVersionMS),
               HIWORD(fixedFileInfo.dwFileVersionLS), LOWORD(fixedFileInfo.dwFileVersionLS),
               HIWORD(fixedFileInfo.dwProductVersionMS), LOWORD(fixedFileInfo.dwProductVersionMS),
               HIWORD(fixedFileInfo.dwProductVersionLS), LOWORD(fixedFileInfo.dwProductVersionLS),
               HIWORD(fixedFileInfo.dwStrucVersion), LOWORD(fixedFileInfo.dwStrucVersion),
               fixedFileInfo.dwFileFlags,          // e.g. VFF_DEBUG | VFF_PRERELEASE
               fixedFileInfo.dwFileFlagsMask,      // = 0x3F for version "0.42"
               fixedFileInfo.dwFileOS,             // e.g. VOS_DOS_WINDOWS16
               fixedFileInfo.dwFileType,           // e.g. VFT_DRIVER
               fixedFileInfo.dwFileSubtype,        // e.g. VFT2_DRV_KEYBOARD
               fixedFileInfo.dwFileDateMS,         // e.g. 0
               fixedFileInfo.dwFileDateLS,         // e.g. 0
               fixedFileInfo.GetFileOS().GetString(),
               fixedFileInfo.GetFileType().GetString());
         }

         // show languages and codepages
         {
            std::vector<Win32::LANGANDCODEPAGE> langAndCodepagesList;
            vir.GetLangAndCodepages(langAndCodepagesList);

            Assert::IsTrue(langAndCodepagesList.size() > 0);

            // print out all languages and codepages
            for (size_t i = 0; i < langAndCodepagesList.size(); i++)
            {
               ATLTRACE(_T("language %04x [%d] codepage %04x [%d]"),
                  langAndCodepagesList[i].wLanguage, langAndCodepagesList[i].wLanguage,
                  langAndCodepagesList[i].wCodePage, langAndCodepagesList[i].wCodePage);

               // show all language-dependent strings
               LPCTSTR allNames[] =
               {
                  _T("Comments"),
                  _T("CompanyName"),
                  _T("FileDescription"),
                  _T("FileVersion"),
                  _T("InternalName"),
                  _T("LegalCopyright"),
                  _T("LegalTrademarks"),
                  _T("OriginalFilename"),
                  _T("ProductName"),
                  _T("ProductVersion"),
                  _T("PrivateBuild"),
                  _T("SpecialBuild")
               };

               for (unsigned int j = 0; j < sizeof(allNames) / sizeof(*allNames); j++)
               {
                  ATLTRACE(_T("  name \"%-17s: [%s]"),
                     (CString(allNames[j]) + _T("\"")).GetString(),
                     vir.GetStringValue(langAndCodepagesList[i], allNames[j]).GetString());
               }
            }
         }
      }
   };

} // namespace UnitTest
<|endoftext|>


<commit_before>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_option_message.hpp
 * @brief		iris unit test コマンドラインメッセージ ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_
#define INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_

//======================================================================
// include
#include "iutest_console.hpp"

namespace iutest {
namespace detail
{

//======================================================================
// class
class iuOptionMessage
{
public:
	/**
	 * @brief	ヘルプの出力
	*/
	static void ShowHelp();
	/**
	 * @brief	バージョン出力
	*/
	static void ShowVersion();
	/**
	 * @brief	機能出力
	*/
	static void ShowFeature();
	/**
	 * @brief	コンパイラスペック出力
	*/
	static void ShowSpec();
};

inline void iuOptionMessage::ShowHelp()
{
	const char* readme =
		"--------------------------------------------------\n"
		"Name\n"
		"    iutest - iris unit test framework\n"
		"--------------------------------------------------\n"
		"Command Line Options\n"
		"\n"
		"    --help, -h                       : Generate help message.\n"
		"    --iutest_output=xml[:path]       : Path of xml report.\n"
		"    --iutest_list_tests              : List up tests.\n"
		"    --iutest_list_tests_with_where   : List up tests with where.\n"
		"    --iutest_color=<yes|no|auto|ansi>: Console color enable.\n"
		"    --iutest_flagfile=<file>         : Set the flag from the file.\n"
		"    --iutest_filter=<filter>         : Select the test run.\n"
		"    --iutest_shuffle                 : Do shuffle test.\n"
		"    --iutest_random_seed=<seed>      : Set random seed.\n"
		"    --iutest_also_run_disabled_tests : Run disabled tests.\n"
		"    --iutest_break_on_failure[=0|1]  : When that failed to break.\n"
		"    --iutest_throw_on_failure[=0|1]  : When that failed to throw.\n"
		"    --iutest_catch_exceptions=<0|1>  : Catch exceptions enable.\n"
		"    --iutest_print_time=<0|1>        : Setting the display of elapsed time.\n"
		"    --iutest_repeat=<count>          : Set the number of repetitions\n"
		"                                       of the test.\n"
#if IUTEST_HAS_STREAM_RESULT
		"    --iutest_stream_result_to=<host:port>\n"
		"                                     : Set stream test results server.\n"
#endif
		"    --iutest_file_location=<auto|vs|gcc>\n"
		"                                     : Format file location messages.\n"
		"    --verbose                        : Verbose option.\n"
		"    --feature                        : Show iutest feature.\n"
		"    --version, -v                    : Show iutest version.\n"
		"\n"
		"--------------------------------------------------\n"
		"License\n"
		"\n"
		"    Copyright (c) 2011-2015, Takazumi-Shirayanagi\n"
		"\n"
		"    This software is released under the new BSD License, see LICENSE\n"
		"\n";
	detail::iuConsole::color_output(detail::iuConsole::cyan, readme);
}

inline void iuOptionMessage::ShowVersion()
{
	detail::iuConsole::output("iutest version %x.%x.%x.%x\n"
		, IUTEST_MAJORVER, IUTEST_MINORVER, IUTEST_BUILD, IUTEST_REVISION);
}

/** @private */
#define IIUT_SHOW_MACRO(macro)	detail::iuConsole::output("#define %s  %s\n", #macro, IUTEST_PP_TOSTRING(macro))

inline void iuOptionMessage::ShowFeature()
{
	IIUT_SHOW_MACRO(IUTEST_HAS_ANY_PARAM_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT);
	IIUT_SHOW_MACRO(IUTEST_HAS_ASSERTION_RETURN);
	IIUT_SHOW_MACRO(IUTEST_HAS_AUTOFIXTURE_PARAM_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_COMBINE);
	IIUT_SHOW_MACRO(IUTEST_HAS_CONCAT);
	IIUT_SHOW_MACRO(IUTEST_HAS_CSVPARAMS);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
	IIUT_SHOW_MACRO(IUTEST_HAS_GENRAND);
	IIUT_SHOW_MACRO(IUTEST_HAS_IGNORE_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_LIB);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHERS);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_ELEMENTSARE);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_REGEX);
	IIUT_SHOW_MACRO(IUTEST_HAS_MINIDUMP);
	IIUT_SHOW_MACRO(IUTEST_HAS_PACKAGE);
	IIUT_SHOW_MACRO(IUTEST_HAS_PAIRWISE);
	IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_METHOD_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_CLASS);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_FUNC);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_STATIC_FUNC);
	IIUT_SHOW_MACRO(IUTEST_HAS_PRINT_TO);
	IIUT_SHOW_MACRO(IUTEST_HAS_RANDOMVALUES);
	IIUT_SHOW_MACRO(IUTEST_HAS_REGEX);
	IIUT_SHOW_MACRO(IUTEST_HAS_REPORT_SKIPPED);
	IIUT_SHOW_MACRO(IUTEST_HAS_SOCKET);
	IIUT_SHOW_MACRO(IUTEST_HAS_SPI_LAMBDA_SUPPORT);
	IIUT_SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT);
	IIUT_SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT_TYPEEQ);
	IIUT_SHOW_MACRO(IUTEST_HAS_STREAM_BUFFER);
	IIUT_SHOW_MACRO(IUTEST_HAS_STREAM_RESULT);
	IIUT_SHOW_MACRO(IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE);
	IIUT_SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS);
	IIUT_SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS_JP);
	IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME);
	IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST_P);
	IIUT_SHOW_MACRO(IUTEST_HAS_VALUESGEN);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_COMBINE);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_PAIRWISE);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_VALUES);
	IIUT_SHOW_MACRO(IUTEST_CHECK_STRICT);
	IIUT_SHOW_MACRO(IUTEST_PLATFORM);
	IIUT_SHOW_MACRO(IUTEST_USE_THROW_ON_ASSERTION_FAILURE);
}

inline void iuOptionMessage::ShowSpec()
{
	IIUT_SHOW_MACRO(IUTEST_HAS_ANALYSIS_ASSUME);
	IIUT_SHOW_MACRO(IUTEST_HAS_ATTRIBUTE);
	IIUT_SHOW_MACRO(IUTEST_HAS_AUTO);
	IIUT_SHOW_MACRO(IUTEST_HAS_CHAR16_T);
	IIUT_SHOW_MACRO(IUTEST_HAS_CHAR32_T);
	IIUT_SHOW_MACRO(IUTEST_HAS_CLOCK);
	IIUT_SHOW_MACRO(IUTEST_HAS_CONSTEXPR);
	IIUT_SHOW_MACRO(IUTEST_HAS_COUNTER_MACRO);
	IIUT_SHOW_MACRO(IUTEST_HAS_CTIME);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CHRONO);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CODECVT);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_RANDOM);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_REGEX);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX11);
	IIUT_SHOW_MACRO(IUTEST_HAS_DECLTYPE);
	IIUT_SHOW_MACRO(IUTEST_HAS_DELETED_FUNCTIONS);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXPLICIT_CONVERSION);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXTERN_TEMPLATE);
	IIUT_SHOW_MACRO(IUTEST_HAS_GETTIMEOFDAY);
	IIUT_SHOW_MACRO(IUTEST_HAS_HDR_CXXABI);
	IIUT_SHOW_MACRO(IUTEST_HAS_HDR_SYSTIME);
	IIUT_SHOW_MACRO(IUTEST_HAS_HDR_UCHAR);
	IIUT_SHOW_MACRO(IUTEST_HAS_IF_EXISTS);
	IIUT_SHOW_MACRO(IUTEST_HAS_INITIALIZER_LIST);
	IIUT_SHOW_MACRO(IUTEST_HAS_LAMBDA);
	IIUT_SHOW_MACRO(IUTEST_HAS_LAMBDA_STATEMENTS);
	IIUT_SHOW_MACRO(IUTEST_HAS_NOEXCEPT);
	IIUT_SHOW_MACRO(IUTEST_HAS_NULLPTR);
	IIUT_SHOW_MACRO(IUTEST_HAS_OVERRIDE_AND_FINAL);
	IIUT_SHOW_MACRO(IUTEST_HAS_RTTI);
	IIUT_SHOW_MACRO(IUTEST_HAS_RVALUE_REFS);
	IIUT_SHOW_MACRO(IUTEST_HAS_SEH);
	IIUT_SHOW_MACRO(IUTEST_HAS_STD_BEGIN_END);
	IIUT_SHOW_MACRO(IUTEST_HAS_STD_DECLVAL);
	IIUT_SHOW_MACRO(IUTEST_HAS_STD_EMPLACE);
	IIUT_SHOW_MACRO(IUTEST_HAS_STRINGSTREAM);
	IIUT_SHOW_MACRO(IUTEST_HAS_STRONG_ENUMS);
	IIUT_SHOW_MACRO(IUTEST_HAS_STRSTREAM);
	IIUT_SHOW_MACRO(IUTEST_HAS_TUPLE);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATES);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES);

#ifdef _MSC_FULL_VER
	IIUT_SHOW_MACRO(_MSC_FULL_VER);
#endif
#ifdef _LIBCPP_VERSION
	IIUT_SHOW_MACRO(_LIBCPP_VERSION);
#endif
#ifdef __GLIBCXX__
	IIUT_SHOW_MACRO(__GLIBCXX__);
#endif
#ifdef __GLIBCPP__
	IIUT_SHOW_MACRO(__GLIBCPP__);
#endif

#undef IIUT_SHOW_MACRO
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_
<commit_msg>update r1085 add message<commit_after>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file		iutest_option_message.hpp
 * @brief		iris unit test コマンドラインメッセージ ファイル
 *
 * @author		t.shirayanagi
 * @par			copyright
 * Copyright (C) 2011-2016, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================
#ifndef INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_
#define INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_

//======================================================================
// include
#include "iutest_console.hpp"

namespace iutest {
namespace detail
{

//======================================================================
// class
class iuOptionMessage
{
public:
	/**
	 * @brief	ヘルプの出力
	*/
	static void ShowHelp();
	/**
	 * @brief	バージョン出力
	*/
	static void ShowVersion();
	/**
	 * @brief	機能出力
	*/
	static void ShowFeature();
	/**
	 * @brief	コンパイラスペック出力
	*/
	static void ShowSpec();
};

inline void iuOptionMessage::ShowHelp()
{
	const char* readme =
		"--------------------------------------------------\n"
		"Name\n"
		"    iutest - iris unit test framework\n"
		"--------------------------------------------------\n"
		"Command Line Options\n"
		"\n"
		"    --help, -h                       : Generate help message.\n"
		"    --iutest_output=xml[:path]       : Path of xml report.\n"
		"    --iutest_list_tests              : List up tests.\n"
		"    --iutest_list_tests_with_where   : List up tests with where.\n"
		"    --iutest_color=<yes|no|auto|ansi>: Console color enable.\n"
		"    --iutest_flagfile=<file>         : Set the flag from the file.\n"
		"    --iutest_filter=<filter>         : Select the test run.\n"
		"    --iutest_shuffle                 : Do shuffle test.\n"
		"    --iutest_random_seed=<seed>      : Set random seed.\n"
		"    --iutest_also_run_disabled_tests : Run disabled tests.\n"
		"    --iutest_break_on_failure[=0|1]  : When that failed to break.\n"
		"    --iutest_throw_on_failure[=0|1]  : When that failed to throw.\n"
		"    --iutest_catch_exceptions=<0|1>  : Catch exceptions enable.\n"
		"    --iutest_print_time=<0|1>        : Setting the display of elapsed time.\n"
		"    --iutest_repeat=<count>          : Set the number of repetitions\n"
		"                                       of the test.\n"
#if IUTEST_HAS_STREAM_RESULT
		"    --iutest_stream_result_to=<host:port>\n"
		"                                     : Set stream test results server.\n"
#endif
		"    --iutest_file_location=<auto|vs|gcc>\n"
		"                                     : Format file location messages.\n"
		"    --verbose                        : Verbose option.\n"
		"    --feature                        : Show iutest feature.\n"
		"    --version, -v                    : Show iutest version.\n"
		"\n"
		"--------------------------------------------------\n"
		"License\n"
		"\n"
		"    Copyright (c) 2011-2015, Takazumi-Shirayanagi\n"
		"\n"
		"    This software is released under the new BSD License, see LICENSE\n"
		"\n";
	detail::iuConsole::color_output(detail::iuConsole::cyan, readme);
}

inline void iuOptionMessage::ShowVersion()
{
	detail::iuConsole::output("iutest version %x.%x.%x.%x\n"
		, IUTEST_MAJORVER, IUTEST_MINORVER, IUTEST_BUILD, IUTEST_REVISION);
}

/** @private */
#define IIUT_SHOW_MACRO(macro)	detail::iuConsole::output("#define %s  %s\n", #macro, IUTEST_PP_TOSTRING(macro))

inline void iuOptionMessage::ShowFeature()
{
	IIUT_SHOW_MACRO(IUTEST_HAS_ANY_PARAM_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_ASSERTION_NOEQUALTO_OBJECT);
	IIUT_SHOW_MACRO(IUTEST_HAS_ASSERTION_RETURN);
	IIUT_SHOW_MACRO(IUTEST_HAS_AUTOFIXTURE_PARAM_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_COMBINE);
	IIUT_SHOW_MACRO(IUTEST_HAS_CONCAT);
	IIUT_SHOW_MACRO(IUTEST_HAS_CSVPARAMS);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
	IIUT_SHOW_MACRO(IUTEST_HAS_GENRAND);
	IIUT_SHOW_MACRO(IUTEST_HAS_IGNORE_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_LIB);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHERS);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_ALLOF_AND_ANYOF);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_ELEMENTSARE);
	IIUT_SHOW_MACRO(IUTEST_HAS_MATCHER_REGEX);
	IIUT_SHOW_MACRO(IUTEST_HAS_MINIDUMP);
	IIUT_SHOW_MACRO(IUTEST_HAS_PACKAGE);
	IIUT_SHOW_MACRO(IUTEST_HAS_PAIRWISE);
	IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_METHOD_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_PARAM_TEST_PARAM_NAME_GENERATOR);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_CLASS);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_FUNC);
	IIUT_SHOW_MACRO(IUTEST_HAS_PEEP_STATIC_FUNC);
	IIUT_SHOW_MACRO(IUTEST_HAS_PRINT_TO);
	IIUT_SHOW_MACRO(IUTEST_HAS_RANDOMVALUES);
	IIUT_SHOW_MACRO(IUTEST_HAS_REGEX);
	IIUT_SHOW_MACRO(IUTEST_HAS_REPORT_SKIPPED);
	IIUT_SHOW_MACRO(IUTEST_HAS_SOCKET);
	IIUT_SHOW_MACRO(IUTEST_HAS_SPI_LAMBDA_SUPPORT);
	IIUT_SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT);
	IIUT_SHOW_MACRO(IUTEST_HAS_STATIC_ASSERT_TYPEEQ);
	IIUT_SHOW_MACRO(IUTEST_HAS_STREAM_BUFFER);
	IIUT_SHOW_MACRO(IUTEST_HAS_STREAM_RESULT);
	IIUT_SHOW_MACRO(IUTEST_HAS_TESTFIXTURE_ALIAS_BY_TUPLE);
	IIUT_SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS);
	IIUT_SHOW_MACRO(IUTEST_HAS_TESTNAME_ALIAS_JP);
	IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST);
	IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST_APPEND_TYPENAME);
	IIUT_SHOW_MACRO(IUTEST_HAS_TYPED_TEST_P);
	IIUT_SHOW_MACRO(IUTEST_HAS_VALUESGEN);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_COMBINE);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_PAIRWISE);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_VALUES);
	IIUT_SHOW_MACRO(IUTEST_CHECK_STRICT);
	IIUT_SHOW_MACRO(IUTEST_PLATFORM);
	IIUT_SHOW_MACRO(IUTEST_USE_THROW_ON_ASSERTION_FAILURE);
}

inline void iuOptionMessage::ShowSpec()
{
	IIUT_SHOW_MACRO(IUTEST_HAS_ANALYSIS_ASSUME);
	IIUT_SHOW_MACRO(IUTEST_HAS_ATTRIBUTE);
	IIUT_SHOW_MACRO(IUTEST_HAS_AUTO);
	IIUT_SHOW_MACRO(IUTEST_HAS_CHAR16_T);
	IIUT_SHOW_MACRO(IUTEST_HAS_CHAR32_T);
	IIUT_SHOW_MACRO(IUTEST_HAS_CLOCK);
	IIUT_SHOW_MACRO(IUTEST_HAS_CONSTEXPR);
	IIUT_SHOW_MACRO(IUTEST_HAS_COUNTER_MACRO);
	IIUT_SHOW_MACRO(IUTEST_HAS_CTIME);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CHRONO);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_CODECVT);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_RANDOM);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX_HDR_REGEX);
	IIUT_SHOW_MACRO(IUTEST_HAS_CXX11);
	IIUT_SHOW_MACRO(IUTEST_HAS_DECLTYPE);
	IIUT_SHOW_MACRO(IUTEST_HAS_DELETED_FUNCTIONS);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXCEPTIONS);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXPLICIT_CONVERSION);
	IIUT_SHOW_MACRO(IUTEST_HAS_EXTERN_TEMPLATE);
	IIUT_SHOW_MACRO(IUTEST_HAS_GETTIMEOFDAY);
	IIUT_SHOW_MACRO(IUTEST_HAS_HDR_CXXABI);
	IIUT_SHOW_MACRO(IUTEST_HAS_HDR_SYSTIME);
	IIUT_SHOW_MACRO(IUTEST_HAS_HDR_UCHAR);
	IIUT_SHOW_MACRO(IUTEST_HAS_IF_EXISTS);
	IIUT_SHOW_MACRO(IUTEST_HAS_INITIALIZER_LIST);
	IIUT_SHOW_MACRO(IUTEST_HAS_LAMBDA);
	IIUT_SHOW_MACRO(IUTEST_HAS_LAMBDA_STATEMENTS);
	IIUT_SHOW_MACRO(IUTEST_HAS_NOEXCEPT);
	IIUT_SHOW_MACRO(IUTEST_HAS_NULLPTR);
	IIUT_SHOW_MACRO(IUTEST_HAS_OVERRIDE_AND_FINAL);
	IIUT_SHOW_MACRO(IUTEST_HAS_RTTI);
	IIUT_SHOW_MACRO(IUTEST_HAS_RVALUE_REFS);
	IIUT_SHOW_MACRO(IUTEST_HAS_SEH);
	IIUT_SHOW_MACRO(IUTEST_HAS_STD_BEGIN_END);
	IIUT_SHOW_MACRO(IUTEST_HAS_STD_DECLVAL);
	IIUT_SHOW_MACRO(IUTEST_HAS_STD_EMPLACE);
	IIUT_SHOW_MACRO(IUTEST_HAS_STRINGSTREAM);
	IIUT_SHOW_MACRO(IUTEST_HAS_STRONG_ENUMS);
	IIUT_SHOW_MACRO(IUTEST_HAS_STRSTREAM);
	IIUT_SHOW_MACRO(IUTEST_HAS_TUPLE);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATES);
	IIUT_SHOW_MACRO(IUTEST_HAS_VARIADIC_TEMPLATE_TEMPLATES);

#ifdef _MSC_FULL_VER
	IIUT_SHOW_MACRO(_MSC_FULL_VER);
#endif
#ifdef _LIBCPP_VERSION
	IIUT_SHOW_MACRO(_LIBCPP_VERSION);
#endif
#ifdef __GLIBCXX__
	IIUT_SHOW_MACRO(__GLIBCXX__);
#endif
#ifdef __GLIBCPP__
	IIUT_SHOW_MACRO(__GLIBCPP__);
#endif
#ifdef _LIBCPP_VERSION
	IIUT_SHOW_MACRO(_LIBCPP_VERSION);
#endif

#undef IIUT_SHOW_MACRO
}

}	// end of namespace detail
}	// end of namespace iutest

#endif // INCG_IRIS_IUTEST_OPTION_MESSAGE_HPP_00EB9B17_0615_4678_9AD0_1F5B295B404F_
<|endoftext|>


<commit_before>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/compositor_impl_android.h"

#include <android/bitmap.h>
#include <android/native_window_jni.h>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "cc/font_atlas.h"
#include "cc/input_handler.h"
#include "cc/layer.h"
#include "cc/layer_tree_host.h"
#include "cc/output_surface.h"
#include "cc/thread_impl.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/image_transport_factory_android.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/common/content_switches.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#include "ui/gfx/android/java_bitmap.h"
#include "webkit/glue/webthread_impl.h"
#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"

namespace gfx {
class JavaBitmap;
}

namespace {

static bool g_initialized = false;
static webkit_glue::WebThreadImpl* g_impl_thread = NULL;
static bool g_use_direct_gl = false;

// Adapts a pure WebGraphicsContext3D into a cc::OutputSurface.
class WebGraphicsContextToOutputSurfaceAdapter : public cc::OutputSurface {
 public:
  explicit WebGraphicsContextToOutputSurfaceAdapter(
      WebKit::WebGraphicsContext3D* context)
      : context3d_(context),
        client_(0) {
  }

  virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE {
    DCHECK(client);
    if (!context3d_->makeContextCurrent())
      return false;
    client_ = client;
    return true;
  }

  virtual const struct Capabilities& Capabilities() const OVERRIDE {
    return capabilities_;
  }

  virtual WebKit::WebGraphicsContext3D* Context3D() const OVERRIDE {
    return context3d_.get();
  }

  virtual cc::SoftwareOutputDevice* SoftwareDevice() const OVERRIDE {
    return NULL;
  }

  virtual void SendFrameToParentCompositor(
      const cc::CompositorFrame&) OVERRIDE {
  }

 private:
  scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
  struct Capabilities capabilities_;
  cc::OutputSurfaceClient* client_;
};

} // anonymous namespace

namespace content {

// static
Compositor* Compositor::Create(Client* client) {
  return client ? new CompositorImpl(client) : NULL;
}

// static
void Compositor::Initialize() {
  DCHECK(!CompositorImpl::IsInitialized());
  g_initialized = true;
}

// static
void Compositor::InitializeWithFlags(uint32 flags) {
  g_use_direct_gl = flags & DIRECT_CONTEXT_ON_DRAW_THREAD;
  if (flags & ENABLE_COMPOSITOR_THREAD) {
    TRACE_EVENT_INSTANT0("test_gpu", "ThreadedCompositingInitialization");
    g_impl_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
  }
  Compositor::Initialize();
}

// static
bool CompositorImpl::IsInitialized() {
  return g_initialized;
}

// static
bool CompositorImpl::IsThreadingEnabled() {
  return g_impl_thread;
}

// static
bool CompositorImpl::UsesDirectGL() {
  return g_use_direct_gl;
}

CompositorImpl::CompositorImpl(Compositor::Client* client)
    : root_layer_(cc::Layer::create()),
      has_transparent_background_(false),
      window_(NULL),
      surface_id_(0),
      client_(client),
      weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
  DCHECK(client);
}

CompositorImpl::~CompositorImpl() {
}

void CompositorImpl::Composite() {
  if (host_.get())
    host_->composite();
}

void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
  root_layer_->removeAllChildren();
  root_layer_->addChild(root_layer);
}

void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
  GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();

  if (window_) {
    tracker->RemoveSurface(surface_id_);
    ANativeWindow_release(window_);
    window_ = NULL;
    surface_id_ = 0;
    SetVisible(false);
  }

  if (window) {
    window_ = window;
    ANativeWindow_acquire(window);
    surface_id_ = tracker->AddSurfaceForNativeWidget(window);
    tracker->SetSurfaceHandle(
        surface_id_,
        gfx::GLSurfaceHandle(gfx::kDummyPluginWindow, false));
    SetVisible(true);
  }
}

void CompositorImpl::SetVisible(bool visible) {
  if (!visible) {
    host_.reset();
  } else if (!host_.get()) {
    cc::LayerTreeSettings settings;
    settings.refreshRate = 60.0;

    // Do not clear the framebuffer when rendering into external GL contexts
    // like Android View System's.
    if (UsesDirectGL())
      settings.shouldClearRootRenderPass = false;

    scoped_ptr<cc::Thread> impl_thread;
    if (g_impl_thread)
      impl_thread = cc::ThreadImpl::createForDifferentThread(
          g_impl_thread->message_loop()->message_loop_proxy());

    host_ = cc::LayerTreeHost::create(this, settings, impl_thread.Pass());
    host_->setRootLayer(root_layer_);

    host_->setVisible(true);
    host_->setSurfaceReady();
    host_->setViewportSize(size_, size_);
    host_->setHasTransparentBackground(has_transparent_background_);
  }
}

void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
  if (size_ == size)
    return;

  size_ = size;
  if (host_)
    host_->setViewportSize(size, size);
  root_layer_->setBounds(size);
}

void CompositorImpl::SetHasTransparentBackground(bool flag) {
  has_transparent_background_ = flag;
  if (host_.get())
    host_->setHasTransparentBackground(flag);
}

bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
  if (host_.get())
    return host_->compositeAndReadback(pixels, rect);
  else
    return false;
}

WebKit::WebGLId CompositorImpl::GenerateTexture(gfx::JavaBitmap& bitmap) {
  unsigned int texture_id = BuildBasicTexture();
  WebKit::WebGraphicsContext3D* context =
      ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (texture_id == 0 || context->isContextLost() ||
      !context->makeContextCurrent())
    return 0;
  WebKit::WebGLId format = GetGLFormatForBitmap(bitmap);
  WebKit::WebGLId type = GetGLTypeForBitmap(bitmap);

  context->texImage2D(GL_TEXTURE_2D,
                      0,
                      format,
                      bitmap.size().width(),
                      bitmap.size().height(),
                      0,
                      format,
                      type,
                      bitmap.pixels());
  context->shallowFlushCHROMIUM();
  DCHECK(context->getError() == GL_NO_ERROR);
  return texture_id;
}

WebKit::WebGLId CompositorImpl::GenerateCompressedTexture(gfx::Size& size,
                                                          int data_size,
                                                          void* data) {
  unsigned int texture_id = BuildBasicTexture();
  WebKit::WebGraphicsContext3D* context =
        ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (texture_id == 0 || context->isContextLost() ||
      !context->makeContextCurrent())
    return 0;
  context->compressedTexImage2D(GL_TEXTURE_2D,
                                0,
                                GL_ETC1_RGB8_OES,
                                size.width(),
                                size.height(),
                                0,
                                data_size,
                                data);
  context->shallowFlushCHROMIUM();
  DCHECK(context->getError() == GL_NO_ERROR);
  return texture_id;
}

void CompositorImpl::DeleteTexture(WebKit::WebGLId texture_id) {
  WebKit::WebGraphicsContext3D* context =
      ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (context->isContextLost() || !context->makeContextCurrent())
    return;
  context->deleteTexture(texture_id);
  context->shallowFlushCHROMIUM();
  DCHECK(context->getError() == GL_NO_ERROR);
}

bool CompositorImpl::CopyTextureToBitmap(WebKit::WebGLId texture_id,
                                         gfx::JavaBitmap& bitmap) {
  return CopyTextureToBitmap(texture_id, gfx::Rect(bitmap.size()), bitmap);
}

bool CompositorImpl::CopyTextureToBitmap(WebKit::WebGLId texture_id,
                                         const gfx::Rect& sub_rect,
                                         gfx::JavaBitmap& bitmap) {
  // The sub_rect should match the bitmap size.
  DCHECK(bitmap.size() == sub_rect.size());
  if (bitmap.size() != sub_rect.size() || texture_id == 0) return false;

  GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
  helper->ReadbackTextureSync(texture_id,
                              sub_rect,
                              static_cast<unsigned char*> (bitmap.pixels()));
  return true;
}

void CompositorImpl::animate(double monotonicFrameBeginTime) {
}

void CompositorImpl::layout() {
}

void CompositorImpl::applyScrollAndScale(gfx::Vector2d scrollDelta,
                                         float pageScale) {
}

scoped_ptr<cc::OutputSurface> CompositorImpl::createOutputSurface() {
  if (g_use_direct_gl) {
    WebKit::WebGraphicsContext3D::Attributes attrs;
    attrs.shareResources = false;
    attrs.noAutomaticFlushes = true;
    scoped_ptr<webkit::gpu::WebGraphicsContext3DInProcessImpl> context(
        webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow(
            attrs,
            window_,
            NULL));
    return scoped_ptr<cc::OutputSurface>(
        new WebGraphicsContextToOutputSurfaceAdapter(context.release()));
  } else {
    DCHECK(window_ && surface_id_);
    WebKit::WebGraphicsContext3D::Attributes attrs;
    attrs.shareResources = true;
    attrs.noAutomaticFlushes = true;
    GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance();
    GURL url("chrome://gpu/Compositor::createContext3D");
    scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
        new WebGraphicsContext3DCommandBufferImpl(surface_id_,
                                                  url,
                                                  factory,
                                                  weak_factory_.GetWeakPtr()));
    if (!context->Initialize(
        attrs,
        false,
        CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) {
      LOG(ERROR) << "Failed to create 3D context for compositor.";
      return scoped_ptr<cc::OutputSurface>();
    }
    return scoped_ptr<cc::OutputSurface>(
        new WebGraphicsContextToOutputSurfaceAdapter(context.release()));
  }
}

scoped_ptr<cc::InputHandler> CompositorImpl::createInputHandler() {
  return scoped_ptr<cc::InputHandler>();
}

void CompositorImpl::didRecreateOutputSurface(bool success) {
}

void CompositorImpl::didCommit() {
}

void CompositorImpl::didCommitAndDrawFrame() {
}

void CompositorImpl::didCompleteSwapBuffers() {
  client_->OnSwapBuffersCompleted();
}

void CompositorImpl::scheduleComposite() {
  client_->ScheduleComposite();
}

scoped_ptr<cc::FontAtlas> CompositorImpl::createFontAtlas() {
  return scoped_ptr<cc::FontAtlas>();
}

void CompositorImpl::OnViewContextSwapBuffersPosted() {
  TRACE_EVENT0("compositor", "CompositorImpl::OnViewContextSwapBuffersPosted");
}

void CompositorImpl::OnViewContextSwapBuffersComplete() {
  TRACE_EVENT0("compositor",
               "CompositorImpl::OnViewContextSwapBuffersComplete");
  client_->OnSwapBuffersCompleted();
}

void CompositorImpl::OnViewContextSwapBuffersAborted() {
  TRACE_EVENT0("compositor", "CompositorImpl::OnViewContextSwapBuffersAborted");
  client_->OnSwapBuffersCompleted();
}

WebKit::WebGLId CompositorImpl::BuildBasicTexture() {
  WebKit::WebGraphicsContext3D* context =
            ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (context->isContextLost() || !context->makeContextCurrent())
    return 0;
  WebKit::WebGLId texture_id = context->createTexture();
  context->bindTexture(GL_TEXTURE_2D, texture_id);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  DCHECK(context->getError() == GL_NO_ERROR);
  return texture_id;
}

WebKit::WGC3Denum CompositorImpl::GetGLFormatForBitmap(
    gfx::JavaBitmap& bitmap) {
  switch (bitmap.format()) {
    case ANDROID_BITMAP_FORMAT_A_8:
      return GL_ALPHA;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_4444:
      return GL_RGBA;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_8888:
      return GL_RGBA;
      break;
    case ANDROID_BITMAP_FORMAT_RGB_565:
    default:
      return GL_RGB;
  }
}

WebKit::WGC3Denum CompositorImpl::GetGLTypeForBitmap(gfx::JavaBitmap& bitmap) {
  switch (bitmap.format()) {
    case ANDROID_BITMAP_FORMAT_A_8:
      return GL_UNSIGNED_BYTE;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_4444:
      return GL_UNSIGNED_SHORT_4_4_4_4;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_8888:
      return GL_UNSIGNED_BYTE;
      break;
    case ANDROID_BITMAP_FORMAT_RGB_565:
    default:
      return GL_UNSIGNED_SHORT_5_6_5;
  }
}

} // namespace content
<commit_msg>cc: Disable impl-side painting in browser compositor.<commit_after>// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/browser/renderer_host/compositor_impl_android.h"

#include <android/bitmap.h>
#include <android/native_window_jni.h>

#include "base/bind.h"
#include "base/command_line.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "cc/font_atlas.h"
#include "cc/input_handler.h"
#include "cc/layer.h"
#include "cc/layer_tree_host.h"
#include "cc/output_surface.h"
#include "cc/thread_impl.h"
#include "content/browser/gpu/browser_gpu_channel_host_factory.h"
#include "content/browser/gpu/gpu_surface_tracker.h"
#include "content/browser/renderer_host/image_transport_factory_android.h"
#include "content/common/gpu/client/gl_helper.h"
#include "content/common/gpu/client/gpu_channel_host.h"
#include "content/common/gpu/client/webgraphicscontext3d_command_buffer_impl.h"
#include "content/common/gpu/gpu_process_launch_causes.h"
#include "content/public/common/content_switches.h"
#include "third_party/khronos/GLES2/gl2.h"
#include "third_party/khronos/GLES2/gl2ext.h"
#include "third_party/WebKit/Source/Platform/chromium/public/WebGraphicsContext3D.h"
#include "ui/gfx/android/java_bitmap.h"
#include "webkit/glue/webthread_impl.h"
#include "webkit/gpu/webgraphicscontext3d_in_process_impl.h"

namespace gfx {
class JavaBitmap;
}

namespace {

static bool g_initialized = false;
static webkit_glue::WebThreadImpl* g_impl_thread = NULL;
static bool g_use_direct_gl = false;

// Adapts a pure WebGraphicsContext3D into a cc::OutputSurface.
class WebGraphicsContextToOutputSurfaceAdapter : public cc::OutputSurface {
 public:
  explicit WebGraphicsContextToOutputSurfaceAdapter(
      WebKit::WebGraphicsContext3D* context)
      : context3d_(context),
        client_(0) {
  }

  virtual bool BindToClient(cc::OutputSurfaceClient* client) OVERRIDE {
    DCHECK(client);
    if (!context3d_->makeContextCurrent())
      return false;
    client_ = client;
    return true;
  }

  virtual const struct Capabilities& Capabilities() const OVERRIDE {
    return capabilities_;
  }

  virtual WebKit::WebGraphicsContext3D* Context3D() const OVERRIDE {
    return context3d_.get();
  }

  virtual cc::SoftwareOutputDevice* SoftwareDevice() const OVERRIDE {
    return NULL;
  }

  virtual void SendFrameToParentCompositor(
      const cc::CompositorFrame&) OVERRIDE {
  }

 private:
  scoped_ptr<WebKit::WebGraphicsContext3D> context3d_;
  struct Capabilities capabilities_;
  cc::OutputSurfaceClient* client_;
};

} // anonymous namespace

namespace content {

// static
Compositor* Compositor::Create(Client* client) {
  return client ? new CompositorImpl(client) : NULL;
}

// static
void Compositor::Initialize() {
  DCHECK(!CompositorImpl::IsInitialized());
  g_initialized = true;
}

// static
void Compositor::InitializeWithFlags(uint32 flags) {
  g_use_direct_gl = flags & DIRECT_CONTEXT_ON_DRAW_THREAD;
  if (flags & ENABLE_COMPOSITOR_THREAD) {
    TRACE_EVENT_INSTANT0("test_gpu", "ThreadedCompositingInitialization");
    g_impl_thread = new webkit_glue::WebThreadImpl("Browser Compositor");
  }
  Compositor::Initialize();
}

// static
bool CompositorImpl::IsInitialized() {
  return g_initialized;
}

// static
bool CompositorImpl::IsThreadingEnabled() {
  return g_impl_thread;
}

// static
bool CompositorImpl::UsesDirectGL() {
  return g_use_direct_gl;
}

CompositorImpl::CompositorImpl(Compositor::Client* client)
    : root_layer_(cc::Layer::create()),
      has_transparent_background_(false),
      window_(NULL),
      surface_id_(0),
      client_(client),
      weak_factory_(ALLOW_THIS_IN_INITIALIZER_LIST(this)) {
  DCHECK(client);
}

CompositorImpl::~CompositorImpl() {
}

void CompositorImpl::Composite() {
  if (host_.get())
    host_->composite();
}

void CompositorImpl::SetRootLayer(scoped_refptr<cc::Layer> root_layer) {
  root_layer_->removeAllChildren();
  root_layer_->addChild(root_layer);
}

void CompositorImpl::SetWindowSurface(ANativeWindow* window) {
  GpuSurfaceTracker* tracker = GpuSurfaceTracker::Get();

  if (window_) {
    tracker->RemoveSurface(surface_id_);
    ANativeWindow_release(window_);
    window_ = NULL;
    surface_id_ = 0;
    SetVisible(false);
  }

  if (window) {
    window_ = window;
    ANativeWindow_acquire(window);
    surface_id_ = tracker->AddSurfaceForNativeWidget(window);
    tracker->SetSurfaceHandle(
        surface_id_,
        gfx::GLSurfaceHandle(gfx::kDummyPluginWindow, false));
    SetVisible(true);
  }
}

void CompositorImpl::SetVisible(bool visible) {
  if (!visible) {
    host_.reset();
  } else if (!host_.get()) {
    cc::LayerTreeSettings settings;
    settings.refreshRate = 60.0;
    settings.implSidePainting = false;

    // Do not clear the framebuffer when rendering into external GL contexts
    // like Android View System's.
    if (UsesDirectGL())
      settings.shouldClearRootRenderPass = false;

    scoped_ptr<cc::Thread> impl_thread;
    if (g_impl_thread)
      impl_thread = cc::ThreadImpl::createForDifferentThread(
          g_impl_thread->message_loop()->message_loop_proxy());

    host_ = cc::LayerTreeHost::create(this, settings, impl_thread.Pass());
    host_->setRootLayer(root_layer_);

    host_->setVisible(true);
    host_->setSurfaceReady();
    host_->setViewportSize(size_, size_);
    host_->setHasTransparentBackground(has_transparent_background_);
  }
}

void CompositorImpl::SetWindowBounds(const gfx::Size& size) {
  if (size_ == size)
    return;

  size_ = size;
  if (host_)
    host_->setViewportSize(size, size);
  root_layer_->setBounds(size);
}

void CompositorImpl::SetHasTransparentBackground(bool flag) {
  has_transparent_background_ = flag;
  if (host_.get())
    host_->setHasTransparentBackground(flag);
}

bool CompositorImpl::CompositeAndReadback(void *pixels, const gfx::Rect& rect) {
  if (host_.get())
    return host_->compositeAndReadback(pixels, rect);
  else
    return false;
}

WebKit::WebGLId CompositorImpl::GenerateTexture(gfx::JavaBitmap& bitmap) {
  unsigned int texture_id = BuildBasicTexture();
  WebKit::WebGraphicsContext3D* context =
      ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (texture_id == 0 || context->isContextLost() ||
      !context->makeContextCurrent())
    return 0;
  WebKit::WebGLId format = GetGLFormatForBitmap(bitmap);
  WebKit::WebGLId type = GetGLTypeForBitmap(bitmap);

  context->texImage2D(GL_TEXTURE_2D,
                      0,
                      format,
                      bitmap.size().width(),
                      bitmap.size().height(),
                      0,
                      format,
                      type,
                      bitmap.pixels());
  context->shallowFlushCHROMIUM();
  DCHECK(context->getError() == GL_NO_ERROR);
  return texture_id;
}

WebKit::WebGLId CompositorImpl::GenerateCompressedTexture(gfx::Size& size,
                                                          int data_size,
                                                          void* data) {
  unsigned int texture_id = BuildBasicTexture();
  WebKit::WebGraphicsContext3D* context =
        ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (texture_id == 0 || context->isContextLost() ||
      !context->makeContextCurrent())
    return 0;
  context->compressedTexImage2D(GL_TEXTURE_2D,
                                0,
                                GL_ETC1_RGB8_OES,
                                size.width(),
                                size.height(),
                                0,
                                data_size,
                                data);
  context->shallowFlushCHROMIUM();
  DCHECK(context->getError() == GL_NO_ERROR);
  return texture_id;
}

void CompositorImpl::DeleteTexture(WebKit::WebGLId texture_id) {
  WebKit::WebGraphicsContext3D* context =
      ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (context->isContextLost() || !context->makeContextCurrent())
    return;
  context->deleteTexture(texture_id);
  context->shallowFlushCHROMIUM();
  DCHECK(context->getError() == GL_NO_ERROR);
}

bool CompositorImpl::CopyTextureToBitmap(WebKit::WebGLId texture_id,
                                         gfx::JavaBitmap& bitmap) {
  return CopyTextureToBitmap(texture_id, gfx::Rect(bitmap.size()), bitmap);
}

bool CompositorImpl::CopyTextureToBitmap(WebKit::WebGLId texture_id,
                                         const gfx::Rect& sub_rect,
                                         gfx::JavaBitmap& bitmap) {
  // The sub_rect should match the bitmap size.
  DCHECK(bitmap.size() == sub_rect.size());
  if (bitmap.size() != sub_rect.size() || texture_id == 0) return false;

  GLHelper* helper = ImageTransportFactoryAndroid::GetInstance()->GetGLHelper();
  helper->ReadbackTextureSync(texture_id,
                              sub_rect,
                              static_cast<unsigned char*> (bitmap.pixels()));
  return true;
}

void CompositorImpl::animate(double monotonicFrameBeginTime) {
}

void CompositorImpl::layout() {
}

void CompositorImpl::applyScrollAndScale(gfx::Vector2d scrollDelta,
                                         float pageScale) {
}

scoped_ptr<cc::OutputSurface> CompositorImpl::createOutputSurface() {
  if (g_use_direct_gl) {
    WebKit::WebGraphicsContext3D::Attributes attrs;
    attrs.shareResources = false;
    attrs.noAutomaticFlushes = true;
    scoped_ptr<webkit::gpu::WebGraphicsContext3DInProcessImpl> context(
        webkit::gpu::WebGraphicsContext3DInProcessImpl::CreateForWindow(
            attrs,
            window_,
            NULL));
    return scoped_ptr<cc::OutputSurface>(
        new WebGraphicsContextToOutputSurfaceAdapter(context.release()));
  } else {
    DCHECK(window_ && surface_id_);
    WebKit::WebGraphicsContext3D::Attributes attrs;
    attrs.shareResources = true;
    attrs.noAutomaticFlushes = true;
    GpuChannelHostFactory* factory = BrowserGpuChannelHostFactory::instance();
    GURL url("chrome://gpu/Compositor::createContext3D");
    scoped_ptr<WebGraphicsContext3DCommandBufferImpl> context(
        new WebGraphicsContext3DCommandBufferImpl(surface_id_,
                                                  url,
                                                  factory,
                                                  weak_factory_.GetWeakPtr()));
    if (!context->Initialize(
        attrs,
        false,
        CAUSE_FOR_GPU_LAUNCH_WEBGRAPHICSCONTEXT3DCOMMANDBUFFERIMPL_INITIALIZE)) {
      LOG(ERROR) << "Failed to create 3D context for compositor.";
      return scoped_ptr<cc::OutputSurface>();
    }
    return scoped_ptr<cc::OutputSurface>(
        new WebGraphicsContextToOutputSurfaceAdapter(context.release()));
  }
}

scoped_ptr<cc::InputHandler> CompositorImpl::createInputHandler() {
  return scoped_ptr<cc::InputHandler>();
}

void CompositorImpl::didRecreateOutputSurface(bool success) {
}

void CompositorImpl::didCommit() {
}

void CompositorImpl::didCommitAndDrawFrame() {
}

void CompositorImpl::didCompleteSwapBuffers() {
  client_->OnSwapBuffersCompleted();
}

void CompositorImpl::scheduleComposite() {
  client_->ScheduleComposite();
}

scoped_ptr<cc::FontAtlas> CompositorImpl::createFontAtlas() {
  return scoped_ptr<cc::FontAtlas>();
}

void CompositorImpl::OnViewContextSwapBuffersPosted() {
  TRACE_EVENT0("compositor", "CompositorImpl::OnViewContextSwapBuffersPosted");
}

void CompositorImpl::OnViewContextSwapBuffersComplete() {
  TRACE_EVENT0("compositor",
               "CompositorImpl::OnViewContextSwapBuffersComplete");
  client_->OnSwapBuffersCompleted();
}

void CompositorImpl::OnViewContextSwapBuffersAborted() {
  TRACE_EVENT0("compositor", "CompositorImpl::OnViewContextSwapBuffersAborted");
  client_->OnSwapBuffersCompleted();
}

WebKit::WebGLId CompositorImpl::BuildBasicTexture() {
  WebKit::WebGraphicsContext3D* context =
            ImageTransportFactoryAndroid::GetInstance()->GetContext3D();
  if (context->isContextLost() || !context->makeContextCurrent())
    return 0;
  WebKit::WebGLId texture_id = context->createTexture();
  context->bindTexture(GL_TEXTURE_2D, texture_id);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
  context->texParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
  DCHECK(context->getError() == GL_NO_ERROR);
  return texture_id;
}

WebKit::WGC3Denum CompositorImpl::GetGLFormatForBitmap(
    gfx::JavaBitmap& bitmap) {
  switch (bitmap.format()) {
    case ANDROID_BITMAP_FORMAT_A_8:
      return GL_ALPHA;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_4444:
      return GL_RGBA;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_8888:
      return GL_RGBA;
      break;
    case ANDROID_BITMAP_FORMAT_RGB_565:
    default:
      return GL_RGB;
  }
}

WebKit::WGC3Denum CompositorImpl::GetGLTypeForBitmap(gfx::JavaBitmap& bitmap) {
  switch (bitmap.format()) {
    case ANDROID_BITMAP_FORMAT_A_8:
      return GL_UNSIGNED_BYTE;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_4444:
      return GL_UNSIGNED_SHORT_4_4_4_4;
      break;
    case ANDROID_BITMAP_FORMAT_RGBA_8888:
      return GL_UNSIGNED_BYTE;
      break;
    case ANDROID_BITMAP_FORMAT_RGB_565:
    default:
      return GL_UNSIGNED_SHORT_5_6_5;
  }
}

} // namespace content
<|endoftext|>