<commit_before>/*--------------------------------------------------------------------------------------------------
 * Author:
 * Date:        2016-08-18
 * Assignment:  Final Project
 * Source File: interface.cpp
 * Language:    C/C++
 * Course:      Operating Systems
 * Purpose:     Contains the implementation of the interface class.
 -------------------------------------------------------------------------------------------------*/

#include "constants.h"
#include "ext2.h"
#include "interface.h"
#include "utility.h"

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <stdexcept>
#include <cstdio>
#include <time.h>

using namespace std;
using namespace vdi_explorer;

namespace vdi_explorer
{
    // @TODO Make an actual throwable error.
    interface::interface(ext2 * _file_system)
    {
        file_system = _file_system;
        if (file_system == nullptr)
        {
            cout << "Error opening the file system object.";
            throw;
        }
    }

    interface::~interface()
    {
        return;
    }

    void interface::interactive()
    {
        string command_string;
        vector<string> tokens;
        vector<string> tokens2;

        while (true)
        {
            cout << "\nCommand: ";
            getline(cin, command_string);
            tokens = utility::tokenize(command_string, DELIMITER_SPACE);
            tokens2 = utility::tokenize(command_string, DELIMITER_FSLASH);

            // Debug info.
            for (unsigned int i = 0; i < tokens.size(); i++)
                cout << "debug (ext2::interface::interactive): " << tokens[i] << endl;
            // End debug info.

            if (tokens.size() == 0)
                continue;

            switch (hash_command(tokens[0]))
            {
                case code_cd:
                    if (tokens.size() < 2)
                    {
                        cout << "Not enough arguments.\n";
                        command_help("cd");
                    }
                    else
                    {
                        command_cd(tokens[1]);
                    }
                    break;

                case code_cp:
                    if (tokens.size() < 4)
                    {
                        cout << "Not enough arguments.\n";
                        command_help("cp");
                    }
                    else
                    {
                        command_cp(tokens[1], tokens[2], tokens[3]);
                    }
                    break;

                case code_exit:
                    command_exit();
                    break;

                case code_help:
                    if (tokens.size() < 2)
                    {
                        command_help("");
                    }
                    else
                    {
                        command_help(tokens[1]);
                    }
                    break;

                case code_ls:
                    if (tokens.size() < 2)
                    {
                        command_ls("");
                    }
                    else
                    {
                        command_ls(tokens[1]);
                    }
                    break;

                case code_pwd:
                    command_pwd();
                    break;

                // Debug
                case code_dump_pwd_inode:
                    command_dump_pwd_inode();
                    break;

                case code_dump_block:
                    command_dump_block(stoi(tokens[1]));
                    break;

                case code_dump_inode:
                    command_dump_inode(stoi(tokens[1]));
                    break;
                // End debug.

                case code_unknown:
                    cout << "Unknown command.\n";
                    break;

                default:
                    // A Bad Thing happened.  This should never get triggered.
                    cout << "A Bad Thing happened.  You should not be seeing this.";
                    break;
            }
        }
    }

    void interface::command_cd(const string & directory)
    {
        file_system->set_pwd(directory);
        return;
    }

    void interface::command_cp(const string & direction,
                               const string & copy_from,
                               const string & copy_to)
    {
        cout << "*** Implementation in progress.  Bust out the bugspray. ***\n";

        fstream os_file;

        if (direction == "in")
        {
            cout << "Not implemented yet.\n";
            return;
        }
        else if (direction == "out")
        {
            // Attempt to open the file for input to see if it already exists.
            os_file.open(copy_to, ios_base::in);
            bool file_exists = os_file.good();
            os_file.close();

            // Actually check if the file exists.
            if (file_exists)
            {
                cout << "Error, file already exists.";
                return;
            }
            else
            {
                // Open file for writing.
                os_file.open(copy_to, ios::out | ios::binary);
                if (!os_file.good())
                {
                    cout << "Error opening file for writing.\n";
                    return;
                }

                // Actually copy file out from the other file system.
                bool successful = file_system->file_read(os_file, copy_from);
                os_file.close();

                if (!successful)
                {
                    remove(copy_to.c_str());
                }
            }
        }
    }

    // @TODO format output neatly into appropriately sized columns -> function in utility?
    // @TODO sort vector by name
    // @TODO colorize:
        // Yellow with black background: Device
        // Pink: Graphic image file
    void interface::command_ls(const string & switches)
    {
        vector<fs_entry_posix> file_listing = file_system->get_directory_contents();
        vector<string> filename_tokens;
        for (u32 i = 0; i < file_listing.size(); i++)
        {
            filename_tokens = utility::tokenize(file_listing[i].name, DELIMITER_DOT);
            string file_extension = (filename_tokens.size() > 1 ? filename_tokens.back() : "");

            if (switches == "-l" || switches == "-al"){
                if (switches == "-l" && (file_listing[i].name == "." || file_listing[i].name ==".."));
                else
                    { // list permissions for each file
                if (file_listing[i].type == EXT2_DIR_TYPE_DIR)
                    cout << "d";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_USER_READ)
                    cout << "r";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_USER_WRITE)
                    cout << "w";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_USER_EXECUTE)
                    cout << "x";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_GROUP_READ)
                    cout << "r";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_GROUP_WRITE)
                    cout << "w";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_GROUP_EXECUTE)
                    cout << "x";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_OTHER_READ)
                    cout << "r";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_OTHER_WRITE)
                    cout << "w";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_OTHER_EXECUTE)
                    cout << "x ";
                else
                    cout << "- ";

                // set file type, UID, GID, and size
                cout << setw(2) << ((file_listing[i].type== EXT2_DIR_TYPE_DIR)?2:1)<< " ";
                cout << setw(5) << file_listing[i].user_id<< " ";
                cout << setw(5) << file_listing[i].group_id << " ";
                cout << setw(10) << file_listing[i].size << " ";

                // translate unix epoch timestamps to readable time
                time_t     curr;
                struct tm  ts;
                char       buf[80];
                curr = file_listing[i].timestamp_modified;
                ts = *localtime(&curr);
                strftime(buf, sizeof(buf), "%b %d %M:%S", &ts);
                printf("%s ", buf);

                }
            }
            if (file_listing[i].type == EXT2_DIR_TYPE_DIR){
                if (switches != "-al" ){
                    if (file_listing[i].name == "." || file_listing[i].name ==".."); // don't print out . and .. directories with -l switch
                    else
                        cout << "\033[1;34m" << file_listing[i].name << "\033[0m"<< "/"; //blue (bold) - directory or recognized data file                }
                }
                else if ((switches == "-al" ) && (file_listing[i].name == "." || file_listing[i].name ==".."))
                    cout << "\033[1;34m" << file_listing[i].name << "\033[0m";
                else
                    cout << "\033[1;34m" << file_listing[i].name << "\033[0m" << "/"; //blue (bold) - directory or recognized data file
            }
            else if ((file_listing[i].type == EXT2_DIR_TYPE_FILE) &&
                    (file_listing[i].permissions & EXT2_INODE_PERM_USER_EXECUTE ||
                     file_listing[i].permissions & EXT2_INODE_PERM_GROUP_EXECUTE ||
                     file_listing[i].permissions & EXT2_INODE_PERM_OTHER_EXECUTE)){
                cout << "\033[1;32m" << file_listing[i].name << "\033[0m" << "*"; //green - executable files
                     }
            else if (file_listing[i].type == EXT2_INODE_TYPE_SYMLINK)
                cout << "\033[6;36m" << file_listing[i].name << "\033[0m"; //cyan - linked file
            else if (file_listing[i].type == EXT2_INODE_TYPE_SYMLINK)
                cout << "\033[3;33m" << file_listing[i].name << "\033[0m"; //yellow (with black background) - device
            else if ((file_listing[i].type == EXT2_DIR_TYPE_FILE) &&
                    (file_extension == "png" ||
                     file_extension == "jpg" ||
                     file_extension == "raw" ||
                     file_extension == "gif" ||
                     file_extension == "bmp" ||
                     file_extension == "tif")){ //38 - black
                cout << "\033[5;31m" << file_listing[i].name << "\033[0m"; }//pink - graphic image file
            else if ((file_listing[i].type == EXT2_DIR_TYPE_FILE) &&
                    (file_extension == "zip" ||
                     file_extension == "tar" ||
                     file_extension == "rar" ||
                     file_extension == "7z" ||
                     file_extension == "xz")){
                cout << "\033[0;31m" << file_listing[i].name << "\033[0m"; }//red - archive file
            else
                cout << file_extension << file_listing[i].name;

            if ((switches == "-l" && (file_listing[i].name != "." && file_listing[i].name !="..")) || switches == "-al")
                cout << "\n";
            else if (switches != "-al" && (file_listing[i].name == "." || file_listing[i].name ==".."));
            else
                cout << "\t";
        }
        return;
    }

    void interface::command_exit()
    {
        // exit the program
        exit(0);
    }

    void interface::command_help(const string & command)
    {
        command_code hashed_command = hash_command(command);
        switch (hashed_command)
        {
            case code_none:
            case code_cd:
                // explain cd command
                cout << "cd <directory_to_change_to>\n";
                cout << "Change directory command. This command will change the present working " <<
                        "directory to the one specified.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_cp:
                // explain cp command
                cout << "cp <in|out> <file_to_copy_from> <file_to_copy_to>\n";
                cout << "Copy a file between the host OS and the virtual hard drive and vice " <<
                        "versa.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_exit:
                // explain exit command
                cout << "exit\n";
                cout << "Exits the program.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_help:
                // explain help command
                cout << "help [command]\n";
                cout << "Procides help on the various commands.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_ls:
                // explain ls command
                cout << "ls [-al]\n";
                cout << "List the contents of the present working directory.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_pwd:
                // explain pwd command
                cout << "pwd\n";
                cout << "Prints out the present working directory.\n";
                break;

            case code_unknown:
                // unknown command
                cout << command << endl;
                cout << "Unknown command.\n";
                break;

            default:
                // A Bad Thing happened.  This should never get triggered.
                cout << "A Bad Thing happened.  You should not be seeing this.";
                break;
        }
    }

    void interface::command_pwd()
    {
        cout << file_system->get_pwd() << endl;
        return;
    }

    // Debug.
    void interface::command_dump_pwd_inode()
    {
        file_system->debug_dump_pwd_inode();
    }
    void interface::command_dump_block(u32 block_to_dump)
    {
        file_system->debug_dump_block(block_to_dump);
    }
    void interface::command_dump_inode(u32 inode_to_dump)
    {
        file_system->debug_dump_inode(inode_to_dump);
    }
    // End debug.

    interface::command_code interface::hash_command(const string & command)
    {
        if (command == "cd")
        {
            return code_cd;
        }
        else if (command == "cp")
        {
            return code_cp;
        }
        else if (command == "exit")
        {
            return code_exit;
        }
        else if (command == "help")
        {
            return code_help;
        }
        else if (command == "ls")
        {
            return code_ls;
        }
        else if (command == "ls -l") // long list version of ls
        {
            return code_ls;
        }
        else if (command == "pwd")
        {
            return code_pwd;
        }
        else if (command == "")
        {
            return code_none;
        }
        // Debug.
        else if (command == "dump_pwd_inode")
        {
            return code_dump_pwd_inode;
        }
        else if (command == "dump_block")
        {
            return code_dump_block;
        }
        else if (command == "dump_inode")
        {
            return code_dump_inode;
        }
        // End debug.
        else
        {
            return code_unknown;
        }
    }
} // namespace vdi_explorer<commit_msg>Minor Bug Fixes and cp in complete, cp out started<commit_after>/*--------------------------------------------------------------------------------------------------
 * Author:
 * Date:        2016-08-18
 * Assignment:  Final Project
 * Source File: interface.cpp
 * Language:    C/C++
 * Course:      Operating Systems
 * Purpose:     Contains the implementation of the interface class.
 -------------------------------------------------------------------------------------------------*/

#include "constants.h"
#include "ext2.h"
#include "interface.h"
#include "utility.h"

#include <cstdlib>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <string>
#include <stdexcept>
#include <cstdio>
#include <time.h>

using namespace std;
using namespace vdi_explorer;

namespace vdi_explorer
{
    // @TODO Make an actual throwable error.
    interface::interface(ext2 * _file_system)
    {
        file_system = _file_system;
        if (file_system == nullptr)
        {
            cout << "Error opening the file system object.";
            throw;
        }
    }

    interface::~interface()
    {
        return;
    }

    void interface::interactive()
    {
        string command_string;
        vector<string> tokens;
        vector<string> tokens2;

        while (true)
        {
            cout << "\nCommand: ";
            getline(cin, command_string);
            tokens = utility::tokenize(command_string, DELIMITER_SPACE);
            tokens2 = utility::tokenize(command_string, DELIMITER_FSLASH);

            // Debug info.
            for (unsigned int i = 0; i < tokens.size(); i++)
                cout << "debug (ext2::interface::interactive): " << tokens[i] << endl;
            // End debug info.

            if (tokens.size() == 0)
                continue;

            switch (hash_command(tokens[0]))
            {
                case code_cd:
                    if (tokens.size() < 2)
                    {
                        cout << "Not enough arguments.\n";
                        command_help("cd");
                    }
                    else
                    {
                        command_cd(tokens[1]);
                    }
                    break;

                case code_cp:
                    if (tokens.size() < 4)
                    {
                        cout << "Not enough arguments.\n";
                        command_help("cp");
                    }
                    else
                    {
                        command_cp(tokens[1], tokens[2], tokens[3]);
                    }
                    break;

                case code_exit:
                    command_exit();
                    break;

                case code_help:
                    if (tokens.size() < 2)
                    {
                        command_help("");
                    }
                    else
                    {
                        command_help(tokens[1]);
                    }
                    break;

                case code_ls:
                    if (tokens.size() < 2)
                    {
                        command_ls("");
                    }
                    else
                    {
                        command_ls(tokens[1]);
                    }
                    break;

                case code_pwd:
                    command_pwd();
                    break;

                // Debug
                case code_dump_pwd_inode:
                    command_dump_pwd_inode();
                    break;

                case code_dump_block:
                    command_dump_block(stoi(tokens[1]));
                    break;

                case code_dump_inode:
                    command_dump_inode(stoi(tokens[1]));
                    break;
                // End debug.

                case code_unknown:
                    cout << "Unknown command.\n";
                    break;

                default:
                    // A Bad Thing happened.  This should never get triggered.
                    cout << "A Bad Thing happened.  You should not be seeing this.";
                    break;
            }
        }
    }

    void interface::command_cd(const string & directory)
    {
        file_system->set_pwd(directory);
        return;
    }

    void interface::command_cp(const string & direction,
                               const string & copy_from,
                               const string & copy_to)
    {
        cout << "*** Implementation in progress.  Bust out the bugspray. ***\n";

        fstream os_file;

        if (direction == "in")
        {
            cout << "Not implemented yet.\n";
            return;
        }
        else if (direction == "out")
        {
            // Attempt to open the file for input to see if it already exists.
            os_file.open(copy_to, ios_base::in);
            bool file_exists = os_file.good();
            os_file.close();

            // Actually check if the file exists.
            if (file_exists)
            {
                cout << "Error, file already exists.";
                return;
            }
            else
            {
                // Open file for writing.
                os_file.open(copy_to, ios::out | ios::binary);
                if (!os_file.good())
                {
                    cout << "Error opening file for writing.\n";
                    return;
                }

                // Actually copy file out from the other file system.
                bool successful = file_system->file_read(os_file, copy_from);
                os_file.close();

                if (!successful)
                {
                    remove(copy_to.c_str());
                }
            }
        }
    }

    // @TODO format output neatly into appropriately sized columns -> function in utility?
    // @TODO sort vector by name
    // @TODO colorize:
        // Yellow with black background: Device
        // Pink: Graphic image file
    void interface::command_ls(const string & switches)
    {
        vector<fs_entry_posix> file_listing = file_system->get_directory_contents();
        vector<string> filename_tokens;
        for (u32 i = 0; i < file_listing.size(); i++)
        {
            filename_tokens = utility::tokenize(file_listing[i].name, DELIMITER_DOT);
            string file_extension = (filename_tokens.size() > 1 ? filename_tokens.back() : "");

            if (switches == "-l" || switches == "-al"){
                if (switches == "-l" && (file_listing[i].name == "." || file_listing[i].name ==".."));
                else
                    { // list permissions for each file
                if (file_listing[i].type == EXT2_DIR_TYPE_DIR)
                    cout << "d";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_USER_READ)
                    cout << "r";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_USER_WRITE)
                    cout << "w";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_USER_EXECUTE)
                    cout << "x";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_GROUP_READ)
                    cout << "r";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_GROUP_WRITE)
                    cout << "w";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_GROUP_EXECUTE)
                    cout << "x";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_OTHER_READ)
                    cout << "r";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_OTHER_WRITE)
                    cout << "w";
                else
                    cout << "-";
                if (file_listing[i].permissions & EXT2_INODE_PERM_OTHER_EXECUTE)
                    cout << "x ";
                else
                    cout << "- ";

                // set file type, UID, GID, and size
                cout << setw(2) << ((file_listing[i].type== EXT2_DIR_TYPE_DIR)?2:1)<< " ";
                cout << setw(5) << file_listing[i].user_id<< " ";
                cout << setw(5) << file_listing[i].group_id << " ";
                cout << setw(10) << file_listing[i].size << " ";

                // translate unix epoch timestamps to readable time
                time_t     curr;
                struct tm  ts;
                char       buf[80];
                curr = file_listing[i].timestamp_modified;
                ts = *localtime(&curr);
                strftime(buf, sizeof(buf), "%b %d %M:%S", &ts);
                printf("%s ", buf);

                }
            }
            if (file_listing[i].type == EXT2_DIR_TYPE_DIR){
                if (switches != "-al" ){
                    if (file_listing[i].name == "." || file_listing[i].name ==".."); // don't print out . and .. directories with -l switch
                    else
                        cout << "\033[1;34m" << file_listing[i].name << "\033[0m"<< "/"; //blue (bold) - directory or recognized data file                }
                }
                else if ((switches == "-al" ) && (file_listing[i].name == "." || file_listing[i].name ==".."))
                    cout << "\033[1;34m" << file_listing[i].name << "\033[0m";
                else
                    cout << "\033[1;34m" << file_listing[i].name << "\033[0m" << "/"; //blue (bold) - directory or recognized data file
            }
            else if ((file_listing[i].type == EXT2_DIR_TYPE_FILE) &&
                    (file_listing[i].permissions & EXT2_INODE_PERM_USER_EXECUTE ||
                     file_listing[i].permissions & EXT2_INODE_PERM_GROUP_EXECUTE ||
                     file_listing[i].permissions & EXT2_INODE_PERM_OTHER_EXECUTE)){
                cout << "\033[1;32m" << file_listing[i].name << "\033[0m" << "*"; //green - executable files
                     }
            else if (file_listing[i].type == EXT2_INODE_TYPE_SYMLINK)
                cout << "\033[6;36m" << file_listing[i].name << "\033[0m"; //cyan - linked file
            else if (file_listing[i].type == EXT2_INODE_TYPE_SYMLINK)
                cout << "\033[3;33m" << file_listing[i].name << "\033[0m"; //yellow (with black background) - device
            else if ((file_listing[i].type == EXT2_DIR_TYPE_FILE) &&
                    (file_extension == "png" ||
                     file_extension == "jpg" ||
                     file_extension == "raw" ||
                     file_extension == "gif" ||
                     file_extension == "bmp" ||
                     file_extension == "tif")){ //38 - black
                cout << "\033[5;31m" << file_listing[i].name << "\033[0m"; }//pink - graphic image file
            else if ((file_listing[i].type == EXT2_DIR_TYPE_FILE) &&
                    (file_extension == "zip" ||
                     file_extension == "tar" ||
                     file_extension == "rar" ||
                     file_extension == "7z" ||
                     file_extension == "xz")){
                cout << "\033[0;31m" << file_listing[i].name << "\033[0m"; }//red - archive file
            else
                cout << file_listing[i].name;

            if ((switches == "-l" && (file_listing[i].name != "." && file_listing[i].name !="..")) || switches == "-al")
                cout << "\n";
            else if (switches != "-al" && (file_listing[i].name == "." || file_listing[i].name ==".."));
            else
                cout << "\t";
        }
        return;
    }

    void interface::command_exit()
    {
        // exit the program
        exit(0);
    }

    void interface::command_help(const string & command)
    {
        command_code hashed_command = hash_command(command);
        switch (hashed_command)
        {
            case code_none:
            case code_cd:
                // explain cd command
                cout << "cd <directory_to_change_to>\n";
                cout << "Change directory command. This command will change the present working " <<
                        "directory to the one specified.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_cp:
                // explain cp command
                cout << "cp <in|out> <file_to_copy_from> <file_to_copy_to>\n";
                cout << "Copy a file between the host OS and the virtual hard drive and vice " <<
                        "versa.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_exit:
                // explain exit command
                cout << "exit\n";
                cout << "Exits the program.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_help:
                // explain help command
                cout << "help [command]\n";
                cout << "Procides help on the various commands.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_ls:
                // explain ls command
                cout << "ls [-al]\n";
                cout << "List the contents of the present working directory.\n";
                if (hashed_command != code_none)
                    break;
                else
                    cout << endl;

            case code_pwd:
                // explain pwd command
                cout << "pwd\n";
                cout << "Prints out the present working directory.\n";
                break;

            case code_unknown:
                // unknown command
                cout << command << endl;
                cout << "Unknown command.\n";
                break;

            default:
                // A Bad Thing happened.  This should never get triggered.
                cout << "A Bad Thing happened.  You should not be seeing this.";
                break;
        }
    }

    void interface::command_pwd()
    {
        cout << file_system->get_pwd() << endl;
        return;
    }

    // Debug.
    void interface::command_dump_pwd_inode()
    {
        file_system->debug_dump_pwd_inode();
    }
    void interface::command_dump_block(u32 block_to_dump)
    {
        file_system->debug_dump_block(block_to_dump);
    }
    void interface::command_dump_inode(u32 inode_to_dump)
    {
        file_system->debug_dump_inode(inode_to_dump);
    }
    // End debug.

    interface::command_code interface::hash_command(const string & command)
    {
        if (command == "cd")
        {
            return code_cd;
        }
        else if (command == "cp")
        {
            return code_cp;
        }
        else if (command == "exit")
        {
            return code_exit;
        }
        else if (command == "help")
        {
            return code_help;
        }
        else if (command == "ls")
        {
            return code_ls;
        }
        else if (command == "ls -l") // long list version of ls
        {
            return code_ls;
        }
        else if (command == "pwd")
        {
            return code_pwd;
        }
        else if (command == "")
        {
            return code_none;
        }
        // Debug.
        else if (command == "dump_pwd_inode")
        {
            return code_dump_pwd_inode;
        }
        else if (command == "dump_block")
        {
            return code_dump_block;
        }
        else if (command == "dump_inode")
        {
            return code_dump_inode;
        }
        // End debug.
        else
        {
            return code_unknown;
        }
    }
} // namespace vdi_explorer<|endoftext|>


<commit_before>/*************************************************************************/
/*  ray_cast.cpp                                                         */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "ray_cast.h"

#include "collision_object.h"
#include "mesh_instance.h"
#include "servers/physics_server.h"
void RayCast::set_cast_to(const Vector3 &p_point) {

	cast_to = p_point;
	if (is_inside_tree() && (get_tree()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
		update_gizmo();
	if (is_inside_tree() && get_tree()->is_debugging_collisions_hint())
		_update_debug_shape();
}

Vector3 RayCast::get_cast_to() const {

	return cast_to;
}

void RayCast::set_layer_mask(uint32_t p_mask) {

	layer_mask = p_mask;
}

uint32_t RayCast::get_layer_mask() const {

	return layer_mask;
}

void RayCast::set_type_mask(uint32_t p_mask) {

	type_mask = p_mask;
}

uint32_t RayCast::get_type_mask() const {

	return type_mask;
}

bool RayCast::is_colliding() const {

	return collided;
}
Object *RayCast::get_collider() const {

	if (against == 0)
		return NULL;

	return ObjectDB::get_instance(against);
}

int RayCast::get_collider_shape() const {

	return against_shape;
}
Vector3 RayCast::get_collision_point() const {

	return collision_point;
}
Vector3 RayCast::get_collision_normal() const {

	return collision_normal;
}

void RayCast::set_enabled(bool p_enabled) {

	enabled = p_enabled;
	if (is_inside_tree() && !get_tree()->is_editor_hint())
		set_fixed_process(p_enabled);
	if (!p_enabled)
		collided = false;

	if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
		if (p_enabled)
			_update_debug_shape();
		else
			_clear_debug_shape();
	}
}

bool RayCast::is_enabled() const {

	return enabled;
}

void RayCast::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (enabled && !get_tree()->is_editor_hint()) {
				set_fixed_process(true);

				if (get_tree()->is_debugging_collisions_hint())
					_update_debug_shape();
			} else
				set_fixed_process(false);

		} break;
		case NOTIFICATION_EXIT_TREE: {

			if (enabled) {
				set_fixed_process(false);
			}

			if (debug_shape)
				_clear_debug_shape();

		} break;
		case NOTIFICATION_FIXED_PROCESS: {

			if (!enabled)
				break;

			bool prev_collision_state = collided;
			_update_raycast_state();
			if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) {
				if (debug_material.is_valid()) {
					Ref<FixedSpatialMaterial> line_material = static_cast<Ref<FixedSpatialMaterial> >(debug_material);
					line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6));
				}
			}

		} break;
	}
}

void RayCast::_update_raycast_state() {
	Ref<World> w3d = get_world();
	ERR_FAIL_COND(w3d.is_null());

	PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(w3d->get_space());
	ERR_FAIL_COND(!dss);

	Transform gt = get_global_transform();

	Vector3 to = cast_to;
	if (to == Vector3())
		to = Vector3(0, 0.01, 0);

	PhysicsDirectSpaceState::RayResult rr;

	if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) {

		collided = true;
		against = rr.collider_id;
		collision_point = rr.position;
		collision_normal = rr.normal;
		against_shape = rr.shape;
	} else {
		collided = false;
	}
}

void RayCast::force_raycast_update() {
	_update_raycast_state();
}

void RayCast::add_exception_rid(const RID &p_rid) {

	exclude.insert(p_rid);
}

void RayCast::add_exception(const Object *p_object) {

	ERR_FAIL_NULL(p_object);
	CollisionObject *co = ((Object *)p_object)->cast_to<CollisionObject>();
	if (!co)
		return;
	add_exception_rid(co->get_rid());
}

void RayCast::remove_exception_rid(const RID &p_rid) {

	exclude.erase(p_rid);
}

void RayCast::remove_exception(const Object *p_object) {

	ERR_FAIL_NULL(p_object);
	CollisionObject *co = ((Object *)p_object)->cast_to<CollisionObject>();
	if (!co)
		return;
	remove_exception_rid(co->get_rid());
}

void RayCast::clear_exceptions() {

	exclude.clear();
}

void RayCast::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast::set_enabled);
	ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast::is_enabled);

	ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast::set_cast_to);
	ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast::get_cast_to);

	ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast::is_colliding);
	ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast::force_raycast_update);

	ClassDB::bind_method(D_METHOD("get_collider"), &RayCast::get_collider);
	ClassDB::bind_method(D_METHOD("get_collider_shape"), &RayCast::get_collider_shape);
	ClassDB::bind_method(D_METHOD("get_collision_point"), &RayCast::get_collision_point);
	ClassDB::bind_method(D_METHOD("get_collision_normal"), &RayCast::get_collision_normal);

	ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &RayCast::add_exception_rid);
	ClassDB::bind_method(D_METHOD("add_exception", "node"), &RayCast::add_exception);

	ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &RayCast::remove_exception_rid);
	ClassDB::bind_method(D_METHOD("remove_exception", "node"), &RayCast::remove_exception);

	ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast::clear_exceptions);

	ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &RayCast::set_layer_mask);
	ClassDB::bind_method(D_METHOD("get_layer_mask"), &RayCast::get_layer_mask);

	ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast::set_type_mask);
	ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast::get_type_mask);

	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_layer_mask", "get_layer_mask");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask");
}

void RayCast::_create_debug_shape() {

	if (!debug_material.is_valid()) {
		debug_material = Ref<FixedSpatialMaterial>(memnew(FixedSpatialMaterial));

		Ref<FixedSpatialMaterial> line_material = static_cast<Ref<FixedSpatialMaterial> >(debug_material);
		line_material->set_flag(FixedSpatialMaterial::FLAG_UNSHADED, true);
		line_material->set_line_width(3.0);
		line_material->set_albedo(Color(1.0, 0.8, 0.6));
	}

	Ref<Mesh> mesh = memnew(Mesh);

	MeshInstance *mi = memnew(MeshInstance);
	mi->set_mesh(mesh);

	add_child(mi);
	debug_shape = mi;
}

void RayCast::_update_debug_shape() {

	if (!enabled)
		return;

	if (!debug_shape)
		_create_debug_shape();

	MeshInstance *mi = static_cast<MeshInstance *>(debug_shape);
	if (!mi->get_mesh().is_valid())
		return;

	Ref<Mesh> mesh = mi->get_mesh();
	if (mesh->get_surface_count() > 0)
		mesh->surface_remove(0);

	Array a;
	a.resize(Mesh::ARRAY_MAX);

	Vector<Vector3> verts;
	verts.push_back(Vector3());
	verts.push_back(cast_to);
	a[Mesh::ARRAY_VERTEX] = verts;

	mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
	mesh->surface_set_material(0, debug_material);
}

void RayCast::_clear_debug_shape() {

	if (!debug_shape)
		return;

	MeshInstance *mi = static_cast<MeshInstance *>(debug_shape);
	if (mi->is_inside_tree())
		mi->queue_delete();
	else
		memdelete(mi);

	debug_shape = NULL;
}

RayCast::RayCast() {

	enabled = false;
	against = 0;
	collided = false;
	against_shape = 0;
	layer_mask = 1;
	type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
	cast_to = Vector3(0, -1, 0);
	debug_shape = NULL;
}
<commit_msg>Fixed #8102, by renaming FixedSpatialMaterial to SpatialMaterial<commit_after>/*************************************************************************/
/*  ray_cast.cpp                                                         */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                    http://www.godotengine.org                         */
/*************************************************************************/
/* Copyright (c) 2007-2017 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2017 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/
#include "ray_cast.h"

#include "collision_object.h"
#include "mesh_instance.h"
#include "servers/physics_server.h"
void RayCast::set_cast_to(const Vector3 &p_point) {

	cast_to = p_point;
	if (is_inside_tree() && (get_tree()->is_editor_hint() || get_tree()->is_debugging_collisions_hint()))
		update_gizmo();
	if (is_inside_tree() && get_tree()->is_debugging_collisions_hint())
		_update_debug_shape();
}

Vector3 RayCast::get_cast_to() const {

	return cast_to;
}

void RayCast::set_layer_mask(uint32_t p_mask) {

	layer_mask = p_mask;
}

uint32_t RayCast::get_layer_mask() const {

	return layer_mask;
}

void RayCast::set_type_mask(uint32_t p_mask) {

	type_mask = p_mask;
}

uint32_t RayCast::get_type_mask() const {

	return type_mask;
}

bool RayCast::is_colliding() const {

	return collided;
}
Object *RayCast::get_collider() const {

	if (against == 0)
		return NULL;

	return ObjectDB::get_instance(against);
}

int RayCast::get_collider_shape() const {

	return against_shape;
}
Vector3 RayCast::get_collision_point() const {

	return collision_point;
}
Vector3 RayCast::get_collision_normal() const {

	return collision_normal;
}

void RayCast::set_enabled(bool p_enabled) {

	enabled = p_enabled;
	if (is_inside_tree() && !get_tree()->is_editor_hint())
		set_fixed_process(p_enabled);
	if (!p_enabled)
		collided = false;

	if (is_inside_tree() && get_tree()->is_debugging_collisions_hint()) {
		if (p_enabled)
			_update_debug_shape();
		else
			_clear_debug_shape();
	}
}

bool RayCast::is_enabled() const {

	return enabled;
}

void RayCast::_notification(int p_what) {

	switch (p_what) {

		case NOTIFICATION_ENTER_TREE: {

			if (enabled && !get_tree()->is_editor_hint()) {
				set_fixed_process(true);

				if (get_tree()->is_debugging_collisions_hint())
					_update_debug_shape();
			} else
				set_fixed_process(false);

		} break;
		case NOTIFICATION_EXIT_TREE: {

			if (enabled) {
				set_fixed_process(false);
			}

			if (debug_shape)
				_clear_debug_shape();

		} break;
		case NOTIFICATION_FIXED_PROCESS: {

			if (!enabled)
				break;

			bool prev_collision_state = collided;
			_update_raycast_state();
			if (prev_collision_state != collided && get_tree()->is_debugging_collisions_hint()) {
				if (debug_material.is_valid()) {
					Ref<SpatialMaterial> line_material = static_cast<Ref<SpatialMaterial> >(debug_material);
					line_material->set_albedo(collided ? Color(1.0, 0, 0) : Color(1.0, 0.8, 0.6));
				}
			}

		} break;
	}
}

void RayCast::_update_raycast_state() {
	Ref<World> w3d = get_world();
	ERR_FAIL_COND(w3d.is_null());

	PhysicsDirectSpaceState *dss = PhysicsServer::get_singleton()->space_get_direct_state(w3d->get_space());
	ERR_FAIL_COND(!dss);

	Transform gt = get_global_transform();

	Vector3 to = cast_to;
	if (to == Vector3())
		to = Vector3(0, 0.01, 0);

	PhysicsDirectSpaceState::RayResult rr;

	if (dss->intersect_ray(gt.get_origin(), gt.xform(to), rr, exclude, layer_mask, type_mask)) {

		collided = true;
		against = rr.collider_id;
		collision_point = rr.position;
		collision_normal = rr.normal;
		against_shape = rr.shape;
	} else {
		collided = false;
	}
}

void RayCast::force_raycast_update() {
	_update_raycast_state();
}

void RayCast::add_exception_rid(const RID &p_rid) {

	exclude.insert(p_rid);
}

void RayCast::add_exception(const Object *p_object) {

	ERR_FAIL_NULL(p_object);
	CollisionObject *co = ((Object *)p_object)->cast_to<CollisionObject>();
	if (!co)
		return;
	add_exception_rid(co->get_rid());
}

void RayCast::remove_exception_rid(const RID &p_rid) {

	exclude.erase(p_rid);
}

void RayCast::remove_exception(const Object *p_object) {

	ERR_FAIL_NULL(p_object);
	CollisionObject *co = ((Object *)p_object)->cast_to<CollisionObject>();
	if (!co)
		return;
	remove_exception_rid(co->get_rid());
}

void RayCast::clear_exceptions() {

	exclude.clear();
}

void RayCast::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_enabled", "enabled"), &RayCast::set_enabled);
	ClassDB::bind_method(D_METHOD("is_enabled"), &RayCast::is_enabled);

	ClassDB::bind_method(D_METHOD("set_cast_to", "local_point"), &RayCast::set_cast_to);
	ClassDB::bind_method(D_METHOD("get_cast_to"), &RayCast::get_cast_to);

	ClassDB::bind_method(D_METHOD("is_colliding"), &RayCast::is_colliding);
	ClassDB::bind_method(D_METHOD("force_raycast_update"), &RayCast::force_raycast_update);

	ClassDB::bind_method(D_METHOD("get_collider"), &RayCast::get_collider);
	ClassDB::bind_method(D_METHOD("get_collider_shape"), &RayCast::get_collider_shape);
	ClassDB::bind_method(D_METHOD("get_collision_point"), &RayCast::get_collision_point);
	ClassDB::bind_method(D_METHOD("get_collision_normal"), &RayCast::get_collision_normal);

	ClassDB::bind_method(D_METHOD("add_exception_rid", "rid"), &RayCast::add_exception_rid);
	ClassDB::bind_method(D_METHOD("add_exception", "node"), &RayCast::add_exception);

	ClassDB::bind_method(D_METHOD("remove_exception_rid", "rid"), &RayCast::remove_exception_rid);
	ClassDB::bind_method(D_METHOD("remove_exception", "node"), &RayCast::remove_exception);

	ClassDB::bind_method(D_METHOD("clear_exceptions"), &RayCast::clear_exceptions);

	ClassDB::bind_method(D_METHOD("set_layer_mask", "mask"), &RayCast::set_layer_mask);
	ClassDB::bind_method(D_METHOD("get_layer_mask"), &RayCast::get_layer_mask);

	ClassDB::bind_method(D_METHOD("set_type_mask", "mask"), &RayCast::set_type_mask);
	ClassDB::bind_method(D_METHOD("get_type_mask"), &RayCast::get_type_mask);

	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "enabled"), "set_enabled", "is_enabled");
	ADD_PROPERTY(PropertyInfo(Variant::VECTOR3, "cast_to"), "set_cast_to", "get_cast_to");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "layer_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS), "set_layer_mask", "get_layer_mask");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "type_mask", PROPERTY_HINT_FLAGS, "Static,Kinematic,Rigid,Character,Area"), "set_type_mask", "get_type_mask");
}

void RayCast::_create_debug_shape() {

	if (!debug_material.is_valid()) {
		debug_material = Ref<SpatialMaterial>(memnew(SpatialMaterial));

		Ref<SpatialMaterial> line_material = static_cast<Ref<SpatialMaterial> >(debug_material);
		line_material->set_flag(SpatialMaterial::FLAG_UNSHADED, true);
		line_material->set_line_width(3.0);
		line_material->set_albedo(Color(1.0, 0.8, 0.6));
	}

	Ref<Mesh> mesh = memnew(Mesh);

	MeshInstance *mi = memnew(MeshInstance);
	mi->set_mesh(mesh);

	add_child(mi);
	debug_shape = mi;
}

void RayCast::_update_debug_shape() {

	if (!enabled)
		return;

	if (!debug_shape)
		_create_debug_shape();

	MeshInstance *mi = static_cast<MeshInstance *>(debug_shape);
	if (!mi->get_mesh().is_valid())
		return;

	Ref<Mesh> mesh = mi->get_mesh();
	if (mesh->get_surface_count() > 0)
		mesh->surface_remove(0);

	Array a;
	a.resize(Mesh::ARRAY_MAX);

	Vector<Vector3> verts;
	verts.push_back(Vector3());
	verts.push_back(cast_to);
	a[Mesh::ARRAY_VERTEX] = verts;

	mesh->add_surface_from_arrays(Mesh::PRIMITIVE_LINES, a);
	mesh->surface_set_material(0, debug_material);
}

void RayCast::_clear_debug_shape() {

	if (!debug_shape)
		return;

	MeshInstance *mi = static_cast<MeshInstance *>(debug_shape);
	if (mi->is_inside_tree())
		mi->queue_delete();
	else
		memdelete(mi);

	debug_shape = NULL;
}

RayCast::RayCast() {

	enabled = false;
	against = 0;
	collided = false;
	against_shape = 0;
	layer_mask = 1;
	type_mask = PhysicsDirectSpaceState::TYPE_MASK_COLLISION;
	cast_to = Vector3(0, -1, 0);
	debug_shape = NULL;
}
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"

#include "maya/MPxNode.h"
#include "maya/MSelectionList.h"
#include "maya/MFnDependencyNode.h"

#include "IECore/Parameterised.h"

#include "IECoreMaya/IECoreMaya.h"
#include "IECoreMaya/bindings/FnParameterisedHolderBinding.h"
#include "IECoreMaya/bindings/MayaPythonUtilBinding.h"
#include "IECoreMaya/bindings/FromMayaConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaPlugConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaObjectConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaCameraConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaCameraConverterBinding.h"
#include "IECoreMaya/bindings/MayaMeshBuilderBinding.h"
#include "IECoreMaya/bindings/FromMayaShapeConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaCurveConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaParticleConverterBinding.h"
#include "IECoreMaya/bindings/StandaloneBinding.h"
#include "IECoreMaya/bindings/FromMayaDagNodeConverterBinding.h"
#include "IECoreMaya/bindings/TypeIdBinding.h"
#include "IECoreMaya/bindings/MPlugFromPython.h"
#include "IECoreMaya/bindings/MObjectFromPython.h"
#include "IECoreMaya/bindings/MDagPathFromPython.h"
#include "IECoreMaya/bindings/ToMayaConverterBinding.h"
#include "IECoreMaya/bindings/ToMayaPlugConverterBinding.h"
#include "IECoreMaya/bindings/ToMayaObjectConverterBinding.h"
#include "IECoreMaya/bindings/MayaTypeIdsBinding.h"

using namespace IECore;
using namespace IECoreMaya;

using namespace boost::python;

/// Maya is built with 4-byte Unicode characters, so we need to ensure that we're doing
/// the same so that all external symbols resolve correctly at runtime.
#if ( MAYA_API_VERSION >= 2008 )
/// \todo Assert for earlier versions too, once installations of Python 2.5 for gcc4.0.2
/// are built correctly
BOOST_STATIC_ASSERT(sizeof(Py_UNICODE) == 4);
#endif

BOOST_PYTHON_MODULE(_IECoreMaya)
{
	bindMayaPythonUtil();
	bindFnParameterisedHolder();
	bindFromMayaConverter();
	bindFromMayaPlugConverter();
	bindFromMayaObjectConverter();
	bindFromMayaDagNodeConverter();
	bindFromMayaCameraConverter();
	bindMayaMeshBuilder();
	bindTypeId();
	bindFromMayaShapeConverter();
	bindFromMayaCurveConverter();
	bindFromMayaParticleConverter();
	bindStandalone();
	bindMPlugFromPython();
	bindMObjectFromPython();
	bindMDagPathFromPython();
	bindToMayaConverter();
	bindToMayaPlugConverter();
	bindToMayaObjectConverter();
	bindMayaTypeId();
}
<commit_msg>Fixed name of include file<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2008, Image Engine Design Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//
//     * Neither the name of Image Engine Design nor the names of any
//       other contributors to this software may be used to endorse or
//       promote products derived from this software without specific prior
//       written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
//  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
//  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
//  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
//  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
//  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
//  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
//  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"

#include "maya/MPxNode.h"
#include "maya/MSelectionList.h"
#include "maya/MFnDependencyNode.h"

#include "IECore/Parameterised.h"

#include "IECoreMaya/IECoreMaya.h"
#include "IECoreMaya/bindings/FnParameterisedHolderBinding.h"
#include "IECoreMaya/bindings/MayaPythonUtilBinding.h"
#include "IECoreMaya/bindings/FromMayaConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaPlugConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaObjectConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaCameraConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaCameraConverterBinding.h"
#include "IECoreMaya/bindings/MayaMeshBuilderBinding.h"
#include "IECoreMaya/bindings/FromMayaShapeConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaCurveConverterBinding.h"
#include "IECoreMaya/bindings/FromMayaParticleConverterBinding.h"
#include "IECoreMaya/bindings/StandaloneBinding.h"
#include "IECoreMaya/bindings/FromMayaDagNodeConverterBinding.h"
#include "IECoreMaya/bindings/TypeIdBinding.h"
#include "IECoreMaya/bindings/MPlugFromPython.h"
#include "IECoreMaya/bindings/MObjectFromPython.h"
#include "IECoreMaya/bindings/MDagPathFromPython.h"
#include "IECoreMaya/bindings/ToMayaConverterBinding.h"
#include "IECoreMaya/bindings/ToMayaPlugConverterBinding.h"
#include "IECoreMaya/bindings/ToMayaObjectConverterBinding.h"
#include "IECoreMaya/bindings/MayaTypeIdBinding.h"

using namespace IECore;
using namespace IECoreMaya;

using namespace boost::python;

/// Maya is built with 4-byte Unicode characters, so we need to ensure that we're doing
/// the same so that all external symbols resolve correctly at runtime.
#if ( MAYA_API_VERSION >= 2008 )
/// \todo Assert for earlier versions too, once installations of Python 2.5 for gcc4.0.2
/// are built correctly
BOOST_STATIC_ASSERT(sizeof(Py_UNICODE) == 4);
#endif

BOOST_PYTHON_MODULE(_IECoreMaya)
{
	bindMayaPythonUtil();
	bindFnParameterisedHolder();
	bindFromMayaConverter();
	bindFromMayaPlugConverter();
	bindFromMayaObjectConverter();
	bindFromMayaDagNodeConverter();
	bindFromMayaCameraConverter();
	bindMayaMeshBuilder();
	bindTypeId();
	bindFromMayaShapeConverter();
	bindFromMayaCurveConverter();
	bindFromMayaParticleConverter();
	bindStandalone();
	bindMPlugFromPython();
	bindMObjectFromPython();
	bindMDagPathFromPython();
	bindToMayaConverter();
	bindToMayaPlugConverter();
	bindToMayaObjectConverter();
	bindMayaTypeId();
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <types.hpp>
#include <unique_ptr.hpp>
#include <algorithms.hpp>
#include <errors.hpp>
#include <string.hpp>

#include "fs/procfs.hpp"

#include "scheduler.hpp"
#include "logging.hpp"

namespace {

const scheduler::process_control_t* pcb = nullptr;

std::vector<vfs::file> standard_contents;

size_t read(const std::string& value, char* buffer, size_t count, size_t offset, size_t& read){
    if(offset > value.size()){
        return std::ERROR_INVALID_OFFSET;
    }

    read = std::min(count, value.size() - offset);
    std::copy_n(buffer, value.c_str() + offset, read);

    return 0;
}

std::string get_value(uint64_t pid, const std::string& name){
    auto& process = pcb[pid];

    if(name == "pid"){
        return std::to_string(process.process.pid);
    } else if(name == "ppid"){
        return std::to_string(process.process.ppid);
    } else if(name == "state"){
        return std::to_string(static_cast<uint8_t>(process.state));
    } else if(name == "system"){
        return process.process.system ? "true" : "false";
    } else if(name == "priority"){
        return std::to_string(process.process.priority);
    } else if(name == "name"){
        return process.process.name;
    } else if(name == "memory"){
        return std::to_string(process.process.brk_end - process.process.brk_start);
    } else {
        return "";
    }
}

} //end of anonymous namespace

void procfs::set_pcb(const scheduler::process_control_t* pcb_ptr){
    pcb = pcb_ptr;
}

procfs::procfs_file_system::procfs_file_system(std::string mp) : mount_point(mp) {
    standard_contents.reserve(7);
    standard_contents.emplace_back("pid", false, false, false, 0);
    standard_contents.emplace_back("ppid", false, false, false, 0);
    standard_contents.emplace_back("state", false, false, false, 0);
    standard_contents.emplace_back("system", false, false, false, 0);
    standard_contents.emplace_back("priority", false, false, false, 0);
    standard_contents.emplace_back("name", false, false, false, 0);
    standard_contents.emplace_back("memory", false, false, false, 0);
}

procfs::procfs_file_system::~procfs_file_system(){
    //Nothing to delete
}

size_t procfs::procfs_file_system::get_file(const std::vector<std::string>& file_path, vfs::file& f){
    // Access the root folder
    if(file_path.empty()){
        f.file_name = "/";
        f.directory = true;
        f.hidden = false;
        f.system = false;
        f.size = 0;

        return 0;
    }

    auto i = atoui(file_path[0]);

    // Check the pid folder
    if(i >= scheduler::MAX_PROCESS){
        return std::ERROR_NOT_EXISTS;
    }

    auto& process = pcb[i];

    if(process.state == scheduler::process_state::EMPTY){
        return std::ERROR_NOT_EXISTS;
    }

    // Access a pid folder
    if(file_path.size() == 1){
        f.file_name = file_path[0];
        f.directory = true;
        f.hidden = false;
        f.system = false;
        f.size = 0;

        return 0;
    }

    // Access a file directly
    if(file_path.size() == 2){
        auto value = get_value(i, file_path[1]);

        if(value.size()){
            f.file_name = file_path[1];
            f.directory = false;
            f.hidden = false;
            f.system = false;
            f.size = value.size();

            return 0;
        } else {
            return std::ERROR_NOT_EXISTS;
        }
    }

    // There are no more levels
    return std::ERROR_NOT_EXISTS;
}

size_t procfs::procfs_file_system::read(const std::vector<std::string>& file_path, char* buffer, size_t count, size_t offset, size_t& read){
    //Cannot access the root nor the pid directores for reading
    if(file_path.size() < 2){
        return std::ERROR_PERMISSION_DENIED;
    }

    if(file_path.size() == 2){
        auto i = atoui(file_path[0]);

        if(i >= scheduler::MAX_PROCESS){
            return std::ERROR_NOT_EXISTS;
        }

        auto& process = pcb[i];

        if(process.state == scheduler::process_state::EMPTY){
            return std::ERROR_NOT_EXISTS;
        }

        auto value = get_value(i, file_path[1]);

        if(value.size()){
            return ::read(value, buffer, count, offset, read);
        } else {
            return std::ERROR_NOT_EXISTS;
        }
    }

    return std::ERROR_NOT_EXISTS;
}

size_t procfs::procfs_file_system::ls(const std::vector<std::string>& file_path, std::vector<vfs::file>& contents){
    logging::logf(logging::log_level::DEBUG, "procfs ls %u\n", file_path.size());

    if(file_path.size() == 0){
        for(size_t i = 0; i < scheduler::MAX_PROCESS; ++i){
            auto& process = pcb[i];

            if(process.state != scheduler::process_state::EMPTY){
                vfs::file f;
                f.file_name = std::to_string(process.process.pid);
                f.directory = true;
                f.hidden = false;
                f.system = false;
                f.size = 0;
                contents.emplace_back(std::move(f));
            }
        }

        return 0;
    }

    if(file_path.size() == 1){
        contents = standard_contents;
        return 0;
    }

    //No more subfolder support
    return std::ERROR_NOT_EXISTS;
}

size_t procfs::procfs_file_system::statfs(statfs_info& file){
    file.total_size = 0;
    file.free_size = 0;

    return 0;
}

size_t procfs::procfs_file_system::write(const std::vector<std::string>& file_path, const char* buffer, size_t count, size_t offset, size_t& written){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::truncate(const std::vector<std::string>&, size_t){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::touch(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::mkdir(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::rm(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}
<commit_msg>Silence some warnings<commit_after>//=======================================================================
// Copyright Baptiste Wicht 2013-2016.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//=======================================================================

#include <types.hpp>
#include <unique_ptr.hpp>
#include <algorithms.hpp>
#include <errors.hpp>
#include <string.hpp>

#include "fs/procfs.hpp"

#include "scheduler.hpp"
#include "logging.hpp"

namespace {

const scheduler::process_control_t* pcb = nullptr;

std::vector<vfs::file> standard_contents;

size_t read(const std::string& value, char* buffer, size_t count, size_t offset, size_t& read){
    if(offset > value.size()){
        return std::ERROR_INVALID_OFFSET;
    }

    read = std::min(count, value.size() - offset);
    std::copy_n(buffer, value.c_str() + offset, read);

    return 0;
}

std::string get_value(uint64_t pid, const std::string& name){
    auto& process = pcb[pid];

    if(name == "pid"){
        return std::to_string(process.process.pid);
    } else if(name == "ppid"){
        return std::to_string(process.process.ppid);
    } else if(name == "state"){
        return std::to_string(static_cast<uint8_t>(process.state));
    } else if(name == "system"){
        return process.process.system ? "true" : "false";
    } else if(name == "priority"){
        return std::to_string(process.process.priority);
    } else if(name == "name"){
        return process.process.name;
    } else if(name == "memory"){
        return std::to_string(process.process.brk_end - process.process.brk_start);
    } else {
        return "";
    }
}

} //end of anonymous namespace

void procfs::set_pcb(const scheduler::process_control_t* pcb_ptr){
    pcb = pcb_ptr;
}

procfs::procfs_file_system::procfs_file_system(std::string mp) : mount_point(mp) {
    standard_contents.reserve(7);
    standard_contents.emplace_back("pid", false, false, false, 0);
    standard_contents.emplace_back("ppid", false, false, false, 0);
    standard_contents.emplace_back("state", false, false, false, 0);
    standard_contents.emplace_back("system", false, false, false, 0);
    standard_contents.emplace_back("priority", false, false, false, 0);
    standard_contents.emplace_back("name", false, false, false, 0);
    standard_contents.emplace_back("memory", false, false, false, 0);
}

procfs::procfs_file_system::~procfs_file_system(){
    //Nothing to delete
}

size_t procfs::procfs_file_system::get_file(const std::vector<std::string>& file_path, vfs::file& f){
    // Access the root folder
    if(file_path.empty()){
        f.file_name = "/";
        f.directory = true;
        f.hidden = false;
        f.system = false;
        f.size = 0;

        return 0;
    }

    auto i = atoui(file_path[0]);

    // Check the pid folder
    if(i >= scheduler::MAX_PROCESS){
        return std::ERROR_NOT_EXISTS;
    }

    auto& process = pcb[i];

    if(process.state == scheduler::process_state::EMPTY){
        return std::ERROR_NOT_EXISTS;
    }

    // Access a pid folder
    if(file_path.size() == 1){
        f.file_name = file_path[0];
        f.directory = true;
        f.hidden = false;
        f.system = false;
        f.size = 0;

        return 0;
    }

    // Access a file directly
    if(file_path.size() == 2){
        auto value = get_value(i, file_path[1]);

        if(value.size()){
            f.file_name = file_path[1];
            f.directory = false;
            f.hidden = false;
            f.system = false;
            f.size = value.size();

            return 0;
        } else {
            return std::ERROR_NOT_EXISTS;
        }
    }

    // There are no more levels
    return std::ERROR_NOT_EXISTS;
}

size_t procfs::procfs_file_system::read(const std::vector<std::string>& file_path, char* buffer, size_t count, size_t offset, size_t& read){
    //Cannot access the root nor the pid directores for reading
    if(file_path.size() < 2){
        return std::ERROR_PERMISSION_DENIED;
    }

    if(file_path.size() == 2){
        auto i = atoui(file_path[0]);

        if(i >= scheduler::MAX_PROCESS){
            return std::ERROR_NOT_EXISTS;
        }

        auto& process = pcb[i];

        if(process.state == scheduler::process_state::EMPTY){
            return std::ERROR_NOT_EXISTS;
        }

        auto value = get_value(i, file_path[1]);

        if(value.size()){
            return ::read(value, buffer, count, offset, read);
        } else {
            return std::ERROR_NOT_EXISTS;
        }
    }

    return std::ERROR_NOT_EXISTS;
}

size_t procfs::procfs_file_system::ls(const std::vector<std::string>& file_path, std::vector<vfs::file>& contents){
    logging::logf(logging::log_level::DEBUG, "procfs ls %u\n", file_path.size());

    if(file_path.size() == 0){
        for(size_t i = 0; i < scheduler::MAX_PROCESS; ++i){
            auto& process = pcb[i];

            if(process.state != scheduler::process_state::EMPTY){
                vfs::file f;
                f.file_name = std::to_string(process.process.pid);
                f.directory = true;
                f.hidden = false;
                f.system = false;
                f.size = 0;
                contents.emplace_back(std::move(f));
            }
        }

        return 0;
    }

    if(file_path.size() == 1){
        contents = standard_contents;
        return 0;
    }

    //No more subfolder support
    return std::ERROR_NOT_EXISTS;
}

size_t procfs::procfs_file_system::statfs(statfs_info& file){
    file.total_size = 0;
    file.free_size = 0;

    return 0;
}

size_t procfs::procfs_file_system::write(const std::vector<std::string>&, const char*, size_t, size_t, size_t&){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::truncate(const std::vector<std::string>&, size_t){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::touch(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::mkdir(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}

size_t procfs::procfs_file_system::rm(const std::vector<std::string>& ){
    return std::ERROR_PERMISSION_DENIED;
}
<|endoftext|>


<commit_before>// -------------------------------------------------------------------
//
// Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved.
//
// This file is provided to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file
// except in compliance with the License.  You may obtain
// a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// -------------------------------------------------------------------
#include <cstddef>

template <typename T>
class cas_pointer
{
public:
    cas_pointer() {}
    explicit cas_pointer(T* p) : ptr_(p) {}
public:
    inline T* load() const
    {
        return __sync_fetch_and_add(&ptr_, 0);
    }
    inline void store(T* p)
    {
        do
        {
            __sync_val_compare_and_swap(&ptr_, ptr_, p);
        } while(ptr_ != p);
    }
private:
    mutable T* ptr_;
};

template <typename T>
class barrier_pointer
{
public:
    barrier_pointer() {}
    explicit barrier_pointer(T* p) : ptr_(p) {}
public:
    inline T* load() const
    {
        T* result = ptr_;
        memory_barrier();
        return result;
    }
    inline void store(T* p)
    {
        memory_barrier();
        ptr_ = p;
    }
private:
    void memory_barrier() const { __sync_synchronize(); }
private:
    T* ptr_;
};

template <typename T, template <class> class PointerType=barrier_pointer>
class lockfree_queue
{
private:
    struct node
    {
        node(T val)
            : value(val),
              next(0) {};
        T value;
        node *next;
    };
    typedef PointerType<node> atomic_node_pointer;

public:
    lockfree_queue()
        : first_(new node(T())),
          divider_(atomic_node_pointer(first_)),
          last_(atomic_node_pointer(first_)) {}

    ~lockfree_queue()
    {
        while (first_ != 0)
        {
            node* tmp = first_;
            first_ = tmp->next;
            delete tmp;
        }
    }
public:
    void produce(const T& t)
    {
        last_.load()->next = new node(t);
        last_.store(last_.load()->next);
        __sync_add_and_fetch(&len_, 1);
        while (first_ != divider_.load())
        {
            node *tmp = first_;
            first_ = first_->next;
            delete tmp;
        }
    }

    bool consume(T& result)
    {
        if (divider_.load() != last_.load())
        {
            result = divider_.load()->next->value;
            divider_.store(divider_.load()->next);
            __sync_sub_and_fetch(&len_, 1);
            return true;
        }
        return false;
    }

    std::size_t len() const
    {
        return __sync_fetch_and_add(&len_, 0);
    }

private:
    node *first_;
    atomic_node_pointer divider_, last_;
    std::size_t len_;
};
<commit_msg>make len_ mutable<commit_after>// -------------------------------------------------------------------
//
// Copyright (c) 2007-2012 Basho Technologies, Inc. All Rights Reserved.
//
// This file is provided to you under the Apache License,
// Version 2.0 (the "License"); you may not use this file
// except in compliance with the License.  You may obtain
// a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.
//
// -------------------------------------------------------------------
#include <cstddef>

template <typename T>
class cas_pointer
{
public:
    cas_pointer() {}
    explicit cas_pointer(T* p) : ptr_(p) {}
public:
    inline T* load() const
    {
        return __sync_fetch_and_add(&ptr_, 0);
    }
    inline void store(T* p)
    {
        do
        {
            __sync_val_compare_and_swap(&ptr_, ptr_, p);
        } while(ptr_ != p);
    }
private:
    mutable T* ptr_;
};

template <typename T>
class barrier_pointer
{
public:
    barrier_pointer() {}
    explicit barrier_pointer(T* p) : ptr_(p) {}
public:
    inline T* load() const
    {
        T* result = ptr_;
        memory_barrier();
        return result;
    }
    inline void store(T* p)
    {
        memory_barrier();
        ptr_ = p;
    }
private:
    void memory_barrier() const { __sync_synchronize(); }
private:
    T* ptr_;
};

template <typename T, template <class> class PointerType=barrier_pointer>
class lockfree_queue
{
private:
    struct node
    {
        node(T val)
            : value(val),
              next(0) {};
        T value;
        node *next;
    };
    typedef PointerType<node> atomic_node_pointer;

public:
    lockfree_queue()
        : first_(new node(T())),
          divider_(atomic_node_pointer(first_)),
          last_(atomic_node_pointer(first_)) {}

    ~lockfree_queue()
    {
        while (first_ != 0)
        {
            node* tmp = first_;
            first_ = tmp->next;
            delete tmp;
        }
    }
public:
    void produce(const T& t)
    {
        last_.load()->next = new node(t);
        last_.store(last_.load()->next);
        __sync_add_and_fetch(&len_, 1);
        while (first_ != divider_.load())
        {
            node *tmp = first_;
            first_ = first_->next;
            delete tmp;
        }
    }

    bool consume(T& result)
    {
        if (divider_.load() != last_.load())
        {
            result = divider_.load()->next->value;
            divider_.store(divider_.load()->next);
            __sync_sub_and_fetch(&len_, 1);
            return true;
        }
        return false;
    }

    std::size_t len() const
    {
        return __sync_fetch_and_add(&len_, 0);
    }

private:
    node *first_;
    atomic_node_pointer divider_, last_;
    mutable std::size_t len_;
};
<|endoftext|>


<commit_before>#include "getpath.h"

#include <vector>

#ifdef _WIN32
#include <windows.h> // GetFullPathNameA
#else
#include <libgen.h> // dirname
#include <cstring> // std::strcpy
#endif

namespace cura
{
std::string getPathName(const std::string& filePath) {
    std::vector<char> buffer(filePath.size() + 1);
#ifdef _WIN32
    char* name_start;
    GetFullPathNameA(filePath.c_str(), static_cast<DWORD>(buffer.size()), buffer.data(), &name_start);
    std::string folder_name{buffer.data(), name_start};
#else
    std::strcpy(buffer.data(), filePath.c_str()); // copy the string because dirname(.) changes the input string!!!
    std::string folder_name{dirname(buffer.data())};
#endif
    return folder_name;
}
}<commit_msg>Fix getPathName()<commit_after>#include "getpath.h"

#include <iostream>

#ifdef _WIN32
#include <windows.h> // GetFullPathNameA
#else
#include <libgen.h> // dirname
#include <cstring> // std::strcpy
#endif

namespace cura
{
std::string getPathName(const std::string& filePath) {
#ifdef _WIN32
    char buffer[MAX_PATH];
    char* name_start;
    DWORD path_size = GetFullPathNameA(filePath.c_str(), static_cast<DWORD>(MAX_PATH), buffer, &name_start);
    if (path_size == 0)
    {
        std::cerr << "Failed to get full path for [" << filePath.c_str() << "]" << std::endl;
        exit(1);
    }
    std::string folder_name{name_start, path_size};
#else
    char buffer[filePath.size()];
    std::strcpy(buffer, filePath.c_str()); // copy the string because dirname(.) changes the input string!!!
    std::string folder_name{dirname(buffer)};
#endif
    return folder_name;
}
}<|endoftext|>


<commit_before>#include "restapi.h"

#include "jansson.h"
#include <assert.h>
#include <unistd.h> // sleep

namespace
{
// automatic init of curl's systems
struct CurlStartup
{
  CurlStartup()   { curl_global_init(CURL_GLOBAL_ALL); }
  ~CurlStartup()  { curl_global_cleanup(); }
}runCurlStartup;

// internal helpers
size_t recvCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  auto &buffer = *static_cast<std::string *> (userp);
  auto n = size * nmemb;
  return buffer.append((char*)contents, n), n;
}

json_t* doRequest(CURL *C,
                  const std::string &url,
                  const curl_slist *headers,
                  std::ostream &log)
{
  std::string recvBuffer;
  curl_easy_setopt(C, CURLOPT_WRITEDATA, &recvBuffer);

  curl_easy_setopt(C, CURLOPT_URL, url.c_str());
  curl_easy_setopt(C, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(C, CURLOPT_DNS_CACHE_TIMEOUT, 3600);

  goto curl_state;

retry_state:
  log << "  Retry in 2 sec..." << std::endl;
  sleep(2.0);
  recvBuffer.clear();
  curl_easy_setopt(C, CURLOPT_DNS_CACHE_TIMEOUT, 0);

curl_state:
  CURLcode resCurl = curl_easy_perform(C);
  if (resCurl != CURLE_OK)
  {
    log << "Error with cURL: " << curl_easy_strerror(resCurl) << '\n'
        << "  URL: " << url << '\n';

    goto retry_state;
  }

/* documentation label */
// json_state:
  json_error_t error;
  json_t *root = json_loads(recvBuffer.c_str(), 0, &error);
  if (!root)
  {
    long resp_code;
    curl_easy_getinfo(C, CURLINFO_RESPONSE_CODE, &resp_code);
    log << "Server Response: " << resp_code << " - " << url << '\n'
        << "Error with JSON: " << error.text << '\n'
        << "Buffer:\n"         << recvBuffer << '\n';

    goto retry_state;
  }

  return root;
}
}

void RestApi::CURL_deleter::operator () (CURL *C)
{
  curl_easy_cleanup(C);
}

void RestApi::CURL_deleter::operator () (curl_slist *slist)
{
  curl_slist_free_all(slist);
}

RestApi::RestApi(std::string host,  const char *cacert, std::ostream &log)
    : C(curl_easy_init()), host(std::move(host)), log(log)
{
  assert(C != nullptr);

  if (cacert)
        curl_easy_setopt(C.get(), CURLOPT_CAINFO, cacert);
  else  curl_easy_setopt(C.get(), CURLOPT_SSL_VERIFYPEER, false);

  curl_easy_setopt(C.get(), CURLOPT_CONNECTTIMEOUT, 10L);
  curl_easy_setopt(C.get(), CURLOPT_TIMEOUT, 20L);
  curl_easy_setopt(C.get(), CURLOPT_ACCEPT_ENCODING, "gzip");

  curl_easy_setopt(C.get(), CURLOPT_WRITEFUNCTION, recvCallback);
}

json_t* RestApi::getRequest(const std::string &uri, unique_slist headers)
{
  curl_easy_setopt(C.get(), CURLOPT_HTTPGET, true);
  return doRequest(C.get(), host + uri, headers.get(), log);
}

json_t* RestApi::postRequest (const std::string &uri,
                              unique_slist headers,
                              const std::string &post_data)
{
  curl_easy_setopt(C.get(), CURLOPT_POSTFIELDS,     post_data.data());
  curl_easy_setopt(C.get(), CURLOPT_POSTFIELDSIZE,  post_data.size());
  return doRequest(C.get(), host + uri, headers.get(), log);
}

json_t* RestApi::postRequest (const std::string &uri, const std::string &post_data)
{
  return postRequest(uri, nullptr, post_data);
}
<commit_msg>Removed extra 'std' qualifier from 'string'.<commit_after>#include "restapi.h"

#include "jansson.h"
#include <assert.h>
#include <unistd.h> // sleep

namespace
{
// automatic init of curl's systems
struct CurlStartup
{
  CurlStartup()   { curl_global_init(CURL_GLOBAL_ALL); }
  ~CurlStartup()  { curl_global_cleanup(); }
}runCurlStartup;

// internal helpers
size_t recvCallback(void *contents, size_t size, size_t nmemb, void *userp)
{
  auto &buffer = *static_cast<std::string *> (userp);
  auto n = size * nmemb;
  return buffer.append((char*)contents, n), n;
}

json_t* doRequest(CURL *C,
                  const std::string &url,
                  const curl_slist *headers,
                  std::ostream &log)
{
  std::string recvBuffer;
  curl_easy_setopt(C, CURLOPT_WRITEDATA, &recvBuffer);

  curl_easy_setopt(C, CURLOPT_URL, url.c_str());
  curl_easy_setopt(C, CURLOPT_HTTPHEADER, headers);
  curl_easy_setopt(C, CURLOPT_DNS_CACHE_TIMEOUT, 3600);

  goto curl_state;

retry_state:
  log << "  Retry in 2 sec..." << std::endl;
  sleep(2.0);
  recvBuffer.clear();
  curl_easy_setopt(C, CURLOPT_DNS_CACHE_TIMEOUT, 0);

curl_state:
  CURLcode resCurl = curl_easy_perform(C);
  if (resCurl != CURLE_OK)
  {
    log << "Error with cURL: " << curl_easy_strerror(resCurl) << '\n'
        << "  URL: " << url << '\n';

    goto retry_state;
  }

/* documentation label */
// json_state:
  json_error_t error;
  json_t *root = json_loads(recvBuffer.c_str(), 0, &error);
  if (!root)
  {
    long resp_code;
    curl_easy_getinfo(C, CURLINFO_RESPONSE_CODE, &resp_code);
    log << "Server Response: " << resp_code << " - " << url << '\n'
        << "Error with JSON: " << error.text << '\n'
        << "Buffer:\n"         << recvBuffer << '\n';

    goto retry_state;
  }

  return root;
}
}

void RestApi::CURL_deleter::operator () (CURL *C)
{
  curl_easy_cleanup(C);
}

void RestApi::CURL_deleter::operator () (curl_slist *slist)
{
  curl_slist_free_all(slist);
}

RestApi::RestApi(string host, const char *cacert, std::ostream &log)
    : C(curl_easy_init()), host(std::move(host)), log(log)
{
  assert(C != nullptr);

  if (cacert)
        curl_easy_setopt(C.get(), CURLOPT_CAINFO, cacert);
  else  curl_easy_setopt(C.get(), CURLOPT_SSL_VERIFYPEER, false);

  curl_easy_setopt(C.get(), CURLOPT_CONNECTTIMEOUT, 10L);
  curl_easy_setopt(C.get(), CURLOPT_TIMEOUT, 20L);
  curl_easy_setopt(C.get(), CURLOPT_ACCEPT_ENCODING, "gzip");

  curl_easy_setopt(C.get(), CURLOPT_WRITEFUNCTION, recvCallback);
}

json_t* RestApi::getRequest(const string &uri, unique_slist headers)
{
  curl_easy_setopt(C.get(), CURLOPT_HTTPGET, true);
  return doRequest(C.get(), host + uri, headers.get(), log);
}

json_t* RestApi::postRequest (const string &uri,
                              unique_slist headers,
                              const string &post_data)
{
  curl_easy_setopt(C.get(), CURLOPT_POSTFIELDS,     post_data.data());
  curl_easy_setopt(C.get(), CURLOPT_POSTFIELDSIZE,  post_data.size());
  return doRequest(C.get(), host + uri, headers.get(), log);
}

json_t* RestApi::postRequest (const string &uri, const string &post_data)
{
  return postRequest(uri, nullptr, post_data);
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>

#include <boost/program_options.hpp>

#include <amgcl/amg.hpp>
#include <amgcl/make_solver.hpp>

#include <amgcl/backend/builtin.hpp>
#include <amgcl/adapter/crs_tuple.hpp>
#include <amgcl/adapter/block_matrix.hpp>
#include <amgcl/value_type/static_matrix.hpp>

#ifdef AMGCL_HAVE_EIGEN
#  include <amgcl/value_type/eigen.hpp>
#endif

#include <amgcl/coarsening/smoothed_aggregation.hpp>
#include <amgcl/relaxation/gauss_seidel.hpp>
#include <amgcl/solver/bicgstabl.hpp>

#include <amgcl/profiler.hpp>
#include <amgcl/io/mm.hpp>

namespace amgcl {
    profiler<> prof;
}

template <int B>
void solve(const std::string &matrix_file, const std::string &rhs_file) {
#if 1 && defined(AMGCL_HAVE_EIGEN)
    // Use Eigen static matrices for value types.
    typedef Eigen::Matrix<double, B, B> value_type;
    typedef Eigen::Matrix<double, B, 1> rhs_type;
#else
    // Use builtin static matrices for value types.
    typedef amgcl::static_matrix<double, B, B> value_type;
    typedef amgcl::static_matrix<double, B, 1> rhs_type;
#endif

    using amgcl::precondition;
    using amgcl::prof;

    prof.tic("read problem");
    // Read scalar matrix
    std::vector<int> ptr, col;
    std::vector<double> val;
    int rows, cols;
    boost::tie(rows, cols) = amgcl::io::mm_reader(matrix_file)(ptr, col, val);

    precondition(rows == cols, "System matrix is not square");
    precondition(rows % B == 0, "System size is not divisible by block size");

    int n = rows / B;

    // Read RHS (if any).
    std::vector<rhs_type> rhs(n, amgcl::math::constant<rhs_type>(1.0));
    if (!rhs_file.empty()) {
        int nn, mm;
        std::vector<double> b;
        boost::tie(nn, mm) = amgcl::io::mm_reader(rhs_file)(b);

        precondition(nn == rows && mm == 1, "RHS has incorrect size");

        for(int ip = 0, ia = 0; ip < n; ++ip) {
            for(int k = 0; k < B; ++k, ++ia) {
                rhs[ip](k) = b[ia];
            }
        }
    }

    prof.toc("read problem");

    typedef amgcl::backend::builtin<value_type> Backend;

    boost::property_tree::ptree prm;
    prm.put("solver.maxiter", 1000);

    prof.tic("setup");
    amgcl::make_solver<
        amgcl::amg<
            Backend,
            amgcl::coarsening::smoothed_aggregation,
            amgcl::relaxation::gauss_seidel
            >,
        amgcl::solver::bicgstabl<Backend>
        > solve(amgcl::adapter::block_matrix<B, value_type>(boost::tie(rows, ptr, col, val)), prm);
    prof.toc("setup");

    std::cout << solve.precond() << std::endl;

    std::vector<rhs_type> x(n, amgcl::math::zero<rhs_type>());

    int    iters;
    double resid;

    prof.tic("solve");
    boost::tie(iters, resid) = solve(rhs, x);
    prof.toc("solve");

    std::cout << "Iterations: " << iters << std::endl
              << "Error:      " << resid << std::endl
              ;

    std::cout << prof << std::endl;
}

int main(int argc, char *argv[]) {
    int block_size = 3;
    std::string matrix_file;
    std::string rhs_file;

    namespace po = boost::program_options;
    po::options_description desc("Options");

    desc.add_options()
        ("help,h", "show help")
        (
         "block_size,b",
         po::value<int>(&block_size)->default_value(block_size)->required(),
         "Block size. Supported values: 2-6"
        )
        (
         "matrix,A",
         po::value<std::string>(&matrix_file)->required(),
         "The system matrix in MatrixMarket format"
        )
        (
         "rhs,f",
         po::value<std::string>(&rhs_file),
         "The right-hand side in MatrixMarket format"
        )
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 0;
    }

    po::notify(vm);

    switch (block_size) {
        case 2:
            solve<2>(matrix_file, rhs_file);
            break;
        case 3:
            solve<3>(matrix_file, rhs_file);
            break;
        case 4:
            solve<4>(matrix_file, rhs_file);
            break;
        case 5:
            solve<5>(matrix_file, rhs_file);
            break;
        case 6:
            solve<6>(matrix_file, rhs_file);
            break;
        default:
            std::cerr << "Unsupported block size" << std::endl;
            return 1;
    }
}
<commit_msg>Use reinterpret_cast for rhs in nonscalar<commit_after>#include <iostream>
#include <string>

#include <boost/program_options.hpp>

#include <amgcl/amg.hpp>
#include <amgcl/make_solver.hpp>

#include <amgcl/backend/builtin.hpp>
#include <amgcl/adapter/crs_tuple.hpp>
#include <amgcl/adapter/block_matrix.hpp>
#include <amgcl/value_type/static_matrix.hpp>

#ifdef AMGCL_HAVE_EIGEN
#  include <amgcl/value_type/eigen.hpp>
#endif

#include <amgcl/coarsening/smoothed_aggregation.hpp>
#include <amgcl/relaxation/gauss_seidel.hpp>
#include <amgcl/solver/bicgstabl.hpp>

#include <amgcl/profiler.hpp>
#include <amgcl/io/mm.hpp>

namespace amgcl {
    profiler<> prof;
}

template <int B>
void solve(const std::string &matrix_file, const std::string &rhs_file) {
#if 1 && defined(AMGCL_HAVE_EIGEN)
    // Use Eigen static matrices for value types.
    typedef Eigen::Matrix<double, B, B> value_type;
    typedef Eigen::Matrix<double, B, 1> rhs_type;
#else
    // Use builtin static matrices for value types.
    typedef amgcl::static_matrix<double, B, B> value_type;
    typedef amgcl::static_matrix<double, B, 1> rhs_type;
#endif

    using amgcl::precondition;
    using amgcl::prof;

    prof.tic("read problem");
    // Read scalar matrix
    std::vector<int> ptr, col;
    std::vector<double> val;
    int rows, cols;
    boost::tie(rows, cols) = amgcl::io::mm_reader(matrix_file)(ptr, col, val);

    precondition(rows == cols, "System matrix is not square");
    precondition(rows % B == 0, "System size is not divisible by block size");

    int n = rows / B;

    // Read RHS (if any).
    std::vector<double> b;
    if (!rhs_file.empty()) {
        int nn, mm;
        boost::tie(nn, mm) = amgcl::io::mm_reader(rhs_file)(b);

        precondition(nn == rows && mm == 1, "RHS has incorrect size");
    }

    prof.toc("read problem");

    typedef amgcl::backend::builtin<value_type> Backend;

    boost::property_tree::ptree prm;
    prm.put("solver.maxiter", 1000);

    prof.tic("setup");
    amgcl::make_solver<
        amgcl::amg<
            Backend,
            amgcl::coarsening::smoothed_aggregation,
            amgcl::relaxation::gauss_seidel
            >,
        amgcl::solver::bicgstabl<Backend>
        > solve(amgcl::adapter::block_matrix<B, value_type>(boost::tie(rows, ptr, col, val)), prm);
    prof.toc("setup");

    std::cout << solve.precond() << std::endl;

    std::vector<rhs_type> x(n, amgcl::math::zero<rhs_type>());

    int    iters;
    double resid;

    prof.tic("solve");

    const rhs_type* b_begin = reinterpret_cast<const rhs_type*>(&b[0]);
    boost::iterator_range<const rhs_type*> b_range = boost::make_iterator_range(b_begin, b_begin + n);

    boost::tie(iters, resid) = solve(b_range, x);
    prof.toc("solve");

    std::cout << "Iterations: " << iters << std::endl
              << "Error:      " << resid << std::endl
              ;

    std::cout << prof << std::endl;
}

int main(int argc, char *argv[]) {
    int block_size = 3;
    std::string matrix_file;
    std::string rhs_file;

    namespace po = boost::program_options;
    po::options_description desc("Options");

    desc.add_options()
        ("help,h", "show help")
        (
         "block_size,b",
         po::value<int>(&block_size)->default_value(block_size)->required(),
         "Block size. Supported values: 2-6"
        )
        (
         "matrix,A",
         po::value<std::string>(&matrix_file)->required(),
         "The system matrix in MatrixMarket format"
        )
        (
         "rhs,f",
         po::value<std::string>(&rhs_file),
         "The right-hand side in MatrixMarket format"
        )
        ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);

    if (vm.count("help")) {
        std::cout << desc << std::endl;
        return 0;
    }

    po::notify(vm);

    switch (block_size) {
        case 2:
            solve<2>(matrix_file, rhs_file);
            break;
        case 3:
            solve<3>(matrix_file, rhs_file);
            break;
        case 4:
            solve<4>(matrix_file, rhs_file);
            break;
        case 5:
            solve<5>(matrix_file, rhs_file);
            break;
        case 6:
            solve<6>(matrix_file, rhs_file);
            break;
        default:
            std::cerr << "Unsupported block size" << std::endl;
            return 1;
    }
}
<|endoftext|>