<commit_before>/**
 * File        : AStar.cc
 * Description : Implementation of A* algorithm using a specified "world"
 *               from the worlds folder.
 */

#include <iostream>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <forward_list>
#include <vector>
#include <cmath>
#include <chrono>
#include <thread>
#include <mutex>

#include <boost/lexical_cast.hpp>

#include "algorithms/tools/PathTile.h"
#include "common/Results.h"

using namespace pathFind;

const std::string WORLD_DIR = "worlds";
const std::string WORLD_EXT = ".world";

const std::string ALG_NAME = "fringe";
/*
void search (uint startX, uint startY, uint endX, uint endY, std::unordered_set<uint>& tileIdsFound,
             std::unordered_map<uint, PathTile>& expandedTiles,
             pathFind::PathTile& tile, const pathFind::World& world,
             std::mutex& m, bool& finished, bool& iFound);
*/

int main (int args, char* argv[])
{
    // Program should be started with 5 command line parameter
    // that specifies the name of the world file to read from,
    // the start x, start y, end x, and end y
    if (args != 6 )
    {
        std::cout << "Incorrect inputs. Usage: <filename> <start x> <start y> <end x> <end y>" << std::endl;
        return EXIT_FAILURE;
    }

    // Parse the world file
    std::stringstream filename;
    filename << WORLD_DIR << "/" << argv[1] << WORLD_EXT;

    std::ifstream worldFile (filename.str (),
            std::ifstream::in | std::ifstream::binary);

    if (!worldFile)
    {
        std::cout << "World file doesn't exist." << std::endl;
        return EXIT_FAILURE;
    }
    pathFind::World world;

    worldFile >> world;

    // Parse the start and end points
    uint startX, startY, endX, endY;
    try
    {
        startX = boost::lexical_cast<uint> (argv[2]);
        startY = boost::lexical_cast<uint> (argv[3]);
        endX = boost::lexical_cast<uint> (argv[4]);
        endY = boost::lexical_cast<uint> (argv[5]);
    } catch (boost::bad_lexical_cast &e)
    {
        std::cout << "Start and end points failed to convert to numeric types" << std::endl;
        return EXIT_FAILURE;
    }

    auto t1 = std::chrono::high_resolution_clock::now();

    std::function<uint (uint, uint)> h = [endX, endY] (uint x, uint y)
    {
        return  (x < endX ? endX - x : x - endX) +
                (y < endY ? endY - y : y - endY);
    };
    uint threshold = h (startX, startY);

    std::forward_list<PathTile> now, later;
    now.emplace_front (world (startX, startY), Point{startX, startY}, h (startX, startY));

    std::unordered_map <uint, PathTile> closed;

    bool found = false;
    PathTile endTile;

    while (!found)
    {
        std::unordered_map<uint, PathTile> seen;
        uint min = PathTile::INF;

        while (!now.empty ())
        {
            PathTile current = now.front();
            now.pop_front();

            if (current.getCombinedHeuristic () > threshold)
            {
                min = std::min(current.getCombinedHeuristic (), min);
                continue;
            }

            if (current.xy().x == endX && current.xy().y == endY)
            {
                found = true;
                endTile = current;
                break;
            }

            seen[current.getTile ().id] = current;

            Point adjPoint {current.xy ().x + 1, current.xy ().y}; // east
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_after (now.end (), worldTile, adjPoint, current.xy(),
                                          current.getBestCost (), h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.insert_after (now.end (), seenTile->second);
                    }
                }
            }

            adjPoint = {current.xy ().x, current.xy ().y + 1}; // south
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_after (now.end (), worldTile, adjPoint, current.xy(),
                                          current.getBestCost (), h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.insert_after (now.end (), seenTile->second);
                    }
                }
            }

            adjPoint = {current.xy ().x - 1, current.xy ().y}; // west
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_after (now.end (), worldTile, adjPoint, current.xy(),
                                          current.getBestCost (), h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.insert_after (now.end (), seenTile->second);
                    }
                }
            }
            adjPoint = {current.xy ().x, current.xy ().y - 1}; // north
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_after (now.end (), worldTile, adjPoint, current.xy(),
                                          current.getBestCost (), h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.insert_after (now.end (), seenTile->second);
                    }
                }
            }
        }
        now.splice_after(now.end(), later);
        closed.insert (seen.begin (), seen.end ());
    }

    auto t2 = std::chrono::high_resolution_clock::now();

    // Parse reverse results
    uint totalCost = endTile.getBestCost() - endTile.getTile().cost;
    std::vector<Point> finalPath;
    while (endTile.xy ().x != startX || endTile.xy ().y != startY)
    {
        finalPath.emplace_back(endTile.xy ());
        endTile = closed.at((endTile.bestTile ().y * world.getWidth()) + endTile.bestTile ().x);
    }
    finalPath.emplace_back(endTile.xy ());

    writeResults (finalPath, argv[1], ALG_NAME,
            std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count(), totalCost);

    return EXIT_SUCCESS;
}

/*
void search (uint startX, uint startY, uint endX, uint endY, std::unordered_set<uint>& tileIdsFound,
             std::unordered_map<uint, PathTile>& expandedTiles,
             pathFind::PathTile& tile, const pathFind::World& world,
             std::mutex& m, bool& finished, bool& iFound)
{
    PriorityQueue openTiles (world.getWidth (), world.getHeight (), [endX, endY] (uint x, uint y)
    {
        return  (x < endX ? endX - x : x - endX) +
                (y < endY ? endY - y : y - endY);
    });

    openTiles.push (world (startX, startY), {startX, startY}, 0);

    tile = openTiles.top ();
    while (tile.xy ().x != endX || tile.xy ().y != endY)
    {
        tile = openTiles.top ();

        m.lock ();
        if (finished)
        {
            m.unlock ();
            break;
        }
        if (tileIdsFound.count(tile.getTile().id))
        {
            // Best path found
            iFound = true;
            finished = true;
            m.unlock ();
            break;
        }
        tileIdsFound.insert(tile.getTile().id);
        m.unlock ();

        expandedTiles[tile.getTile ().id] = tile;
        openTiles.pop ();

        // Check each neighbor
        Point adjPoint {tile.xy ().x + 1, tile.xy ().y}; // east
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }

        adjPoint = {tile.xy ().x, tile.xy ().y + 1}; // south
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }

        adjPoint = {tile.xy ().x - 1, tile.xy ().y}; // west
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }

        adjPoint = {tile.xy ().x, tile.xy ().y - 1}; // north
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }
    }
}
*/

<commit_msg>Fringe search now runs, but is slow.<commit_after>/**
 * File        : AStar.cc
 * Description : Implementation of A* algorithm using a specified "world"
 *               from the worlds folder.
 */

#include <iostream>
#include <fstream>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <vector>
#include <cmath>
#include <chrono>
#include <thread>
#include <mutex>

#include <boost/lexical_cast.hpp>

#include "algorithms/tools/PathTile.h"
#include "common/Results.h"

using namespace pathFind;

const std::string WORLD_DIR = "worlds";
const std::string WORLD_EXT = ".world";

const std::string ALG_NAME = "fringe";
/*
void search (uint startX, uint startY, uint endX, uint endY, std::unordered_set<uint>& tileIdsFound,
             std::unordered_map<uint, PathTile>& expandedTiles,
             pathFind::PathTile& tile, const pathFind::World& world,
             std::mutex& m, bool& finished, bool& iFound);
*/

int main (int args, char* argv[])
{
    // Program should be started with 5 command line parameter
    // that specifies the name of the world file to read from,
    // the start x, start y, end x, and end y
    if (args != 6 )
    {
        std::cout << "Incorrect inputs. Usage: <filename> <start x> <start y> <end x> <end y>" << std::endl;
        return EXIT_FAILURE;
    }

    // Parse the world file
    std::stringstream filename;
    filename << WORLD_DIR << "/" << argv[1] << WORLD_EXT;

    std::ifstream worldFile (filename.str (),
            std::ifstream::in | std::ifstream::binary);

    if (!worldFile)
    {
        std::cout << "World file doesn't exist." << std::endl;
        return EXIT_FAILURE;
    }
    pathFind::World world;

    worldFile >> world;

    // Parse the start and end points
    uint startX, startY, endX, endY;
    try
    {
        startX = boost::lexical_cast<uint> (argv[2]);
        startY = boost::lexical_cast<uint> (argv[3]);
        endX = boost::lexical_cast<uint> (argv[4]);
        endY = boost::lexical_cast<uint> (argv[5]);
    } catch (boost::bad_lexical_cast &e)
    {
        std::cout << "Start and end points failed to convert to numeric types" << std::endl;
        return EXIT_FAILURE;
    }

    auto t1 = std::chrono::high_resolution_clock::now();

    std::function<uint (uint, uint)> h = [endX, endY] (uint x, uint y)
    {
        return  (x < endX ? endX - x : x - endX) +
                (y < endY ? endY - y : y - endY);
    };

    std::list<PathTile> now, later;
    now.emplace_front (world (startX, startY), Point{startX, startY},
    		Point {startX, startY}, 0, h (startX, startY));

    uint threshold = now.front().getCombinedHeuristic();
    std::unordered_map <uint, PathTile> closed;

    bool found = false;
    PathTile endTile;

    while (!found)
    {
        std::unordered_map<uint, PathTile> seen;
        uint min = PathTile::INF;

        while (!now.empty ())
        {
            PathTile current = now.front();
            now.pop_front();

            if (current.getCombinedHeuristic () > threshold)
            {
                min = std::min(current.getCombinedHeuristic (), min);
                later.push_back(current);
                continue;
            }

            if (current.xy().x == endX && current.xy().y == endY)
            {
                found = true;
                endTile = current;
                break;
            }

            seen[current.getTile ().id] = current;

            Point adjPoint {current.xy ().x + 1, current.xy ().y}; // east
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_back (worldTile, adjPoint, current.xy(),
                                          current.getBestCost () + worldTile.cost, h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.push_back(seenTile->second);
                    }
                }
            }

            adjPoint = {current.xy ().x, current.xy ().y + 1}; // south
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_back (worldTile, adjPoint, current.xy(),
                                          current.getBestCost () + worldTile.cost, h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.push_back(seenTile->second);
                    }
                }
            }

            adjPoint = {current.xy ().x - 1, current.xy ().y}; // west
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_back (worldTile, adjPoint, current.xy(),
                                          current.getBestCost () + worldTile.cost, h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.push_back(seenTile->second);
                    }
                }
            }
            adjPoint = {current.xy ().x, current.xy ().y - 1}; // north
            if (adjPoint.x < world.getWidth () && adjPoint.y < world.getHeight ())
            {
                World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
                if (worldTile.cost != 0 &&
                    closed.find (worldTile.id) == closed.end ())
                {
                    auto seenTile = seen.find(worldTile.id);
                    if (seenTile == seen.end ())
                    {
                        now.emplace_back (worldTile, adjPoint, current.xy(),
                                          current.getBestCost () + worldTile.cost, h (adjPoint.x, adjPoint.y));
                    }
                    else if (seenTile->second.getBestCost () > current.getBestCost () + seenTile->second.getTile ().cost)
                    {
                        seenTile->second.setBestCost (current.getBestCost() + seenTile->second.getTile().cost);
                        seenTile->second.setBestTile (current.xy());
                        now.push_back(seenTile->second);
                    }
                }
            }
        }
        threshold = min;
        now.splice(now.end(), std::move (later));
        closed.insert (seen.begin (), seen.end ());
    }

    auto t2 = std::chrono::high_resolution_clock::now();

    // Parse reverse results
    uint totalCost = endTile.getBestCost() - endTile.getTile().cost;
    std::vector<Point> finalPath;
    while (endTile.xy ().x != startX || endTile.xy ().y != startY)
    {
        finalPath.emplace_back(endTile.xy ());
        endTile = closed.at((endTile.bestTile ().y * world.getWidth()) + endTile.bestTile ().x);
    }
    finalPath.emplace_back(endTile.xy ());

    writeResults (finalPath, argv[1], ALG_NAME,
            std::chrono::duration_cast<std::chrono::milliseconds>(t2-t1).count(), totalCost);

    return EXIT_SUCCESS;
}

/*
void search (uint startX, uint startY, uint endX, uint endY, std::unordered_set<uint>& tileIdsFound,
             std::unordered_map<uint, PathTile>& expandedTiles,
             pathFind::PathTile& tile, const pathFind::World& world,
             std::mutex& m, bool& finished, bool& iFound)
{
    PriorityQueue openTiles (world.getWidth (), world.getHeight (), [endX, endY] (uint x, uint y)
    {
        return  (x < endX ? endX - x : x - endX) +
                (y < endY ? endY - y : y - endY);
    });

    openTiles.push (world (startX, startY), {startX, startY}, 0);

    tile = openTiles.top ();
    while (tile.xy ().x != endX || tile.xy ().y != endY)
    {
        tile = openTiles.top ();

        m.lock ();
        if (finished)
        {
            m.unlock ();
            break;
        }
        if (tileIdsFound.count(tile.getTile().id))
        {
            // Best path found
            iFound = true;
            finished = true;
            m.unlock ();
            break;
        }
        tileIdsFound.insert(tile.getTile().id);
        m.unlock ();

        expandedTiles[tile.getTile ().id] = tile;
        openTiles.pop ();

        // Check each neighbor
        Point adjPoint {tile.xy ().x + 1, tile.xy ().y}; // east
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }

        adjPoint = {tile.xy ().x, tile.xy ().y + 1}; // south
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }

        adjPoint = {tile.xy ().x - 1, tile.xy ().y}; // west
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }

        adjPoint = {tile.xy ().x, tile.xy ().y - 1}; // north
        if (adjPoint.x < world.getWidth() && adjPoint.y < world.getHeight ())
        {
            World::tile_t worldTile = world (adjPoint.x, adjPoint.y);
            if (worldTile.cost != 0 &&
                expandedTiles.find (worldTile.id) == expandedTiles.end ())
            {
                openTiles.tryUpdateBestCost (worldTile, adjPoint, tile);
            }
        }
    }
}
*/

<|endoftext|>


<commit_before>/*
 * Radiation Watch Pocket Geiger Type 5 library for Arduino.
 *
 * Documentation and usage at:
 * https://github.com/MonsieurV/RadiationWatch
 *
 * Released under MIT License. See LICENSE file.
 *
 * Contributed by:
 * Radiation Watch <http://www.radiation-watch.org/>
 * thomasaw <https://github.com/thomasaw>
 * Tourmal <https://github.com/Toumal>
 * Yoan Tournade <yoan@ytotech.com>
 */
#define LIBCALL_RADIATIONWATCH
#include "RadiationWatch.h"

int volatile RadiationWatch::_radiationCount = 0;
int volatile RadiationWatch::_noiseCount = 0;

void RadiationWatch::_onRadiationHandler()
{
  _radiationCount++;
}

void RadiationWatch::_onNoiseHandler()
{
  _noiseCount++;
}

RadiationWatch::RadiationWatch(byte signPin, byte noisePin):
    _signPin(signPin), _noisePin(noisePin)
{
  previousTime = 0;
  previousHistoryTime = 0;
  _count = 0;
  historyIndex = 0;
  historyLength = 0;
  _radiationCallback = NULL;
  _noiseCallback = NULL;
}

void RadiationWatch::setup()
{
  pinMode(_signPin, INPUT_PULLUP);
  pinMode(_noisePin, INPUT_PULLUP);
  // Initialize _countHistory[].
  for(int i = 0; i < HISTORY_LENGTH; i++)
    _countHistory[i] = 0;
  // Init measurement time.
  previousTime = millis();
  previousHistoryTime = millis();
  // Attach interrupt handlers.
  setupInterrupt();
}

void RadiationWatch::loop()
{
  // Process radiation dose if the process period has elapsed.
  unsigned long currentTime = millis();
  if(currentTime - previousTime >= PROCESS_PERIOD) {
    noInterrupts();
    int currentCount = _radiationCount;
    int currentNoiseCount = _noiseCount;
    _radiationCount = 0;
    _noiseCount = 0;
    interrupts();
    if(currentNoiseCount == 0) {
      // Store count log.
      _countHistory[historyIndex] += currentCount;
      // Add number of counts.
      _count += currentCount;
    }
    // Shift an array for counting log for each 6 seconds.
    if(currentTime - previousHistoryTime >= HISTORY_UNIT * 1000) {
      previousHistoryTime += (unsigned long)(HISTORY_UNIT * 1000);
      historyIndex = (historyIndex + 1) % HISTORY_LENGTH;
      if(historyLength < (HISTORY_LENGTH-1)) {
        // Since, we overwrite the oldest value in the history,
        // the effective maximum length is HISTORY_LENGTH-1
        historyLength++;
      }
      _count -= _countHistory[historyIndex];
      _countHistory[historyIndex] = 0;
    }
    // Save time of current process period
    previousTime = currentTime;
    // Enable the callbacks.
    if(_noiseCallback && currentNoiseCount > 0) {
      _noiseCallback();
    }
    if(_radiationCallback && currentCount > 0) {
      _radiationCallback();
    }
  }
}

void RadiationWatch::registerRadiationCallback(void (*callback)(void))
{
  _radiationCallback = callback;
}

void RadiationWatch::registerNoiseCallback(void (*callback)(void))
{
  _noiseCallback = callback;
}

unsigned long RadiationWatch::integrationTime()
{
  return (historyLength * HISTORY_UNIT * 1000UL
          + previousTime - previousHistoryTime);
}

int RadiationWatch::currentRadiationCount() {
  noInterrupts();
  int currentCount = _radiationCount;
  interrupts();
  return currentCount;
}

unsigned long RadiationWatch::radiationCount() {
  return _count;
}

double RadiationWatch::cpm()
{
  // cpm = uSv x alpha
  double min = integrationTime() / 60000.0;
  return (min > 0) ? radiationCount() / min : 0;
}

double RadiationWatch::uSvh()
{
  return cpm() / kAlpha;
}

double RadiationWatch::uSvhError()
{
  double min = integrationTime() / 60000.0;
  return (min > 0) ? sqrt(radiationCount()) / min / kAlpha : 0;
}
<commit_msg>RadiationWatch.cpp: initialize all history related variables in setup()<commit_after>/*
 * Radiation Watch Pocket Geiger Type 5 library for Arduino.
 *
 * Documentation and usage at:
 * https://github.com/MonsieurV/RadiationWatch
 *
 * Released under MIT License. See LICENSE file.
 *
 * Contributed by:
 * Radiation Watch <http://www.radiation-watch.org/>
 * thomasaw <https://github.com/thomasaw>
 * Tourmal <https://github.com/Toumal>
 * Yoan Tournade <yoan@ytotech.com>
 */
#define LIBCALL_RADIATIONWATCH
#include "RadiationWatch.h"

int volatile RadiationWatch::_radiationCount = 0;
int volatile RadiationWatch::_noiseCount = 0;

void RadiationWatch::_onRadiationHandler()
{
  _radiationCount++;
}

void RadiationWatch::_onNoiseHandler()
{
  _noiseCount++;
}

RadiationWatch::RadiationWatch(byte signPin, byte noisePin):
    _signPin(signPin), _noisePin(noisePin)
{
  previousTime = 0;
  previousHistoryTime = 0;
  _count = 0;
  historyIndex = 0;
  historyLength = 0;
  _radiationCallback = NULL;
  _noiseCallback = NULL;
}

void RadiationWatch::setup()
{
  pinMode(_signPin, INPUT_PULLUP);
  pinMode(_noisePin, INPUT_PULLUP);
  // Initialize _countHistory[].
  for(int i = 0; i < HISTORY_LENGTH; i++)
    _countHistory[i] = 0;
  _count = 0;
  historyIndex = 0;
  historyLength = 0;
  // Init measurement time.
  previousTime = millis();
  previousHistoryTime = millis();
  // Attach interrupt handlers.
  setupInterrupt();
}

void RadiationWatch::loop()
{
  // Process radiation dose if the process period has elapsed.
  unsigned long currentTime = millis();
  if(currentTime - previousTime >= PROCESS_PERIOD) {
    noInterrupts();
    int currentCount = _radiationCount;
    int currentNoiseCount = _noiseCount;
    _radiationCount = 0;
    _noiseCount = 0;
    interrupts();
    if(currentNoiseCount == 0) {
      // Store count log.
      _countHistory[historyIndex] += currentCount;
      // Add number of counts.
      _count += currentCount;
    }
    // Shift an array for counting log for each 6 seconds.
    if(currentTime - previousHistoryTime >= HISTORY_UNIT * 1000) {
      previousHistoryTime += (unsigned long)(HISTORY_UNIT * 1000);
      historyIndex = (historyIndex + 1) % HISTORY_LENGTH;
      if(historyLength < (HISTORY_LENGTH-1)) {
        // Since, we overwrite the oldest value in the history,
        // the effective maximum length is HISTORY_LENGTH-1
        historyLength++;
      }
      _count -= _countHistory[historyIndex];
      _countHistory[historyIndex] = 0;
    }
    // Save time of current process period
    previousTime = currentTime;
    // Enable the callbacks.
    if(_noiseCallback && currentNoiseCount > 0) {
      _noiseCallback();
    }
    if(_radiationCallback && currentCount > 0) {
      _radiationCallback();
    }
  }
}

void RadiationWatch::registerRadiationCallback(void (*callback)(void))
{
  _radiationCallback = callback;
}

void RadiationWatch::registerNoiseCallback(void (*callback)(void))
{
  _noiseCallback = callback;
}

unsigned long RadiationWatch::integrationTime()
{
  return (historyLength * HISTORY_UNIT * 1000UL
          + previousTime - previousHistoryTime);
}

int RadiationWatch::currentRadiationCount() {
  noInterrupts();
  int currentCount = _radiationCount;
  interrupts();
  return currentCount;
}

unsigned long RadiationWatch::radiationCount() {
  return _count;
}

double RadiationWatch::cpm()
{
  // cpm = uSv x alpha
  double min = integrationTime() / 60000.0;
  return (min > 0) ? radiationCount() / min : 0;
}

double RadiationWatch::uSvh()
{
  return cpm() / kAlpha;
}

double RadiationWatch::uSvhError()
{
  double min = integrationTime() / 60000.0;
  return (min > 0) ? sqrt(radiationCount()) / min / kAlpha : 0;
}
<|endoftext|>


<commit_before>/**
 *   C++ Examples - a collection of C++ examples intended to serve as a tutorial
 *   Copyright (C) 2011 Alejandro Cabrera
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **/

struct X {
  X() = default;
  ~X() = default;
  explicit X(const int val) : x{val} {}
  X(const X&) = delete;
  const X& operator=(const X&) = delete;

  int x;
};

int main()
{
  X a{1};
  X b{2};

  // a = b; // error
  // X c{a}; // error

  return 0;
}
<commit_msg>Updated class_control example.<commit_after>/**
 *   C++ Examples - a collection of C++ examples intended to serve as a tutorial
 *   Copyright (C) 2011 Alejandro Cabrera
 *
 *   This program is free software: you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *   This program 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 **/
#include <bits/move.h>

struct X {
  X() = default;
  ~X() = default;

  X(const X&) = delete;
  X& operator=(const X&) = delete;

  X(const X&&) = delete;
  X& operator=(const X&&)  = delete;
};

int main()
{
  X x;
  //X xx(x);
  X xy;

  //xy = x;

  // X xm(std::move(x));
  // X xmm;
  // xmm = std::move(x);

  return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) Sometrik oy 2015
 *
 */

#include <string.h>
#include <android/log.h>
#include "Menu.h"
#include <jni.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <iostream>
#include <android/bitmap.h>
#include <ContextAndroid.h>
#include <AndroidClient.h>
#include <AndroidPlatform.h>
#include <FWApplication.h>

#include <TouchEvent.h>
#include <CommandEvent.h>
#include <DrawEvent.h>

#include <android_fopen.h>

using namespace std;

extern FWApplication * applicationMain();

bool AndroidPlatform::onTouchesEvent(jobject * _obj, int mode, int fingerIndex, double time, float x, float y) {

  x /= getDisplayScale();
  y /= getDisplayScale();
  switch (mode) {
  case 1:
    {
      TouchEvent ev(getActiveViewId(), TouchEvent::ACTION_DOWN, x, y, time, fingerIndex);
      postEvent(ev);
    }
    break;
  case 2:
    {
      TouchEvent ev(getActiveViewId(), TouchEvent::ACTION_MOVE, x, y, time, fingerIndex);
      postEvent(ev);
    }
    break;
  case 3:
    {
      TouchEvent ev(getActiveViewId(), TouchEvent::ACTION_UP, x, y, time, fingerIndex);
      postEvent(ev);
    }
    break;
  }

  return true;
}

void AndroidPlatform::onResize(int width, int height) {

  __android_log_print(ANDROID_LOG_ERROR, "Sometrik", "resize: %d %d ", width, height);
  getApplication().onResize(width / getDisplayScale(), height / getDisplayScale(), width, height);
}

void
AndroidPlatform::menuPressed() {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Platform menupressed called");
  CommandEvent ce(FW_ID_MENU);
  postEvent(ce);

//	jclass handlerClass = env->GetObjectClass(handler);
//	jmethodID emptyMessageMethod = env->GetMethodID(handlerClass, "sendEmptyMessage", "(I)Z");
//	env->CallVoidMethod(handler, emptyMessageMethod, 1);
}

int AndroidPlatform::showActionSheet(const FWRect & rect, const FWActionSheet & sheet) {

  //Initialize java int and string arrays
  auto env = getJNIEnv();
  std::vector<FWOption> optionsVector = sheet.getOptions();
  jobjectArray stringArray = (jobjectArray) env->NewObjectArray(optionsVector.size(), env->FindClass("java/lang/String"), 0);
  jintArray intArray = env->NewIntArray(optionsVector.size());
  jint fill[optionsVector.size()];

  //Set values to java arrays
  for (int i = 0; i < optionsVector.size(); i++) {
    const char * text = optionsVector[i].getText().c_str();
    jstring jtext = env->NewStringUTF(text);
    env->SetObjectArrayElement(stringArray, i, jtext);
    fill[i] = optionsVector[i].getId();
    env->ReleaseStringUTFChars(jtext, text);
  }
  env->SetIntArrayRegion(intArray, 0, optionsVector.size(), fill);

  //Send values to java to create the action sheet
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "createOptionsFromJNI", "(Lcom/sometrik/framework/FrameWork;I[I[Ljava/lang/String;)V");
  env->CallStaticVoidMethod(cls, methodRef, framework, 22, intArray, stringArray);

  //Not returning anything
  return 0;
}

bool AndroidPlatform::onUpdate(double timestamp) {
  bool shouldUpdate =  getApplication().onUpdate(timestamp);
  return shouldUpdate;
}

void
AndroidPlatform::onDraw() {
  DrawEvent ev(0);
  postEvent(ev);
}

std::string AndroidPlatform::showTextEntryDialog(const std::string & message) {
  return "";
}

void AndroidPlatform::showMessageBox(const std::string & title, const std::string & message) {

  messagePoster(5, title, message);
}

void AndroidPlatform::createInputDialog(const char * _title, const char * _message, int params) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");

  jmethodID methodRef = env->GetMethodID(cls, "createInputDialog", "(Ljava/lang/String;Ljava/lang/String;)V");
  jstring title = env->NewStringUTF(_title);
  jstring message = env->NewStringUTF(_message);

  //Call method with void return (env, object, method, parameters...)
  //String has to be made with jstring name = (*env)->NewStringUTF(env, "What you want");
  env->CallVoidMethod(framework, methodRef, title, message);
  env->ReleaseStringUTFChars(title, _title);
  env->ReleaseStringUTFChars(message, _message);
}

void AndroidPlatform::showCanvas(canvas::ContextAndroid & context) {

  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "showCanvas called");
  auto env = getJNIEnv();
  jclass cls = env->GetObjectClass(framework);
  jmethodID methodRef = env->GetMethodID(cls, "setNativeCanvas", "(Landroid/graphics/Bitmap;)V");
  env->CallVoidMethod(framework, methodRef, dynamic_cast<canvas::AndroidSurface&>(context.getDefaultSurface()).getBitmap());

}

void
AndroidPlatform::onInit(JNIEnv * env, JavaVM * _gJavaVM) {
//  gJavaVM = NULL;
//  env->GetJavaVM(&gJavaVM);
  gJavaVM = _gJavaVM;
  gJavaVM->AttachCurrentThread(&env, NULL);
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "checking gjavavm");
  if (gJavaVM == NULL){
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "1");
  }
  if (_gJavaVM == NULL){
      __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "2");
    }
}

std::string AndroidPlatform::getBundleFilename(const char * filename) {
  return filename;
}

std::string AndroidPlatform::getLocalFilename(const char * filename, FileType type) {

  auto env = getJNIEnv();
  jstring path;
  jstring jfilename;
  std::string result;
  switch (type) {
  case DATABASE:
  case CACHE_DATABASE:
    jfilename = env->NewStringUTF(filename);
    path = (jstring) env->CallObjectMethod(framework, env->GetMethodID(env->GetObjectClass(framework), "getDBPath", "(Ljava/lang/String;)Ljava/lang/String;"), jfilename);
    result = env->GetStringUTFChars(path, JNI_FALSE);
    env->ReleaseStringUTFChars(jfilename, filename);
    env->ReleaseStringUTFChars(path, result.c_str());
    return result;
  case NORMAL:
    return "";
  }
  return "";
}

std::string AndroidPlatform::loadValue(const std::string & key) {
  auto env = getJNIEnv();
  jstring jkey = env->NewStringUTF(key.c_str());
  jstring value = (jstring) env->CallObjectMethod(framework, env->GetMethodID(env->GetObjectClass(framework), "getFromPrefs", "(Ljava/lang/String;)Ljava/lang/String;"), jkey);
  std::string result = env->GetStringUTFChars(value, JNI_FALSE);
  env->ReleaseStringUTFChars(jkey, key.c_str());
  env->ReleaseStringUTFChars(value, result.c_str());

  return result;
}

void AndroidPlatform::storeValue(const std::string & key, const std::string & value) {
  auto env = getJNIEnv();
  jstring jkey = env->NewStringUTF(key.c_str());
  jstring jvalue = env->NewStringUTF(value.c_str());
  env->CallVoidMethod(framework, env->GetMethodID(env->GetObjectClass(framework), "addToPrefs", "(Ljava/lang/String;Ljava/lang/String;)V"), jkey, jvalue);
  env->ReleaseStringUTFChars(jkey, key.c_str());
  env->ReleaseStringUTFChars(jvalue, value.c_str());
}

void AndroidPlatform::messagePoster(int message, const std::string text) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "LeaveMessageToSurface", "(Lcom/sometrik/framework/FrameWork;ILjava/lang/String;)V");

  jstring jtext = env->NewStringUTF(text.c_str());
  env->CallStaticVoidMethod(cls, methodRef, framework, message, jtext);
  env->ReleaseStringUTFChars(jtext, text.c_str());

}

void AndroidPlatform::messagePoster(int message, int content) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "LeaveMessageToSurface", "(Lcom/sometrik/framework/FrameWork;II)V");

  env->CallStaticVoidMethod(cls, methodRef, framework, message, content);

}

void AndroidPlatform::messagePoster(int message, const std::string title, const std::string text) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "LeaveMessageToSurface", "(Lcom/sometrik/framework/FrameWork;ILjava/lang/String;Ljava/lang/String;)V");

  jstring jtitle = env->NewStringUTF(title.c_str());
  jstring jtext = env->NewStringUTF(text.c_str());
  env->CallStaticVoidMethod(cls, methodRef, framework, message, jtitle, jtext);
  env->ReleaseStringUTFChars(jtitle, title.c_str());
  env->ReleaseStringUTFChars(jtext, text.c_str());
}

double AndroidPlatform::getTime() const {

  auto env = getJNIEnv();
  jclass systemClass = env->FindClass("Ljava/lang/System");
  double currentTime = (double)env->CallStaticLongMethod(systemClass, env->GetStaticMethodID(systemClass, "currentTimeMillis", "()L"));
  env->DeleteLocalRef(systemClass);

  return currentTime;
}

JNIEnv* AndroidPlatform::getJNIEnv() const {
  if (gJavaVM == NULL) {
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "JavaVM is null");
    return NULL;
  }

  JNIEnv *Myenv = NULL;
  gJavaVM->GetEnv((void**)&Myenv, JNI_VERSION_1_6);
  if (Myenv == NULL){
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Env is null");
  }
  return Myenv;
}

std::shared_ptr<AndroidPlatform> platform;

extern "C" {

void Java_com_sometrik_framework_MyGLRenderer_onResize(JNIEnv* env, jobject thiz, float x, float y) {
  platform->setDisplayWidth(x);
  platform->setDisplayHeight(y);
  platform->onResize(x, y);
}

void Java_com_sometrik_framework_FrameWork_menuPressed(JNIEnv* env, jobject thiz) {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "menu pressed: env = %p", env);
  platform->menuPressed();
}

void Java_com_sometrik_framework_FrameWork_touchEvent(JNIEnv* env, jobject thiz, int mode, int fingerIndex, long time, float x, float y) {
  platform->onTouchesEvent(&thiz, mode, fingerIndex, time, x, y);
}

jboolean Java_com_sometrik_framework_MyGLRenderer_onUpdate(JNIEnv* env, jobject thiz, double timestamp) {
  if (platform->onUpdate(timestamp)) {
    return JNI_TRUE;
  } else {
    return JNI_FALSE;
  }
}

static JavaVM * gJavaVM = 0;
void Java_com_sometrik_framework_MyGLRenderer_onInit(JNIEnv* env, jobject thiz, jobject assetManager, jobject surface, float screenWidth, float screenHeight, float displayScale, bool hasEs3) {
  if (!platform.get()) {
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Creating Platform");
    const char* glslVersion = "#version 100"; // "#version es 300"

    AAssetManager* manager = AAssetManager_fromJava(env, assetManager);
    android_fopen_set_asset_manager(manager);

    platform = std::make_shared<AndroidPlatform>(env, assetManager, surface, displayScale, glslVersion, hasEs3);
  }
  FWApplication * application = applicationMain();
  platform->setApplication(application);
  platform->onInit(env, gJavaVM);
  application->initialize(this);
  platform->setDisplayWidth(screenWidth);
  platform->setDisplayHeight(screenHeight);
  platform->onResize(screenWidth, screenHeight);
  application->initializeContent();
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Init end");
}

void Java_com_sometrik_framework_NativeLooper_test(JNIEnv* env, jobject thiz) {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Test");
//  platform->onInit();
}

void Java_com_sometrik_framework_MyGLRenderer_nativeOnDraw(JNIEnv* env, jobject thiz) {
  platform->onDraw();
}

void Java_com_sometrik_framework_FrameWork_okPressed(JNIEnv* env, jobject thiz, jstring text) {

  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetMethodID(cls, "printText", "(Ljava/lang/String;)V");

  env->CallVoidMethod(thiz, methodRef, text);

}

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "JNI_Onload on AndroidPlatform");
  gJavaVM = vm;

  return JNI_VERSION_1_6;
}
}
<commit_msg>Fix onInit application->initialize call<commit_after>/*
 * Copyright (C) Sometrik oy 2015
 *
 */

#include <string.h>
#include <android/log.h>
#include "Menu.h"
#include <jni.h>
#include <android/asset_manager.h>
#include <android/asset_manager_jni.h>
#include <iostream>
#include <android/bitmap.h>
#include <ContextAndroid.h>
#include <AndroidClient.h>
#include <AndroidPlatform.h>
#include <FWApplication.h>

#include <TouchEvent.h>
#include <CommandEvent.h>
#include <DrawEvent.h>

#include <android_fopen.h>

using namespace std;

extern FWApplication * applicationMain();

bool AndroidPlatform::onTouchesEvent(jobject * _obj, int mode, int fingerIndex, double time, float x, float y) {

  x /= getDisplayScale();
  y /= getDisplayScale();
  switch (mode) {
  case 1:
    {
      TouchEvent ev(getActiveViewId(), TouchEvent::ACTION_DOWN, x, y, time, fingerIndex);
      postEvent(ev);
    }
    break;
  case 2:
    {
      TouchEvent ev(getActiveViewId(), TouchEvent::ACTION_MOVE, x, y, time, fingerIndex);
      postEvent(ev);
    }
    break;
  case 3:
    {
      TouchEvent ev(getActiveViewId(), TouchEvent::ACTION_UP, x, y, time, fingerIndex);
      postEvent(ev);
    }
    break;
  }

  return true;
}

void AndroidPlatform::onResize(int width, int height) {

  __android_log_print(ANDROID_LOG_ERROR, "Sometrik", "resize: %d %d ", width, height);
  getApplication().onResize(width / getDisplayScale(), height / getDisplayScale(), width, height);
}

void
AndroidPlatform::menuPressed() {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Platform menupressed called");
  CommandEvent ce(FW_ID_MENU);
  postEvent(ce);

//	jclass handlerClass = env->GetObjectClass(handler);
//	jmethodID emptyMessageMethod = env->GetMethodID(handlerClass, "sendEmptyMessage", "(I)Z");
//	env->CallVoidMethod(handler, emptyMessageMethod, 1);
}

int AndroidPlatform::showActionSheet(const FWRect & rect, const FWActionSheet & sheet) {

  //Initialize java int and string arrays
  auto env = getJNIEnv();
  std::vector<FWOption> optionsVector = sheet.getOptions();
  jobjectArray stringArray = (jobjectArray) env->NewObjectArray(optionsVector.size(), env->FindClass("java/lang/String"), 0);
  jintArray intArray = env->NewIntArray(optionsVector.size());
  jint fill[optionsVector.size()];

  //Set values to java arrays
  for (int i = 0; i < optionsVector.size(); i++) {
    const char * text = optionsVector[i].getText().c_str();
    jstring jtext = env->NewStringUTF(text);
    env->SetObjectArrayElement(stringArray, i, jtext);
    fill[i] = optionsVector[i].getId();
    env->ReleaseStringUTFChars(jtext, text);
  }
  env->SetIntArrayRegion(intArray, 0, optionsVector.size(), fill);

  //Send values to java to create the action sheet
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "createOptionsFromJNI", "(Lcom/sometrik/framework/FrameWork;I[I[Ljava/lang/String;)V");
  env->CallStaticVoidMethod(cls, methodRef, framework, 22, intArray, stringArray);

  //Not returning anything
  return 0;
}

bool AndroidPlatform::onUpdate(double timestamp) {
  bool shouldUpdate =  getApplication().onUpdate(timestamp);
  return shouldUpdate;
}

void
AndroidPlatform::onDraw() {
  DrawEvent ev(0);
  postEvent(ev);
}

std::string AndroidPlatform::showTextEntryDialog(const std::string & message) {
  return "";
}

void AndroidPlatform::showMessageBox(const std::string & title, const std::string & message) {

  messagePoster(5, title, message);
}

void AndroidPlatform::createInputDialog(const char * _title, const char * _message, int params) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");

  jmethodID methodRef = env->GetMethodID(cls, "createInputDialog", "(Ljava/lang/String;Ljava/lang/String;)V");
  jstring title = env->NewStringUTF(_title);
  jstring message = env->NewStringUTF(_message);

  //Call method with void return (env, object, method, parameters...)
  //String has to be made with jstring name = (*env)->NewStringUTF(env, "What you want");
  env->CallVoidMethod(framework, methodRef, title, message);
  env->ReleaseStringUTFChars(title, _title);
  env->ReleaseStringUTFChars(message, _message);
}

void AndroidPlatform::showCanvas(canvas::ContextAndroid & context) {

  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "showCanvas called");
  auto env = getJNIEnv();
  jclass cls = env->GetObjectClass(framework);
  jmethodID methodRef = env->GetMethodID(cls, "setNativeCanvas", "(Landroid/graphics/Bitmap;)V");
  env->CallVoidMethod(framework, methodRef, dynamic_cast<canvas::AndroidSurface&>(context.getDefaultSurface()).getBitmap());

}

void
AndroidPlatform::onInit(JNIEnv * env, JavaVM * _gJavaVM) {
//  gJavaVM = NULL;
//  env->GetJavaVM(&gJavaVM);
  gJavaVM = _gJavaVM;
  gJavaVM->AttachCurrentThread(&env, NULL);
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "checking gjavavm");
  if (gJavaVM == NULL){
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "1");
  }
  if (_gJavaVM == NULL){
      __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "2");
    }
}

std::string AndroidPlatform::getBundleFilename(const char * filename) {
  return filename;
}

std::string AndroidPlatform::getLocalFilename(const char * filename, FileType type) {

  auto env = getJNIEnv();
  jstring path;
  jstring jfilename;
  std::string result;
  switch (type) {
  case DATABASE:
  case CACHE_DATABASE:
    jfilename = env->NewStringUTF(filename);
    path = (jstring) env->CallObjectMethod(framework, env->GetMethodID(env->GetObjectClass(framework), "getDBPath", "(Ljava/lang/String;)Ljava/lang/String;"), jfilename);
    result = env->GetStringUTFChars(path, JNI_FALSE);
    env->ReleaseStringUTFChars(jfilename, filename);
    env->ReleaseStringUTFChars(path, result.c_str());
    return result;
  case NORMAL:
    return "";
  }
  return "";
}

std::string AndroidPlatform::loadValue(const std::string & key) {
  auto env = getJNIEnv();
  jstring jkey = env->NewStringUTF(key.c_str());
  jstring value = (jstring) env->CallObjectMethod(framework, env->GetMethodID(env->GetObjectClass(framework), "getFromPrefs", "(Ljava/lang/String;)Ljava/lang/String;"), jkey);
  std::string result = env->GetStringUTFChars(value, JNI_FALSE);
  env->ReleaseStringUTFChars(jkey, key.c_str());
  env->ReleaseStringUTFChars(value, result.c_str());

  return result;
}

void AndroidPlatform::storeValue(const std::string & key, const std::string & value) {
  auto env = getJNIEnv();
  jstring jkey = env->NewStringUTF(key.c_str());
  jstring jvalue = env->NewStringUTF(value.c_str());
  env->CallVoidMethod(framework, env->GetMethodID(env->GetObjectClass(framework), "addToPrefs", "(Ljava/lang/String;Ljava/lang/String;)V"), jkey, jvalue);
  env->ReleaseStringUTFChars(jkey, key.c_str());
  env->ReleaseStringUTFChars(jvalue, value.c_str());
}

void AndroidPlatform::messagePoster(int message, const std::string text) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "LeaveMessageToSurface", "(Lcom/sometrik/framework/FrameWork;ILjava/lang/String;)V");

  jstring jtext = env->NewStringUTF(text.c_str());
  env->CallStaticVoidMethod(cls, methodRef, framework, message, jtext);
  env->ReleaseStringUTFChars(jtext, text.c_str());

}

void AndroidPlatform::messagePoster(int message, int content) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "LeaveMessageToSurface", "(Lcom/sometrik/framework/FrameWork;II)V");

  env->CallStaticVoidMethod(cls, methodRef, framework, message, content);

}

void AndroidPlatform::messagePoster(int message, const std::string title, const std::string text) {

  auto env = getJNIEnv();
  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetStaticMethodID(cls, "LeaveMessageToSurface", "(Lcom/sometrik/framework/FrameWork;ILjava/lang/String;Ljava/lang/String;)V");

  jstring jtitle = env->NewStringUTF(title.c_str());
  jstring jtext = env->NewStringUTF(text.c_str());
  env->CallStaticVoidMethod(cls, methodRef, framework, message, jtitle, jtext);
  env->ReleaseStringUTFChars(jtitle, title.c_str());
  env->ReleaseStringUTFChars(jtext, text.c_str());
}

double AndroidPlatform::getTime() const {

  auto env = getJNIEnv();
  jclass systemClass = env->FindClass("Ljava/lang/System");
  double currentTime = (double)env->CallStaticLongMethod(systemClass, env->GetStaticMethodID(systemClass, "currentTimeMillis", "()L"));
  env->DeleteLocalRef(systemClass);

  return currentTime;
}

JNIEnv* AndroidPlatform::getJNIEnv() const {
  if (gJavaVM == NULL) {
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "JavaVM is null");
    return NULL;
  }

  JNIEnv *Myenv = NULL;
  gJavaVM->GetEnv((void**)&Myenv, JNI_VERSION_1_6);
  if (Myenv == NULL){
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Env is null");
  }
  return Myenv;
}

std::shared_ptr<AndroidPlatform> platform;

extern "C" {

void Java_com_sometrik_framework_MyGLRenderer_onResize(JNIEnv* env, jobject thiz, float x, float y) {
  platform->setDisplayWidth(x);
  platform->setDisplayHeight(y);
  platform->onResize(x, y);
}

void Java_com_sometrik_framework_FrameWork_menuPressed(JNIEnv* env, jobject thiz) {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "menu pressed: env = %p", env);
  platform->menuPressed();
}

void Java_com_sometrik_framework_FrameWork_touchEvent(JNIEnv* env, jobject thiz, int mode, int fingerIndex, long time, float x, float y) {
  platform->onTouchesEvent(&thiz, mode, fingerIndex, time, x, y);
}

jboolean Java_com_sometrik_framework_MyGLRenderer_onUpdate(JNIEnv* env, jobject thiz, double timestamp) {
  if (platform->onUpdate(timestamp)) {
    return JNI_TRUE;
  } else {
    return JNI_FALSE;
  }
}

static JavaVM * gJavaVM = 0;
void Java_com_sometrik_framework_MyGLRenderer_onInit(JNIEnv* env, jobject thiz, jobject assetManager, jobject surface, float screenWidth, float screenHeight, float displayScale, bool hasEs3) {
  if (!platform.get()) {
    __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Creating Platform");
    const char* glslVersion = "#version 100"; // "#version es 300"

    AAssetManager* manager = AAssetManager_fromJava(env, assetManager);
    android_fopen_set_asset_manager(manager);

    platform = std::make_shared<AndroidPlatform>(env, assetManager, surface, displayScale, glslVersion, hasEs3);
  }
  FWApplication * application = applicationMain();
  platform->setApplication(application);
  platform->onInit(env, gJavaVM);
  application->initialize(platform.get());
  platform->setDisplayWidth(screenWidth);
  platform->setDisplayHeight(screenHeight);
  platform->onResize(screenWidth, screenHeight);
  application->initializeContent();
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Init end");
}

void Java_com_sometrik_framework_NativeLooper_test(JNIEnv* env, jobject thiz) {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "Test");
//  platform->onInit();
}

void Java_com_sometrik_framework_MyGLRenderer_nativeOnDraw(JNIEnv* env, jobject thiz) {
  platform->onDraw();
}

void Java_com_sometrik_framework_FrameWork_okPressed(JNIEnv* env, jobject thiz, jstring text) {

  jclass cls = env->FindClass("com/sometrik/framework/FrameWork");
  jmethodID methodRef = env->GetMethodID(cls, "printText", "(Ljava/lang/String;)V");

  env->CallVoidMethod(thiz, methodRef, text);

}

jint JNI_OnLoad(JavaVM *vm, void *reserved) {
  __android_log_print(ANDROID_LOG_VERBOSE, "Sometrik", "JNI_Onload on AndroidPlatform");
  gJavaVM = vm;

  return JNI_VERSION_1_6;
}
}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 *  $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/framework/XMLRecognizer.hpp>
#include <string.h>

// ---------------------------------------------------------------------------
//  Local data
//
//  gEncodingNameMap
//      This array maps the Encodings enum values to their canonical names.
//      Be sure to keep this in sync with that enum!
// ---------------------------------------------------------------------------
static const XMLCh* gEncodingNameMap[XMLRecognizer::Encodings_Count] =
{
    XMLUni::fgEBCDICEncodingString
    , XMLUni::fgUCS4BEncodingString
    , XMLUni::fgUCS4LEncodingString
    , XMLUni::fgUSASCIIEncodingString
    , XMLUni::fgUTF8EncodingString
    , XMLUni::fgUTF16BEncodingString
    , XMLUni::fgUTF16LEncodingString
};

// ---------------------------------------------------------------------------
//  XMLRecognizer: Public, const static data
//
//  gXXXPre
//  gXXXPreLen
//      The byte sequence prefixes for all of the encodings that we can
//      auto sense. Also included is the length of each sequence.
// ---------------------------------------------------------------------------
const char           XMLRecognizer::fgASCIIPre[]  = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20 };
const unsigned int   XMLRecognizer::fgASCIIPreLen = 6;
const XMLByte        XMLRecognizer::fgEBCDICPre[] = { 0x4C, 0x6F, 0xA7, 0x94, 0x93, 0x40 };
const unsigned int   XMLRecognizer::fgEBCDICPreLen = 6;
const XMLByte        XMLRecognizer::fgUTF16BPre[] = { 0x00, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00, 0x20 };
const XMLByte        XMLRecognizer::fgUTF16LPre[] = { 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00, 0x20, 0x00 };
const unsigned int   XMLRecognizer::fgUTF16PreLen = 12;
const XMLByte        XMLRecognizer::fgUCS4BPre[]  =
{
        0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3F
    ,   0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x6D
    ,   0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x20
};
const XMLByte        XMLRecognizer::fgUCS4LPre[]  =
{
        0x3C, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00
    ,   0x78, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00
    ,   0x6C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
};
const unsigned int   XMLRecognizer::fgUCS4PreLen = 24;

const char           XMLRecognizer::fgUTF8BOM[] = {(char)0xEF, (char)0xBB, (char)0xBF};
const unsigned int   XMLRecognizer::fgUTF8BOMLen = 3;

// ---------------------------------------------------------------------------
//  XMLRecognizer: Encoding recognition methods
// ---------------------------------------------------------------------------
XMLRecognizer::Encodings
XMLRecognizer::basicEncodingProbe(  const   XMLByte* const  rawBuffer
                                    , const unsigned int    rawByteCount)
{
    //
    //  As an optimization to check the 90% case, check first for the ASCII
    //  sequence '<?xml', which means its either US-ASCII, UTF-8, or some
    //  other encoding that we don't do manually but which happens to share
    //  the US-ASCII code points for these characters. So just return UTF-8
    //  to get us through the first line.
    //
    if (rawByteCount >= fgASCIIPreLen)
    {
        if (!memcmp(rawBuffer, fgASCIIPre, fgASCIIPreLen))
            return UTF_8;
    }

    //
    //  If the count of raw bytes is less than 2, it cannot be anything
    //  we understand, so return UTF-8 as a fallback.
    //
    if (rawByteCount < 2)
        return UTF_8;

    //
    //  We know its at least two bytes, so lets check for a UTF-16 BOM. That
    //  is quick to check and enough to identify two major encodings.
    //
    if ((rawBuffer[0] == 0xFE) && (rawBuffer[1] == 0xFF))
        return UTF_16B;
    else if ((rawBuffer[0] == 0xFF) && (rawBuffer[1] == 0xFE))
        return UTF_16L;

    //
    //  Oh well, not one of those. So now lets see if we have at least 4
    //  bytes. If not, then we are out of ideas and can return UTF-8 as the
    //  fallback.
    //
    if (rawByteCount < 4)
        return UTF_8;

    //
    //  We have at least 4 bytes. So lets check the 4 byte sequences that
    //  indicate other UTF-16 and UCS encodings.
    //
    if ((rawBuffer[0] == 0x00) || (rawBuffer[0] == 0x3C))
    {
        if (!memcmp(rawBuffer, fgUCS4BPre, fgUCS4PreLen))
            return UCS_4B;
        else if (!memcmp(rawBuffer, fgUCS4LPre, fgUCS4PreLen))
            return UCS_4L;
        else if (!memcmp(rawBuffer, fgUTF16BPre, fgUTF16PreLen))
            return UTF_16B;
        else if (!memcmp(rawBuffer, fgUTF16LPre, fgUTF16PreLen))
            return UTF_16L;
    }

    //
    //  See if we have enough bytes to possibly match the EBCDIC prefix.
    //  If so, try it.
    //
    if (rawByteCount > fgEBCDICPreLen)
    {
        if (!memcmp(rawBuffer, fgEBCDICPre, fgEBCDICPreLen))
            return EBCDIC;
    }

    //
    //  Does not seem to be anything we know, so go with UTF-8 to get at
    //  least through the first line and see what it really is.
    //
    return UTF_8;
}

XMLRecognizer::Encodings
XMLRecognizer::encodingForName(const XMLCh* const encName)
{
    //
    //  Compare the passed string, case insensitively, to the variations
    //  that we recognize.
    //
    //  !!NOTE: Note that we don't handle EBCDIC here because we don't handle
    //  that one ourselves. It is allowed to fall into 'other'.
    //
   if (encName == XMLUni::fgXMLChEncodingString ||
        !XMLString::compareIString(encName, XMLUni::fgXMLChEncodingString))
   {
        return XMLRecognizer::OtherEncoding;
   }
   else if (!XMLString::compareIString(encName, XMLUni::fgUTF8EncodingString)
    ||  !XMLString::compareIString(encName, XMLUni::fgUTF8EncodingString2))
    {
        return XMLRecognizer::UTF_8;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString2)
          ||  !XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString3)
          ||  !XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString4))
    {
        return XMLRecognizer::US_ASCII;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUTF16LEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUTF16LEncodingString2))
    {
        return XMLRecognizer::UTF_16L;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUTF16BEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUTF16BEncodingString2))
    {
        return XMLRecognizer::UTF_16B;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUCS4LEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUCS4LEncodingString2))
    {
        return XMLRecognizer::UCS_4L;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUCS4BEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUCS4BEncodingString2))
    {
        return XMLRecognizer::UCS_4B;
    }

    // Return 'other' since we don't recognizer it
    return XMLRecognizer::OtherEncoding;
}

const XMLCh*
XMLRecognizer::nameForEncoding(const XMLRecognizer::Encodings theEncoding)
{
    if (theEncoding > Encodings_Count)
        ThrowXML(RuntimeException, XMLExcepts::XMLRec_UnknownEncoding);

    return gEncodingNameMap[theEncoding];
}
<commit_msg>[Bug 9553] purify UMR in XMLRecognizer::basicEncodingProbe.  Patch from Case Larsen.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xerces" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache\@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation, and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com .  For more information
 * on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */

/**
 *  $Id$
 */

// ---------------------------------------------------------------------------
//  Includes
// ---------------------------------------------------------------------------
#include <xercesc/util/RuntimeException.hpp>
#include <xercesc/util/XMLString.hpp>
#include <xercesc/util/XMLUni.hpp>
#include <xercesc/framework/XMLRecognizer.hpp>
#include <string.h>

// ---------------------------------------------------------------------------
//  Local data
//
//  gEncodingNameMap
//      This array maps the Encodings enum values to their canonical names.
//      Be sure to keep this in sync with that enum!
// ---------------------------------------------------------------------------
static const XMLCh* gEncodingNameMap[XMLRecognizer::Encodings_Count] =
{
    XMLUni::fgEBCDICEncodingString
    , XMLUni::fgUCS4BEncodingString
    , XMLUni::fgUCS4LEncodingString
    , XMLUni::fgUSASCIIEncodingString
    , XMLUni::fgUTF8EncodingString
    , XMLUni::fgUTF16BEncodingString
    , XMLUni::fgUTF16LEncodingString
};

// ---------------------------------------------------------------------------
//  XMLRecognizer: Public, const static data
//
//  gXXXPre
//  gXXXPreLen
//      The byte sequence prefixes for all of the encodings that we can
//      auto sense. Also included is the length of each sequence.
// ---------------------------------------------------------------------------
const char           XMLRecognizer::fgASCIIPre[]  = { 0x3C, 0x3F, 0x78, 0x6D, 0x6C, 0x20 };
const unsigned int   XMLRecognizer::fgASCIIPreLen = 6;
const XMLByte        XMLRecognizer::fgEBCDICPre[] = { 0x4C, 0x6F, 0xA7, 0x94, 0x93, 0x40 };
const unsigned int   XMLRecognizer::fgEBCDICPreLen = 6;
const XMLByte        XMLRecognizer::fgUTF16BPre[] = { 0x00, 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00, 0x20 };
const XMLByte        XMLRecognizer::fgUTF16LPre[] = { 0x3C, 0x00, 0x3F, 0x00, 0x78, 0x00, 0x6D, 0x00, 0x6C, 0x00, 0x20, 0x00 };
const unsigned int   XMLRecognizer::fgUTF16PreLen = 12;
const XMLByte        XMLRecognizer::fgUCS4BPre[]  =
{
        0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x3F
    ,   0x00, 0x00, 0x00, 0x78, 0x00, 0x00, 0x00, 0x6D
    ,   0x00, 0x00, 0x00, 0x6C, 0x00, 0x00, 0x00, 0x20
};
const XMLByte        XMLRecognizer::fgUCS4LPre[]  =
{
        0x3C, 0x00, 0x00, 0x00, 0x3F, 0x00, 0x00, 0x00
    ,   0x78, 0x00, 0x00, 0x00, 0x6D, 0x00, 0x00, 0x00
    ,   0x6C, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00
};
const unsigned int   XMLRecognizer::fgUCS4PreLen = 24;

const char           XMLRecognizer::fgUTF8BOM[] = {(char)0xEF, (char)0xBB, (char)0xBF};
const unsigned int   XMLRecognizer::fgUTF8BOMLen = 3;

// ---------------------------------------------------------------------------
//  XMLRecognizer: Encoding recognition methods
// ---------------------------------------------------------------------------
XMLRecognizer::Encodings
XMLRecognizer::basicEncodingProbe(  const   XMLByte* const  rawBuffer
                                    , const unsigned int    rawByteCount)
{
    //
    //  As an optimization to check the 90% case, check first for the ASCII
    //  sequence '<?xml', which means its either US-ASCII, UTF-8, or some
    //  other encoding that we don't do manually but which happens to share
    //  the US-ASCII code points for these characters. So just return UTF-8
    //  to get us through the first line.
    //
    if (rawByteCount >= fgASCIIPreLen)
    {
        if (!memcmp(rawBuffer, fgASCIIPre, fgASCIIPreLen))
            return UTF_8;
    }

    //
    //  If the count of raw bytes is less than 2, it cannot be anything
    //  we understand, so return UTF-8 as a fallback.
    //
    if (rawByteCount < 2)
        return UTF_8;

    //
    //  We know its at least two bytes, so lets check for a UTF-16 BOM. That
    //  is quick to check and enough to identify two major encodings.
    //
    if ((rawBuffer[0] == 0xFE) && (rawBuffer[1] == 0xFF))
        return UTF_16B;
    else if ((rawBuffer[0] == 0xFF) && (rawBuffer[1] == 0xFE))
        return UTF_16L;

    //
    //  Oh well, not one of those. So now lets see if we have at least 4
    //  bytes. If not, then we are out of ideas and can return UTF-8 as the
    //  fallback.
    //
    if (rawByteCount < 4)
        return UTF_8;

    //
    //  We have at least 4 bytes. So lets check the 4 byte sequences that
    //  indicate other UTF-16 and UCS encodings.
    //
    if ((rawBuffer[0] == 0x00) || (rawBuffer[0] == 0x3C))
    {
        if (rawByteCount >= fgUCS4PreLen && !memcmp(rawBuffer, fgUCS4BPre, fgUCS4PreLen))
            return UCS_4B;
        else if (rawByteCount >= fgUCS4PreLen && !memcmp(rawBuffer, fgUCS4LPre, fgUCS4PreLen))
            return UCS_4L;
        else if (rawByteCount >= fgUTF16PreLen && !memcmp(rawBuffer, fgUTF16BPre, fgUTF16PreLen))
            return UTF_16B;
        else if (rawByteCount >= fgUTF16PreLen && !memcmp(rawBuffer, fgUTF16LPre, fgUTF16PreLen))
            return UTF_16L;
    }

    //
    //  See if we have enough bytes to possibly match the EBCDIC prefix.
    //  If so, try it.
    //
    if (rawByteCount > fgEBCDICPreLen)
    {
        if (!memcmp(rawBuffer, fgEBCDICPre, fgEBCDICPreLen))
            return EBCDIC;
    }

    //
    //  Does not seem to be anything we know, so go with UTF-8 to get at
    //  least through the first line and see what it really is.
    //
    return UTF_8;
}

XMLRecognizer::Encodings
XMLRecognizer::encodingForName(const XMLCh* const encName)
{
    //
    //  Compare the passed string, case insensitively, to the variations
    //  that we recognize.
    //
    //  !!NOTE: Note that we don't handle EBCDIC here because we don't handle
    //  that one ourselves. It is allowed to fall into 'other'.
    //
   if (encName == XMLUni::fgXMLChEncodingString ||
        !XMLString::compareIString(encName, XMLUni::fgXMLChEncodingString))
   {
        return XMLRecognizer::OtherEncoding;
   }
   else if (!XMLString::compareIString(encName, XMLUni::fgUTF8EncodingString)
    ||  !XMLString::compareIString(encName, XMLUni::fgUTF8EncodingString2))
    {
        return XMLRecognizer::UTF_8;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString2)
          ||  !XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString3)
          ||  !XMLString::compareIString(encName, XMLUni::fgUSASCIIEncodingString4))
    {
        return XMLRecognizer::US_ASCII;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUTF16LEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUTF16LEncodingString2))
    {
        return XMLRecognizer::UTF_16L;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUTF16BEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUTF16BEncodingString2))
    {
        return XMLRecognizer::UTF_16B;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUCS4LEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUCS4LEncodingString2))
    {
        return XMLRecognizer::UCS_4L;
    }
     else if (!XMLString::compareIString(encName, XMLUni::fgUCS4BEncodingString)
          ||  !XMLString::compareIString(encName, XMLUni::fgUCS4BEncodingString2))
    {
        return XMLRecognizer::UCS_4B;
    }

    // Return 'other' since we don't recognizer it
    return XMLRecognizer::OtherEncoding;
}

const XMLCh*
XMLRecognizer::nameForEncoding(const XMLRecognizer::Encodings theEncoding)
{
    if (theEncoding > Encodings_Count)
        ThrowXML(RuntimeException, XMLExcepts::XMLRec_UnknownEncoding);

    return gEncodingNameMap[theEncoding];
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

#include "Buffer.h"

#include "RamCloudBackend.h"
#include "Postgres.h"

const char* ramcloudConnectionString() {
  char* conn = (char*) malloc(128 * sizeof(char));
  snprintf(conn, 127, "fast+udp:host=%s,port=%d",
           RAMCLOUD_HOST.c_str(), RAMCLOUD_PORT);
  printf("connecting to %s\n", conn);
  return conn;
}

//
// RamCloudFactDB
//

// Construct the requisite tables for storing facts
// in RamCloud, if they don't already exist.
RamCloudFactDB::RamCloudFactDB()
    : ramcloud(ramcloudConnectionString()),
      factTableName("Facts")
    {

  factTableId = ramcloud.createTable(factTableName);

  // Create a Postgres connection
  char factQuery[127];
  snprintf(factQuery, 127, "SELECT left_arg, rel, right_arg, weight FROM %s LIMIT 10000000;", PG_TABLE_FACT.c_str());
  PGIterator iter = PGIterator(factQuery);
  uint64_t totalRead = 0;

  while (iter.hasNext()) {
    RAMCloud::MultiWriteObject requestObjects[100];
    RAMCloud::MultiWriteObject* requests[100];
    float confidences[100];
    uint32_t numRequests = 0;
    for (uint16_t i = 0; i < 100; ++i) {
      // If no more to write, break;
      if (!iter.hasNext()) { break; }

      // Get data from Postgres
      PGRow row = iter.next();
      word fact[256];
      uint8_t factLength = 0;
      for (int k = 0; k < 3; ++k) {  // for each argument...
        if (row[k] == NULL) { continue; }
        // ...read it as a string
        uint32_t stringLength = strlen(row[k]);
        char stringWithoutBrackets[stringLength + 1];
        printf("input: %s\n", row[k]);
        memcpy( stringWithoutBrackets, &row[k][1], stringLength - 2 );
        stringWithoutBrackets[stringLength] = '\0';
        printf("string without brackets: %s\n", stringWithoutBrackets);

        // ...tokenize it
        const char* token = strtok(stringWithoutBrackets, ",");
        while (token != NULL) {
          char* end;
          fact[factLength] = strtol(token, &end, 10);
          if (end == token || *end != '\0') {
            printf("Could not convert string to integer: %s\n", token);
            std::exit(1);
          }
          factLength += 1;  // append the word to the buffer
          token = strtok(NULL, ",");
        }
        // sanity check to prevent too long of a fact
        if (factLength >= 256) { break; }
      }
      confidences[i] = atof(row[3]);

      // Create request object
      requestObjects[i] =
        RAMCloud::MultiWriteObject(factTableId, fact, factLength,
          &confidences[i], sizeof(float));
      requests[i] = &requestObjects[i];
      numRequests += 1;
      totalRead += 1;
    }
    // Write request
    ramcloud.multiWrite(requests, numRequests);
    if (totalRead % 1000000 == 0) {
      printf("Read %luM facts\n", totalRead / 1000000);
    }
  }

}

const bool RamCloudFactDB::contains(const word* key, const uint8_t wordLength) {
  RAMCloud::Buffer buffer;
  ramcloud.read(factTableId, key, wordLength, &buffer);
  if (buffer.getTotalLength() > 0)
    return true;
  else
    return false;
}

// Clean up
RamCloudFactDB::~RamCloudFactDB() {
//  dropTable(factTableName);  // TODO(gabor) drop me somewhere!
}

FactDB* ReadRamCloudFactDB() {
  return new RamCloudFactDB();
}
<commit_msg>More debugging output<commit_after>#include <stdio.h>
#include <stdlib.h>

#include "Buffer.h"

#include "RamCloudBackend.h"
#include "Postgres.h"

const char* ramcloudConnectionString() {
  char* conn = (char*) malloc(128 * sizeof(char));
  snprintf(conn, 127, "fast+udp:host=%s,port=%d",
           RAMCLOUD_HOST.c_str(), RAMCLOUD_PORT);
  printf("connecting to %s\n", conn);
  return conn;
}

//
// RamCloudFactDB
//

// Construct the requisite tables for storing facts
// in RamCloud, if they don't already exist.
RamCloudFactDB::RamCloudFactDB()
    : ramcloud(ramcloudConnectionString()),
      factTableName("Facts")
    {

  factTableId = ramcloud.createTable(factTableName);

  // Create a Postgres connection
  char factQuery[127];
  snprintf(factQuery, 127, "SELECT left_arg, rel, right_arg, weight FROM %s LIMIT 10000000;", PG_TABLE_FACT.c_str());
  PGIterator iter = PGIterator(factQuery);
  uint64_t totalRead = 0;

  while (iter.hasNext()) {
    RAMCloud::MultiWriteObject requestObjects[100];
    RAMCloud::MultiWriteObject* requests[100];
    float confidences[100];
    uint32_t numRequests = 0;
    for (uint16_t i = 0; i < 100; ++i) {
      // If no more to write, break;
      if (!iter.hasNext()) { break; }

      // Get data from Postgres
      PGRow row = iter.next();
      word fact[256];
      uint8_t factLength = 0;
      for (int k = 0; k < 3; ++k) {  // for each argument...
        if (row[k] == NULL) { continue; }
        // ...read it as a string
        uint32_t stringLength = strlen(row[k]);
        char stringWithoutBrackets[stringLength + 1];
        memcpy( stringWithoutBrackets, &row[k][1], stringLength - 2 );
        stringWithoutBrackets[stringLength] = '\0';

        // ...tokenize it
        const char* token = strtok(stringWithoutBrackets, ",");
        while (token != NULL) {
          char* end;
          fact[factLength] = strtol(token, &end, 10);
          if (end == token || *end != '\0') {
            printf("Could not convert string to integer: %s\n (end is '%c')", token);
            std::exit(1);
          }
          factLength += 1;  // append the word to the buffer
          token = strtok(NULL, ",");
        }
        // sanity check to prevent too long of a fact
        if (factLength >= 256) { break; }
      }
      confidences[i] = atof(row[3]);

      // Create request object
      requestObjects[i] =
        RAMCloud::MultiWriteObject(factTableId, fact, factLength,
          &confidences[i], sizeof(float));
      requests[i] = &requestObjects[i];
      numRequests += 1;
      totalRead += 1;
    }
    // Write request
    ramcloud.multiWrite(requests, numRequests);
    if (totalRead % 1000000 == 0) {
      printf("Read %luM facts\n", totalRead / 1000000);
    }
  }

}

const bool RamCloudFactDB::contains(const word* key, const uint8_t wordLength) {
  RAMCloud::Buffer buffer;
  ramcloud.read(factTableId, key, wordLength, &buffer);
  if (buffer.getTotalLength() > 0)
    return true;
  else
    return false;
}

// Clean up
RamCloudFactDB::~RamCloudFactDB() {
//  dropTable(factTableName);  // TODO(gabor) drop me somewhere!
}

FactDB* ReadRamCloudFactDB() {
  return new RamCloudFactDB();
}
<|endoftext|>


<commit_before>
#include "common_headers.h"

#include "parser/token.h"
#include "parser/token_stream.h"
#include "bootstrapping.h"
#include "branch.h"
#include "builtin_functions.h"
#include "errors.h"
#include "function.h"
#include "operations.h"
#include "structs.h"
#include "subroutine.h"
#include "term.h"
#include "type.h"

namespace circa {

Branch* KERNEL = NULL;
Term* CONST_GENERATOR = NULL;
Term* INT_TYPE = NULL;
Term* FLOAT_TYPE = NULL;
Term* BOOL_TYPE = NULL;
Term* STRING_TYPE = NULL;
Term* TYPE_TYPE = NULL;
Term* FUNCTION_TYPE = NULL;
Term* CODEUNIT_TYPE = NULL;
Term* SUBROUTINE_TYPE = NULL;
Term* STRUCT_DEFINITION_TYPE = NULL;
Term* BRANCH_TYPE = NULL;
Term* ANY_TYPE = NULL;
Term* VOID_TYPE = NULL;
Term* REFERENCE_TYPE = NULL;
Term* LIST_TYPE = NULL;
Term* CONSTANT_0 = NULL;
Term* CONSTANT_1 = NULL;
Term* CONSTANT_2 = NULL;

void empty_execute_function(Term*) { }
void empty_alloc_function(Term*) { }
void empty_function(Term*) { }

void const_generator(Term* caller)
{
    Function *output = as_function(caller);
    Type* type = as_type(caller->inputs[0]);
    output->name = "const-" + type->name;
    output->outputType = caller->inputs[0];
    output->execute = empty_execute_function;
}

Term* get_global(string name)
{
    if (KERNEL->containsName(name))
        return KERNEL->getNamed(name);

    throw errors::KeyError(name);
}

void bootstrap_kernel()
{
    KERNEL = new Branch();

    // Create const-generator function
    Term* CONST_GENERATOR = new Term();
    Function_alloc(CONST_GENERATOR);
    as_function(CONST_GENERATOR)->name = "const-generator";
    as_function(CONST_GENERATOR)->pureFunction = true;
    as_function(CONST_GENERATOR)->execute = const_generator;
    KERNEL->bindName(CONST_GENERATOR, "const-generator");

    // Create const-Type function
    Term* constTypeFunc = new Term();
    constTypeFunc->function = CONST_GENERATOR;
    Function_alloc(constTypeFunc);
    as_function(constTypeFunc)->name = "const-Type";
    as_function(constTypeFunc)->pureFunction = true;

    // Create Type type
    Term* typeType = new Term();
    TYPE_TYPE = typeType;
    typeType->function = constTypeFunc;
    typeType->type = typeType;
    Type_alloc(typeType);
    as_type(typeType)->name = "Type";
    as_type(typeType)->alloc = Type_alloc;
    KERNEL->bindName(typeType, "Type");

    // Implant the Type type
    set_input(constTypeFunc, 0, typeType);
    as_function(CONST_GENERATOR)->inputTypes.setAt(0, typeType);
    as_function(constTypeFunc)->outputType = typeType;

    // Create const-Function function
    Term* constFuncFunc = new Term();
    constFuncFunc->function = CONST_GENERATOR;
    Function_alloc(constFuncFunc);
    as_function(constFuncFunc)->name = "const-Function";
    as_function(constFuncFunc)->pureFunction = true;
    KERNEL->bindName(constFuncFunc, "const-Function");

    // Implant const-Function
    CONST_GENERATOR->function = constFuncFunc;

    // Create Function type
    Term* functionType = new Term();
    FUNCTION_TYPE = functionType;
    functionType->function = constTypeFunc;
    functionType->type = typeType;
    Type_alloc(functionType);
    as_type(functionType)->name = "Function";
    as_type(functionType)->alloc = Function_alloc;
    as_type(functionType)->dealloc = Function_dealloc;
    KERNEL->bindName(functionType, "Function");

    // Implant Function type
    set_input(CONST_GENERATOR, 0, typeType);
    set_input(constFuncFunc, 0, functionType);
    CONST_GENERATOR->type = functionType;
    constFuncFunc->type = functionType;
    constTypeFunc->type = functionType;
    as_function(CONST_GENERATOR)->outputType = functionType;
    as_function(constFuncFunc)->outputType = functionType;

    // Don't let these terms get updated
    CONST_GENERATOR->needsUpdate = false;
    constFuncFunc->needsUpdate = false;
    constTypeFunc->needsUpdate = false;
    functionType->needsUpdate = false;
    typeType->needsUpdate = false;
}

void int_alloc(Term* caller)
{
    caller->value = new int;
}
void int_dealloc(Term* caller)
{
    delete (int*) caller->value;
}
void int_copy(Term* source, Term* dest)
{
    as_int(dest) = as_int(source);
}

void float_alloc(Term* caller)
{
    caller->value = new float;
}
void float_dealloc(Term* caller)
{
    delete (float*) caller->value;
}
void float_copy(Term* source, Term* dest)
{
    as_float(dest) = as_float(source);
}

void string_alloc(Term* caller)
{
    caller->value = new string;
}

void string_dealloc(Term* caller)
{
    delete (string*) caller->value;
}

void bool_alloc(Term* caller)
{
    caller->value = new bool;
}

void bool_dealloc(Term* caller)
{
    delete (bool*) caller->value;
}

void bool_copy(Term* source, Term* dest)
{
    as_bool(dest) = as_bool(source);
}

void int_tostring(Term* caller)
{
    std::stringstream strm;
    strm << as_int(caller->inputs[0]);
    as_string(caller) = strm.str();
}
void float_tostring(Term* caller)
{
    std::stringstream strm;
    strm << as_float(caller->inputs[0]);
    as_string(caller) = strm.str();
}
void string_tostring(Term* caller)
{
    as_string(caller) = as_string(caller->inputs[0]);
}
void string_copy(Term* source, Term* dest)
{
    as_string(dest) = as_string(source);
}

void bool_tostring(Term* caller)
{
    if (as_bool(caller))
        as_string(caller) = "true";
    else
        as_string(caller) = "false";
}

void create_builtin_types()
{
    STRING_TYPE = quick_create_type(KERNEL, "string",
            string_alloc,
            string_dealloc,
            string_copy,
            string_tostring);
    INT_TYPE = quick_create_type(KERNEL, "int",
            int_alloc, int_dealloc, int_copy, int_tostring);
    FLOAT_TYPE = quick_create_type(KERNEL, "float",
            float_alloc, float_dealloc, float_copy, float_tostring);
    BOOL_TYPE = quick_create_type(KERNEL, "bool",
            bool_alloc, bool_dealloc, bool_copy, bool_tostring);
    ANY_TYPE = quick_create_type(KERNEL, "any",
            empty_function, empty_function, NULL);
    VOID_TYPE = quick_create_type(KERNEL, "void",
            empty_function, empty_function, NULL);
    REFERENCE_TYPE = quick_create_type(KERNEL, "Reference",
            empty_function, empty_function, NULL);
}

void initialize_constants()
{
    CONSTANT_0 = constant_int(KERNEL, 0);
    CONSTANT_1 = constant_int(KERNEL, 1);
    CONSTANT_2 = constant_int(KERNEL, 2);
}

void initialize()
{
    try {
        bootstrap_kernel();
        create_builtin_types();

        initialize_constants();

        // Do initialize_term first
        initialize_term(KERNEL);

        // Then initialize structs
        initialize_structs(KERNEL);

        initialize_branch(KERNEL);
        initialize_builtin_functions(KERNEL);
        initialize_functions(KERNEL);
        initialize_subroutine(KERNEL);

        initialize_bootstrapped_code(KERNEL);

    } catch (errors::CircaError& e)
    {
        std::cout << "An error occured while initializing." << std::endl;
        std::cout << e.message() << std::endl;
        exit(1);
    }
}

} // namespace circa
<commit_msg>Added reference type<commit_after>
#include "common_headers.h"

#include "parser/token.h"
#include "parser/token_stream.h"
#include "bootstrapping.h"
#include "branch.h"
#include "builtin_functions.h"
#include "errors.h"
#include "function.h"
#include "operations.h"
#include "structs.h"
#include "subroutine.h"
#include "term.h"
#include "type.h"

namespace circa {

Branch* KERNEL = NULL;
Term* CONST_GENERATOR = NULL;
Term* INT_TYPE = NULL;
Term* FLOAT_TYPE = NULL;
Term* BOOL_TYPE = NULL;
Term* STRING_TYPE = NULL;
Term* TYPE_TYPE = NULL;
Term* FUNCTION_TYPE = NULL;
Term* CODEUNIT_TYPE = NULL;
Term* SUBROUTINE_TYPE = NULL;
Term* STRUCT_DEFINITION_TYPE = NULL;
Term* BRANCH_TYPE = NULL;
Term* ANY_TYPE = NULL;
Term* VOID_TYPE = NULL;
Term* REFERENCE_TYPE = NULL;
Term* LIST_TYPE = NULL;
Term* CONSTANT_0 = NULL;
Term* CONSTANT_1 = NULL;
Term* CONSTANT_2 = NULL;

void empty_execute_function(Term*) { }
void empty_alloc_function(Term*) { }
void empty_function(Term*) { }

void const_generator(Term* caller)
{
    Function *output = as_function(caller);
    Type* type = as_type(caller->inputs[0]);
    output->name = "const-" + type->name;
    output->outputType = caller->inputs[0];
    output->execute = empty_execute_function;
}

Term* get_global(string name)
{
    if (KERNEL->containsName(name))
        return KERNEL->getNamed(name);

    throw errors::KeyError(name);
}

void bootstrap_kernel()
{
    KERNEL = new Branch();

    // Create const-generator function
    Term* CONST_GENERATOR = new Term();
    Function_alloc(CONST_GENERATOR);
    as_function(CONST_GENERATOR)->name = "const-generator";
    as_function(CONST_GENERATOR)->pureFunction = true;
    as_function(CONST_GENERATOR)->execute = const_generator;
    KERNEL->bindName(CONST_GENERATOR, "const-generator");

    // Create const-Type function
    Term* constTypeFunc = new Term();
    constTypeFunc->function = CONST_GENERATOR;
    Function_alloc(constTypeFunc);
    as_function(constTypeFunc)->name = "const-Type";
    as_function(constTypeFunc)->pureFunction = true;

    // Create Type type
    Term* typeType = new Term();
    TYPE_TYPE = typeType;
    typeType->function = constTypeFunc;
    typeType->type = typeType;
    Type_alloc(typeType);
    as_type(typeType)->name = "Type";
    as_type(typeType)->alloc = Type_alloc;
    KERNEL->bindName(typeType, "Type");

    // Implant the Type type
    set_input(constTypeFunc, 0, typeType);
    as_function(CONST_GENERATOR)->inputTypes.setAt(0, typeType);
    as_function(constTypeFunc)->outputType = typeType;

    // Create const-Function function
    Term* constFuncFunc = new Term();
    constFuncFunc->function = CONST_GENERATOR;
    Function_alloc(constFuncFunc);
    as_function(constFuncFunc)->name = "const-Function";
    as_function(constFuncFunc)->pureFunction = true;
    KERNEL->bindName(constFuncFunc, "const-Function");

    // Implant const-Function
    CONST_GENERATOR->function = constFuncFunc;

    // Create Function type
    Term* functionType = new Term();
    FUNCTION_TYPE = functionType;
    functionType->function = constTypeFunc;
    functionType->type = typeType;
    Type_alloc(functionType);
    as_type(functionType)->name = "Function";
    as_type(functionType)->alloc = Function_alloc;
    as_type(functionType)->dealloc = Function_dealloc;
    KERNEL->bindName(functionType, "Function");

    // Implant Function type
    set_input(CONST_GENERATOR, 0, typeType);
    set_input(constFuncFunc, 0, functionType);
    CONST_GENERATOR->type = functionType;
    constFuncFunc->type = functionType;
    constTypeFunc->type = functionType;
    as_function(CONST_GENERATOR)->outputType = functionType;
    as_function(constFuncFunc)->outputType = functionType;

    // Don't let these terms get updated
    CONST_GENERATOR->needsUpdate = false;
    constFuncFunc->needsUpdate = false;
    constTypeFunc->needsUpdate = false;
    functionType->needsUpdate = false;
    typeType->needsUpdate = false;
}

void int_alloc(Term* caller)
{
    caller->value = new int;
}
void int_dealloc(Term* caller)
{
    delete (int*) caller->value;
}
void int_copy(Term* source, Term* dest)
{
    as_int(dest) = as_int(source);
}
void int_tostring(Term* caller)
{
    std::stringstream strm;
    strm << as_int(caller->inputs[0]);
    as_string(caller) = strm.str();
}

void float_alloc(Term* caller)
{
    caller->value = new float;
}
void float_dealloc(Term* caller)
{
    delete (float*) caller->value;
}
void float_copy(Term* source, Term* dest)
{
    as_float(dest) = as_float(source);
}
void float_tostring(Term* caller)
{
    std::stringstream strm;
    strm << as_float(caller->inputs[0]);
    as_string(caller) = strm.str();
}

void string_alloc(Term* caller)
{
    caller->value = new string;
}

void string_dealloc(Term* caller)
{
    delete (string*) caller->value;
}

void bool_alloc(Term* caller)
{
    caller->value = new bool;
}

void bool_dealloc(Term* caller)
{
    delete (bool*) caller->value;
}

void bool_copy(Term* source, Term* dest)
{
    as_bool(dest) = as_bool(source);
}

void string_tostring(Term* caller)
{
    as_string(caller) = as_string(caller->inputs[0]);
}
void string_copy(Term* source, Term* dest)
{
    as_string(dest) = as_string(source);
}

void bool_tostring(Term* caller)
{
    if (as_bool(caller))
        as_string(caller) = "true";
    else
        as_string(caller) = "false";
}

void reference_alloc(Term* caller)
{
    caller->value = NULL;
}
void reference_dealloc(Term* caller)
{
    caller->value = NULL;
}
Term* as_reference(Term* term)
{
    return (Term*) term->value;
}
void reference_copy(Term* source, Term* dest)
{
    dest->value = source->value;
}

void create_builtin_types()
{
    STRING_TYPE = quick_create_type(KERNEL, "string",
            string_alloc,
            string_dealloc,
            string_copy,
            string_tostring);
    INT_TYPE = quick_create_type(KERNEL, "int",
            int_alloc, int_dealloc, int_copy, int_tostring);
    FLOAT_TYPE = quick_create_type(KERNEL, "float",
            float_alloc, float_dealloc, float_copy, float_tostring);
    BOOL_TYPE = quick_create_type(KERNEL, "bool",
            bool_alloc, bool_dealloc, bool_copy, bool_tostring);
    ANY_TYPE = quick_create_type(KERNEL, "any",
            empty_function, empty_function, NULL);
    VOID_TYPE = quick_create_type(KERNEL, "void",
            empty_function, empty_function, NULL);
    REFERENCE_TYPE = quick_create_type(KERNEL, "Reference",
            reference_alloc,
            reference_dealloc,
            reference_copy);
}

void initialize_constants()
{
    CONSTANT_0 = constant_int(KERNEL, 0);
    CONSTANT_1 = constant_int(KERNEL, 1);
    CONSTANT_2 = constant_int(KERNEL, 2);
}

void initialize()
{
    try {
        bootstrap_kernel();
        create_builtin_types();

        initialize_constants();

        // Do initialize_term first
        initialize_term(KERNEL);

        // Then initialize structs
        initialize_structs(KERNEL);

        initialize_branch(KERNEL);
        initialize_builtin_functions(KERNEL);
        initialize_functions(KERNEL);
        initialize_subroutine(KERNEL);

        initialize_bootstrapped_code(KERNEL);

    } catch (errors::CircaError& e)
    {
        std::cout << "An error occured while initializing." << std::endl;
        std::cout << e.message() << std::endl;
        exit(1);
    }
}

} // namespace circa
<|endoftext|>