<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkRandom.h"

static SkShader* make_shader(SkScalar w, SkScalar h) {
    const SkColor colors[] = {
        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
        SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
    };
    const SkPoint pts[] = { { w/4, 0 }, { 3*w/4, h } };

    return SkGradientShader::CreateLinear(pts, colors, NULL,
                                          SK_ARRAY_COUNT(colors),
                                          SkShader::kMirror_TileMode);
}

class VerticesGM : public skiagm::GM {
    SkPoint     fPts[9];
    SkPoint     fTexs[9];
    SkColor     fColors[9];
    SkShader*   fShader;

public:
    VerticesGM() : fShader(NULL) {
    }

    virtual ~VerticesGM() {
        SkSafeUnref(fShader);
    }

protected:
    virtual void onOnceBeforeDraw() SK_OVERRIDE {
        const SkScalar X = 150;
        const SkScalar Y = 150;

        fPts[0].set(0, 0);      fPts[1].set(X/2, 10);   fPts[2].set(X, 0);
        fPts[3].set(10, Y/2);   fPts[4].set(X/2, Y/2);  fPts[5].set(X-10, Y/2);
        fPts[6].set(0, Y);    fPts[7].set(X/2, Y-10);  fPts[8].set(X, Y);

        const SkScalar w = 200;
        const SkScalar h = 200;

        fTexs[0].set(0, 0);     fTexs[1].set(w/2, 0);   fTexs[2].set(w, 0);
        fTexs[3].set(0, h/2);   fTexs[4].set(w/2, h/2); fTexs[5].set(w, h/2);
        fTexs[6].set(0, h);     fTexs[7].set(w/2, h);   fTexs[8].set(w, h);

        fShader = make_shader(w, h);

        SkRandom rand;
        for (size_t i = 0; i < SK_ARRAY_COUNT(fColors); ++i) {
            fColors[i] = rand.nextU() | 0xFF000000;
        }
    }

    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("vertices");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(600, 600);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        // start with the center of a 3x3 grid
        static const uint16_t fan[] = {
            4,
            0, 1, 2, 5, 8, 7, 6, 3, 0
        };

        const struct {
            const SkColor*  fColors;
            const SkPoint*  fTexs;
        } rec[] = {
            { fColors,  NULL },
            { NULL,     fTexs },
            { fColors,  fTexs },
        };

        const SkXfermode::Mode modes[] = {
            SkXfermode::kSrc_Mode,
            SkXfermode::kDst_Mode,
            SkXfermode::kModulate_Mode,
        };

        SkPaint paint;
        paint.setShader(fShader);

        canvas->translate(20, 20);
        for (size_t j = 0; j < SK_ARRAY_COUNT(modes); ++j) {
            SkXfermode* xfer = SkXfermode::Create(modes[j]);
            canvas->save();
            for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
                canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode,
                                     SK_ARRAY_COUNT(fPts), fPts,
                                     rec[i].fTexs, rec[i].fColors,
                                     xfer, fan, SK_ARRAY_COUNT(fan), paint);
                canvas->translate(200, 0);
            }
            canvas->restore();
            canvas->translate(0, 200);
            xfer->unref();
        }
    }

#if 1
    virtual uint32_t onGetFlags() const {
        // https://code.google.com/p/skia/issues/detail?id=1956
        return kSkipGPU_Flag;
    }
#endif

private:
    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW(VerticesGM); )
<commit_msg>Remove GPU-only flag for vertices GM<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkGradientShader.h"
#include "SkRandom.h"

static SkShader* make_shader(SkScalar w, SkScalar h) {
    const SkColor colors[] = {
        SK_ColorRED, SK_ColorCYAN, SK_ColorGREEN, SK_ColorWHITE,
        SK_ColorMAGENTA, SK_ColorBLUE, SK_ColorYELLOW,
    };
    const SkPoint pts[] = { { w/4, 0 }, { 3*w/4, h } };

    return SkGradientShader::CreateLinear(pts, colors, NULL,
                                          SK_ARRAY_COUNT(colors),
                                          SkShader::kMirror_TileMode);
}

class VerticesGM : public skiagm::GM {
    SkPoint     fPts[9];
    SkPoint     fTexs[9];
    SkColor     fColors[9];
    SkShader*   fShader;

public:
    VerticesGM() : fShader(NULL) {
    }

    virtual ~VerticesGM() {
        SkSafeUnref(fShader);
    }

protected:
    virtual void onOnceBeforeDraw() SK_OVERRIDE {
        const SkScalar X = 150;
        const SkScalar Y = 150;

        fPts[0].set(0, 0);      fPts[1].set(X/2, 10);   fPts[2].set(X, 0);
        fPts[3].set(10, Y/2);   fPts[4].set(X/2, Y/2);  fPts[5].set(X-10, Y/2);
        fPts[6].set(0, Y);    fPts[7].set(X/2, Y-10);  fPts[8].set(X, Y);

        const SkScalar w = 200;
        const SkScalar h = 200;

        fTexs[0].set(0, 0);     fTexs[1].set(w/2, 0);   fTexs[2].set(w, 0);
        fTexs[3].set(0, h/2);   fTexs[4].set(w/2, h/2); fTexs[5].set(w, h/2);
        fTexs[6].set(0, h);     fTexs[7].set(w/2, h);   fTexs[8].set(w, h);

        fShader = make_shader(w, h);

        SkRandom rand;
        for (size_t i = 0; i < SK_ARRAY_COUNT(fColors); ++i) {
            fColors[i] = rand.nextU() | 0xFF000000;
        }
    }

    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("vertices");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        return SkISize::Make(600, 600);
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        // start with the center of a 3x3 grid
        static const uint16_t fan[] = {
            4,
            0, 1, 2, 5, 8, 7, 6, 3, 0
        };

        const struct {
            const SkColor*  fColors;
            const SkPoint*  fTexs;
        } rec[] = {
            { fColors,  NULL },
            { NULL,     fTexs },
            { fColors,  fTexs },
        };

        const SkXfermode::Mode modes[] = {
            SkXfermode::kSrc_Mode,
            SkXfermode::kDst_Mode,
            SkXfermode::kModulate_Mode,
        };

        SkPaint paint;
        paint.setShader(fShader);

        canvas->translate(20, 20);
        for (size_t j = 0; j < SK_ARRAY_COUNT(modes); ++j) {
            SkXfermode* xfer = SkXfermode::Create(modes[j]);
            canvas->save();
            for (size_t i = 0; i < SK_ARRAY_COUNT(rec); ++i) {
                canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode,
                                     SK_ARRAY_COUNT(fPts), fPts,
                                     rec[i].fTexs, rec[i].fColors,
                                     xfer, fan, SK_ARRAY_COUNT(fan), paint);
                canvas->translate(200, 0);
            }
            canvas->restore();
            canvas->translate(0, 200);
            xfer->unref();
        }
    }

private:
    typedef skiagm::GM INHERITED;
};

DEF_GM( return SkNEW(VerticesGM); )
<|endoftext|>


<commit_before>/*
 * System_httpServer.cpp
 *
 *  Created on: Jun 15, 2014
 *      Author: Pimenta
 */

// this
#include "System.hpp"

// standard
#include <cstring>
#include <cstdio>
#include <string>

// local
#include "Defines.hpp"
#include "Concurrency.hpp"
#include "Network.hpp"
#include "Helpers.hpp"
#include "FileSystem.hpp"

// FIXME: esse define eh zoado, tem que tirar
#define SIZE_HTTPSERVER_MAXBUF 0x1000

using namespace std;
using namespace concurrency;
using namespace network;
using namespace helpers;

// static variables
static TCPConnection* client = nullptr;

void System::httpServer() {
  client = httpTCPServer.accept();
  if (client == nullptr)
    return;

  ByteQueue data(SIZE_HTTPSERVER_MAXBUF);
  client->recv(data);
  data.push(char('\0'));
  printf("total bytes request: %d\n%s\n", data.size() - 1, (char*)data.ptr());
  fflush(stdout);

  char fn[100], buftmp[100];
  sscanf((char*)data.ptr(), "%s %s", buftmp, fn);

  if (string(fn).find("?") != string::npos) {
    httpServer_dataRequest(fn);
  } else {
    if (string(fn) == "/")
      strcpy(fn, "/index.html");
    FILE* fp = fopen((string("./www") + fn).c_str(), "rb");
    if (fp) {
      if (string(fn).find(".html") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/html\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (string(fn).find(".css") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/css\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (string(fn).find(".js") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/javascript\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/octet-stream\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      client->send(FileSystem::readFile(fp));
      fclose(fp);
    }
    else {
      const char* msg = "Pagina nao encontrada.";
      client->send(msg, strlen(msg) + 1);
    }
  }

  delete client;
  client = nullptr;
}

void System::httpServer_dataRequest(char* cRequest) {
  string request = string(cRequest).substr(string(cRequest).find("?") + 1, strlen(cRequest));

  if (request == "host-ip"){
    client->send(localAddress.toString());
  } else if( request == "total-files" ){
    client->send(toString(FileSystem::getTotalFiles()));
  } else if( request == "total-folders" ){
    client->send(toString(FileSystem::getTotalFolders()));
  } else if( request == "total-size" ){
    string totalFiles = toString(FileSystem::getTotalSize());
    client->send(totalFiles);
  } else if( request == "n-hosts" ){
    char tmp[10];
    sprintf(tmp, "%d", users.size());
    client->send(tmp, strlen(tmp) + 1);
  } else if( request == "server-state" ){
    client->send("On", 3);
  } else if( request.find("Cfolder") != string::npos ){
    string tmp = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::createFolder(tmp)){
      client->send("0");
    } else {
      client->send("1");
    }
  } else if( request.find("Rfolder") != string::npos ){
    string folderPath = string(request).substr(string(request).find("=") + 1, request.size());
    FileSystem::Folder* folder = FileSystem::retrieveFolder(folderPath);
    if (!folder){
      client->send("0");
      return;
    }
    string tableContent;
    for(auto& kv : folder->subfolders) {
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += kv.second.getTotalSize();
      tableContent += "
";
    }
    for(auto& kv : folder->files){
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += kv.second.size;
      tableContent += "	";
      tableContent += kv.second.author;
      tableContent += "
";
    }
    client->send(tableContent.c_str(), tableContent.size());
  } else if( request.find("Ufolder") != string::npos ){
  } else if( request.find("Dfolder") != string::npos ){
    if(!FileSystem::deleteFolder(string(request).substr(string(request).find("=") + 1, request.size()))){
      client->send("0");
    } else {
      client->send("1");
    }
  } else if( request.find("Cfile") != string::npos ){
  } else if( request.find("Rfile") != string::npos ){
  } else if( request.find("Ufile") != string::npos ){
  } else if( request.find("Dfile") != string::npos ){
  } else if( request.find("detail-file") != string::npos ){
    string fullPath = string(request).substr(string(request).find("=") + 1, request.size());
    FileSystem::File* file = FileSystem::retrieveFile(fullPath);
    if (!file){
      client->send("0");
      return;
    }
    string json = "{ 'fullPath' : '";
    json += fullPath;
    json += "', 'size' : '";
    json += file->size;
    json += "', 'peer1' : '";
    json += file->peer1;
    json += "', 'peer2' : '";
    json += file->peer2;
    json += "}";
    client->send(json.c_str(), json.size());
  } else if( request == "list-users" ){
    string tableContent;
    for(auto& kv : users) {
      tableContent += "
";
      tableContent += kv.second.name;
      tableContent += "	";
      tableContent += "";
      tableContent += Address(kv.first, 0).toString();
      tableContent += "
";
    }
    client->send(tableContent.c_str(), tableContent.size());
  }
}
<commit_msg>Sending folder sync messages<commit_after>/*
 * System_httpServer.cpp
 *
 *  Created on: Jun 15, 2014
 *      Author: Pimenta
 */

// this
#include "System.hpp"

// standard
#include <cstring>
#include <cstdio>
#include <string>

// local
#include "Defines.hpp"
#include "Concurrency.hpp"
#include "Network.hpp"
#include "Helpers.hpp"
#include "FileSystem.hpp"

// FIXME: esse define eh zoado, tem que tirar
#define SIZE_HTTPSERVER_MAXBUF 0x1000

using namespace std;
using namespace concurrency;
using namespace network;
using namespace helpers;

// static variables
static TCPConnection* client = nullptr;

void System::httpServer() {
  client = httpTCPServer.accept();
  if (client == nullptr)
    return;

  ByteQueue data(SIZE_HTTPSERVER_MAXBUF);
  client->recv(data);
  data.push(char('\0'));
  printf("total bytes request: %d\n%s\n", data.size() - 1, (char*)data.ptr());
  fflush(stdout);

  char fn[100], buftmp[100];
  sscanf((char*)data.ptr(), "%s %s", buftmp, fn);

  if (string(fn).find("?") != string::npos) {
    httpServer_dataRequest(fn);
  } else {
    if (string(fn) == "/")
      strcpy(fn, "/index.html");
    FILE* fp = fopen((string("./www") + fn).c_str(), "rb");
    if (fp) {
      if (string(fn).find(".html") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/html\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (string(fn).find(".css") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/css\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (string(fn).find(".js") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/javascript\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/octet-stream\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      client->send(FileSystem::readFile(fp));
      fclose(fp);
    }
    else {
      const char* msg = "Pagina nao encontrada.";
      client->send(msg, strlen(msg) + 1);
    }
  }

  delete client;
  client = nullptr;
}

void System::httpServer_dataRequest(char* cRequest) {
  string request = string(cRequest).substr(string(cRequest).find("?") + 1, strlen(cRequest));

  if (request == "host-ip"){
    client->send(localAddress.toString());
  } else if( request == "total-files" ){
    client->send(toString(FileSystem::getTotalFiles()));
  } else if( request == "total-folders" ){
    client->send(toString(FileSystem::getTotalFolders()));
  } else if( request == "total-size" ){
    string totalFiles = toString(FileSystem::getTotalSize());
    client->send(totalFiles);
  } else if( request == "n-hosts" ){
    char tmp[10];
    sprintf(tmp, "%d", users.size());
    client->send(tmp, strlen(tmp) + 1);
  } else if( request == "server-state" ){
    client->send("On", 3);
  } else if( request.find("Cfolder") != string::npos ){
    string tmp = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::createFolder(tmp)){
      client->send("0");
    } else {
      client->send("1");
      send_createFolder(tmp);
    }
  } else if( request.find("Rfolder") != string::npos ){
    string folderPath = string(request).substr(string(request).find("=") + 1, request.size());
    FileSystem::Folder* folder = FileSystem::retrieveFolder(folderPath);
    if (!folder){
      client->send("0");
      return;
    }
    string tableContent;
    for(auto& kv : folder->subfolders) {
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += kv.second.getTotalSize();
      tableContent += "
";
    }
    for(auto& kv : folder->files){
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += kv.second.size;
      tableContent += "	";
      tableContent += kv.second.author;
      tableContent += "
";
    }
    client->send(tableContent.c_str(), tableContent.size());
  } else if( request.find("Ufolder") != string::npos ){
  } else if( request.find("Dfolder") != string::npos ){
    string tmp = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::deleteFolder(tmp)){
      client->send("0");
    } else {
      client->send("1");
      send_deleteFolder(tmp);
    }
  } else if( request.find("Cfile") != string::npos ){
  } else if( request.find("Rfile") != string::npos ){
  } else if( request.find("Ufile") != string::npos ){
  } else if( request.find("Dfile") != string::npos ){
  } else if( request.find("detail-file") != string::npos ){
    string fullPath = string(request).substr(string(request).find("=") + 1, request.size());
    FileSystem::File* file = FileSystem::retrieveFile(fullPath);
    if (!file){
      client->send("0");
      return;
    }
    string json = "{ 'fullPath' : '";
    json += fullPath;
    json += "', 'size' : '";
    json += file->size;
    json += "', 'peer1' : '";
    json += file->peer1;
    json += "', 'peer2' : '";
    json += file->peer2;
    json += "}";
    client->send(json.c_str(), json.size());
  } else if( request == "list-users" ){
    string tableContent;
    for(auto& kv : users) {
      tableContent += "
";
      tableContent += kv.second.name;
      tableContent += "	";
      tableContent += "";
      tableContent += Address(kv.first, 0).toString();
      tableContent += "
";
    }
    client->send(tableContent.c_str(), tableContent.size());
  }
}
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2017 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_MARKERS_PLACEMENTS_VERTEXT_LAST_HPP
#define MAPNIK_MARKERS_PLACEMENTS_VERTEXT_LAST_HPP

#include <mapnik/markers_placements/point.hpp>

namespace mapnik {

template <typename Locator, typename Detector>
class markers_vertex_last_placement : public markers_point_placement<Locator, Detector>
{
public:
    using point_placement = markers_point_placement<Locator, Detector>;
    using point_placement::point_placement;

    bool get_point(double &x, double &y, double &angle, bool ignore_placement)
    {
        if (this->done_)
        {
            return false;
        }

        double x0, y0;
        unsigned command0 = this->locator_.vertex(&x0, &y0);

        if (agg::is_stop(command0))
        {
            this->done_ = true;
            return false;
        }

        double next_x, next_y;
        double x1 = x0, y1 = y0;
        unsigned command1 = command0;

        while (!agg::is_stop(command0 = this->locator_.vertex(&next_x, &next_y)))
        {
            command1 = command0;
            x1 = x0;
            y1 = y0;
            x0 = next_x;
            y0 = next_y;
        }

        x = x0;
        y = y0;

        if (agg::is_line_to(command1))
        {
            angle = std::atan2(y0 - y1, x0 - x1);
            if (!this->set_direction(angle))
            {
                return false;
            }
        }

        if (!this->push_to_detector(x, y, angle, ignore_placement))
        {
            return false;
        }

        this->done_ = true;
        return true;
    }
};

}

#endif // MAPNIK_MARKERS_PLACEMENTS_VERTEXT_LAST_HPP
<commit_msg>fix polygon handling<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2017 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_MARKERS_PLACEMENTS_VERTEXT_LAST_HPP
#define MAPNIK_MARKERS_PLACEMENTS_VERTEXT_LAST_HPP

#include <mapnik/markers_placements/point.hpp>

namespace mapnik {

template <typename Locator, typename Detector>
class markers_vertex_last_placement : public markers_point_placement<Locator, Detector>
{
public:
    using point_placement = markers_point_placement<Locator, Detector>;
    using point_placement::point_placement;

    bool get_point(double &x, double &y, double &angle, bool ignore_placement)
    {
        if (this->done_)
        {
            return false;
        }

        geometry::point<double> p0;
        geometry::point<double> p1;
        geometry::point<double> p_next;
        geometry::point<double> move_to;
        unsigned cmd0 = SEG_END;
        unsigned cmd1 = SEG_END;
        unsigned cmd_next = SEG_END;

        while ((cmd_next = this->locator_.vertex(&p_next.x, &p_next.y)) != SEG_END)
        {
            switch (cmd_next)
            {
                case SEG_MOVETO:
                    move_to = p_next;
                    p0 = p_next;
                    cmd0 = cmd_next;
                    break;
                case SEG_LINETO:
                    p1 = p0;
                    cmd1 = cmd0;
                    p0 = p_next;
                    cmd0 = cmd_next;
                    break;
                case SEG_CLOSE:
                    p1 = p0;
                    cmd1 = cmd0;
                    p0 = move_to;
                    cmd0 = cmd_next;
                    break;
            }
        }

        // Empty geometry
        if (cmd0 == SEG_END)
        {
            this->done_ = true;
            return false;
        }

        // Last point
        x = p0.x;
        y = p0.y;

        // Line or polygon
        if (cmd0 == SEG_LINETO || cmd0 == SEG_CLOSE)
        {
            angle = std::atan2(p0.y - p1.y, p0.x - p1.x);
            if (!this->set_direction(angle))
            {
                this->done_ = true;
                return false;
            }
        }
        else
        {
            angle = 0.0;
        }

        if (!this->push_to_detector(x, y, angle, ignore_placement))
        {
            this->done_ = true;
            return false;
        }

        this->done_ = true;
        return true;
    }
};

}

#endif // MAPNIK_MARKERS_PLACEMENTS_VERTEXT_LAST_HPP
<|endoftext|>


<commit_before>/*
 * System_httpServer.cpp
 *
 *  Created on: Jun 15, 2014
 *      Author: Pimenta
 */

// this
#include "System.hpp"

// standard
#include <cstring>
#include <cstdio>
#include <string>

// local
#include "Defines.hpp"
#include "Concurrency.hpp"
#include "Network.hpp"
#include "Helpers.hpp"
#include "FileSystem.hpp"

using namespace std;
using namespace concurrency;
using namespace network;
using namespace helpers;

// static variables
static TCPConnection* client = nullptr;
static ByteQueue fileData;

static void recvFile() {
  fileData.resize(0);
  string tmp;

  while(true){
    tmp = "";
    for (char c; (c = client->recv<char>()) != '\n'; tmp += c);
    if(tmp.find("Tamanho") != string::npos){
      fileData.resize(fromString<int>(tmp.substr(tmp.find(":") + 1, tmp.size() - 2).c_str()));
    } else if (tmp == "\r"){
      break;
    }
  }
  while(true){
    tmp = "";
    for (char c; (c = client->recv<char>()) != '\n'; tmp += c);
    if (tmp == "\r"){
      break;
    }
  }
  client->recv(fileData);
  client->recv<char>();
  client->recv<char>();
  for (char c; (c = client->recv<char>()) != '\n';);
}

void System::httpServer() {
  client = httpTCPServer.accept();
  if (client == nullptr)
    return;

  string requestLine;

  // check dumb requests
  {
    char c;
    if (!client->recv(&c, 1)) return;
    else requestLine += c;
  }
  for (char c; (c = client->recv<char>()) != '\n'; requestLine += c); // receive the request line
  for (; requestLine[0] != ' '; requestLine = requestLine.substr(1, requestLine.size())); // remove method
  requestLine = requestLine.substr(1, requestLine.size()); // remove space after method
  for (; requestLine[requestLine.size() - 1] != ' '; requestLine = requestLine.substr(0, requestLine.size() - 1)); // remove http version
  requestLine = requestLine.substr(0, requestLine.size() - 1);// remove space before http version
  if (requestLine.find("Cfile") != string::npos)
    recvFile();
  else { // if the request is NOT for file upload
    fileData.resize(SIZE_HTTPSERVER_MAXBUF);
    client->recv(fileData); // actually, this is the request body... discarding
  }

  if (requestLine.find("?") != string::npos) {
    httpServer_dataRequest(requestLine);
  } else {
    if (requestLine == "/")
    requestLine += "/index.html";
    FILE* fp = fopen((string("./www") + requestLine).c_str(), "rb");
    if (fp) {
      if (requestLine.find(".html") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/html\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (requestLine.find(".css") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/css\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (requestLine.find(".js") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/javascript\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/octet-stream\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      client->send(FileSystem::readFile(fp));
      fclose(fp);
    }
    else {
      const char* msg =
        "HTTP/1.1 200 OK\r\n"
        "Connection: close\r\r"
        "Content-Type: text/html\r\n"
        "\r\n"
        "Pagina nao encontrada."
      ;
      client->send(msg, strlen(msg) + 1);
    }
  }

  delete client;
  client = nullptr;
}

void System::httpServer_dataRequest(const string& cRequest) {
  string request = cRequest.substr(cRequest.find("?") + 1, cRequest.size());
  if (request == "host-ip"){
    client->send(localAddress.toString());
  } else if( request == "total-files" ){
    client->send(toString(FileSystem::getTotalFiles()));
  } else if( request == "username" ){
    client->send(users[localAddress.ip].name);
  } else if( request == "total-folders" ){
    client->send(toString(FileSystem::getTotalFolders()));
  } else if( request == "total-size" ){
    client->send(toString(FileSystem::getTotalSize()));
  } else if( request == "n-hosts" ){
    client->send(toString(users.size()));
  } else if( request == "server-state" ){
    client->send("1");
  } else if( request.find("Cfolder") != string::npos ){
    string tmp = request.substr(request.find("=") + 1, request.size());
    if(!FileSystem::createFolder(tmp)){
      client->send("0");
    } else {
      client->send(string("1"), true);
      send_createFolder(tmp);
    }
  } else if( request.find("RfolderPath") != string::npos ){
    string folderPath = request.substr(request.find("=") + 1, request.size());
    string foundPath;
    FileSystem::retrieveFolder(folderPath, foundPath);
    client->send(foundPath, true);
  } else if( request.find("Rfolder") != string::npos ){
    string folderPath = request.substr(request.find("=") + 1, request.size());
    string foundPath;
    FileSystem::Folder* folder = FileSystem::retrieveFolder(folderPath, foundPath);
    if (!folder){
      client->send("0");
      return;
    }
    string tableContent;
    for(auto& kv : folder->subfolders) {
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += toString(kv.second.getTotalSize());
      tableContent += "
";
    }
    for(auto& kv : folder->files){
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += toString(kv.second.size);
      tableContent += "	";
      tableContent += kv.second.author;
      tableContent += "
";
    }
    client->send(tableContent);
  } else if( request.find("Ufolder") != string::npos ){
    string data = request.substr(request.find("=") + 1, request.size());
    string oldPath = data.substr(0, data.find("?&"));
    string newName = data.substr(data.find("?&") + 2, data.size());
    if(!FileSystem::updateFolder(oldPath, newName))
      client->send("0");
    else {
      client->send(string("1"), true);
      send_updateFolder(oldPath, newName);
    }
  } else if( request.find("Dfolder") != string::npos ){
    string tmp = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::deleteFolder(tmp)){
      client->send("0");
    } else {
      client->send(string("1"), true);
      send_deleteFolder(tmp);
    }
  } else if( request.find("Cfile") != string::npos ){
    string fullPath = request.substr(request.find("=") + 1, request.size());
    FileSystem::File* file = FileSystem::createFile(fullPath, fileData, users[localAddress.ip].name);
    if(!file){
      client->send("0");
    } else {
      client->send(string("1"), true);
      ByteQueue info;
      file->serialize(info);
      send_createFile(fullPath, info);
    }
  } else if( request.find("Rfile") != string::npos ){
    //TODO
  } else if( request.find("Ufile") != string::npos ){
    string data = request.substr(request.find("=") + 1, request.size());
    string oldPath = data.substr(0, data.find("?&"));
    string newName = data.substr(data.find("?&") + 2, data.size());
    if(!FileSystem::updateFile(oldPath, newName))
      client->send("0");
    else {
      client->send(string("1"), true);
      send_updateFile(oldPath, newName);
    }
  } else if( request.find("Dfile") != string::npos ){
    string fullPath = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::deleteFile(fullPath)){
      client->send("0");
    } else {
      client->send(string("1"), true);
      send_deleteFile(fullPath);
    }
  } else if( request == "list-users" ){
    string tableContent;
    for(auto& kv : users) {
      tableContent += "
";
      tableContent += kv.second.name;
      tableContent += "	";
      tableContent += "";
      tableContent += Address(kv.first, 0).toString();
      tableContent += "
";
    }
    client->send(tableContent);
  }
}
<commit_msg>Adding links to download files<commit_after>/*
 * System_httpServer.cpp
 *
 *  Created on: Jun 15, 2014
 *      Author: Pimenta
 */

// this
#include "System.hpp"

// standard
#include <cstring>
#include <cstdio>
#include <string>

// local
#include "Defines.hpp"
#include "Concurrency.hpp"
#include "Network.hpp"
#include "Helpers.hpp"
#include "FileSystem.hpp"

using namespace std;
using namespace concurrency;
using namespace network;
using namespace helpers;

// static variables
static TCPConnection* client = nullptr;
static ByteQueue fileData;

static void recvFile() {
  fileData.resize(0);
  string tmp;

  while(true){
    tmp = "";
    for (char c; (c = client->recv<char>()) != '\n'; tmp += c);
    if(tmp.find("Tamanho") != string::npos){
      fileData.resize(fromString<int>(tmp.substr(tmp.find(":") + 1, tmp.size() - 2).c_str()));
    } else if (tmp == "\r"){
      break;
    }
  }
  while(true){
    tmp = "";
    for (char c; (c = client->recv<char>()) != '\n'; tmp += c);
    if (tmp == "\r"){
      break;
    }
  }
  client->recv(fileData);
  client->recv<char>();
  client->recv<char>();
  for (char c; (c = client->recv<char>()) != '\n';);
}

void System::httpServer() {
  client = httpTCPServer.accept();
  if (client == nullptr)
    return;

  string requestLine;

  // check dumb requests
  {
    char c;
    if (!client->recv(&c, 1)) return;
    else requestLine += c;
  }
  for (char c; (c = client->recv<char>()) != '\n'; requestLine += c); // receive the request line
  for (; requestLine[0] != ' '; requestLine = requestLine.substr(1, requestLine.size())); // remove method
  requestLine = requestLine.substr(1, requestLine.size()); // remove space after method
  for (; requestLine[requestLine.size() - 1] != ' '; requestLine = requestLine.substr(0, requestLine.size() - 1)); // remove http version
  requestLine = requestLine.substr(0, requestLine.size() - 1);// remove space before http version
  if (requestLine.find("Cfile") != string::npos)
    recvFile();
  else { // if the request is NOT for file upload
    fileData.resize(SIZE_HTTPSERVER_MAXBUF);
    client->recv(fileData); // actually, this is the request body... discarding
  }

  if (requestLine.find("?") != string::npos) {
    httpServer_dataRequest(requestLine);
  } else {
    if (requestLine == "/")
    requestLine += "/index.html";
    FILE* fp = fopen((string("./www") + requestLine).c_str(), "rb");
    if (fp) {
      if (requestLine.find(".html") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/html\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (requestLine.find(".css") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: text/css\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else if (requestLine.find(".js") != string::npos) {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/javascript\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      else {
        const char* header =
          "HTTP/1.1 200 OK\r\n"
          "Connection: close\r\r"
          "Content-Type: application/octet-stream\r\n"
          "\r\n"
        ;
        client->send(header, strlen(header));
      }
      client->send(FileSystem::readFile(fp));
      fclose(fp);
    }
    else {
      const char* msg =
        "HTTP/1.1 200 OK\r\n"
        "Connection: close\r\r"
        "Content-Type: text/html\r\n"
        "\r\n"
        "Pagina nao encontrada."
      ;
      client->send(msg, strlen(msg) + 1);
    }
  }

  delete client;
  client = nullptr;
}

void System::httpServer_dataRequest(const string& cRequest) {
  string request = cRequest.substr(cRequest.find("?") + 1, cRequest.size());
  if (request == "host-ip"){
    client->send(localAddress.toString());
  } else if( request == "total-files" ){
    client->send(toString(FileSystem::getTotalFiles()));
  } else if( request == "username" ){
    client->send(users[localAddress.ip].name);
  } else if( request == "total-folders" ){
    client->send(toString(FileSystem::getTotalFolders()));
  } else if( request == "total-size" ){
    client->send(toString(FileSystem::getTotalSize()));
  } else if( request == "n-hosts" ){
    client->send(toString(users.size()));
  } else if( request == "server-state" ){
    client->send("1");
  } else if( request.find("Cfolder") != string::npos ){
    string tmp = request.substr(request.find("=") + 1, request.size());
    if(!FileSystem::createFolder(tmp)){
      client->send("0");
    } else {
      client->send(string("1"), true);
      send_createFolder(tmp);
    }
  } else if( request.find("RfolderPath") != string::npos ){
    string folderPath = request.substr(request.find("=") + 1, request.size());
    string foundPath;
    FileSystem::retrieveFolder(folderPath, foundPath);
    client->send(foundPath, true);
  } else if( request.find("Rfolder") != string::npos ){
    string folderPath = request.substr(request.find("=") + 1, request.size());
    string foundPath;
    FileSystem::Folder* folder = FileSystem::retrieveFolder(folderPath, foundPath);
    if (!folder){
      client->send("0");
      return;
    }
    string tableContent;
    for(auto& kv : folder->subfolders) {
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += toString(kv.second.getTotalSize());
      tableContent += "
";
    }
    for(auto& kv : folder->files){
      tableContent += "
	";
      tableContent += kv.first.substr(1, kv.first.size());
      tableContent += "	";
      tableContent += toString(kv.second.size);
      tableContent += "	";
      tableContent += kv.second.author;
      tableContent += "
";
    }
    client->send(tableContent);
  } else if( request.find("Ufolder") != string::npos ){
    string data = request.substr(request.find("=") + 1, request.size());
    string oldPath = data.substr(0, data.find("?&"));
    string newName = data.substr(data.find("?&") + 2, data.size());
    if(!FileSystem::updateFolder(oldPath, newName))
      client->send("0");
    else {
      client->send(string("1"), true);
      send_updateFolder(oldPath, newName);
    }
  } else if( request.find("Dfolder") != string::npos ){
    string tmp = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::deleteFolder(tmp)){
      client->send("0");
    } else {
      client->send(string("1"), true);
      send_deleteFolder(tmp);
    }
  } else if( request.find("Cfile") != string::npos ){
    string fullPath = request.substr(request.find("=") + 1, request.size());
    FileSystem::File* file = FileSystem::createFile(fullPath, fileData, users[localAddress.ip].name);
    if(!file){
      client->send("0");
    } else {
      client->send(string("1"), true);
      ByteQueue info;
      file->serialize(info);
      send_createFile(fullPath, info);
    }
  } else if( request.find("Rfile") != string::npos ){
    FileSystem::File* file = FileSystem::retrieveFile(string(request).substr(string(request).find("=") + 1, request.size()));
    if (file)
      client->send(file->read());
  } else if( request.find("Ufile") != string::npos ){
    string data = request.substr(request.find("=") + 1, request.size());
    string oldPath = data.substr(0, data.find("?&"));
    string newName = data.substr(data.find("?&") + 2, data.size());
    if(!FileSystem::updateFile(oldPath, newName))
      client->send("0");
    else {
      client->send(string("1"), true);
      send_updateFile(oldPath, newName);
    }
  } else if( request.find("Dfile") != string::npos ){
    string fullPath = string(request).substr(string(request).find("=") + 1, request.size());
    if(!FileSystem::deleteFile(fullPath)){
      client->send("0");
    } else {
      client->send(string("1"), true);
      send_deleteFile(fullPath);
    }
  } else if( request == "list-users" ){
    string tableContent;
    for(auto& kv : users) {
      tableContent += "
";
      tableContent += kv.second.name;
      tableContent += "	";
      tableContent += "";
      tableContent += Address(kv.first, 0).toString();
      tableContent += "
";
    }
    client->send(tableContent);
  }
}
<|endoftext|>


<commit_before>#pragma once

#include <vector>
#include <tuple>
#include <array>

#include <tudocomp/util.hpp>
#include <tudocomp/io.hpp>
#include <tudocomp/Algorithm.hpp>

#include <tudocomp/ds/IntVector.hpp>

#include <sdsl/cst_sct3.hpp>

namespace tdc {
namespace lfs {

template<uint min_lrf = 2 >
class SimSTStrategy : public Algorithm {
private:

    inline virtual std::vector<int> select_starting_positions(std::vector<int> starting_positions, int length){
        std::vector<int> selected_starting_positions;
        //select occurences greedily non-overlapping:
        selected_starting_positions.reserve(starting_positions.size());

        int last =  0-length;
        int current;
        for (auto it=starting_positions.begin(); it!=starting_positions.end(); ++it){

            current = *it;
            //DLOG(INFO) << "checking starting position: " << current << " length: " << top.first << "last " << last;
            if(last+length <= current && !dead_positions[current] && !dead_positions[current+length-1]){

                selected_starting_positions.push_back(current);
                last = current;

            }

        }
        return selected_starting_positions;
    }

    //(position in text, non_terminal_symbol_number, length_of_symbol);
    typedef std::tuple<uint,uint,uint> non_term;
    typedef std::vector<non_term> non_terminal_symbols;
    typedef std::vector<std::pair<uint,uint>> rules;

    typedef sdsl::cst_sct3<> cst_t;
    cst_t stree;

    BitVector dead_positions;

public:

    using Algorithm::Algorithm; //import constructor

    inline static Meta meta() {
        Meta m("lfs_comp", "sim_st");
        return m;
    }

    inline void compute_rules(io::InputView & input, rules & dictionary, non_terminal_symbols & nts_symbols){

        //build suffixtree
        DLOG(INFO)<<"build suffixtree";

        dead_positions = BitVector(input.size(), 0);

        StatPhase::wrap("Constructing ST", [&]{
             sdsl::construct_im(stree, (const char*) input.data(), 1);
        });

        DLOG(INFO)<<"computing string depth";

        //array of vectors for bins of nodes with string depth
        std::vector<std::vector<int> > bins;
        bins.resize(stree.size()+1);

        uint node_counter = 0;

        typedef sdsl::cst_bfs_iterator<cst_t> iterator;
            iterator begin = iterator(&stree, stree.root());
            iterator end   = iterator(&stree, stree.root(), true, true);

            for (iterator it = begin; it != end; ++it) {
                bins[stree.depth(*it)].push_back(stree.id(*it));
                node_counter++;
            }

        uint nts_number =0;

        for(uint i = bins.size()-1; i>=min_lrf; i--){
            auto bin_it = bins[i].begin();
            while (bin_it!= bins[i].end()){

                auto node = stree.inv_id(*bin_it);

                uint offset = stree.csa[stree.lb(node)];
                uint fac_length = stree.depth(node);

                bin_it++;

                if(stree.size(node)>=2){

                    //iterate over corresponding sa and find min and max
                    offset = stree.lb(node);
                    int min = stree.csa[offset];
                    int max = stree.csa[offset];
                    //int min_pos = offset;
                    //int max_pos = offset;
                    std::vector<int> beginning_positions;
                    for(uint c = 0;c<stree.size(node); c++){
                        int val = stree.csa[c+offset];
                        beginning_positions.push_back(val);
                        if(min > val){
                            min = val;
                         //   min_pos = offset+c;
                        }
                        if(max < val){
                            max = val;
                          //  max_pos = offset+c;
                        }

                    }
                    uint dif = max -min;
                    if(dif < stree.depth(node)){
                        continue;
                    }

                    std::sort(beginning_positions.begin(), beginning_positions.end());

                    //Add new rule

                    //and add new non-terminal symbols
                    std::vector<int> selected_bp = select_starting_positions(beginning_positions, stree.depth(node));
                    if(! (selected_bp.size() >=2) ){
                        continue;
                    }

                    //vector of text position, length
                    std::pair<uint,uint> rule = std::make_pair(selected_bp.at(0), fac_length);

                    dictionary.push_back(rule);

                    //iterate over selected pos, add non terminal symbols
                    for(auto bp_it = selected_bp.begin(); bp_it != selected_bp.end(); bp_it++){
                        //(position in text, non_terminal_symbol_number, length_of_symbol);
                        //typedef std::tuple<uint,uint,uint> non_term;
                        non_term nts = std::make_tuple(*bp_it, nts_number, fac_length);
                        nts_symbols.push_back(nts);
                        //typedef std::vector<non_term> non_terminal_symbols;
                        //mark as used
                        for(uint pos = 0; pos<=fac_length;pos++){
                            dead_positions[pos+ *bp_it] = 1;
                        }
                    }
                    nts_number++;
                }

            }

        }

        DLOG(INFO) << "sorting occurences";
        std::sort(nts_symbols.begin(), nts_symbols.end());

    }
};
}

}
<commit_msg>changes<commit_after>#pragma once

#include <vector>
#include <tuple>
#include <array>

#include <tudocomp/util.hpp>
#include <tudocomp/io.hpp>
#include <tudocomp/Algorithm.hpp>

#include <tudocomp/ds/IntVector.hpp>

#include <sdsl/cst_sct3.hpp>

namespace tdc {
namespace lfs {

template<uint min_lrf = 2 >
class SimSTStrategy : public Algorithm {
private:

    inline virtual std::vector<int> select_starting_positions(std::vector<int> starting_positions, int length){
        std::vector<int> selected_starting_positions;
        //select occurences greedily non-overlapping:
        selected_starting_positions.reserve(starting_positions.size());

        int last =  0-length;
        int current;
        for (auto it=starting_positions.begin(); it!=starting_positions.end(); ++it){

            current = *it;
            //DLOG(INFO) << "checking starting position: " << current << " length: " << top.first << "last " << last;
            if(last+length <= current && !dead_positions[current] && !dead_positions[current+length-1]){

                selected_starting_positions.push_back(current);
                last = current;

            }

        }
        return selected_starting_positions;
    }

    //(position in text, non_terminal_symbol_number, length_of_symbol);
    typedef std::tuple<uint,uint,uint> non_term;
    typedef std::vector<non_term> non_terminal_symbols;
    typedef std::vector<std::pair<uint,uint>> rules;

    typedef sdsl::cst_sct3<> cst_t;
    cst_t stree;

    BitVector dead_positions;

public:

    using Algorithm::Algorithm; //import constructor

    inline static Meta meta() {
        Meta m("lfs_comp", "sim_st");
        return m;
    }

    inline void compute_rules(io::InputView & input, rules & dictionary, non_terminal_symbols & nts_symbols){

        //build suffixtree
        DLOG(INFO)<<"build suffixtree";

        dead_positions = BitVector(input.size(), 0);

        typedef sdsl::bp_interval<long unsigned int> node_type;

        StatPhase::wrap("Constructing ST", [&]{
             sdsl::construct_im(stree, (const char*) input.data(), 1);
        });

        StatPhase::wrap("Computing LRF", [&]{

            //array of vectors for bins of nodes with string depth
            std::vector<std::vector<node_type> > bins;
            bins.resize(stree.size()+1);

            uint node_counter = 0;

            typedef sdsl::cst_bfs_iterator<cst_t> iterator;
            iterator begin = iterator(&stree, stree.root());
            iterator end   = iterator(&stree, stree.root(), true, true);

            StatPhase::wrap("Iterate over ST", [&]{

                for (iterator it = begin; it != end; ++it) {
                    bins[stree.depth(*it)].push_back(*it);
                    node_counter++;
                }
            });

            uint nts_number =0;
            StatPhase::wrap("Iterate over Node Bins", [&]{

                for(uint i = bins.size()-1; i>=min_lrf; i--){
                    auto bin_it = bins[i].begin();
                    while (bin_it!= bins[i].end()){

                        node_type node = *bin_it;

                        uint offset = stree.csa[stree.lb(node)];
                        uint fac_length = stree.depth(node);

                        bin_it++;

                        if(stree.size(node)>=2){

                            //iterate over corresponding sa and find min and max
                            offset = stree.lb(node);
                            int min = stree.csa[offset];
                            int max = stree.csa[offset];
                            //int min_pos = offset;
                            //int max_pos = offset;
                            std::vector<int> beginning_positions;
                            for(uint c = 0;c<stree.size(node); c++){
                                int val = stree.csa[c+offset];
                                beginning_positions.push_back(val);
                                if(min > val){
                                    min = val;
                                    //   min_pos = offset+c;
                                }
                                if(max < val){
                                    max = val;
                                    //  max_pos = offset+c;
                                }

                            }
                            uint dif = max -min;
                            if(dif < stree.depth(node)){
                                continue;
                            }

                            std::sort(beginning_positions.begin(), beginning_positions.end());

                            //Add new rule

                            //and add new non-terminal symbols
                            std::vector<int> selected_bp = select_starting_positions(beginning_positions, stree.depth(node));
                            if(! (selected_bp.size() >=2) ){
                                continue;
                            }

                            //vector of text position, length
                            std::pair<uint,uint> rule = std::make_pair(selected_bp.at(0), fac_length);

                            dictionary.push_back(rule);

                            //iterate over selected pos, add non terminal symbols
                            for(auto bp_it = selected_bp.begin(); bp_it != selected_bp.end(); bp_it++){
                                //(position in text, non_terminal_symbol_number, length_of_symbol);
                                //typedef std::tuple<uint,uint,uint> non_term;
                                non_term nts = std::make_tuple(*bp_it, nts_number, fac_length);
                                nts_symbols.push_back(nts);
                                //typedef std::vector<non_term> non_terminal_symbols;
                                //mark as used
                                for(uint pos = 0; pos<=fac_length;pos++){
                                    dead_positions[pos+ *bp_it] = 1;
                                }
                            }
                            nts_number++;
                        }

                    }

                }

            });
        });

        StatPhase::wrap("Sorting occurences", [&]{

            DLOG(INFO) << "sorting occurences";
            std::sort(nts_symbols.begin(), nts_symbols.end());

        });

    }
};
}

}
<|endoftext|>


<commit_before>#ifndef WIGWAG_DETAIL_CREATION_STORAGE_ADAPTER_HPP
#define WIGWAG_DETAIL_CREATION_STORAGE_ADAPTER_HPP

// Copyright (c) 2016, Dmitry Koplyarov <koplyarov.da@gmail.com>
//
// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
// provided that the above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#include <utility>

namespace wigwag {
namespace detail
{

	template < typename Storage_ >
	class creation_storage_adapter
	{
	private:
		Storage_		_s;

	public:
		creation_storage_adapter()
			: _s()
		{ }

		template < typename T_, typename... Args_ >
		void create(Args_&&... args)
		{ _s.template create<T_>(std::forward<Args_>(args)...); }

		explicit operator bool() const
		{ return _s.constructed(); }

		auto get_ptr() const -> decltype(_s.get_ptr())
		{ return _s.get_ptr(); }

		auto operator -> () const -> decltype(&*get_ptr())
		{ return &*get_ptr(); }
	};

}}

#endif
<commit_msg>Fixing g++-4.8 build<commit_after>#ifndef WIGWAG_DETAIL_CREATION_STORAGE_ADAPTER_HPP
#define WIGWAG_DETAIL_CREATION_STORAGE_ADAPTER_HPP

// Copyright (c) 2016, Dmitry Koplyarov <koplyarov.da@gmail.com>
//
// Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted,
// provided that the above copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
// IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
// WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

#include <utility>

namespace wigwag {
namespace detail
{

	template < typename Storage_ >
	class creation_storage_adapter
	{
	private:
		Storage_		_s;

	public:
		creation_storage_adapter()
			: _s()
		{ }

		template < typename T_, typename... Args_ >
		void create(Args_&&... args)
		{ _s.template create<T_>(std::forward<Args_>(args)...); }

		explicit operator bool() const
		{ return _s.constructed(); }

		auto get_ptr() const -> decltype(_s.get_ptr())
		{ return _s.get_ptr(); }

		auto operator -> () const -> decltype(&*_s.get_ptr())
		{ return &*_s.get_ptr(); }
	};

}}

#endif
<|endoftext|>


<commit_before>#include <sstream>
#include <cmath>

#include "Tools/Exception/exception.hpp"
#include "Tools/Math/Galois.hpp"

using namespace aff3ct;
using namespace aff3ct::tools;

template <typename I>
Galois<I>
::Galois(const int& N, const std::vector<I> p)
 : N(N), m((int)std::ceil(std::log2(N))), alpha_to(N +1), index_of(N +1), p(m +1, 0)
{
	if (N <= 0)
	{
		std::stringstream message;
		message << "'N' has to be greater than 0 ('N' = " << N << ").";
		throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (m != (int)std::ceil(std::log2(N +1)))
	{
		std::stringstream message;
		message << "'m' has to be equal to ceil(log2('N' +1)) ('m' = " << m << ", 'N' = " << N << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (m <= 1)
	{
		std::stringstream message;
		message << "'m' has to be strictly greater than 1 ('m' = " << m << ", 'N' = " << N << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (m > 20)
	{
		std::stringstream message;
		message << "'m' is supported until 20 ('m' = " << m << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (N != ((1 << m) -1))
	{
		std::stringstream message;
		message << "'N' has to be a power of 2 minus 1 ('N' = " << N << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (!p.empty() && (p.size() != static_cast<size_t>(m +1)))
	{
		std::stringstream message;
		message << "The order of the Galois primitive polynomial (p) must be m + 1 (= " << m +1 << ") .";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (p.empty())
		select_polynomial();
	else
		this->p = p;

	generate_gf();
}

template <typename I>
int Galois<I>
::get_N() const
{
	return N;
}

template <typename I>
int Galois<I>
::get_m() const
{
	return m;
}

template <typename I>
const std::vector<I>& Galois<I>
::get_alpha_to() const
{
	return alpha_to;
}

template <typename I>
const std::vector<I>& Galois<I>
::get_index_of() const
{
	return index_of;
}

template <typename I>
const std::vector<I>& Galois<I>
::get_p() const
{
	return p;
}

template <typename I>
void Galois<I>
::select_polynomial()
{
	p[0] = p[m] = 1;
	if      (m ==  2) p[1] = 1;
	else if (m ==  3) p[1] = 1;
	else if (m ==  4) p[1] = 1;
	else if (m ==  5) p[2] = 1;
	else if (m ==  6) p[1] = 1;
	else if (m ==  7) p[1] = 1;
	else if (m ==  8) p[4] = p[5] = p[6] = 1;
	else if (m ==  9) p[4] = 1;
	else if (m == 10) p[3] = 1;
	else if (m == 11) p[2] = 1;
	else if (m == 12) p[3] = p[4] = p[7] = 1;
	else if (m == 13) p[1] = p[3] = p[4] = 1;
	else if (m == 14) p[1] = p[11] = p[12] = 1;
	else if (m == 15) p[1] = 1;
	else if (m == 16) p[2] = p[3] = p[5] = 1;
	else if (m == 17) p[3] = 1;
	else if (m == 18) p[7] = 1;
	else if (m == 19) p[1] = p[5] = p[6] = 1;
	else if (m == 20) p[3] = 1;
}

template <typename I>
void Galois<I>
::generate_gf()
{
	int i, mask;

	mask = 1;
	alpha_to[m] = 0;
	for (i = 0; i < m; i++)
	{
		alpha_to[i] = mask;
		index_of[alpha_to[i]] = i;
		if (p[i] != 0)
			alpha_to[m] ^= mask;
		mask <<= 1;
	}
	index_of[alpha_to[m]] = m;
	mask >>= 1;
	for (i = m + 1; i < N; i++)
	{
		if (alpha_to[i - 1] >= mask)
			alpha_to[i] = alpha_to[m] ^ ((alpha_to[i - 1] ^ mask) << 1);
		else
			alpha_to[i] = alpha_to[i - 1] << 1;
		const auto idx = alpha_to[i];
		index_of[idx] = i;
	}
	index_of[0] = -1;
}

// ==================================================================================== explicit template instantiation
#include "Tools/types.h"
template class aff3ct::tools::Galois<B_8 >;
template class aff3ct::tools::Galois<B_16>;
template class aff3ct::tools::Galois<B_32>;
template class aff3ct::tools::Galois<B_64>;<commit_msg>Fix Galois field related segfault.<commit_after>#include <sstream>
#include <cmath>

#include "Tools/Exception/exception.hpp"
#include "Tools/Math/Galois.hpp"

using namespace aff3ct;
using namespace aff3ct::tools;

template <typename I>
Galois<I>
::Galois(const int& N, const std::vector<I> p)
 : N(N), m((int)std::ceil(std::log2(N))), alpha_to(N +1), index_of(N +1), p(m +1, 0)
{
	if (N <= 0)
	{
		std::stringstream message;
		message << "'N' has to be greater than 0 ('N' = " << N << ").";
		throw tools::invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (m != (int)std::ceil(std::log2(N +1)))
	{
		std::stringstream message;
		message << "'m' has to be equal to ceil(log2('N' +1)) ('m' = " << m << ", 'N' = " << N << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (m <= 1)
	{
		std::stringstream message;
		message << "'m' has to be strictly greater than 1 ('m' = " << m << ", 'N' = " << N << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (m > 20)
	{
		std::stringstream message;
		message << "'m' is supported until 20 ('m' = " << m << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if ((size_t)m > sizeof(I) * 8)
	{
		std::stringstream message;
		message << "'m' can't be higher than 'sizeof(I) * 8' ('m' = " << m << ", 'sizeof(I) * 8' = "
		        << (sizeof(I) * 8) << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (N != ((1 << m) -1))
	{
		std::stringstream message;
		message << "'N' has to be a power of 2 minus 1 ('N' = " << N << ").";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (!p.empty() && (p.size() != static_cast<size_t>(m +1)))
	{
		std::stringstream message;
		message << "The order of the Galois primitive polynomial (p) must be m + 1 (= " << m +1 << ") .";
		throw invalid_argument(__FILE__, __LINE__, __func__, message.str());
	}

	if (p.empty())
		select_polynomial();
	else
		this->p = p;

	generate_gf();
}

template <typename I>
int Galois<I>
::get_N() const
{
	return N;
}

template <typename I>
int Galois<I>
::get_m() const
{
	return m;
}

template <typename I>
const std::vector<I>& Galois<I>
::get_alpha_to() const
{
	return alpha_to;
}

template <typename I>
const std::vector<I>& Galois<I>
::get_index_of() const
{
	return index_of;
}

template <typename I>
const std::vector<I>& Galois<I>
::get_p() const
{
	return p;
}

template <typename I>
void Galois<I>
::select_polynomial()
{
	p[0] = p[m] = 1;
	if      (m ==  2) p[1] = 1;
	else if (m ==  3) p[1] = 1;
	else if (m ==  4) p[1] = 1;
	else if (m ==  5) p[2] = 1;
	else if (m ==  6) p[1] = 1;
	else if (m ==  7) p[1] = 1;
	else if (m ==  8) p[4] = p[5] = p[6] = 1;
	else if (m ==  9) p[4] = 1;
	else if (m == 10) p[3] = 1;
	else if (m == 11) p[2] = 1;
	else if (m == 12) p[3] = p[4] = p[7] = 1;
	else if (m == 13) p[1] = p[3] = p[4] = 1;
	else if (m == 14) p[1] = p[11] = p[12] = 1;
	else if (m == 15) p[1] = 1;
	else if (m == 16) p[2] = p[3] = p[5] = 1;
	else if (m == 17) p[3] = 1;
	else if (m == 18) p[7] = 1;
	else if (m == 19) p[1] = p[5] = p[6] = 1;
	else if (m == 20) p[3] = 1;
}

template <typename I>
void Galois<I>
::generate_gf()
{
	int i, mask;

	mask = 1;
	alpha_to[m] = 0;
	for (i = 0; i < m; i++)
	{
		alpha_to[i] = mask;
		index_of[alpha_to[i]] = i;
		if (p[i] != 0)
			alpha_to[m] ^= mask;
		mask <<= 1;
	}
	index_of[alpha_to[m]] = m;
	mask >>= 1;
	for (i = m + 1; i < N; i++)
	{
		if (alpha_to[i - 1] >= mask)
			alpha_to[i] = alpha_to[m] ^ ((alpha_to[i - 1] ^ mask) << 1);
		else
			alpha_to[i] = alpha_to[i - 1] << 1;
		const auto idx = alpha_to[i];
		index_of[idx] = i;
	}
	index_of[0] = -1;
}

// ==================================================================================== explicit template instantiation
#include "Tools/types.h"
template class aff3ct::tools::Galois<B_8 >;
template class aff3ct::tools::Galois<B_16>;
template class aff3ct::tools::Galois<B_32>;
template class aff3ct::tools::Galois<B_64>;<|endoftext|>


<commit_before>//===--- Multilib.cpp - Multilib Implementation ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Multilib.h"
#include "Tools.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>

using namespace clang::driver;
using namespace clang;
using namespace llvm::opt;

static void normalizePathSegment(std::string &Segment) {
  if (Segment.empty() || Segment == "/." || Segment == "/" || Segment == ".") {
    Segment = "";
  } else {
    if (StringRef(Segment).back() == '/')
      Segment.erase(Segment.begin() + Segment.size() - 1);
    if (StringRef(Segment).front() != '/')
      Segment = "/" + Segment;
  }
}

Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
                   StringRef IncludeSuffix)
    : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) {
  normalizePathSegment(this->GCCSuffix);
  normalizePathSegment(this->OSSuffix);
  normalizePathSegment(this->IncludeSuffix);
}

Multilib &Multilib::gccSuffix(StringRef S) {
  GCCSuffix = S;
  normalizePathSegment(GCCSuffix);
  return *this;
}

Multilib &Multilib::osSuffix(StringRef S) {
  OSSuffix = S;
  normalizePathSegment(OSSuffix);
  return *this;
}

Multilib &Multilib::includeSuffix(StringRef S) {
  IncludeSuffix = S;
  normalizePathSegment(IncludeSuffix);
  return *this;
}

void Multilib::print(raw_ostream &OS) const {
  assert(GCCSuffix.empty() || (StringRef(GCCSuffix).front() == '/'));
  if (GCCSuffix.empty())
    OS << ".";
  else {
    OS << StringRef(GCCSuffix).drop_front();
  }
  OS << ";";
  for (flags_list::const_iterator I = Flags.begin(), E = Flags.end(); I != E;
       ++I) {
    if (StringRef(*I).front() == '+')
      OS << "@" << I->substr(1);
  }
}

bool Multilib::isValid() const {
  llvm::StringMap<int> FlagSet;
  for (unsigned I = 0, N = Flags.size(); I != N; ++I) {
    StringRef Flag(Flags[I]);
    llvm::StringMap<int>::iterator SI = FlagSet.find(Flag.substr(1));

    assert(StringRef(Flag).front() == '+' || StringRef(Flag).front() == '-');

    if (SI == FlagSet.end())
      FlagSet[Flag.substr(1)] = I;
    else if (Flags[I] != Flags[SI->getValue()])
      return false;
  }
  return true;
}

bool Multilib::operator==(const Multilib &Other) const {
  // Check whether the flags sets match
  // allowing for the match to be order invariant
  llvm::StringSet<> MyFlags;
  for (flags_list::const_iterator I = Flags.begin(), E = Flags.end(); I != E;
       ++I) {
    MyFlags.insert(*I);
  }
  for (flags_list::const_iterator I = Other.Flags.begin(),
                                  E = Other.Flags.end();
       I != E; ++I) {
    if (MyFlags.find(*I) == MyFlags.end())
      return false;
  }

  if (osSuffix() != Other.osSuffix())
    return false;

  if (gccSuffix() != Other.gccSuffix())
    return false;

  if (includeSuffix() != Other.includeSuffix())
    return false;

  return true;
}

raw_ostream &clang::driver::operator<<(raw_ostream &OS, const Multilib &M) {
  M.print(OS);
  return OS;
}

MultilibSet &MultilibSet::Maybe(const Multilib &M) {
  Multilib Opposite;
  // Negate any '+' flags
  for (Multilib::flags_list::const_iterator I = M.flags().begin(),
                                            E = M.flags().end();
       I != E; ++I) {
    StringRef Flag(*I);
    if (Flag.front() == '+')
      Opposite.flags().push_back(("-" + Flag.substr(1)).str());
  }
  return Either(M, Opposite);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  return Either(Ms);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
                                 const Multilib &M3) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  Ms.push_back(M3);
  return Either(Ms);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
                                 const Multilib &M3, const Multilib &M4) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  Ms.push_back(M3);
  Ms.push_back(M4);
  return Either(Ms);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
                                 const Multilib &M3, const Multilib &M4,
                                 const Multilib &M5) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  Ms.push_back(M3);
  Ms.push_back(M4);
  Ms.push_back(M5);
  return Either(Ms);
}

static Multilib compose(const Multilib &Base, const Multilib &New) {
  SmallString<128> GCCSuffix;
  llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
  SmallString<128> OSSuffix;
  llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
  SmallString<128> IncludeSuffix;
  llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
                          New.includeSuffix());

  Multilib Composed(GCCSuffix.str(), OSSuffix.str(), IncludeSuffix.str());

  Multilib::flags_list &Flags = Composed.flags();

  Flags.insert(Flags.end(), Base.flags().begin(), Base.flags().end());
  Flags.insert(Flags.end(), New.flags().begin(), New.flags().end());

  return Composed;
}

MultilibSet &
MultilibSet::Either(const std::vector<Multilib> &MultilibSegments) {
  multilib_list Composed;

  if (Multilibs.empty())
    Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
                     MultilibSegments.end());
  else {
    for (std::vector<Multilib>::const_iterator NewI = MultilibSegments.begin(),
                                               NewE = MultilibSegments.end();
         NewI != NewE; ++NewI) {
      for (const_iterator BaseI = begin(), BaseE = end(); BaseI != BaseE;
           ++BaseI) {
        Multilib MO = compose(*BaseI, *NewI);
        if (MO.isValid())
          Composed.push_back(MO);
      }
    }

    Multilibs = Composed;
  }

  return *this;
}

MultilibSet &MultilibSet::FilterOut(const MultilibSet::FilterCallback &F) {
  filterInPlace(F, Multilibs);
  return *this;
}

MultilibSet &MultilibSet::FilterOut(std::string Regex) {
  class REFilter : public MultilibSet::FilterCallback {
    mutable llvm::Regex R;

  public:
    REFilter(std::string Regex) : R(Regex) {}
    bool operator()(const Multilib &M) const LLVM_OVERRIDE {
      std::string Error;
      if (!R.isValid(Error)) {
        llvm::errs() << Error;
        assert(false);
        return false;
      }
      return R.match(M.gccSuffix());
    }
  };

  REFilter REF(Regex);
  filterInPlace(REF, Multilibs);
  return *this;
}

void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }

void MultilibSet::combineWith(const MultilibSet &Other) {
  Multilibs.insert(Multilibs.end(), Other.begin(), Other.end());
}

bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
  class FilterFlagsMismatch : public MultilibSet::FilterCallback {
    llvm::StringMap<bool> FlagSet;

  public:
    FilterFlagsMismatch(const std::vector<std::string> &Flags) {
      // Stuff all of the flags into the FlagSet such that a true mappend
      // indicates the flag was enabled, and a false mappend indicates the
      // flag was disabled
      for (Multilib::flags_list::const_iterator I = Flags.begin(),
                                                E = Flags.end();
           I != E; ++I) {
        FlagSet[StringRef(*I).substr(1)] = isFlagEnabled(*I);
      }
    }
    bool operator()(const Multilib &M) const LLVM_OVERRIDE {
      for (Multilib::flags_list::const_iterator I = M.flags().begin(),
                                                E = M.flags().end();
           I != E; ++I) {
        StringRef Flag(*I);
        llvm::StringMap<bool>::const_iterator SI = FlagSet.find(Flag.substr(1));
        if (SI != FlagSet.end())
          if ((*SI).getValue() != isFlagEnabled(Flag))
            return true;
      }
      return false;
    }
  private:
    bool isFlagEnabled(StringRef Flag) const {
      char Indicator = Flag.front();
      assert(Indicator == '+' || Indicator == '-');
      return Indicator == '+';
    }
  };

  FilterFlagsMismatch FlagsMismatch(Flags);

  multilib_list Filtered = filterCopy(FlagsMismatch, Multilibs);

  if (Filtered.size() == 0) {
    return false;
  } else if (Filtered.size() == 1) {
    M = Filtered[0];
    return true;
  }

  // TODO: pick the "best" multlib when more than one is suitable
  assert(false);

  return false;
}

void MultilibSet::print(raw_ostream &OS) const {
  for (const_iterator I = begin(), E = end(); I != E; ++I)
    OS << *I << "\n";
}

MultilibSet::multilib_list
MultilibSet::filterCopy(const MultilibSet::FilterCallback &F,
                        const multilib_list &Ms) {
  multilib_list Copy(Ms);
  filterInPlace(F, Copy);
  return Copy;
}

namespace {
// Wrapper for FilterCallback to make operator() nonvirtual so it
// can be passed by value to std::remove_if
class FilterWrapper {
  const MultilibSet::FilterCallback &F;
public:
  FilterWrapper(const MultilibSet::FilterCallback &F) : F(F) {}
  bool operator()(const Multilib &M) const { return F(M); }
};
} // end anonymous namespace

void MultilibSet::filterInPlace(const MultilibSet::FilterCallback &F,
                                multilib_list &Ms) {
  Ms.erase(std::remove_if(Ms.begin(), Ms.end(), FilterWrapper(F)), Ms.end());
}

raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) {
  MS.print(OS);
  return OS;
}
<commit_msg>clang/lib/Driver/Multilib.cpp: Rewrite normalizePathSegment() to be tolerant dosish pathsep.<commit_after>//===--- Multilib.cpp - Multilib Implementation ---------------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Driver/Multilib.h"
#include "Tools.h"
#include "clang/Driver/Options.h"
#include "llvm/ADT/StringMap.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Regex.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/YAMLTraits.h"
#include <algorithm>

using namespace clang::driver;
using namespace clang;
using namespace llvm::opt;
using namespace llvm::sys;

/// normalize Segment to "/foo/bar" or "".
static void normalizePathSegment(std::string &Segment) {
  StringRef seg = Segment;

  // Prune trailing "/" or "./"
  while (1) {
    StringRef last = *--path::end(seg);
    if (last != ".")
      break;
    seg = path::parent_path(seg);
  }

  if (seg.empty() || seg == "/") {
    Segment = "";
    return;
  }

  // Add leading '/'
  if (seg.front() != '/') {
    Segment = "/" + seg.str();
  } else {
    Segment = seg;
  }
}

Multilib::Multilib(StringRef GCCSuffix, StringRef OSSuffix,
                   StringRef IncludeSuffix)
    : GCCSuffix(GCCSuffix), OSSuffix(OSSuffix), IncludeSuffix(IncludeSuffix) {
  normalizePathSegment(this->GCCSuffix);
  normalizePathSegment(this->OSSuffix);
  normalizePathSegment(this->IncludeSuffix);
}

Multilib &Multilib::gccSuffix(StringRef S) {
  GCCSuffix = S;
  normalizePathSegment(GCCSuffix);
  return *this;
}

Multilib &Multilib::osSuffix(StringRef S) {
  OSSuffix = S;
  normalizePathSegment(OSSuffix);
  return *this;
}

Multilib &Multilib::includeSuffix(StringRef S) {
  IncludeSuffix = S;
  normalizePathSegment(IncludeSuffix);
  return *this;
}

void Multilib::print(raw_ostream &OS) const {
  assert(GCCSuffix.empty() || (StringRef(GCCSuffix).front() == '/'));
  if (GCCSuffix.empty())
    OS << ".";
  else {
    OS << StringRef(GCCSuffix).drop_front();
  }
  OS << ";";
  for (flags_list::const_iterator I = Flags.begin(), E = Flags.end(); I != E;
       ++I) {
    if (StringRef(*I).front() == '+')
      OS << "@" << I->substr(1);
  }
}

bool Multilib::isValid() const {
  llvm::StringMap<int> FlagSet;
  for (unsigned I = 0, N = Flags.size(); I != N; ++I) {
    StringRef Flag(Flags[I]);
    llvm::StringMap<int>::iterator SI = FlagSet.find(Flag.substr(1));

    assert(StringRef(Flag).front() == '+' || StringRef(Flag).front() == '-');

    if (SI == FlagSet.end())
      FlagSet[Flag.substr(1)] = I;
    else if (Flags[I] != Flags[SI->getValue()])
      return false;
  }
  return true;
}

bool Multilib::operator==(const Multilib &Other) const {
  // Check whether the flags sets match
  // allowing for the match to be order invariant
  llvm::StringSet<> MyFlags;
  for (flags_list::const_iterator I = Flags.begin(), E = Flags.end(); I != E;
       ++I) {
    MyFlags.insert(*I);
  }
  for (flags_list::const_iterator I = Other.Flags.begin(),
                                  E = Other.Flags.end();
       I != E; ++I) {
    if (MyFlags.find(*I) == MyFlags.end())
      return false;
  }

  if (osSuffix() != Other.osSuffix())
    return false;

  if (gccSuffix() != Other.gccSuffix())
    return false;

  if (includeSuffix() != Other.includeSuffix())
    return false;

  return true;
}

raw_ostream &clang::driver::operator<<(raw_ostream &OS, const Multilib &M) {
  M.print(OS);
  return OS;
}

MultilibSet &MultilibSet::Maybe(const Multilib &M) {
  Multilib Opposite;
  // Negate any '+' flags
  for (Multilib::flags_list::const_iterator I = M.flags().begin(),
                                            E = M.flags().end();
       I != E; ++I) {
    StringRef Flag(*I);
    if (Flag.front() == '+')
      Opposite.flags().push_back(("-" + Flag.substr(1)).str());
  }
  return Either(M, Opposite);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  return Either(Ms);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
                                 const Multilib &M3) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  Ms.push_back(M3);
  return Either(Ms);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
                                 const Multilib &M3, const Multilib &M4) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  Ms.push_back(M3);
  Ms.push_back(M4);
  return Either(Ms);
}

MultilibSet &MultilibSet::Either(const Multilib &M1, const Multilib &M2,
                                 const Multilib &M3, const Multilib &M4,
                                 const Multilib &M5) {
  std::vector<Multilib> Ms;
  Ms.push_back(M1);
  Ms.push_back(M2);
  Ms.push_back(M3);
  Ms.push_back(M4);
  Ms.push_back(M5);
  return Either(Ms);
}

static Multilib compose(const Multilib &Base, const Multilib &New) {
  SmallString<128> GCCSuffix;
  llvm::sys::path::append(GCCSuffix, "/", Base.gccSuffix(), New.gccSuffix());
  SmallString<128> OSSuffix;
  llvm::sys::path::append(OSSuffix, "/", Base.osSuffix(), New.osSuffix());
  SmallString<128> IncludeSuffix;
  llvm::sys::path::append(IncludeSuffix, "/", Base.includeSuffix(),
                          New.includeSuffix());

  Multilib Composed(GCCSuffix.str(), OSSuffix.str(), IncludeSuffix.str());

  Multilib::flags_list &Flags = Composed.flags();

  Flags.insert(Flags.end(), Base.flags().begin(), Base.flags().end());
  Flags.insert(Flags.end(), New.flags().begin(), New.flags().end());

  return Composed;
}

MultilibSet &
MultilibSet::Either(const std::vector<Multilib> &MultilibSegments) {
  multilib_list Composed;

  if (Multilibs.empty())
    Multilibs.insert(Multilibs.end(), MultilibSegments.begin(),
                     MultilibSegments.end());
  else {
    for (std::vector<Multilib>::const_iterator NewI = MultilibSegments.begin(),
                                               NewE = MultilibSegments.end();
         NewI != NewE; ++NewI) {
      for (const_iterator BaseI = begin(), BaseE = end(); BaseI != BaseE;
           ++BaseI) {
        Multilib MO = compose(*BaseI, *NewI);
        if (MO.isValid())
          Composed.push_back(MO);
      }
    }

    Multilibs = Composed;
  }

  return *this;
}

MultilibSet &MultilibSet::FilterOut(const MultilibSet::FilterCallback &F) {
  filterInPlace(F, Multilibs);
  return *this;
}

MultilibSet &MultilibSet::FilterOut(std::string Regex) {
  class REFilter : public MultilibSet::FilterCallback {
    mutable llvm::Regex R;

  public:
    REFilter(std::string Regex) : R(Regex) {}
    bool operator()(const Multilib &M) const LLVM_OVERRIDE {
      std::string Error;
      if (!R.isValid(Error)) {
        llvm::errs() << Error;
        assert(false);
        return false;
      }
      return R.match(M.gccSuffix());
    }
  };

  REFilter REF(Regex);
  filterInPlace(REF, Multilibs);
  return *this;
}

void MultilibSet::push_back(const Multilib &M) { Multilibs.push_back(M); }

void MultilibSet::combineWith(const MultilibSet &Other) {
  Multilibs.insert(Multilibs.end(), Other.begin(), Other.end());
}

bool MultilibSet::select(const Multilib::flags_list &Flags, Multilib &M) const {
  class FilterFlagsMismatch : public MultilibSet::FilterCallback {
    llvm::StringMap<bool> FlagSet;

  public:
    FilterFlagsMismatch(const std::vector<std::string> &Flags) {
      // Stuff all of the flags into the FlagSet such that a true mappend
      // indicates the flag was enabled, and a false mappend indicates the
      // flag was disabled
      for (Multilib::flags_list::const_iterator I = Flags.begin(),
                                                E = Flags.end();
           I != E; ++I) {
        FlagSet[StringRef(*I).substr(1)] = isFlagEnabled(*I);
      }
    }
    bool operator()(const Multilib &M) const LLVM_OVERRIDE {
      for (Multilib::flags_list::const_iterator I = M.flags().begin(),
                                                E = M.flags().end();
           I != E; ++I) {
        StringRef Flag(*I);
        llvm::StringMap<bool>::const_iterator SI = FlagSet.find(Flag.substr(1));
        if (SI != FlagSet.end())
          if ((*SI).getValue() != isFlagEnabled(Flag))
            return true;
      }
      return false;
    }
  private:
    bool isFlagEnabled(StringRef Flag) const {
      char Indicator = Flag.front();
      assert(Indicator == '+' || Indicator == '-');
      return Indicator == '+';
    }
  };

  FilterFlagsMismatch FlagsMismatch(Flags);

  multilib_list Filtered = filterCopy(FlagsMismatch, Multilibs);

  if (Filtered.size() == 0) {
    return false;
  } else if (Filtered.size() == 1) {
    M = Filtered[0];
    return true;
  }

  // TODO: pick the "best" multlib when more than one is suitable
  assert(false);

  return false;
}

void MultilibSet::print(raw_ostream &OS) const {
  for (const_iterator I = begin(), E = end(); I != E; ++I)
    OS << *I << "\n";
}

MultilibSet::multilib_list
MultilibSet::filterCopy(const MultilibSet::FilterCallback &F,
                        const multilib_list &Ms) {
  multilib_list Copy(Ms);
  filterInPlace(F, Copy);
  return Copy;
}

namespace {
// Wrapper for FilterCallback to make operator() nonvirtual so it
// can be passed by value to std::remove_if
class FilterWrapper {
  const MultilibSet::FilterCallback &F;
public:
  FilterWrapper(const MultilibSet::FilterCallback &F) : F(F) {}
  bool operator()(const Multilib &M) const { return F(M); }
};
} // end anonymous namespace

void MultilibSet::filterInPlace(const MultilibSet::FilterCallback &F,
                                multilib_list &Ms) {
  Ms.erase(std::remove_if(Ms.begin(), Ms.end(), FilterWrapper(F)), Ms.end());
}

raw_ostream &clang::driver::operator<<(raw_ostream &OS, const MultilibSet &MS) {
  MS.print(OS);
  return OS;
}
<|endoftext|>


<commit_before>/**
 * A GPX factory. For each coordinate in the GPX file, it will signal
 * listeners to "available" with a double time and a fr::coordinates::
 * lat_long point. This could be used to build a vector or something.
 *
 * I'm writing this to some sample data dumped by the Mytracks android
 * application, so I might miss some stuff from the standard.
 */

#ifndef _HPP_GPX_FACTORY
#define _HPP_GPX_FACTORY

#include <boost/signals/signal2.hpp>
#include "engine.hpp"
#include <fstream>
#include <iostream>
#include <iomanip>
#include "lat_long.hpp"
#include "node_engine.hpp"
#include "string_converts.hpp"
#include <sys/time.h>
#include <time.h>
#include "timezone_manager.hpp"
#include "xml_node.hpp"

namespace fr {

  namespace data {

    class gpx_factory {
    private:

      std::string gpx_filename;
      const std::string trkpt = std::string("trkpt");
      const std::string ele = std::string("ele");
      const std::string node_time = std::string("time");
      const std::string lat = std::string("lat");
      const std::string lon = std::string("lon");

    public:
      gpx_factory(const std::string &filename) : gpx_filename(filename)
      {
      }

      ~gpx_factory()
      {
      }

      // available provides timestamp (as a double) and a lat_long
      boost::signals2::signal<void(double, const fr::coordinates::lat_long &)> available;

      // Reads in the file and starts spitting out points through
      // available
      void process()
      {
	// GPX coordinates use GMT (Well, UTC, but close enough.)
	fr::time::timezone_manager tz("GMT");
	cppxml::node_engine engine(gpx_filename);
	cppxml::node_pointer document;
	document = engine.get_document();
	cppxml::child_vector xml_points = document->find_children(trkpt);
	cppxml::child_vector::iterator i;
	fr::time::string_to<double> string_to_double;
	fr::time::string_to<timeval> string_to_time;
	for (i = xml_points.begin(); i != xml_points.end(); ++i) {
	  std::shared_ptr<std::string> lat_string, lon_string;
	  double point_lat, point_lon, time_at, elevation;
	  timeval timeval_at;
	  time_at = 0.0;
	  elevation = 0.0;
	  // Dereference the iterator to get at the shared pointer
	  lat_string = (*i)->find_attribute(lat);
	  lon_string = (*i)->find_attribute(lon);
	  if (nullptr == lat_string.get()) {
	    throw std::string("Error: Missing lat attribute in gpx node.");
	  }
	  if (nullptr == lon_string.get()) {
	    throw std::string("Error: Missing lon attribute in gpx node.");
	  }
	  point_lat = string_to_double(*lat_string);
	  point_lon = string_to_double(*lon_string);
	  cppxml::node_pointer ele_node = (*i)->find_child(ele);
	  if (nullptr != ele_node.get()) {
	    std::string ele_string = ele_node->get_text();
	    if (ele_string.length() > 0) {
	      elevation = string_to_double(ele_string);
	    }
	  }
	  cppxml::node_pointer time_node = (*i)->find_child(node_time);
	  if (nullptr != time_node.get()) {
	    std::string time_string = time_node->get_text();
	    if (time_string.length() > 0) {
	      timeval_at = string_to_time(time_string);

	      time_at = (double) timeval_at.tv_sec + ((double) timeval_at.tv_usec / 1000000.0);
	    }
	  }
	  fr::coordinates::lat_long ll(point_lat, point_lon, elevation);

	  available(time_at, ll);
	}
      }
    };

  }
}

#endif

<commit_msg>Suppose I should add my copyright message...<commit_after>/**
 * A GPX factory. For each coordinate in the GPX file, it will signal
 * listeners to "available" with a double time and a fr::coordinates::
 * lat_long point. This could be used to build a vector or something.
 *
 * I'm writing this to some sample data dumped by the Mytracks android
 * application, so I might miss some stuff from the standard.
 *
 * Copyright 2013 Bruce Ide
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

#ifndef _HPP_GPX_FACTORY
#define _HPP_GPX_FACTORY

#include <boost/signals/signal2.hpp>
#include "engine.hpp"
#include <fstream>
#include <iostream>
#include <iomanip>
#include "lat_long.hpp"
#include "node_engine.hpp"
#include "string_converts.hpp"
#include <sys/time.h>
#include <time.h>
#include "timezone_manager.hpp"
#include "xml_node.hpp"

namespace fr {

  namespace data {

    class gpx_factory {
    private:

      std::string gpx_filename;
      const std::string trkpt = std::string("trkpt");
      const std::string ele = std::string("ele");
      const std::string node_time = std::string("time");
      const std::string lat = std::string("lat");
      const std::string lon = std::string("lon");

    public:
      gpx_factory(const std::string &filename) : gpx_filename(filename)
      {
      }

      ~gpx_factory()
      {
      }

      // available provides timestamp (as a double) and a lat_long
      boost::signals2::signal<void(double, const fr::coordinates::lat_long &)> available;

      // Reads in the file and starts spitting out points through
      // available
      void process()
      {
	// GPX coordinates use GMT (Well, UTC, but close enough.)
	fr::time::timezone_manager tz("GMT");
	cppxml::node_engine engine(gpx_filename);
	cppxml::node_pointer document;
	document = engine.get_document();
	cppxml::child_vector xml_points = document->find_children(trkpt);
	cppxml::child_vector::iterator i;
	fr::time::string_to<double> string_to_double;
	fr::time::string_to<timeval> string_to_time;
	for (i = xml_points.begin(); i != xml_points.end(); ++i) {
	  std::shared_ptr<std::string> lat_string, lon_string;
	  double point_lat, point_lon, time_at, elevation;
	  timeval timeval_at;
	  time_at = 0.0;
	  elevation = 0.0;
	  // Dereference the iterator to get at the shared pointer
	  lat_string = (*i)->find_attribute(lat);
	  lon_string = (*i)->find_attribute(lon);
	  if (nullptr == lat_string.get()) {
	    throw std::string("Error: Missing lat attribute in gpx node.");
	  }
	  if (nullptr == lon_string.get()) {
	    throw std::string("Error: Missing lon attribute in gpx node.");
	  }
	  point_lat = string_to_double(*lat_string);
	  point_lon = string_to_double(*lon_string);
	  cppxml::node_pointer ele_node = (*i)->find_child(ele);
	  if (nullptr != ele_node.get()) {
	    std::string ele_string = ele_node->get_text();
	    if (ele_string.length() > 0) {
	      elevation = string_to_double(ele_string);
	    }
	  }
	  cppxml::node_pointer time_node = (*i)->find_child(node_time);
	  if (nullptr != time_node.get()) {
	    std::string time_string = time_node->get_text();
	    if (time_string.length() > 0) {
	      timeval_at = string_to_time(time_string);

	      time_at = (double) timeval_at.tv_sec + ((double) timeval_at.tv_usec / 1000000.0);
	    }
	  }
	  fr::coordinates::lat_long ll(point_lat, point_lon, elevation);

	  available(time_at, ll);
	}
      }
    };

  }
}

#endif

<|endoftext|>


<commit_before>/*
 * Copyright 2012-2013 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi 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.
 *
 * BrewPi 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 BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Platform.h"
#include "Brewpi.h"
#include "Ticks.h"
#include "TempControl.h"
#include "PiLink.h"
#include "TempSensor.h"
#include "TempSensorMock.h"
#include "TempSensorExternal.h"
#include "ActuatorMocks.h"
#include "Sensor.h"
#include "SettingsManager.h"
#include "UI.h"

#if BREWPI_SIMULATE
	#include "Simulator.h"
#endif

// global class objects static and defined in class cpp and h files

// instantiate and configure the sensors, actuators and controllers we want to use

void setup(void);
void loop (void);

/* Configure the counter and delay timer. The actual type of these will vary depending upon the environment.
 * They are non-virtual to keep code size minimal, so typedefs and preprocessing are used to select the actual compile-time type used. */
TicksImpl ticks = TicksImpl(TICKS_IMPL_CONFIG);
DelayImpl wait = DelayImpl(DELAY_IMPL_CONFIG);

UI ui;

SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);

void setup()
{
    boardInit();
    bool resetEeprom = platform_init();
    eepromManager.init();
    if (resetEeprom) {
        eepromManager.initializeEeprom();
    }
	ui.init();

    uint32_t start = ticks.millis();
    uint32_t delay = ui.showStartupPage();

    piLink.init();
    // flush any waiting input.
    // Linux can put garbage in the serial input buffer during connect
    piLink.flushInput();

    logDebug("started");

    while (ticks.millis()-start <= delay) {
        ui.ticks();
    }

    // initialize OneWire
    if (!primaryOneWireBus.init()) {
        logError(ERROR_ONEWIRE_INIT_FAILED);
    }

#if BREWPI_SIMULATE
	simulator.step();
	// initialize the filters with the assigned initial temp value
	//tempControl.beerSensor->init();
	//tempControl.fridgeSensor->init();
#endif
    settingsManager.loadSettings();

    control.update();

    WiFi.connect(WIFI_CONNECT_SKIP_LISTEN);

	logDebug("init complete");
}

void brewpiLoop(void)
{
	static unsigned long lastUpdate = -1000; // init at -1000 to update immediately
    ui.ticks();

    if(!ui.inStartup() && (ticks.millis() - lastUpdate >= (1000))) { //update settings every second
		lastUpdate = ticks.millis();
		control.update();
        ui.update();
    }

    control.fastUpdate(); // update actuators as often as possible for PWM

    //listen for incoming serial connections while waiting to update
    piLink.receive();
}

void loop() {
	#if BREWPI_SIMULATE
	simulateLoop();
	#else
	brewpiLoop();
	#endif
}

<commit_msg>connect to particle cloud, this could help keep wifi alive<commit_after>/*
 * Copyright 2012-2013 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi 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.
 *
 * BrewPi 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 BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Platform.h"
#include "Brewpi.h"
#include "Ticks.h"
#include "TempControl.h"
#include "PiLink.h"
#include "TempSensor.h"
#include "TempSensorMock.h"
#include "TempSensorExternal.h"
#include "ActuatorMocks.h"
#include "Sensor.h"
#include "SettingsManager.h"
#include "UI.h"

#if BREWPI_SIMULATE
	#include "Simulator.h"
#endif

// global class objects static and defined in class cpp and h files

// instantiate and configure the sensors, actuators and controllers we want to use

void setup(void);
void loop (void);

/* Configure the counter and delay timer. The actual type of these will vary depending upon the environment.
 * They are non-virtual to keep code size minimal, so typedefs and preprocessing are used to select the actual compile-time type used. */
TicksImpl ticks = TicksImpl(TICKS_IMPL_CONFIG);
DelayImpl wait = DelayImpl(DELAY_IMPL_CONFIG);

UI ui;

SYSTEM_MODE(MANUAL);
SYSTEM_THREAD(ENABLED);

void setup()
{
    boardInit();
    bool resetEeprom = platform_init();
    eepromManager.init();
    if (resetEeprom) {
        eepromManager.initializeEeprom();
    }
	ui.init();

    uint32_t start = ticks.millis();
    uint32_t delay = ui.showStartupPage();

    piLink.init();
    // flush any waiting input.
    // Linux can put garbage in the serial input buffer during connect
    piLink.flushInput();

    logDebug("started");

    while (ticks.millis()-start <= delay) {
        ui.ticks();
    }

    // initialize OneWire
    if (!primaryOneWireBus.init()) {
        logError(ERROR_ONEWIRE_INIT_FAILED);
    }

#if BREWPI_SIMULATE
	simulator.step();
	// initialize the filters with the assigned initial temp value
	//tempControl.beerSensor->init();
	//tempControl.fridgeSensor->init();
#endif
    settingsManager.loadSettings();

    control.update();

    if(WiFi.hasCredentials()){
        Particle.connect();
    }

	logDebug("init complete");
}

void brewpiLoop(void)
{
	static unsigned long lastUpdate = -1000; // init at -1000 to update immediately
    ui.ticks();

    if(!ui.inStartup() && (ticks.millis() - lastUpdate >= (1000))) { //update settings every second
		lastUpdate = ticks.millis();
		control.update();
        ui.update();
    }

    control.fastUpdate(); // update actuators as often as possible for PWM

    //listen for incoming serial connections while waiting to update
    piLink.receive();

    // System thread enable mode is used so this is not necessary to keep the cloud
    // connection is alive, but it is necessary to handle the system events, including
    // the button, so it's here, regardless of the connection state.
    Particle.process();
}

void loop() {
	#if BREWPI_SIMULATE
	simulateLoop();
	#else
	brewpiLoop();
	#endif
}

<|endoftext|>