<commit_before>#include <iostream>
#include <fstream>
#include <cstdint>
#include <algorithm>
#include <memory>
#include <stdio.h>
#include <chrono>

#include "config.hpp"
#include "dcpu_opcodes.hpp"
#include "dcpu.hpp"
#include "disassembler.hpp"
#include "gclock.hpp"
#include "gkeyboard.hpp"
#include "lem1802.hpp"
#include "lem1803.hpp"
#include "cgm.hpp"

using namespace cpu;

void print_help(std::string program_name)
{
    std::cout << "usage : " << program_name << " [--options] <dcpu16-exe>\n";
    std::cout << "--------------------------------------------------------\n";
    std::cout << "  options:" << std::endl;
    std::cout << "    --debug                  : start in debug mode\n";
    std::cout << "            F1  : next step" << std::endl;
    std::cout << "            F2  : print registers" << std::endl;
    std::cout << "            F3  : reset (no need debug mode)" << std::endl;
    std::cout << "            F12 : switch debug/run" << std::endl;
    std::cout << "    --monitor=<monitor_name> : use the following monitor\n";
    std::cout << "            1802 -> Lem1802 (default) [c]" << std::endl;
    std::cout << "            1803 -> Lem1803 [c]" << std::endl;
    std::cout << "            cgm -> Colour Graphics Monitor" << std::endl;
    std::cout << "            [c] : compatible with Lem1802 0x10c programs\n";
}

int main (int argc, char **argv)
{

    std::string filename;
    int monitor_type=0;
    bool debug=false;
    size_t size = 0;
    uint16_t* data;
    std::ifstream binfile;

    if (argc <= 1) {
        std::cerr << "Missing input file, type --help for list options\n";
        return 0;
    }
    for (int k=1; k < argc; k++) //parse arguments
    {
        if (argv[k][0] == '-')
        {
            std::string opt = argv[k];
            if (opt.find("--monitor") != std::string::npos)
            {
                if (opt == "--monitor=1802") monitor_type=0;
                else if (opt == "--monitor=1803") monitor_type=1;
                else if (opt == "--monitor=cgm") monitor_type=2;
                else {
                    std::cout << "Warning unknow monitor type ";
                    std::cout << opt << std::endl;
                }
            }
            else if (opt=="--help"||opt=="-help"||opt=="-h")
            {
                std::string pn = argv[0];
                pn.erase(0,pn.find_last_of('\\')+1); //windows
                pn.erase(0,pn.find_last_of('/')+1); //linux
                print_help(pn);
                return 0;
            }
            else if (opt=="--debug")
            {
                debug=true;
            }
            else
            {
                std::cout << "Warning: unknow option ";
                std::cout << opt << " it will be ignored !" << std::endl;
            }
        }
        else
        {
            filename = argv[k];
        }

    }

    //TODO make a function which do that but fast
    std::cout <<  "Input BIN File : " << filename << "\n";

    binfile.open (filename.c_str(), std::ios::in | std::ios::binary );

    if (!binfile) {
        std::cerr << "ERROR: I can open file\n";
        exit (1);
    }

    // get length of file:
    binfile.seekg (0, binfile.end);
    size = binfile.tellg();
    binfile.seekg (0, binfile.beg);

    data = new uint16_t[size / 2 + 1]();
    std::fill_n (data, size / 2, 0); // Clean it

    int i = 0;

    while (! binfile.eof() ) {
        //need improvement read (read whole file and then switch endianess
        uint16_t word = 0;
        binfile.read ( (char*) &word, 2);
        uint16_t tmp = ( (word & 0xFF00) >> 8) & 0x00FF;
        word = ( (word & 0x00FF) << 8) | tmp;
        data[i] = word;
        i++;
    }

    binfile.close();

    std::cout << "Readed " << size << " bytes - " << size / 2 << " words\n";
    size /= 2;

    sf::String window_title="dcpu_vm";
    auto dcpu = std::make_shared<DCPU>();
    auto gclock = std::make_shared<Generic_Clock>();
    auto gkeyboard = std::make_shared<keyboard::GKeyboard>();
    std::shared_ptr<AbstractMonitor> monitor;
    switch (monitor_type)
    {
        case 1:
            monitor=std::make_shared<lem::Lem1803>();
            std::cout << "Use Lem1803 Monitor" << std::endl;
            window_title = "Lem 1803";
            break;
        case 2:
            monitor=std::make_shared<cgm::CGM>();
            std::cout << "Use CGM Monitor" << std::endl;
            window_title = "CGM";
            break;
        default :
            monitor=std::make_shared<lem::Lem1802>();
            std::cout << "Use Lem1802 Monitor" << std::endl;
            window_title = "Lem 1802";
            break;
    }

    dcpu->attachHardware (monitor);
    dcpu->attachHardware (gclock);
    dcpu->attachHardware (gkeyboard);
    dcpu->reset();
    dcpu->loadProgram (data, size);

    sf::Texture texture; // texture of the screen
    sf::Sprite sprite;   //sprite of the screen
    const sf::Image* screen = monitor->getScreen();
    sf::Clock clock;
    sf::RenderWindow window;
    float border_add = monitor->borderSize()*2;
    window.create(sf::VideoMode(monitor->phyWidth()+border_add,
                                monitor->phyHeight()+border_add),
                                window_title);
    window.setFramerateLimit(60);

    while (window.isOpen()) //Because non mainthread event are forbidden in OSX
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window : exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            else if (event.type == sf::Event::KeyPressed
                    || event.type == sf::Event::KeyReleased)
            {
                bool pressed = false;
                unsigned char keycode=0;
                if (event.type == sf::Event::KeyPressed) pressed = true;
                if (event.key.code>=sf::Keyboard::A &&
                    event.key.code<=sf::Keyboard::Z)
                {
                    if (event.key.shift)
                        keycode=event.key.code+'A';
                    else
                        keycode=event.key.code+'a';
                }
                else if (event.key.code>=sf::Keyboard::Num0 &&
                        event.key.code<=sf::Keyboard::Num9)
                {
                    keycode=event.key.code-sf::Keyboard::Num0+'0';
                }
                else
                {
                    switch (event.key.code)
                    {
                        case sf::Keyboard::BackSpace:
                            // NOTE: Changes between SFML 2.0 and 2.1
                            keycode=keyboard::BACKSPACE;
                            break;
                        case sf::Keyboard::Return:
                            keycode=keyboard::RETURN;
                            break;
                        case sf::Keyboard::Insert:
                            keycode=keyboard::INSERT;
                            break;
                        case sf::Keyboard::Delete:
                            keycode=keyboard::DELETE;
                            break;
                        case sf::Keyboard::Up:
                            keycode=keyboard::ARROW_UP;
                            break;
                        case sf::Keyboard::Down:
                            keycode=keyboard::ARROW_DOWN;
                            break;
                        case sf::Keyboard::Left:
                            keycode=keyboard::ARROW_LEFT;
                            break;
                        case sf::Keyboard::Right:
                            keycode=keyboard::ARROW_RIGHT;
                            break;
                        case sf::Keyboard::RShift:
                        case sf::Keyboard::LShift:
                            keycode=keyboard::SHIFT;
                            break;
                        case sf::Keyboard::RControl:
                        case sf::Keyboard::LControl:
                            keycode=keyboard::CONTROL;
                            break;
                        case sf::Keyboard::F1:
                            if (debug && pressed)
                            {
                              std::cout << disassembly(dcpu->getMem()
                                                    +dcpu->GetPC(),3);
                              std::cout << std::endl;
                              dcpu->step();
                            }
                            break;
                        case sf::Keyboard::F2:
                            if (debug && !pressed)
                            {
                              printf("A : 0x%04X | B : 0x%04X | C : 0x%04X\n",
                                                dcpu->ra,dcpu->rb,dcpu->rc);
                              printf("X : 0x%04X | Y : 0x%04X | Z : 0x%04X\n",
                                                dcpu->rx,dcpu->ry,dcpu->rz);
                              printf("I : 0x%04X | J : 0x%04X | IA: 0x%04X\n",
                                                dcpu->ri,dcpu->rj,dcpu->ria);
                              printf("PC: 0x%04X | SP: 0x%04X | EX: 0x%04X\n",
                                                dcpu->rpc,dcpu->rsp,dcpu->rex);
                            }
                            break;
                        case sf::Keyboard::F3:
                            //No need to be in debug mode for this one
                            if (!pressed)
                            {
                                std::cout << "Reset dcpu" << std::endl;
                                dcpu->reset();
                                dcpu->loadProgram (data, size);
                            }
                            break;
                        case sf::Keyboard::F12:
                            if (!pressed)
                            {
                                debug = !debug;
                            }
                            break;

                        default: break;
                    }
                }
                if (keycode)
                    gkeyboard->pushKeyEvent(pressed,keycode);

            }
        }

        ///DCPU emulation stuff
        monitor->prepareRender();
        const float delta=clock.getElapsedTime().asSeconds();
        clock.restart();
        unsigned int tick_needed=(float)dcpu->cpu_clock*delta;

        if (!debug)
        {
            if (tick_needed > dcpu->cpu_clock/60)
                tick_needed = dcpu->cpu_clock/60;
            dcpu->tick(tick_needed);
        }
        /*border_add = monitor->borderSize();
        sprite.setPosition(sf::Vector2f(border_add,border_add));
        border_add *=2;

        float r_width = border_add + monitor->getScreen().getSize().x;
        float r_height = border_add + monitor->getScreen().getSize().y;
        border.setSize(sf::Vector2f(r_width,r_height));
        border.setFillColor(monitor->getBorder());*/

        //For emulations modes and windows resizes
        //sf::FloatRect r(0,0,r_width,r_height);
        //window.setView(sf::View(r));
        window.setActive(true);

        texture.loadFromImage(*screen); //Slow function
        sprite.setTexture(texture);
        sprite.scale(
                monitor->phyWidth() / (float)(monitor->width() ) ,
                monitor->phyHeight() / (float)(monitor->height()) );
        sprite.setPosition(monitor->borderSize(), monitor->borderSize());

        window.clear(monitor->getBorder()); //good idea
        window.draw(sprite);
        window.display();
        window.setActive(false);
    }
    return 0;
}

<commit_msg>Fixed resizing scale bug<commit_after>#include <iostream>
#include <fstream>
#include <cstdint>
#include <algorithm>
#include <memory>
#include <stdio.h>
#include <chrono>

#include "config.hpp"
#include "dcpu_opcodes.hpp"
#include "dcpu.hpp"
#include "disassembler.hpp"
#include "gclock.hpp"
#include "gkeyboard.hpp"
#include "lem1802.hpp"
#include "lem1803.hpp"
#include "cgm.hpp"

using namespace cpu;

void print_help(std::string program_name)
{
    std::cout << "usage : " << program_name << " [--options] <dcpu16-exe>\n";
    std::cout << "--------------------------------------------------------\n";
    std::cout << "  options:" << std::endl;
    std::cout << "    --debug                  : start in debug mode\n";
    std::cout << "            F1  : next step" << std::endl;
    std::cout << "            F2  : print registers" << std::endl;
    std::cout << "            F3  : reset (no need debug mode)" << std::endl;
    std::cout << "            F12 : switch debug/run" << std::endl;
    std::cout << "    --monitor=<monitor_name> : use the following monitor\n";
    std::cout << "            1802 -> Lem1802 (default) [c]" << std::endl;
    std::cout << "            1803 -> Lem1803 [c]" << std::endl;
    std::cout << "            cgm -> Colour Graphics Monitor" << std::endl;
    std::cout << "            [c] : compatible with Lem1802 0x10c programs\n";
}

int main (int argc, char **argv)
{

    std::string filename;
    int monitor_type=0;
    bool debug=false;
    size_t size = 0;
    uint16_t* data;
    std::ifstream binfile;

    if (argc <= 1) {
        std::cerr << "Missing input file, type --help for list options\n";
        return 0;
    }
    for (int k=1; k < argc; k++) //parse arguments
    {
        if (argv[k][0] == '-')
        {
            std::string opt = argv[k];
            if (opt.find("--monitor") != std::string::npos)
            {
                if (opt == "--monitor=1802") monitor_type=0;
                else if (opt == "--monitor=1803") monitor_type=1;
                else if (opt == "--monitor=cgm") monitor_type=2;
                else {
                    std::cout << "Warning unknow monitor type ";
                    std::cout << opt << std::endl;
                }
            }
            else if (opt=="--help"||opt=="-help"||opt=="-h")
            {
                std::string pn = argv[0];
                pn.erase(0,pn.find_last_of('\\')+1); //windows
                pn.erase(0,pn.find_last_of('/')+1); //linux
                print_help(pn);
                return 0;
            }
            else if (opt=="--debug")
            {
                debug=true;
            }
            else
            {
                std::cout << "Warning: unknow option ";
                std::cout << opt << " it will be ignored !" << std::endl;
            }
        }
        else
        {
            filename = argv[k];
        }

    }

    //TODO make a function which do that but fast
    std::cout <<  "Input BIN File : " << filename << "\n";

    binfile.open (filename.c_str(), std::ios::in | std::ios::binary );

    if (!binfile) {
        std::cerr << "ERROR: I can open file\n";
        exit (1);
    }

    // get length of file:
    binfile.seekg (0, binfile.end);
    size = binfile.tellg();
    binfile.seekg (0, binfile.beg);

    data = new uint16_t[size / 2 + 1]();
    std::fill_n (data, size / 2, 0); // Clean it

    int i = 0;

    while (! binfile.eof() ) {
        //need improvement read (read whole file and then switch endianess
        uint16_t word = 0;
        binfile.read ( (char*) &word, 2);
        uint16_t tmp = ( (word & 0xFF00) >> 8) & 0x00FF;
        word = ( (word & 0x00FF) << 8) | tmp;
        data[i] = word;
        i++;
    }

    binfile.close();

    std::cout << "Readed " << size << " bytes - " << size / 2 << " words\n";
    size /= 2;

    sf::String window_title="dcpu_vm";
    auto dcpu = std::make_shared<DCPU>();
    auto gclock = std::make_shared<Generic_Clock>();
    auto gkeyboard = std::make_shared<keyboard::GKeyboard>();
    std::shared_ptr<AbstractMonitor> monitor;
    switch (monitor_type)
    {
        case 1:
            monitor=std::make_shared<lem::Lem1803>();
            std::cout << "Use Lem1803 Monitor" << std::endl;
            window_title = "Lem 1803";
            break;
        case 2:
            monitor=std::make_shared<cgm::CGM>();
            std::cout << "Use CGM Monitor" << std::endl;
            window_title = "CGM";
            break;
        default :
            monitor=std::make_shared<lem::Lem1802>();
            std::cout << "Use Lem1802 Monitor" << std::endl;
            window_title = "Lem 1802";
            break;
    }

    dcpu->attachHardware (monitor);
    dcpu->attachHardware (gclock);
    dcpu->attachHardware (gkeyboard);
    dcpu->reset();
    dcpu->loadProgram (data, size);

    sf::Texture texture; // texture of the screen
    sf::Sprite sprite;   //sprite of the screen
    const sf::Image* screen = monitor->getScreen();
    sf::Clock clock;
    sf::RenderWindow window;
    float border_add = monitor->borderSize()*2;
    window.create(sf::VideoMode(monitor->phyWidth()+border_add,
                                monitor->phyHeight()+border_add),
                                window_title);
    window.setFramerateLimit(60);

    while (window.isOpen()) //Because non mainthread event are forbidden in OSX
    {
        // Process events
        sf::Event event;
        while (window.pollEvent(event))
        {
            // Close window : exit
            if (event.type == sf::Event::Closed) {
                window.close();
            }
            else if (event.type == sf::Event::Resized)
            {
                //Rewrap opengl camera
                float r_width = window.getSize().x;
                float r_height = window.getSize().y;
                //For emulations modes and windows resizes
                sf::FloatRect r(0,0,r_width,r_height);
                window.setView(sf::View(r));
            }
            else if (event.type == sf::Event::KeyPressed
                    || event.type == sf::Event::KeyReleased)
            {
                bool pressed = false;
                unsigned char keycode=0;
                if (event.type == sf::Event::KeyPressed) pressed = true;
                if (event.key.code>=sf::Keyboard::A &&
                    event.key.code<=sf::Keyboard::Z)
                {
                    if (event.key.shift)
                        keycode=event.key.code+'A';
                    else
                        keycode=event.key.code+'a';
                }
                else if (event.key.code>=sf::Keyboard::Num0 &&
                        event.key.code<=sf::Keyboard::Num9)
                {
                    keycode=event.key.code-sf::Keyboard::Num0+'0';
                }
                else
                {
                    switch (event.key.code)
                    {
                        case sf::Keyboard::BackSpace:
                            // NOTE: Changes between SFML 2.0 and 2.1
                            keycode=keyboard::BACKSPACE;
                            break;
                        case sf::Keyboard::Return:
                            keycode=keyboard::RETURN;
                            break;
                        case sf::Keyboard::Insert:
                            keycode=keyboard::INSERT;
                            break;
                        case sf::Keyboard::Delete:
                            keycode=keyboard::DELETE;
                            break;
                        case sf::Keyboard::Up:
                            keycode=keyboard::ARROW_UP;
                            break;
                        case sf::Keyboard::Down:
                            keycode=keyboard::ARROW_DOWN;
                            break;
                        case sf::Keyboard::Left:
                            keycode=keyboard::ARROW_LEFT;
                            break;
                        case sf::Keyboard::Right:
                            keycode=keyboard::ARROW_RIGHT;
                            break;
                        case sf::Keyboard::RShift:
                        case sf::Keyboard::LShift:
                            keycode=keyboard::SHIFT;
                            break;
                        case sf::Keyboard::RControl:
                        case sf::Keyboard::LControl:
                            keycode=keyboard::CONTROL;
                            break;
                        case sf::Keyboard::F1:
                            if (debug && pressed)
                            {
                              std::cout << disassembly(dcpu->getMem()
                                                    +dcpu->GetPC(),3);
                              std::cout << std::endl;
                              dcpu->step();
                            }
                            break;
                        case sf::Keyboard::F2:
                            if (debug && !pressed)
                            {
                              printf("A : 0x%04X | B : 0x%04X | C : 0x%04X\n",
                                                dcpu->ra,dcpu->rb,dcpu->rc);
                              printf("X : 0x%04X | Y : 0x%04X | Z : 0x%04X\n",
                                                dcpu->rx,dcpu->ry,dcpu->rz);
                              printf("I : 0x%04X | J : 0x%04X | IA: 0x%04X\n",
                                                dcpu->ri,dcpu->rj,dcpu->ria);
                              printf("PC: 0x%04X | SP: 0x%04X | EX: 0x%04X\n",
                                                dcpu->rpc,dcpu->rsp,dcpu->rex);
                            }
                            break;
                        case sf::Keyboard::F3:
                            //No need to be in debug mode for this one
                            if (!pressed)
                            {
                                std::cout << "Reset dcpu" << std::endl;
                                dcpu->reset();
                                dcpu->loadProgram (data, size);
                            }
                            break;
                        case sf::Keyboard::F12:
                            if (!pressed)
                            {
                                debug = !debug;
                            }
                            break;

                        default: break;
                    }
                }
                if (keycode)
                    gkeyboard->pushKeyEvent(pressed,keycode);

            }
        }

        ///DCPU emulation stuff
        monitor->prepareRender();
        const float delta=clock.getElapsedTime().asSeconds();
        clock.restart();
        unsigned int tick_needed=(float)dcpu->cpu_clock*delta;

        if (!debug)
        {
            if (tick_needed > dcpu->cpu_clock/60)
                tick_needed = dcpu->cpu_clock/60;
            dcpu->tick(tick_needed);
        }

        window.setActive(true);

        //Working resizing code
        border_add = monitor->borderSize();
        texture.loadFromImage(*screen); //Slow function
        sprite.setTexture(texture);
        sprite.setScale(  //Warning setScale and scale are different !!
         (float) (window.getSize().x-border_add*2) / (float)(monitor->width()),
        (float) (window.getSize().y-border_add*2) / (float)(monitor->height()));
        sprite.setPosition(sf::Vector2f(border_add,border_add));

        window.clear(monitor->getBorder()); //good idea
        window.draw(sprite);
        window.display();
        window.setActive(false);
    }
    return 0;
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsBitmapCache.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: rt $ $Date: 2005-10-24 07:39:19 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_BITMAP_CACHE_HXX
#define SD_SLIDESORTER_BITMAP_CACHE_HXX

class SdrPage;

#include <vcl/bitmapex.hxx>
#include <osl/mutex.hxx>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <hash_map>

namespace sd { namespace slidesorter { namespace cache {

class BitmapReplacement;
class CacheCompactor;
class BitmapCompressor;

/** This low level cache is the actual bitmap container.  It supports a
    precious flag for every preview bitmap and keeps track of total sizes
    for all previews with as well as those without the flag.  The precious
    flag is used by compaction algorithms to determine which previews may be
    compressed or even discarded and which have to remain in their original
    form.  The precious flag is usually set for the visible previews.
*/
class BitmapCache
{
public:
    /** The key for looking up preview bitmaps is a pointer to an SdrPage
        object.  The prior use of PageObjectViewObjectContact objects (which
        ultimatly use them) turned out to be less suitable because their
        life time is shorter then that of the page objects.  Frequent
        destruction and re-creation of the preview bitmaps was the result.
    */
    typedef const SdrPage* CacheKey;
    class CacheEntry;
    class CacheBitmapContainer;
    typedef ::std::vector<CacheKey> CacheIndex;

    /** Create a new cache for bitmap objects.
    */
    BitmapCache (void);

    /** The destructor clears the cache and relases all bitmaps still in it.
    */
    ~BitmapCache (void);

    /** Remove all preview bitmaps from the cache.  After this call the
        cache is empty.
    */
    void Clear (void);

    /** Returns <TRUE/> when there is no preview bitmap in the cache.
    */
    bool IsEmpty (void) const;

    /** Return <TRUE/> when the cache is full, i.e. the cache compactor had
        to be run.
    */
    bool IsFull (void) const;

    /** Return the memory size that is occupied by all non-precious bitmaps
        in the cache.
    */
    sal_Int32 GetSize (void);

    /** Return <TRUE/> when a preview bitmap exists for the given key.
    */
    bool HasBitmap (const CacheKey& rKey);

    /** Return <TRUE/> when a preview bitmap exists for the given key and
        when it is up-to-date.
    */
    bool BitmapIsUpToDate (const CacheKey& rKey);

    /** Return the preview bitmap for the given contact object.
    */
    ::boost::shared_ptr<BitmapEx> GetBitmap (const CacheKey& rKey);

    /** Release the reference to the preview bitmap that is associated with
        the given key.
    */
    void ReleaseBitmap (const CacheKey& rKey);

    /** Mark the specified preview bitmap as not being up-to-date anymore.
    */
    void InvalidateBitmap (const CacheKey& rKey);

    /** Mark all preview bitmaps as not being up-to-date anymore.
    */
    void InvalidateCache (void);

    /** Add or replace a bitmap for the given key.
    */
    void SetBitmap (
        const CacheKey& rKey,
        const ::boost::shared_ptr<BitmapEx>& rpPreview,
        bool bIsPrecious);

    /** Return whether the specified preview bitmap has been marked as
        precious.
    */
    bool IsPrecious (const CacheKey& rKey);

    /** Mark the specified preview bitmap as precious, i.e. that it must not
        be compressed or otherwise removed from the cache.
    */
    void SetPrecious (const CacheKey& rKey, bool bIsPrecious);

    /** Calculate the cache size.  This should rarely be necessary because
        the cache size is tracked with each modification of preview
        bitmaps.
    */
    void ReCalculateTotalCacheSize (void);

    /** Use the previews in the given cache to initialize missing previews.
    */
    void Recycle (const BitmapCache& rCache);

    /** Return a list of sorted cache keys that represent an index into (a
        part of) the cache.  The entries of the index are sorted according
        to last access times with the least recently access time first.
        @param bIncludePrecious
            When this flag is <TRUE/> entries with the precious flag set are
            included in the index.  When the flag is <FALSE/> these entries
            are ommited.
        @param bIncludeNoPreview
            When this flag is <TRUE/> entries with that have no preview
            bitmaps are included in the index.  When the flag is <FALSE/> these entries
            are ommited.
    */
    ::std::auto_ptr<CacheIndex> GetCacheIndex (
        bool bIncludePrecious,
        bool bIncludeNoPreview) const;

    /** Compress the specified preview bitmap with the given bitmap
        compressor.  A reference to the compressor is stored for later
        decompression.
    */
    void Compress (
        const CacheKey& rKey,
        const ::boost::shared_ptr<BitmapCompressor>& rpCompressor);

private:
    mutable ::osl::Mutex maMutex;

    ::std::auto_ptr<CacheBitmapContainer> mpBitmapContainer;

    /** Total size of bytes that are occupied by bitmaps in the cache for
        whom the slides are currently not inside the visible area.
    */
    sal_Int32 mnNormalCacheSize;

    /** Total size of bytes that are occupied by bitmaps in the cache for
        whom the slides are currently visible.
    */
    sal_Int32 mnPreciousCacheSize;

    /** At the moment the access time is not an actual time or date value
        but a counter that is increased with every access.  It thus defines
        the same ordering as a true time.
    */
    sal_Int32 mnCurrentAccessTime;

    /** The maximal cache size for the off-screen preview bitmaps.  When
        mnNormalCacheSize grows larger than this value then the
        mpCacheCompactor member is used to reduce the cache size.
    */
    sal_Int32 mnMaximalNormalCacheSize;

    /** The cache compactor is used to reduce the number of bytes used by
        off-screen preview bitmaps.
    */
    ::std::auto_ptr<CacheCompactor> mpCacheCompactor;

    /** This flag stores if the cache is or recently was full, i.e. the
        cache compactor has or had to be run in order to reduce the cache
        size to the allowed value.
    */
    bool mbIsFull;

    /** Update mnNormalCacheSize or mnPreciousCacheSize according to the
        precious flag of the specified preview bitmap and the specified
        operation.
    */
    enum CacheOperation { ADD, REMOVE };
    void UpdateCacheSize (const CacheEntry& rKey, CacheOperation eOperation);
};

} } } // end of namespace ::sd::slidesorter::cache

#endif
<commit_msg>INTEGRATION: CWS presenterview (1.4.354); FILE MERGED 2008/02/26 12:06:31 af 1.4.354.1: #i18486# Maximal cache size can be provided via constructor argument.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SlsBitmapCache.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2008-04-03 14:16:57 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_SLIDESORTER_BITMAP_CACHE_HXX
#define SD_SLIDESORTER_BITMAP_CACHE_HXX

class SdrPage;

#include <vcl/bitmapex.hxx>
#include <osl/mutex.hxx>
#include <memory>
#include <boost/shared_ptr.hpp>
#include <hash_map>

namespace sd { namespace slidesorter { namespace cache {

class BitmapReplacement;
class CacheCompactor;
class BitmapCompressor;

/** This low level cache is the actual bitmap container.  It supports a
    precious flag for every preview bitmap and keeps track of total sizes
    for all previews with as well as those without the flag.  The precious
    flag is used by compaction algorithms to determine which previews may be
    compressed or even discarded and which have to remain in their original
    form.  The precious flag is usually set for the visible previews.
*/
class BitmapCache
{
public:
    /** The key for looking up preview bitmaps is a pointer to an SdrPage
        object.  The prior use of PageObjectViewObjectContact objects (which
        ultimatly use them) turned out to be less suitable because their
        life time is shorter then that of the page objects.  Frequent
        destruction and re-creation of the preview bitmaps was the result.
    */
    typedef const SdrPage* CacheKey;
    class CacheEntry;
    class CacheBitmapContainer;
    typedef ::std::vector<CacheKey> CacheIndex;

    /** Create a new cache for bitmap objects.
        @param nMaximalNormalCacheSize
            When a size larger then zero is given then that size is used.
            Otherwise the default value from the configuration is used.
            When that does not exist either then a internal default value is
            used.
    */
    BitmapCache (const sal_Int32 nMaximalNormalCacheSize = 0);

    /** The destructor clears the cache and relases all bitmaps still in it.
    */
    ~BitmapCache (void);

    /** Remove all preview bitmaps from the cache.  After this call the
        cache is empty.
    */
    void Clear (void);

    /** Returns <TRUE/> when there is no preview bitmap in the cache.
    */
    bool IsEmpty (void) const;

    /** Return <TRUE/> when the cache is full, i.e. the cache compactor had
        to be run.
    */
    bool IsFull (void) const;

    /** Return the memory size that is occupied by all non-precious bitmaps
        in the cache.
    */
    sal_Int32 GetSize (void);

    /** Return <TRUE/> when a preview bitmap exists for the given key.
    */
    bool HasBitmap (const CacheKey& rKey);

    /** Return <TRUE/> when a preview bitmap exists for the given key and
        when it is up-to-date.
    */
    bool BitmapIsUpToDate (const CacheKey& rKey);

    /** Return the preview bitmap for the given contact object.
    */
    ::boost::shared_ptr<BitmapEx> GetBitmap (const CacheKey& rKey);

    /** Release the reference to the preview bitmap that is associated with
        the given key.
    */
    void ReleaseBitmap (const CacheKey& rKey);

    /** Mark the specified preview bitmap as not being up-to-date anymore.
    */
    void InvalidateBitmap (const CacheKey& rKey);

    /** Mark all preview bitmaps as not being up-to-date anymore.
    */
    void InvalidateCache (void);

    /** Add or replace a bitmap for the given key.
    */
    void SetBitmap (
        const CacheKey& rKey,
        const ::boost::shared_ptr<BitmapEx>& rpPreview,
        bool bIsPrecious);

    /** Return whether the specified preview bitmap has been marked as
        precious.
    */
    bool IsPrecious (const CacheKey& rKey);

    /** Mark the specified preview bitmap as precious, i.e. that it must not
        be compressed or otherwise removed from the cache.
    */
    void SetPrecious (const CacheKey& rKey, bool bIsPrecious);

    /** Calculate the cache size.  This should rarely be necessary because
        the cache size is tracked with each modification of preview
        bitmaps.
    */
    void ReCalculateTotalCacheSize (void);

    /** Use the previews in the given cache to initialize missing previews.
    */
    void Recycle (const BitmapCache& rCache);

    /** Return a list of sorted cache keys that represent an index into (a
        part of) the cache.  The entries of the index are sorted according
        to last access times with the least recently access time first.
        @param bIncludePrecious
            When this flag is <TRUE/> entries with the precious flag set are
            included in the index.  When the flag is <FALSE/> these entries
            are ommited.
        @param bIncludeNoPreview
            When this flag is <TRUE/> entries with that have no preview
            bitmaps are included in the index.  When the flag is <FALSE/> these entries
            are ommited.
    */
    ::std::auto_ptr<CacheIndex> GetCacheIndex (
        bool bIncludePrecious,
        bool bIncludeNoPreview) const;

    /** Compress the specified preview bitmap with the given bitmap
        compressor.  A reference to the compressor is stored for later
        decompression.
    */
    void Compress (
        const CacheKey& rKey,
        const ::boost::shared_ptr<BitmapCompressor>& rpCompressor);

private:
    mutable ::osl::Mutex maMutex;

    ::std::auto_ptr<CacheBitmapContainer> mpBitmapContainer;

    /** Total size of bytes that are occupied by bitmaps in the cache for
        whom the slides are currently not inside the visible area.
    */
    sal_Int32 mnNormalCacheSize;

    /** Total size of bytes that are occupied by bitmaps in the cache for
        whom the slides are currently visible.
    */
    sal_Int32 mnPreciousCacheSize;

    /** At the moment the access time is not an actual time or date value
        but a counter that is increased with every access.  It thus defines
        the same ordering as a true time.
    */
    sal_Int32 mnCurrentAccessTime;

    /** The maximal cache size for the off-screen preview bitmaps.  When
        mnNormalCacheSize grows larger than this value then the
        mpCacheCompactor member is used to reduce the cache size.
    */
    sal_Int32 mnMaximalNormalCacheSize;

    /** The cache compactor is used to reduce the number of bytes used by
        off-screen preview bitmaps.
    */
    ::std::auto_ptr<CacheCompactor> mpCacheCompactor;

    /** This flag stores if the cache is or recently was full, i.e. the
        cache compactor has or had to be run in order to reduce the cache
        size to the allowed value.
    */
    bool mbIsFull;

    /** Update mnNormalCacheSize or mnPreciousCacheSize according to the
        precious flag of the specified preview bitmap and the specified
        operation.
    */
    enum CacheOperation { ADD, REMOVE };
    void UpdateCacheSize (const CacheEntry& rKey, CacheOperation eOperation);
};

} } } // end of namespace ::sd::slidesorter::cache

#endif
<|endoftext|>


<commit_before>#include "sock.h"
#include <sstream>
#include <string>
#include <tr1/cstdint>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/tcp.h>

using std::string;

static inline
bool load_peerinfo(int sock, string& host, uint16_t& port)
{
	sockaddr_in addr;
	socklen_t len;

	// Load info about the other end (the peer)
	len = sizeof(addr);
	if (getpeername(sock, reinterpret_cast<sockaddr*>(&addr), &len) == -1)
		return false;

	// Extract the hostname and remote port
	char name[INET_ADDRSTRLEN];
	if (getnameinfo(reinterpret_cast<sockaddr*>(&addr), (socklen_t) sizeof(addr), name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0)
		return false;

	host = std::string(name);
	port = ntohs(addr.sin_port);

	return true;
}

static inline
bool load_addrinfo(addrinfo*& info, const char* host, uint16_t port)
{
	addrinfo hints;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = host == NULL ? AI_PASSIVE : 0;

	std::ostringstream converter;
	converter << port;

	return getaddrinfo(host, converter.str().c_str(), &hints, &info) == 0;
}

static inline
bool bind_port(int sock, uint16_t port)
{
	sockaddr_in addr;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(port);

	// Set the port to quickly reusable, so subsequent connections can quickly
	// reuse the port
	int flag = 1;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

	return bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
}

int Sock::create(uint16_t port)
{
	addrinfo *ptr, *info = NULL;

	// Get info about the service/port
	if (!load_addrinfo(info, NULL, port))
	{
		if (info != NULL)
			freeaddrinfo(info);

		return -1;
	}

	int sock = -1;
	for (ptr = info; ptr != NULL; ptr = ptr->ai_next)
	{
		// Try to create a socket descriptor
		if ((sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == -1)
			continue;

		// Set port to be reusable
		int flag = 1;
		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

		// Try to bind to the port and listen
		if (bind(sock, ptr->ai_addr, ptr->ai_addrlen) == 0
				&& listen(sock, SOMAXCONN) == 0)
			break;

		// Failed, close socket and try again
		::close(sock);
	}

	if (info != NULL)
		freeaddrinfo(info);

	if (ptr == NULL)
		return -1;

	return sock;
}

int Sock::create(const char* host, uint16_t rem_port, uint16_t loc_port)
{
	addrinfo *ptr, *info = NULL;

	// Get info about the service/port
	if (!load_addrinfo(info, host, rem_port))
	{
		if (info != NULL)
			freeaddrinfo(info);

		return -1;
	}

	int sock = -1;
	for (ptr = info; ptr != NULL; ptr = ptr->ai_next)
	{
		// Try to create a socket descriptor
		if ((sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == -1)
			continue;

		// Turn off Nagle's algorithm
		int flag = 1;
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

		// If a local port is given, try to bind to that port
		if (loc_port != 0)
		{
			bind_port(sock, loc_port);
		}

		// Try to connect to the remote host
		if (connect(sock, ptr->ai_addr, ptr->ai_addrlen) != -1)
			break;

		// Failed, close socket and try again
		::close(sock);
	}

	if (info != NULL)
		freeaddrinfo(info);

	if (ptr == NULL)
		return -1;

	return sock;
}

int Sock::create(const char* host, uint16_t port)
{
	return create(host, port, 0);
}

static
void close_sock(int* sfd)
{
	if (*sfd != -1)
		::close(*sfd);

	delete sfd;
}

Sock::Sock(int fd)
	: sfd( new int(fd), &close_sock )
{
	// TODO: Check if valid socket descriptor

	// Set descriptor to non-blocking
	if (*sfd != -1)
	{
		int flag = fcntl(*sfd, F_GETFL, 0);
		fcntl(*sfd, F_SETFL, flag | O_NONBLOCK);
	}
}

bool Sock::connected()
{
	if (*sfd != -1)
	{
		int flag = 0;
		socklen_t len = sizeof(flag);
		getsockopt(*sfd, SOL_SOCKET, SO_ACCEPTCONN, &flag, &len);
		return flag != 0;
	}
	else
	{
		return false;
	}
}

int Sock::raw()
{
	return *sfd;
}

bool Sock::peer(string& name)
{
	uint16_t port;
	return *sfd != -1 && load_peerinfo(*sfd, name, port);
}

bool Sock::peer(uint16_t& port)
{
	string name;
	return *sfd != -1 && load_peerinfo(*sfd, name, port);
}

bool Sock::host(uint16_t& port)
{
	if (*sfd != -1)
	{
		sockaddr_in addr;

		socklen_t len = sizeof(addr);
		if (getsockname(*sfd, reinterpret_cast<sockaddr*>(&addr), &len) == -1)
			return false;

		port = ntohs(addr.sin_port);
		return true;
	}
	else
	{
		return false;
	}
}

void Sock::close()
{
	if (*sfd != -1)
	{
		::close(*sfd);
		*sfd = -1;
	}
}
<commit_msg>added a TODO<commit_after>#include "sock.h"
#include <sstream>
#include <string>
#include <tr1/cstdint>
#include <sys/types.h>
#include <netdb.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <netinet/tcp.h>

using std::string;

static inline
bool load_peerinfo(int sock, string& host, uint16_t& port)
{
	sockaddr_in addr;
	socklen_t len;

	// Load info about the other end (the peer)
	len = sizeof(addr);
	if (getpeername(sock, reinterpret_cast<sockaddr*>(&addr), &len) == -1)
		return false;

	// Extract the hostname and remote port
	char name[INET_ADDRSTRLEN];
	if (getnameinfo(reinterpret_cast<sockaddr*>(&addr), (socklen_t) sizeof(addr), name, sizeof(name), NULL, 0, NI_NUMERICHOST) != 0)
		return false;

	host = std::string(name);
	port = ntohs(addr.sin_port);

	return true;
}

static inline
bool load_addrinfo(addrinfo*& info, const char* host, uint16_t port)
{
	addrinfo hints;

	memset(&hints, 0, sizeof(hints));
	hints.ai_family = AF_INET;
	hints.ai_socktype = SOCK_STREAM;
	hints.ai_flags = host == NULL ? AI_PASSIVE : 0;

	std::ostringstream converter;
	converter << port;

	return getaddrinfo(host, converter.str().c_str(), &hints, &info) == 0;
}

static inline
bool bind_port(int sock, uint16_t port)
{
	sockaddr_in addr;

	memset(&addr, 0, sizeof(addr));
	addr.sin_family = AF_INET;
	addr.sin_addr.s_addr = INADDR_ANY;
	addr.sin_port = htons(port);

	// Set the port to quickly reusable, so subsequent connections can quickly
	// reuse the port
	int flag = 1;
	setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

	return bind(sock, reinterpret_cast<sockaddr*>(&addr), sizeof(addr));
}

int Sock::create(uint16_t port)
{
	addrinfo *ptr, *info = NULL;

	// Get info about the service/port
	if (!load_addrinfo(info, NULL, port))
	{
		if (info != NULL)
			freeaddrinfo(info);

		return -1;
	}

	int sock = -1;
	for (ptr = info; ptr != NULL; ptr = ptr->ai_next)
	{
		// Try to create a socket descriptor
		if ((sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == -1)
			continue;

		// Set port to be reusable
		int flag = 1;
		setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));

		// Try to bind to the port and listen
		if (bind(sock, ptr->ai_addr, ptr->ai_addrlen) == 0
				&& listen(sock, SOMAXCONN) == 0)
			break;

		// Failed, close socket and try again
		::close(sock);
	}

	if (info != NULL)
		freeaddrinfo(info);

	if (ptr == NULL)
		return -1;

	return sock;
}

int Sock::create(const char* host, uint16_t rem_port, uint16_t loc_port)
{
	addrinfo *ptr, *info = NULL;

	// Get info about the service/port
	if (!load_addrinfo(info, host, rem_port))
	{
		if (info != NULL)
			freeaddrinfo(info);

		return -1;
	}

	int sock = -1;
	for (ptr = info; ptr != NULL; ptr = ptr->ai_next)
	{
		// Try to create a socket descriptor
		if ((sock = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol)) == -1)
			continue;

		// Turn off Nagle's algorithm
		int flag = 1;
		setsockopt(sock, IPPROTO_TCP, TCP_NODELAY, &flag, sizeof(flag));

		// If a local port is given, try to bind to that port
		if (loc_port != 0)
		{
			bind_port(sock, loc_port);
		}

		// Try to connect to the remote host
		if (connect(sock, ptr->ai_addr, ptr->ai_addrlen) != -1)
			break;

		// Failed, close socket and try again
		::close(sock);
	}

	if (info != NULL)
		freeaddrinfo(info);

	if (ptr == NULL)
		return -1;

	return sock;
}

int Sock::create(const char* host, uint16_t port)
{
	return create(host, port, 0);
}

static
void close_sock(int* sfd)
{
	if (*sfd != -1)
		::close(*sfd);

	delete sfd;
}

Sock::Sock(int fd)
	: sfd( new int(fd), &close_sock )
{
	// TODO: Check if valid socket descriptor

	// Set descriptor to non-blocking
	if (*sfd != -1)
	{
		int flag = fcntl(*sfd, F_GETFL, 0);
		fcntl(*sfd, F_SETFL, flag | O_NONBLOCK);
	}
}

bool Sock::connected()
{
	if (*sfd != -1)
	{
		// TODO: Check if descriptor is still alive
		int flag = 0;
		socklen_t len = sizeof(flag);
		getsockopt(*sfd, SOL_SOCKET, SO_ACCEPTCONN, &flag, &len);
		return flag != 0;

	}
	else
	{
		return false;
	}
}

int Sock::raw()
{
	return *sfd;
}

bool Sock::peer(string& name)
{
	uint16_t port;
	return *sfd != -1 && load_peerinfo(*sfd, name, port);
}

bool Sock::peer(uint16_t& port)
{
	string name;
	return *sfd != -1 && load_peerinfo(*sfd, name, port);
}

bool Sock::host(uint16_t& port)
{
	if (*sfd != -1)
	{
		sockaddr_in addr;

		socklen_t len = sizeof(addr);
		if (getsockname(*sfd, reinterpret_cast<sockaddr*>(&addr), &len) == -1)
			return false;

		port = ntohs(addr.sin_port);
		return true;
	}
	else
	{
		return false;
	}
}

void Sock::close()
{
	if (*sfd != -1)
	{
		::close(*sfd);
		*sfd = -1;
	}
}
<|endoftext|>


<commit_before>#include "math/vec.hpp"
#include "math/mat.hpp"
#include "math/MatrixTransform.hpp"
#include "math/Sphere.hpp"
#include "math/misc.hpp"
#include "math/Ray.hpp"
#include "math/TransformPair.hpp"
#include "noncopyable.hpp"
#include "output.hpp"
#include "Optional.hpp"
#include <vector>
#include <memory>
#include <algorithm>
#include <limits>

using namespace yks;

struct Material {
	vec3 diffuse;

	Material(vec3 diffuse)
		: diffuse(diffuse)
	{}
};

struct SceneObject;
struct SceneShape;

struct Intersection {
	float t;
	vec3 position;
	vec3 normal;
	vec2 uv;

	const SceneObject* object;
	const SceneShape* shape;
};

struct SceneShape {
	TransformPair transform;

	SceneShape(TransformPair transform)
		: transform(std::move(transform))
	{}

	virtual Optional<float> hasIntersection(const Ray& r) const = 0;

	Optional<float> hasIntersection(const Ray& r, float max_t) const {
		const Optional<float> t = hasIntersection(r);
		if (t && *t > max_t) {
			return Optional<float>();
		}
		return t;
	}

	virtual Optional<Intersection> intersect(const Ray& r) const = 0;

	Optional<Intersection> intersect(const Ray& r, float max_t) const {
		const Optional<Intersection> intersection = intersect(r);
		if (intersection && intersection->t > max_t) {
			return Optional<Intersection>();
		}
		return intersection;
	}
};

struct ShapeSphere : SceneShape {
	ShapeSphere(TransformPair transform)
		: SceneShape(transform)
	{}

	virtual Optional<float> hasIntersection(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const vec3 o = local_ray.origin;
		const vec3 v = local_ray.direction;

		float t1, t2;
		const int solutions = solve_quadratic(dot(v, v), 2*dot(o, v), dot(o, o) - 1.0f, t1, t2);

		if (solutions > 0) {
			return make_optional<float>(t1);
		} else {
			return Optional<float>();
		}
	}

	virtual Optional<Intersection> intersect(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const vec3 o = local_ray.origin;
		const vec3 v = local_ray.direction;

		float t1, t2;
		const int solutions = solve_quadratic(dot(v, v), 2*dot(o, v), dot(o, o) - 1.0f, t1, t2);

		if (solutions == 0) {
			return Optional<Intersection>();
		}

		Intersection i;
		i.t = t1;
		i.position = r(t1);
		vec3 local_pos = local_ray(t1);
		i.uv = mvec2(std::atan2(local_pos[2], local_pos[0]) / (2*pi) + 0.5f, std::acos(local_pos[1]) / pi);
		i.normal = mvec3(transpose(transform.localFromParent) * mvec4(normalized(local_ray(t1)), 0.0f));
		return make_optional<Intersection>(i);
	}
};

struct ShapePlane : SceneShape {
	ShapePlane(TransformPair transform)
		: SceneShape(std::move(transform))
	{}

	virtual Optional<float> hasIntersection(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const float t = -local_ray.origin[1] / local_ray.direction[1];
		return make_optional<float>(t);
	}

	virtual Optional<Intersection> intersect(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const float t = -local_ray.origin[1] / local_ray.direction[1];
		if (t < 0.0f) {
			return Optional<Intersection>();
		}
		Intersection i;
		i.t = t;
		i.position = r(t);
		i.uv = mvec2(0.0f, 0.0f);
		i.normal = mvec3(transpose(transform.localFromParent) * mvec4(vec3_y, 0.0f));
		return make_optional<Intersection>(i);
	}
};

struct SceneObject {
	Material material;
	std::unique_ptr<SceneShape> shape;

	SceneObject(Material material, std::unique_ptr<SceneShape>&& shape)
		: material(material), shape(std::move(shape))
	{}

	SceneObject(SceneObject&& o)
		: material(std::move(o.material)), shape(std::move(o.shape))
	{}

private:
	NONCOPYABLE(SceneObject);
};

struct SceneLight {
	vec3 origin;
	vec3 intensity;
};

float focal_distance_from_fov(const float fov_degrees) {
	const float half_fov = fov_degrees / 360.0f * pi;
	return std::tan(0.5f*pi - half_fov);
}

struct Camera {
	vec3 origin;
	mat3 orientation;
	float focal_length; // distance from image plane

	Camera(vec3 origin, mat3 orientation, float vertical_fov)
		: origin(origin), orientation(orientation), focal_length(focal_distance_from_fov(vertical_fov))
	{}

	Ray createRay(const vec2 film_pos) const {
		const vec3 cameraspace_ray = mvec3(film_pos[0], film_pos[1], focal_length);
		return Ray{origin, orientation * cameraspace_ray};
	}
};

struct Scene {
	Camera camera;
	std::vector<SceneObject> objects;

	Scene(Camera camera)
		: camera(camera)
	{}

	Scene(Scene&& o)
		: camera(std::move(o.camera)), objects(std::move(o.objects))
	{}

private:
	NONCOPYABLE(Scene);
};

Scene setup_scene() {
	Scene s(Camera(vec3_0, orient(vec3_y, vec3_z), 75.0f));
	s.objects.push_back(SceneObject(
		Material(vec3_1),
		std::make_unique<ShapeSphere>(TransformPair().translate(vec3_z * 2))
		));
	s.objects.push_back(SceneObject(
		Material(mvec3(0.5f, 0.0f, 0.0f)),
		std::make_unique<ShapePlane>(TransformPair().translate(vec3_y * -1.5f))
		));

	return std::move(s);
}

static vec2 filmspace_from_screenspace(const vec2 screen_pos, const vec2 screen_size) {
	return (screen_pos - (screen_size * 0.5f)) * 2.0f * (1.0f / screen_size[1]);
}

Optional<Intersection> find_nearest_intersection(const Scene& scene, const Ray ray) {
	Optional<Intersection> nearest_intersection;

	for (const SceneObject& object : scene.objects) {
		const Optional<Intersection> intersection = object.shape->intersect(ray);
		if (intersection && (!nearest_intersection || intersection->t < nearest_intersection->t)) {
			nearest_intersection = intersection;
			nearest_intersection->object = &object;
			nearest_intersection->shape = object.shape.get();
		}
	}

	return nearest_intersection;
}

int main(int, char* []) {
	static const int IMAGE_WIDTH = 1280;
	static const int IMAGE_HEIGHT = 720;
	std::vector<vec3> image_data(IMAGE_WIDTH * IMAGE_HEIGHT);

	const Scene scene = setup_scene();

	for (int y = 0; y < IMAGE_HEIGHT; ++y) {
		for (int x = 0; x < IMAGE_WIDTH; x++) {
			const vec2 film_coord = filmspace_from_screenspace(mvec2(float(x), float(y)), mvec2(float(IMAGE_WIDTH), float(IMAGE_HEIGHT))) * mvec2(1.0f, -1.0f);
			const Ray camera_ray = scene.camera.createRay(film_coord);

			const Optional<Intersection> hit = find_nearest_intersection(scene, camera_ray);
			const vec3 color = hit ? hit->normal * 0.5f + vec3_1 * 0.5f : vec3_1*0.1f;
			//const vec3 color = hit ? hit->object->material.diffuse : vec3_1*0.1f;

			image_data[y*IMAGE_WIDTH + x] = color;
		}
	}

	save_srgb_image(image_data, IMAGE_WIDTH, IMAGE_HEIGHT);
}<commit_msg>Basic lighting.<commit_after>#include "math/vec.hpp"
#include "math/mat.hpp"
#include "math/MatrixTransform.hpp"
#include "math/Sphere.hpp"
#include "math/misc.hpp"
#include "math/Ray.hpp"
#include "math/TransformPair.hpp"
#include "noncopyable.hpp"
#include "output.hpp"
#include "Optional.hpp"
#include <vector>
#include <memory>
#include <algorithm>
#include <limits>

using namespace yks;

struct Material {
	vec3 diffuse;

	Material(vec3 diffuse)
		: diffuse(diffuse)
	{}
};

struct SceneObject;
struct SceneShape;

struct Intersection {
	float t;
	vec3 position;
	vec3 normal;
	vec2 uv;

	const SceneObject* object;
	const SceneShape* shape;
};

struct SceneShape {
	TransformPair transform;

	SceneShape(TransformPair transform)
		: transform(std::move(transform))
	{}

	virtual Optional<float> hasIntersection(const Ray& r) const = 0;

	Optional<float> hasIntersection(const Ray& r, float max_t) const {
		const Optional<float> t = hasIntersection(r);
		if (t && *t > max_t) {
			return Optional<float>();
		}
		return t;
	}

	virtual Optional<Intersection> intersect(const Ray& r) const = 0;

	Optional<Intersection> intersect(const Ray& r, float max_t) const {
		const Optional<Intersection> intersection = intersect(r);
		if (intersection && intersection->t > max_t) {
			return Optional<Intersection>();
		}
		return intersection;
	}
};

struct ShapeSphere : SceneShape {
	ShapeSphere(TransformPair transform)
		: SceneShape(transform)
	{}

	virtual Optional<float> hasIntersection(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const vec3 o = local_ray.origin;
		const vec3 v = local_ray.direction;

		float t1, t2;
		const int solutions = solve_quadratic(dot(v, v), 2*dot(o, v), dot(o, o) - 1.0f, t1, t2);

		if (solutions > 0) {
			return make_optional<float>(t1);
		} else {
			return Optional<float>();
		}
	}

	virtual Optional<Intersection> intersect(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const vec3 o = local_ray.origin;
		const vec3 v = local_ray.direction;

		float t1, t2;
		const int solutions = solve_quadratic(dot(v, v), 2*dot(o, v), dot(o, o) - 1.0f, t1, t2);

		if (solutions == 0) {
			return Optional<Intersection>();
		}

		Intersection i;
		i.t = t1;
		i.position = r(t1);
		vec3 local_pos = local_ray(t1);
		i.uv = mvec2(std::atan2(local_pos[2], local_pos[0]) / (2*pi) + 0.5f, std::acos(local_pos[1]) / pi);
		i.normal = mvec3(transpose(transform.localFromParent) * mvec4(normalized(local_ray(t1)), 0.0f));
		return make_optional<Intersection>(i);
	}
};

struct ShapePlane : SceneShape {
	ShapePlane(TransformPair transform)
		: SceneShape(std::move(transform))
	{}

	virtual Optional<float> hasIntersection(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const float t = -local_ray.origin[1] / local_ray.direction[1];
		return make_optional<float>(t);
	}

	virtual Optional<Intersection> intersect(const Ray& r) const override {
		const Ray local_ray = transform.localFromParent * r;
		const float t = -local_ray.origin[1] / local_ray.direction[1];
		if (t < 0.0f) {
			return Optional<Intersection>();
		}
		Intersection i;
		i.t = t;
		i.position = r(t);
		i.uv = mvec2(0.0f, 0.0f);
		i.normal = mvec3(transpose(transform.localFromParent) * mvec4(vec3_y, 0.0f));
		return make_optional<Intersection>(i);
	}
};

struct SceneObject {
	Material material;
	std::unique_ptr<SceneShape> shape;

	SceneObject(Material material, std::unique_ptr<SceneShape>&& shape)
		: material(material), shape(std::move(shape))
	{}

	SceneObject(SceneObject&& o)
		: material(std::move(o.material)), shape(std::move(o.shape))
	{}

private:
	NONCOPYABLE(SceneObject);
};

struct SceneLight {
	vec3 origin;
	vec3 intensity;

	SceneLight(const vec3& origin, const vec3& intensity)
		: origin(origin), intensity(intensity)
	{}
};

float focal_distance_from_fov(const float fov_degrees) {
	const float half_fov = fov_degrees / 360.0f * pi;
	return std::tan(0.5f*pi - half_fov);
}

struct Camera {
	vec3 origin;
	mat3 orientation;
	float focal_length; // distance from image plane

	Camera(vec3 origin, mat3 orientation, float vertical_fov)
		: origin(origin), orientation(orientation), focal_length(focal_distance_from_fov(vertical_fov))
	{}

	Ray createRay(const vec2 film_pos) const {
		const vec3 cameraspace_ray = mvec3(film_pos[0], film_pos[1], focal_length);
		return Ray{origin, orientation * cameraspace_ray};
	}
};

struct Scene {
	Camera camera;
	std::vector<SceneObject> objects;
	std::vector<SceneLight> lights;

	Scene(Camera camera)
		: camera(camera)
	{}

	Scene(Scene&& o)
		: camera(std::move(o.camera)), objects(std::move(o.objects)), lights(std::move(o.lights))
	{}

private:
	NONCOPYABLE(Scene);
};

Scene setup_scene() {
	Scene s(Camera(vec3_0, orient(vec3_y, -vec3_z), 75.0f));
	s.objects.push_back(SceneObject(
		Material(vec3_1),
		std::make_unique<ShapeSphere>(TransformPair().translate(mvec3(0.0f, 0.0f, -5.0f)))
		));
	s.objects.push_back(SceneObject(
		Material(mvec3(0.5f, 0.0f, 0.0f)),
		std::make_unique<ShapePlane>(TransformPair().translate(vec3_y * -1.0f))
		));

	s.lights.push_back(SceneLight(mvec3(-3.0f, 6.0f, 1.0f), vec3_1));

	return std::move(s);
}

static vec2 filmspace_from_screenspace(const vec2 screen_pos, const vec2 screen_size) {
	return (screen_pos - (screen_size * 0.5f)) * 2.0f * (1.0f / screen_size[1]);
}

Optional<Intersection> find_nearest_intersection(const Scene& scene, const Ray ray) {
	Optional<Intersection> nearest_intersection;

	for (const SceneObject& object : scene.objects) {
		const Optional<Intersection> intersection = object.shape->intersect(ray);
		if (intersection && (!nearest_intersection || intersection->t < nearest_intersection->t)) {
			nearest_intersection = intersection;
			nearest_intersection->object = &object;
			nearest_intersection->shape = object.shape.get();
		}
	}

	return nearest_intersection;
}

int main(int, char* []) {
	static const int IMAGE_WIDTH = 1280;
	static const int IMAGE_HEIGHT = 720;
	std::vector<vec3> image_data(IMAGE_WIDTH * IMAGE_HEIGHT);

	const Scene scene = setup_scene();

	for (int y = 0; y < IMAGE_HEIGHT; ++y) {
		for (int x = 0; x < IMAGE_WIDTH; x++) {
			const vec2 film_coord = filmspace_from_screenspace(mvec2(float(x), float(y)), mvec2(float(IMAGE_WIDTH), float(IMAGE_HEIGHT))) * mvec2(1.0f, -1.0f);
			const Ray camera_ray = scene.camera.createRay(film_coord);

			vec3 color = vec3_0;

			const Optional<Intersection> surface_hit = find_nearest_intersection(scene, camera_ray);
			if (surface_hit) {
				for (const SceneLight& light : scene.lights) {
					const vec3 light_dir = normalized(light.origin - surface_hit->position);
					color += surface_hit->object->material.diffuse * dot(light_dir, surface_hit->normal);
				}
			} else {
				color = vec3_1 * 0.1f;
			}

			image_data[y*IMAGE_WIDTH + x] = color;
		}
	}

	save_srgb_image(image_data, IMAGE_WIDTH, IMAGE_HEIGHT);
}<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: DDriver.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 07:03:10 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_DBASE_DDRIVER_HXX_
#define _CONNECTIVITY_DBASE_DDRIVER_HXX_

#ifndef _CPPUHELPER_COMPBASE2_HXX_
#include <cppuhelper/compbase2.hxx>
#endif
#ifndef _CONNECTIVITY_COMMONTOOLS_HXX_
#include "connectivity/CommonTools.hxx"
#endif
#ifndef _CONNECTIVITY_FILE_ODRIVER_HXX_
#include "file/FDriver.hxx"
#endif

namespace connectivity
{
    namespace dbase
    {

        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ODriver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );

        class ODriver : public file::OFileDriver
        {
        public:
            ODriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) : file::OFileDriver(_rxFactory){}

            // XInterface
            static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
            //  static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);

            ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
            // XDriver
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
        };
    }

}
#endif //_CONNECTIVITY_DBASE_DDRIVER_HXX_

<commit_msg>INTEGRATION: CWS changefileheader (1.3.372); FILE MERGED 2008/04/01 15:09:10 thb 1.3.372.3: #i85898# Stripping all external header guards 2008/04/01 10:53:25 thb 1.3.372.2: #i85898# Stripping all external header guards 2008/03/28 15:24:18 rt 1.3.372.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: DDriver.hxx,v $
 * $Revision: 1.4 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _CONNECTIVITY_DBASE_DDRIVER_HXX_
#define _CONNECTIVITY_DBASE_DDRIVER_HXX_

#include <cppuhelper/compbase2.hxx>
#include "connectivity/CommonTools.hxx"
#include "file/FDriver.hxx"

namespace connectivity
{
    namespace dbase
    {

        ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > SAL_CALL ODriver_CreateInstance(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) throw( ::com::sun::star::uno::Exception );

        class ODriver : public file::OFileDriver
        {
        public:
            ODriver(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory) : file::OFileDriver(_rxFactory){}

            // XInterface
            static ::rtl::OUString getImplementationName_Static(  ) throw(::com::sun::star::uno::RuntimeException);
            //  static ::com::sun::star::uno::Sequence< ::rtl::OUString > getSupportedServiceNames_Static(  ) throw (::com::sun::star::uno::RuntimeException);

            ::rtl::OUString SAL_CALL getImplementationName(  ) throw(::com::sun::star::uno::RuntimeException);
            // XDriver
            virtual ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XConnection > SAL_CALL connect( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual sal_Bool SAL_CALL acceptsURL( const ::rtl::OUString& url ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
            virtual ::com::sun::star::uno::Sequence< ::com::sun::star::sdbc::DriverPropertyInfo > SAL_CALL getPropertyInfo( const ::rtl::OUString& url, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& info ) throw(::com::sun::star::sdbc::SQLException, ::com::sun::star::uno::RuntimeException);
        };
    }

}
#endif //_CONNECTIVITY_DBASE_DDRIVER_HXX_

<|endoftext|>


<commit_before>#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

vector<string> tokenize(string x); //prototype to tokenize the commands
vector<string> separateByDelim(vector<string> origVector, string delimiter);
//function used to separate strings in a vector by a delimiter
char *stringToCstring(string z); //converts a string to a cstring

int main()
{
    string commander;     //string to hold the user command

    bool restart = true; //keep looping until user enters exit
    int test_state = 1;
    while(restart)
    {
        cout << "$ ";       //prompt the user
        getline(cin, commander);      //takes the entire line of prompts
        vector<string> inter = tokenize(commander);
	//calls the tokenize function
	inter.push_back("\0");

        vector<char*> tokens;
        char* cmd;
        for(unsigned it = 0; it < inter.size(); it++)
	//strings to char*
        {
            cmd = stringToCstring(inter.at(it));
            tokens.push_back(cmd);
        }
	char **command = &tokens[0];

	int counter = 0;
        for(unsigned i = 0; i < inter.size(); i++)
        {
            if(((inter.at(i) == ";") || (inter.at(i) == "||") ||
                (inter.at(i) == "&&") || (inter.at(i) == "#") ||
		(inter.at(i) == "\0")))
            {
                pid_t pid = fork(); //creates child process
                int state = 0;

                if(pid < 0)
                {
                    perror("fork failed\n"); //if forking fails
                    exit(1);
                }

                else if(pid == 0)
                {
		    command[counter] = NULL;
                    int status = execvp(command[0], command);

                    if(status < 0)
                    {
                        perror("execution failed\n"); //if command fails
                        exit(1);
                    }
                }

                else
                {
                    waitpid(-1, &state, 0);
                    if(inter.at(i) == "&&" && (state > 0) && (test_state == 0))
			//when the command is and
                    {
                        break;
                    }
                    if(inter.at(i) == "||" && ((state <= 0) || (test_state == 1))) //using or
                    {
                        break;
                    }

		    if(inter.at(i) == "#")
		    {
			break;
		    }
                }

		for(int j = 0; j < counter; j++)
			//makes sure commands don't run again
		{
		    command[j] = NULL;
		}
		counter = 0;
            }

            else if(inter.at(i) == "exit") //user wants to exit
            {
                exit(1);
		return 0;
            }

	    else if(inter.at(i) == "test" || inter.at(i) == "[")
	    {
		string remember = inter.at(i);
		i++;
		//increment over test and [
		struct stat sb;
		if(inter.at(i) == "-d")
		{
		    i++;
		    //increments over -d
		    command[counter] = new char[inter[i].size() + 1];
		    copy(inter[i].begin(), inter[i].end(), command[counter]);
		    command[counter][inter[i].size()] = '\0';
		    counter++;
		    //creates c_string to hold pathname
		    if(stat(command[0], &sb) == 0 && S_ISDIR(sb.st_mode))
		    {
		        test_state = 1;
		    }
		    else
		    {
		        test_state = 0;
		    }
		}

		else if(inter.at(i) == "-f")
		{
		    i++;
		    //increments over -f
		    command[counter] = new char[inter[i].size() + 1];
		    copy(inter[i].begin(), inter[i].end(), command[counter]);
		    command[counter][inter[i].size()] = '\0';
		    counter++;
		    //creates c_string to hold pathname
		    if(stat(command[0], &sb) == 0 && S_ISREG(sb.st_mode))
		    {
		        test_state = 1;
		    }
		    else
		    {
		        test_state = 0;
		    }
		}

		else
		{
		    if(inter.at(i) != "-e")
		    {
			command[counter] = new char[inter[i].size() + 1];
			copy(inter[i].begin(), inter[i].end(), command[counter]);
                	command[counter][inter[i].size()] = '\0';
			counter++;
			if(stat(command[0], &sb) == 0)
			{
			    test_state = 1;
			}
			else
			{
			     test_state = 0;
			}
		    }

		    else
		    {
			i++;
			//increments over -e
			command[counter] = new char[inter[i].size() + 1];
			copy(inter[i].begin(), inter[i].end(), command[counter]);
                	command[counter][inter[i].size()] = '\0';
			counter++;
			//creates c_string to hold pathname
			if(stat(command[0], &sb) == 0)
			{
			   test_state = 1;
			}
			else
			{
			   test_state = 0;
			}
		    }
		}

		if(remember == "[")
		{
		    //if the beginning string was [ increment over ]
		    i++;
		}

		for(int j = 0; j < counter; j++)
		//makes sure commands don't run again
		{
		    command[j] = NULL;
		}
		counter = 0;
	    }

	    else //remake the command array
	    {
		command[counter] = new char[inter[i].size() + 1];
		copy(inter[i].begin(), inter[i].end(), command[counter]);
                command[counter][inter[i].size()] = '\0';
		counter++;
	    }
        }
    }
    return 0;
}

vector<string> tokenize(string x)
{
    vector<string> tokenVector;
    split(tokenVector, x, is_any_of(" "), token_compress_on);
    // separates by spaces

    vector<string> tokenVectorDelim = separateByDelim(tokenVector, "&&");
    // separates by &&
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "||");
    //separates by ||
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "#");
    //separates by #
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "[");
    //separates by [
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "]");
    //separates by ]
    tokenVectorDelim = separateByDelim(tokenVectorDelim, ";");
    //separates by ;
    return tokenVectorDelim;
}

vector<string> separateByDelim(vector<string> origVector, string delimiter)
{
    vector<string> tokenVectorFinal;
    int pos = 0;
    string oldString;
    string newString;
    for(unsigned l = 0; l < origVector.size(); l++)
    {
        oldString = origVector.at(l);
	if((pos = oldString.find(delimiter)) != string::npos
	    && oldString != delimiter)
	{
            while ((pos = oldString.find(delimiter)) != string::npos)
            {
	        newString = oldString.substr(0, pos);
	        tokenVectorFinal.push_back(newString);
		tokenVectorFinal.push_back(delimiter);
	        oldString.erase(0, pos + delimiter.length());
            }
	    tokenVectorFinal.push_back(oldString);
	}

	else
	{
	    tokenVectorFinal.push_back(oldString);
	}
    }
    return tokenVectorFinal;
}

char *stringToCstring(string z) //makes a char* from a string
{
    char *cstr = new char[z.length() + 1];
    strcpy(cstr, z.c_str());
    return cstr;
}
<commit_msg>fixed unsigned to signed comparison<commit_after>#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <vector>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <boost/algorithm/string.hpp>

using namespace std;
using namespace boost;

vector<string> tokenize(string x); //prototype to tokenize the commands
vector<string> separateByDelim(vector<string> origVector, string delimiter);
//function used to separate strings in a vector by a delimiter
char *stringToCstring(string z); //converts a string to a cstring

int main()
{
    string commander;     //string to hold the user command

    bool restart = true; //keep looping until user enters exit
    int test_state = 1;
    while(restart)
    {
        cout << "$ ";       //prompt the user
        getline(cin, commander);      //takes the entire line of prompts
        vector<string> inter = tokenize(commander);
	//calls the tokenize function
	inter.push_back("\0");

        vector<char*> tokens;
        char* cmd;
        for(unsigned it = 0; it < inter.size(); it++)
	//strings to char*
        {
            cmd = stringToCstring(inter.at(it));
            tokens.push_back(cmd);
        }
	char **command = &tokens[0];

	int counter = 0;
        for(unsigned i = 0; i < inter.size(); i++)
        {
            if(((inter.at(i) == ";") || (inter.at(i) == "||") ||
                (inter.at(i) == "&&") || (inter.at(i) == "#") ||
		(inter.at(i) == "\0")))
            {
                pid_t pid = fork(); //creates child process
                int state = 0;

                if(pid < 0)
                {
                    perror("fork failed\n"); //if forking fails
                    exit(1);
                }

                else if(pid == 0)
                {
		    command[counter] = NULL;
                    int status = execvp(command[0], command);

                    if(status < 0)
                    {
                        perror("execution failed\n"); //if command fails
                        exit(1);
                    }
                }

                else
                {
                    waitpid(-1, &state, 0);
                    if(inter.at(i) == "&&" && (state > 0) && (test_state == 0))
			//when the command is and
                    {
                        break;
                    }
                    if(inter.at(i) == "||" && ((state <= 0) || (test_state == 1))) //using or
                    {
                        break;
                    }

		    if(inter.at(i) == "#")
		    {
			break;
		    }
                }

		for(int j = 0; j < counter; j++)
			//makes sure commands don't run again
		{
		    command[j] = NULL;
		}
		counter = 0;
            }

            else if(inter.at(i) == "exit") //user wants to exit
            {
                exit(1);
		return 0;
            }

	    else if(inter.at(i) == "test" || inter.at(i) == "[")
	    {
		string remember = inter.at(i);
		i++;
		//increment over test and [
		struct stat sb;
		if(inter.at(i) == "-d")
		{
		    i++;
		    //increments over -d
		    command[counter] = new char[inter[i].size() + 1];
		    copy(inter[i].begin(), inter[i].end(), command[counter]);
		    command[counter][inter[i].size()] = '\0';
		    counter++;
		    //creates c_string to hold pathname
		    if(stat(command[0], &sb) == 0 && S_ISDIR(sb.st_mode))
		    {
		        test_state = 1;
		    }
		    else
		    {
		        test_state = 0;
		    }
		}

		else if(inter.at(i) == "-f")
		{
		    i++;
		    //increments over -f
		    command[counter] = new char[inter[i].size() + 1];
		    copy(inter[i].begin(), inter[i].end(), command[counter]);
		    command[counter][inter[i].size()] = '\0';
		    counter++;
		    //creates c_string to hold pathname
		    if(stat(command[0], &sb) == 0 && S_ISREG(sb.st_mode))
		    {
		        test_state = 1;
		    }
		    else
		    {
		        test_state = 0;
		    }
		}

		else
		{
		    if(inter.at(i) != "-e")
		    {
			command[counter] = new char[inter[i].size() + 1];
			copy(inter[i].begin(), inter[i].end(), command[counter]);
                	command[counter][inter[i].size()] = '\0';
			counter++;
			if(stat(command[0], &sb) == 0)
			{
			    test_state = 1;
			}
			else
			{
			     test_state = 0;
			}
		    }

		    else
		    {
			i++;
			//increments over -e
			command[counter] = new char[inter[i].size() + 1];
			copy(inter[i].begin(), inter[i].end(), command[counter]);
                	command[counter][inter[i].size()] = '\0';
			counter++;
			//creates c_string to hold pathname
			if(stat(command[0], &sb) == 0)
			{
			   test_state = 1;
			}
			else
			{
			   test_state = 0;
			}
		    }
		}

		if(remember == "[")
		{
		    //if the beginning string was [ increment over ]
		    i++;
		}

		for(int j = 0; j < counter; j++)
		//makes sure commands don't run again
		{
		    command[j] = NULL;
		}
		counter = 0;
	    }

	    else //remake the command array
	    {
		command[counter] = new char[inter[i].size() + 1];
		copy(inter[i].begin(), inter[i].end(), command[counter]);
                command[counter][inter[i].size()] = '\0';
		counter++;
	    }
        }
    }
    return 0;
}

vector<string> tokenize(string x)
{
    vector<string> tokenVector;
    split(tokenVector, x, is_any_of(" "), token_compress_on);
    // separates by spaces

    vector<string> tokenVectorDelim = separateByDelim(tokenVector, "&&");
    // separates by &&
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "||");
    //separates by ||
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "#");
    //separates by #
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "[");
    //separates by [
    tokenVectorDelim = separateByDelim(tokenVectorDelim, "]");
    //separates by ]
    tokenVectorDelim = separateByDelim(tokenVectorDelim, ";");
    //separates by ;
    return tokenVectorDelim;
}

vector<string> separateByDelim(vector<string> origVector, string delimiter)
{
    vector<string> tokenVectorFinal;
    unsigned pos = 0;
    string oldString;
    string newString;
    for(unsigned l = 0; l < origVector.size(); l++)
    {
        oldString = origVector.at(l);
	if((pos = oldString.find(delimiter)) != string::npos
	    && oldString != delimiter)
	{
            while ((pos = oldString.find(delimiter)) != string::npos)
            {
	        newString = oldString.substr(0, pos);
	        tokenVectorFinal.push_back(newString);
		tokenVectorFinal.push_back(delimiter);
	        oldString.erase(0, pos + delimiter.length());
            }
	    tokenVectorFinal.push_back(oldString);
	}

	else
	{
	    tokenVectorFinal.push_back(oldString);
	}
    }
    return tokenVectorFinal;
}

char *stringToCstring(string z) //makes a char* from a string
{
    char *cstr = new char[z.length() + 1];
    strcpy(cstr, z.c_str());
    return cstr;
}
<|endoftext|>


<commit_before>// Copyright 2010 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed 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 <string>
#include <list>
#include <exception>
#include <typeinfo>

#include <utils.hpp>

#ifndef ARGUMENT_LIST_HPP
#define ARGUMENT_LIST_HPP

namespace isa {
namespace utils {

// Exception: no items in the command line
class EmptyCommandLine : public std::exception {};
// Exception: requested switch not present
class SwitchNotFound : public std::exception {
public:
  SwitchNotFound(std::string option);
  ~SwitchNotFound() throw ();

  const char *what() const throw ();

private:
  std::string option;
};

// ArgumentList class
class ArgumentList {
public:
	ArgumentList(int argc, char * argv[]);
	~ArgumentList();

  inline std::string getName();
	template< typename T > T getFirst() throw(EmptyCommandLine);
	bool getSwitch(const std::string & option) throw(EmptyCommandLine);
	template< typename T > T getSwitchArgument(const std::string & option) throw(EmptyCommandLine, SwitchNotFound);

private:
  std::list< std::string > args;
  std::string name;
};

// Implementations

SwitchNotFound::SwitchNotFound(std::string option) : option(option) {}

SwitchNotFound::~SwitchNotFound() throw () {}

const char * SwitchNotFound::what() const throw() {
  return ("Switch \"" + option + "\" not found.").c_str();
}

ArgumentList::ArgumentList(int argc, char * argv[]) {
  name = std::string(argv[0]);

  for ( unsigned int i = 1; i < argc; i++ ) {
    args.push_back(std::string(argv[i]));
  }
}

ArgumentList::~ArgumentList() {}

inline std::string ArgumentList::getName() {
	return name;
}

template< typename T > T ArgumentList::getFirst() throw(EmptyCommandLine) {
	if ( args.empty() ) {
		throw EmptyCommandLine();
	}

  std::string temp = args.front();
	args.pop_front();
	return castToType< std::string, T >(temp);
}

bool ArgumentList::getSwitch(const std::string & option) throw(EmptyCommandLine) {
	if ( args.empty() ) {
		return false;
	}

	for ( std::list< std::string >::iterator s = args.begin(); s != args.end(); ++s ) {
		if ( option.compare(*s) == 0 ) {
			args.erase(s);
			return true;
		}
	}

	return false;
}

template< class T > T ArgumentList::getSwitchArgument(const std::string & option) throw(EmptyCommandLine, SwitchNotFound) {
	if ( args.empty() ) {
		throw EmptyCommandLine();
	}

	for ( std::list< std::string >::iterator s = args.begin(); s != args.end(); ++s ) {
		if ( option.compare(*s) == 0 ) {
      std::string temp = *(++s);
			T retVal = castToType< std::string, T >(temp);

			args.erase(s);
			args.erase(--s);
			return retVal;
		}
	}

	throw SwitchNotFound(option);
}

} // utils
} // isa

#endif // ARGUMENT_LIST_HPP

<commit_msg>Few fixes in ArgumentList.<commit_after>// Copyright 2010 Alessio Sclocco <a.sclocco@vu.nl>
//
// Licensed 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 <string>
#include <list>
#include <exception>
#include <typeinfo>

#include <utils.hpp>

#ifndef ARGUMENT_LIST_HPP
#define ARGUMENT_LIST_HPP

namespace isa {
namespace utils {

// Exception: no items in the command line
class EmptyCommandLine : public std::exception {};
// Exception: requested switch not present
class SwitchNotFound : public std::exception {
public:
  SwitchNotFound(std::string option);
  ~SwitchNotFound() throw ();

  const char *what() const throw ();

private:
  std::string option;
};

// ArgumentList class
class ArgumentList {
public:
	ArgumentList(int argc, char * argv[]);
	~ArgumentList();

  inline std::string getName();
	template< typename T > T getFirst() throw(EmptyCommandLine);
	bool getSwitch(const std::string & option) throw(EmptyCommandLine);
	template< typename T > T getSwitchArgument(const std::string & option) throw(EmptyCommandLine, SwitchNotFound);

private:
  std::list< std::string > args;
  std::string name;
};

// Implementations

SwitchNotFound::SwitchNotFound(std::string option) : option(option) {}

SwitchNotFound::~SwitchNotFound() throw () {}

const char * SwitchNotFound::what() const throw() {
  return ("Switch \"" + option + "\" not found.").c_str();
}

ArgumentList::ArgumentList(int argc, char * argv[]) : name(std::string(argv[0])) {
  for ( int i = 1; i < argc; i++ ) {
    args.push_back(std::string(argv[i]));
  }
}

ArgumentList::~ArgumentList() {}

inline std::string ArgumentList::getName() {
	return name;
}

template< typename T > T ArgumentList::getFirst() throw(EmptyCommandLine) {
	if ( args.empty() ) {
		throw EmptyCommandLine();
	}

  std::string temp = args.front();
	args.pop_front();
	return castToType< std::string, T >(temp);
}

bool ArgumentList::getSwitch(const std::string & option) throw(EmptyCommandLine) {
	if ( args.empty() ) {
		return false;
	}

	for ( std::list< std::string >::iterator s = args.begin(); s != args.end(); ++s ) {
		if ( option.compare(*s) == 0 ) {
			args.erase(s);
			return true;
		}
	}

	return false;
}

template< class T > T ArgumentList::getSwitchArgument(const std::string & option) throw(EmptyCommandLine, SwitchNotFound) {
	if ( args.empty() ) {
		throw EmptyCommandLine();
	}

	for ( std::list< std::string >::iterator s = args.begin(); s != args.end(); ++s ) {
		if ( option.compare(*s) == 0 ) {
      std::string temp = *(++s);
			T retVal = castToType< std::string, T >(temp);

			args.erase(s);
			args.erase(--s);
			return retVal;
		}
	}

	throw SwitchNotFound(option);
}

} // utils
} // isa

#endif // ARGUMENT_LIST_HPP

<|endoftext|>