<commit_before>//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements an _extremely_ simple interprocedural constant
// propagation pass.  It could certainly be improved in many different ways,
// like using a worklist.  This pass makes arguments dead, but does not remove
// them.  The existing dead argument elimination pass should be run after this
// to clean up the mess.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Constants.h"
#include "llvm/Support/CallSite.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;

namespace {
  Statistic<> NumArgumentsProped("ipconstprop",
                                 "Number of args turned into constants");

  /// IPCP - The interprocedural constant propagation pass
  ///
  struct IPCP : public ModulePass {
    bool runOnModule(Module &M);
  private:
    bool processFunction(Function &F);
  };
  RegisterOpt<IPCP> X("ipconstprop", "Interprocedural constant propagation");
}

ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }

bool IPCP::runOnModule(Module &M) {
  bool Changed = false;
  bool LocalChange = true;

  // FIXME: instead of using smart algorithms, we just iterate until we stop
  // making changes.
  while (LocalChange) {
    LocalChange = false;
    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
      if (!I->isExternal() && I->hasInternalLinkage())
        LocalChange |= processFunction(*I);
    Changed |= LocalChange;
  }
  return Changed;
}

/// processFunction - Look at all uses of the specified function.  If all uses
/// are direct call sites, and all pass a particular constant in for an
/// argument, propagate that constant in as the argument.
///
bool IPCP::processFunction(Function &F) {
  if (F.aempty() || F.use_empty()) return false;  // No arguments?  Early exit.

  // Delete any klingons.
  F.removeDeadConstantUsers();

  std::vector<std::pair<Constant*, bool> > ArgumentConstants;
  ArgumentConstants.resize(F.asize());

  unsigned NumNonconstant = 0;

  for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
    if (!isa<Instruction>(*I))
      return false;  // Used by a non-instruction, do not transform
    else {
      CallSite CS = CallSite::get(cast<Instruction>(*I));
      if (CS.getInstruction() == 0 ||
          CS.getCalledFunction() != &F)
        return false;  // Not a direct call site?

      // Check out all of the potentially constant arguments
      CallSite::arg_iterator AI = CS.arg_begin();
      Function::aiterator Arg = F.abegin();
      for (unsigned i = 0, e = ArgumentConstants.size(); i != e;
           ++i, ++AI, ++Arg) {
        if (*AI == &F) return false;  // Passes the function into itself

        if (!ArgumentConstants[i].second) {
          if (Constant *C = dyn_cast<Constant>(*AI)) {
            if (!ArgumentConstants[i].first)
              ArgumentConstants[i].first = C;
            else if (ArgumentConstants[i].first != C) {
              // Became non-constant
              ArgumentConstants[i].second = true;
              ++NumNonconstant;
              if (NumNonconstant == ArgumentConstants.size()) return false;
            }
          } else if (*AI != &*Arg) {    // Ignore recursive calls with same arg
            // This is not a constant argument.  Mark the argument as
            // non-constant.
            ArgumentConstants[i].second = true;
            ++NumNonconstant;
            if (NumNonconstant == ArgumentConstants.size()) return false;
          }
        }
      }
    }

  // If we got to this point, there is a constant argument!
  assert(NumNonconstant != ArgumentConstants.size());
  Function::aiterator AI = F.abegin();
  bool MadeChange = false;
  for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI)
    // Do we have a constant argument!?
    if (!ArgumentConstants[i].second && !AI->use_empty()) {
      assert(ArgumentConstants[i].first && "Unknown constant value!");
      Value *V = ArgumentConstants[i].first;
      AI->replaceAllUsesWith(V);
      ++NumArgumentsProped;
      MadeChange = true;
    }
  return MadeChange;
}

<commit_msg>Fix bug: IPConstantProp/deadarg.ll<commit_after>//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This pass implements an _extremely_ simple interprocedural constant
// propagation pass.  It could certainly be improved in many different ways,
// like using a worklist.  This pass makes arguments dead, but does not remove
// them.  The existing dead argument elimination pass should be run after this
// to clean up the mess.
//
//===----------------------------------------------------------------------===//

#include "llvm/Transforms/IPO.h"
#include "llvm/Module.h"
#include "llvm/Pass.h"
#include "llvm/Constants.h"
#include "llvm/Support/CallSite.h"
#include "llvm/ADT/Statistic.h"
using namespace llvm;

namespace {
  Statistic<> NumArgumentsProped("ipconstprop",
                                 "Number of args turned into constants");

  /// IPCP - The interprocedural constant propagation pass
  ///
  struct IPCP : public ModulePass {
    bool runOnModule(Module &M);
  private:
    bool processFunction(Function &F);
  };
  RegisterOpt<IPCP> X("ipconstprop", "Interprocedural constant propagation");
}

ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }

bool IPCP::runOnModule(Module &M) {
  bool Changed = false;
  bool LocalChange = true;

  // FIXME: instead of using smart algorithms, we just iterate until we stop
  // making changes.
  while (LocalChange) {
    LocalChange = false;
    for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
      if (!I->isExternal() && I->hasInternalLinkage())
        LocalChange |= processFunction(*I);
    Changed |= LocalChange;
  }
  return Changed;
}

/// processFunction - Look at all uses of the specified function.  If all uses
/// are direct call sites, and all pass a particular constant in for an
/// argument, propagate that constant in as the argument.
///
bool IPCP::processFunction(Function &F) {
  if (F.aempty() || F.use_empty()) return false;  // No arguments?  Early exit.

  // Delete any klingons.
  F.removeDeadConstantUsers();

  std::vector<std::pair<Constant*, bool> > ArgumentConstants;
  ArgumentConstants.resize(F.asize());

  unsigned NumNonconstant = 0;

  for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
    if (!isa<Instruction>(*I))
      return false;  // Used by a non-instruction, do not transform
    else {
      CallSite CS = CallSite::get(cast<Instruction>(*I));
      if (CS.getInstruction() == 0 ||
          CS.getCalledFunction() != &F)
        return false;  // Not a direct call site?

      // Check out all of the potentially constant arguments
      CallSite::arg_iterator AI = CS.arg_begin();
      Function::aiterator Arg = F.abegin();
      for (unsigned i = 0, e = ArgumentConstants.size(); i != e;
           ++i, ++AI, ++Arg) {
        if (*AI == &F) return false;  // Passes the function into itself

        if (!ArgumentConstants[i].second) {
          if (Constant *C = dyn_cast<Constant>(*AI)) {
            if (!ArgumentConstants[i].first)
              ArgumentConstants[i].first = C;
            else if (ArgumentConstants[i].first != C) {
              // Became non-constant
              ArgumentConstants[i].second = true;
              ++NumNonconstant;
              if (NumNonconstant == ArgumentConstants.size()) return false;
            }
          } else if (*AI != &*Arg) {    // Ignore recursive calls with same arg
            // This is not a constant argument.  Mark the argument as
            // non-constant.
            ArgumentConstants[i].second = true;
            ++NumNonconstant;
            if (NumNonconstant == ArgumentConstants.size()) return false;
          }
        }
      }
    }

  // If we got to this point, there is a constant argument!
  assert(NumNonconstant != ArgumentConstants.size());
  Function::aiterator AI = F.abegin();
  bool MadeChange = false;
  for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI)
    // Do we have a constant argument!?
    if (!ArgumentConstants[i].second) {
      Value *V = ArgumentConstants[i].first;
      if (V == 0) V = UndefValue::get(AI->getType());
      AI->replaceAllUsesWith(V);
      ++NumArgumentsProped;
      MadeChange = true;
    }
  return MadeChange;
}

<|endoftext|>


<commit_before>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <wtypes.h>
#include "file.h"
#include "functions.h"

struct valueElement {
    std::string Name_;
    DATE Time_;
    float Value1_;
    float Value2_;
    float Value3_;
    bool status;
};

struct dataPoint {
    std::string SpineBase_;
    std::string SpineMid_;
    std::string Neck_;
    std::string Head_;
    std::string ShoulderLeft_;
    std::string ElbowLeft_;
    std::string WristLeft_;
    std::string HandLeft_;
    std::string ShoulderRight_;
    std::string ElbowRight_;
    std::string WristRight_;
    std::string HandRight_;
    std::string HipLeft_;
    std::string KneeLeft_;
    std::string AnkleLeft_;
    std::string FootLeft_;
    std::string HipRight_;
    std::string KneeRight_;
    std::string AnkleRight_;
    std::string FootRight_;
    std::string SpineShoulder_;
    std::string HandTipLeft_;
    std::string ThumbLeft_;
    std::string HandTipRight_;
    std::string ThumbRight_;
};

void file::readFile() {
    std::string line;
    std::vector<std::string> lineVector;
    std::vector<std::vector<std::string>> dataVector;
    char delimiter = ';';
    std::ifstream myFile("C:\\Users\\Birdi\\CLionProjects\\skeletonAuthorization\\data\\skeleton2Data.txt");
    int lineAmount = 0;
    if (myFile.is_open()) {
        while (getline (myFile,line)) {
            lineAmount +=1;
            dataVector.push_back(
                    splitString(line, delimiter)
            );
        }
        myFile.close();
    }
    std::cout << lineAmount << std::endl;

    std::cout << dataVector[0][0] << std::endl;

}
<commit_msg>skeleton<commit_after>#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <wtypes.h>
#include "file.h"
#include "functions.h"

struct valueElement {
    std::string Name_;
    DATE Time_;
    float Value1_;
    float Value2_;
    float Value3_;
    bool status;
};

struct dataPoint {
    std::string SpineBase_;
    std::string SpineMid_;
    std::string Neck_;
    std::string Head_;
    std::string ShoulderLeft_;
    std::string ElbowLeft_;
    std::string WristLeft_;
    std::string HandLeft_;
    std::string ShoulderRight_;
    std::string ElbowRight_;
    std::string WristRight_;
    std::string HandRight_;
    std::string HipLeft_;
    std::string KneeLeft_;
    std::string AnkleLeft_;
    std::string FootLeft_;
    std::string HipRight_;
    std::string KneeRight_;
    std::string AnkleRight_;
    std::string FootRight_;
    std::string SpineShoulder_;
    std::string HandTipLeft_;
    std::string ThumbLeft_;
    std::string HandTipRight_;
    std::string ThumbRight_;
};

void file::readFile() {
    std::string line;
    std::vector<std::string> lineVector;
    std::vector<std::vector<std::string>> dataVector;
    std::vector<dataPoint> bodyData;
    char delimiter = ';';
    //std::ifstream myFile("C:\\Users\\Birdi\\CLionProjects\\skeletonAuthorization\\data\\skeletonDataOneBody.txt");
    std::ifstream myFile("C:\\Users\\Christoph\\CLionProjects\\skeletonAuthorization\\data\\skeletonDataOneBody.txt");
    int lineAmount = 0;
    if (myFile.is_open()) {
        while (getline (myFile,line)) {
            lineAmount +=1;
            dataVector.push_back(
                    splitString(line, delimiter)
            );
        }
        myFile.close();
    }

    std::cout << lineAmount << std::endl;
    std::cout << "==============================" << std::endl;

    int dataTag;
    int bodyTag;
    for (bodyTag = 0; bodyTag < lineAmount; bodyTag++) {
        for (dataTag = 0; dataTag < 24; dataTag++ ) {
            std::cout << dataVector[bodyTag][dataTag] << " - ";
        }
        std::cout << "==============================" << std::endl;
    }

    // std::cout << dataVector[0][0] << std::endl;

}
<|endoftext|>


<commit_before>#ifdef _WIN32
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif

#ifndef FS_CASE_SENSITIVE
#ifdef _WIN32
#define FS_CASE_SENSITIVE 0
#else
#define FS_CASE_SENSITIVE 1
#endif
#endif

#include <iostream>
#include <fstream>
#include <cctype>
#include <algorithm>
#include <sys/stat.h>
#include "file.hpp"
#include "context.hpp"
#include "utf8_string.hpp"
#include "sass2scss.h"

#ifdef _WIN32
#include <windows.h>
#endif

namespace Sass {
  namespace File {
    using namespace std;

    // no physical check on filesystem
    // only a logical cleanup of a path
    string make_canonical_path (string path)
    {

      // declarations
      size_t pos;

      #ifdef _WIN32
        //convert backslashes to forward slashes
        replace(path.begin(), path.end(), '\\', '/');
      #endif

      pos = 0; // remove all self references inside the path string
      while((pos = path.find("/./", pos)) != string::npos) path.erase(pos, 2);

      pos = 0; // remove all leading and trailing self references
      while(path.length() > 1 && path.substr(0, 2) == "./") path.erase(0, 2);
      while((pos = path.length()) > 1 && path.substr(pos - 2) == "/.") path.erase(pos - 2);

      pos = 0; // collapse multiple delimiters into a single one
      while((pos = path.find("//", pos)) != string::npos) path.erase(pos, 1);

      return path;

    }

    size_t find_last_folder_separator(const string& path, size_t limit = string::npos)
    {
      size_t pos = string::npos;
      size_t pos_p = path.find_last_of('/', limit);
      #ifdef _WIN32
      size_t pos_w = path.find_last_of('\\', limit);
      #else
      size_t pos_w = string::npos;
      #endif
      if (pos_p != string::npos && pos_w != string::npos) {
        pos = max(pos_p, pos_w);
      }
      else if (pos_p != string::npos) {
        pos = pos_p;
      }
      else {
        pos = pos_w;
      }
      return pos;
    }

    string base_name(string path)
    {
      size_t pos = find_last_folder_separator(path);
      if (pos == string::npos) return path;
      else                     return path.substr(pos+1);
    }

    string dir_name(string path)
    {
      size_t pos = find_last_folder_separator(path);
      if (pos == string::npos) return "";
      else                     return path.substr(0, pos+1);
    }

    string join_paths(string l, string r)
    {
      if (l.empty()) return r;
      if (r.empty()) return l;
      if (is_absolute_path(r)) return r;

      if (l[l.length()-1] != '/') l += '/';

      while ((r.length() > 3) && ((r.substr(0, 3) == "../") || (r.substr(0, 3)) == "..\\")) {
        r = r.substr(3);
        size_t pos = find_last_folder_separator(l, l.length() - 2);
        l = l.substr(0, pos == string::npos ? pos : pos + 1);
      }

      return l + r;
    }

    bool is_absolute_path(const string& path)
    {
      if (path[0] == '/') return true;
      // TODO: UN-HACKIFY THIS
      #ifdef _WIN32
      if (path.length() >= 2 && isalpha(path[0]) && path[1] == ':') return true;
      #endif
      return false;
    }

    string make_absolute_path(const string& path, const string& cwd)
    {
      return make_canonical_path((is_absolute_path(path) ? path : join_paths(cwd, path)));
    }

    string resolve_relative_path(const string& uri, const string& base, const string& cwd)
    {

      string absolute_uri = make_absolute_path(uri, cwd);
      string absolute_base = make_absolute_path(base, cwd);

      string stripped_uri = "";
      string stripped_base = "";

      size_t index = 0;
      size_t minSize = min(absolute_uri.size(), absolute_base.size());
      for (size_t i = 0; i < minSize; ++i) {
        #ifdef FS_CASE_SENSITIVE
          if (absolute_uri[i] != absolute_base[i]) break;
        #else
          // compare the charactes in a case insensitive manner
          // windows fs is only case insensitive in ascii ranges
          if (tolower(absolute_uri[i]) != tolower(absolute_base[i])) break;
        #endif
        if (absolute_uri[i] == '/') index = i + 1;
      }
      for (size_t i = index; i < absolute_uri.size(); ++i) {
        stripped_uri += absolute_uri[i];
      }
      for (size_t i = index; i < absolute_base.size(); ++i) {
        stripped_base += absolute_base[i];
      }

      size_t left = 0;
      size_t directories = 0;
      for (size_t right = 0; right < stripped_base.size(); ++right) {
        if (stripped_base[right] == '/') {
          if (stripped_base.substr(left, 2) != "..") {
            ++directories;
          }
          else if (directories > 1) {
            --directories;
          }
          else {
            directories = 0;
          }
          left = right + 1;
        }
      }

      string result = "";
      for (size_t i = 0; i < directories; ++i) {
        result += "../";
      }
      result += stripped_uri;

      return result;
    }

    char* resolve_and_load(string path, string& real_path)
    {
      // Resolution order for ambiguous imports:
      // (1) filename as given
      // (2) underscore + given
      // (3) underscore + given + extension
      // (4) given + extension
      char* contents = 0;
      real_path = path;
      // if the file isn't found with the given filename ...
      if (!(contents = read_file(real_path))) {
        string dir(dir_name(path));
        string base(base_name(path));
        string _base("_" + base);
        real_path = dir + _base;
        // if the file isn't found with '_' + filename ...
        if (!(contents = read_file(real_path))) {
          string _base_scss(_base + ".scss");
          real_path = dir + _base_scss;
          // if the file isn't found with '_' + filename + ".scss" ...
          if (!(contents = read_file(real_path))) {
            string _base_sass(_base + ".sass");
            real_path = dir + _base_sass;
            // if the file isn't found with '_' + filename + ".sass" ...
            if (!(contents = read_file(real_path))) {
              string base_scss(base + ".scss");
              real_path = dir + base_scss;
              // if the file isn't found with filename + ".scss" ...
              if (!(contents = read_file(real_path))) {
                string base_sass(base + ".sass");
                real_path = dir + base_sass;
                // if the file isn't found with filename + ".sass" ...
                if (!(contents = read_file(real_path))) {
                  // default back to scss version
                  real_path = dir + base_scss;
                }
              }
            }
          }
        }
      }
#ifdef _WIN32
      // convert Windows backslashes to URL forward slashes
      replace(real_path.begin(), real_path.end(), '\\', '/');
#endif
      return contents;
    }

    char* read_file(string path)
    {
      struct stat st;

#ifdef _WIN32
      BYTE* pBuffer;
      DWORD dwBytes;
      // windows unicode filepaths are encoded in utf16
      const wchar_t* wpath = UTF_8::convert_to_utf16(path).c_str();
      HANDLE hFile = CreateFileW(wpath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
      if (hFile == INVALID_HANDLE_VALUE) return 0;
      DWORD dwFileLength = GetFileSize(hFile, NULL);
      if (dwFileLength == INVALID_FILE_SIZE) return 0;
      pBuffer = new BYTE[dwFileLength + 1];
      ReadFile(hFile, pBuffer, dwFileLength, &dwBytes, NULL);
      pBuffer[dwFileLength] = '\0';
      CloseHandle(hFile);
      // just convert from unsigned char*
      char* contents = (char*) pBuffer;
#else
      if (stat(path.c_str(), &st) == -1 || S_ISDIR(st.st_mode)) return 0;
      ifstream file(path.c_str(), ios::in | ios::binary | ios::ate);
      char* contents = 0;
      if (file.is_open()) {
        size_t size = file.tellg();
        contents = new char[size + 1]; // extra byte for the null char
        file.seekg(0, ios::beg);
        file.read(contents, size);
        contents[size] = '\0';
        file.close();
      }
#endif
      string extension;
      if (path.length() > 5) {
        extension = path.substr(path.length() - 5, 5);
      }
      for(size_t i=0; i<extension.size();++i)
        extension[i] = tolower(extension[i]);
      if (extension == ".sass" && contents != 0) {
        char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1);
        delete[] contents; // free the indented contents
        return converted; // should be freed by caller
      } else {
        return contents;
      }
    }

  }
}
<commit_msg>Fix CreateFileW function usage, otherwise it fails to open file.<commit_after>#ifdef _WIN32
#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR)
#endif

#ifndef FS_CASE_SENSITIVE
#ifdef _WIN32
#define FS_CASE_SENSITIVE 0
#else
#define FS_CASE_SENSITIVE 1
#endif
#endif

#include <iostream>
#include <fstream>
#include <cctype>
#include <algorithm>
#include <sys/stat.h>
#include "file.hpp"
#include "context.hpp"
#include "utf8_string.hpp"
#include "sass2scss.h"

#ifdef _WIN32
#include <windows.h>
#endif

namespace Sass {
  namespace File {
    using namespace std;

    // no physical check on filesystem
    // only a logical cleanup of a path
    string make_canonical_path (string path)
    {

      // declarations
      size_t pos;

      #ifdef _WIN32
        //convert backslashes to forward slashes
        replace(path.begin(), path.end(), '\\', '/');
      #endif

      pos = 0; // remove all self references inside the path string
      while((pos = path.find("/./", pos)) != string::npos) path.erase(pos, 2);

      pos = 0; // remove all leading and trailing self references
      while(path.length() > 1 && path.substr(0, 2) == "./") path.erase(0, 2);
      while((pos = path.length()) > 1 && path.substr(pos - 2) == "/.") path.erase(pos - 2);

      pos = 0; // collapse multiple delimiters into a single one
      while((pos = path.find("//", pos)) != string::npos) path.erase(pos, 1);

      return path;

    }

    size_t find_last_folder_separator(const string& path, size_t limit = string::npos)
    {
      size_t pos = string::npos;
      size_t pos_p = path.find_last_of('/', limit);
      #ifdef _WIN32
      size_t pos_w = path.find_last_of('\\', limit);
      #else
      size_t pos_w = string::npos;
      #endif
      if (pos_p != string::npos && pos_w != string::npos) {
        pos = max(pos_p, pos_w);
      }
      else if (pos_p != string::npos) {
        pos = pos_p;
      }
      else {
        pos = pos_w;
      }
      return pos;
    }

    string base_name(string path)
    {
      size_t pos = find_last_folder_separator(path);
      if (pos == string::npos) return path;
      else                     return path.substr(pos+1);
    }

    string dir_name(string path)
    {
      size_t pos = find_last_folder_separator(path);
      if (pos == string::npos) return "";
      else                     return path.substr(0, pos+1);
    }

    string join_paths(string l, string r)
    {
      if (l.empty()) return r;
      if (r.empty()) return l;
      if (is_absolute_path(r)) return r;

      if (l[l.length()-1] != '/') l += '/';

      while ((r.length() > 3) && ((r.substr(0, 3) == "../") || (r.substr(0, 3)) == "..\\")) {
        r = r.substr(3);
        size_t pos = find_last_folder_separator(l, l.length() - 2);
        l = l.substr(0, pos == string::npos ? pos : pos + 1);
      }

      return l + r;
    }

    bool is_absolute_path(const string& path)
    {
      if (path[0] == '/') return true;
      // TODO: UN-HACKIFY THIS
      #ifdef _WIN32
      if (path.length() >= 2 && isalpha(path[0]) && path[1] == ':') return true;
      #endif
      return false;
    }

    string make_absolute_path(const string& path, const string& cwd)
    {
      return make_canonical_path((is_absolute_path(path) ? path : join_paths(cwd, path)));
    }

    string resolve_relative_path(const string& uri, const string& base, const string& cwd)
    {

      string absolute_uri = make_absolute_path(uri, cwd);
      string absolute_base = make_absolute_path(base, cwd);

      string stripped_uri = "";
      string stripped_base = "";

      size_t index = 0;
      size_t minSize = min(absolute_uri.size(), absolute_base.size());
      for (size_t i = 0; i < minSize; ++i) {
        #ifdef FS_CASE_SENSITIVE
          if (absolute_uri[i] != absolute_base[i]) break;
        #else
          // compare the charactes in a case insensitive manner
          // windows fs is only case insensitive in ascii ranges
          if (tolower(absolute_uri[i]) != tolower(absolute_base[i])) break;
        #endif
        if (absolute_uri[i] == '/') index = i + 1;
      }
      for (size_t i = index; i < absolute_uri.size(); ++i) {
        stripped_uri += absolute_uri[i];
      }
      for (size_t i = index; i < absolute_base.size(); ++i) {
        stripped_base += absolute_base[i];
      }

      size_t left = 0;
      size_t directories = 0;
      for (size_t right = 0; right < stripped_base.size(); ++right) {
        if (stripped_base[right] == '/') {
          if (stripped_base.substr(left, 2) != "..") {
            ++directories;
          }
          else if (directories > 1) {
            --directories;
          }
          else {
            directories = 0;
          }
          left = right + 1;
        }
      }

      string result = "";
      for (size_t i = 0; i < directories; ++i) {
        result += "../";
      }
      result += stripped_uri;

      return result;
    }

    char* resolve_and_load(string path, string& real_path)
    {
      // Resolution order for ambiguous imports:
      // (1) filename as given
      // (2) underscore + given
      // (3) underscore + given + extension
      // (4) given + extension
      char* contents = 0;
      real_path = path;
      // if the file isn't found with the given filename ...
      if (!(contents = read_file(real_path))) {
        string dir(dir_name(path));
        string base(base_name(path));
        string _base("_" + base);
        real_path = dir + _base;
        // if the file isn't found with '_' + filename ...
        if (!(contents = read_file(real_path))) {
          string _base_scss(_base + ".scss");
          real_path = dir + _base_scss;
          // if the file isn't found with '_' + filename + ".scss" ...
          if (!(contents = read_file(real_path))) {
            string _base_sass(_base + ".sass");
            real_path = dir + _base_sass;
            // if the file isn't found with '_' + filename + ".sass" ...
            if (!(contents = read_file(real_path))) {
              string base_scss(base + ".scss");
              real_path = dir + base_scss;
              // if the file isn't found with filename + ".scss" ...
              if (!(contents = read_file(real_path))) {
                string base_sass(base + ".sass");
                real_path = dir + base_sass;
                // if the file isn't found with filename + ".sass" ...
                if (!(contents = read_file(real_path))) {
                  // default back to scss version
                  real_path = dir + base_scss;
                }
              }
            }
          }
        }
      }
#ifdef _WIN32
      // convert Windows backslashes to URL forward slashes
      replace(real_path.begin(), real_path.end(), '\\', '/');
#endif
      return contents;
    }

    char* read_file(string path)
    {
      struct stat st;

#ifdef _WIN32
      BYTE* pBuffer;
      DWORD dwBytes;
      // windows unicode filepaths are encoded in utf16
      wstring wpath = UTF_8::convert_to_utf16(path);
      HANDLE hFile = CreateFileW(wpath.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
      if (hFile == INVALID_HANDLE_VALUE) return 0;
      DWORD dwFileLength = GetFileSize(hFile, NULL);
      if (dwFileLength == INVALID_FILE_SIZE) return 0;
      pBuffer = new BYTE[dwFileLength + 1];
      ReadFile(hFile, pBuffer, dwFileLength, &dwBytes, NULL);
      pBuffer[dwFileLength] = '\0';
      CloseHandle(hFile);
      // just convert from unsigned char*
      char* contents = (char*) pBuffer;
#else
      if (stat(path.c_str(), &st) == -1 || S_ISDIR(st.st_mode)) return 0;
      ifstream file(path.c_str(), ios::in | ios::binary | ios::ate);
      char* contents = 0;
      if (file.is_open()) {
        size_t size = file.tellg();
        contents = new char[size + 1]; // extra byte for the null char
        file.seekg(0, ios::beg);
        file.read(contents, size);
        contents[size] = '\0';
        file.close();
      }
#endif
      string extension;
      if (path.length() > 5) {
        extension = path.substr(path.length() - 5, 5);
      }
      for(size_t i=0; i<extension.size();++i)
        extension[i] = tolower(extension[i]);
      if (extension == ".sass" && contents != 0) {
        char * converted = sass2scss(contents, SASS2SCSS_PRETTIFY_1);
        delete[] contents; // free the indented contents
        return converted; // should be freed by caller
      } else {
        return contents;
      }
    }

  }
}
<|endoftext|>


<commit_before><commit_msg>formatting<commit_after><|endoftext|>


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

#include "xwalk/application/browser/application.h"

#include <string>

#include "base/files/file_enumerator.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "net/base/net_util.h"
#include "xwalk/application/common/application_manifest_constants.h"
#include "xwalk/application/common/constants.h"
#include "xwalk/application/common/manifest_handlers/warp_handler.h"
#include "xwalk/runtime/browser/runtime.h"
#include "xwalk/runtime/browser/runtime_context.h"
#include "xwalk/runtime/browser/runtime_defered_ui_strategy.h"
#include "xwalk/runtime/browser/xwalk_runner.h"

#if defined(OS_TIZEN)
#include "xwalk/application/browser/application_tizen.h"
#endif

using content::RenderProcessHost;

namespace xwalk {

namespace keys = application_manifest_keys;
namespace widget_keys = application_widget_keys;

namespace {
const char* kDefaultWidgetEntryPage[] = {
"index.html",
"index.htm",
"index.svg",
"index.xhtml",
"index.xht"};

GURL GetDefaultWidgetEntryPage(
    scoped_refptr<xwalk::application::ApplicationData> data) {
  base::ThreadRestrictions::SetIOAllowed(true);
  base::FileEnumerator iter(
      data->path(), true,
      base::FileEnumerator::FILES,
      FILE_PATH_LITERAL("index.*"));
  size_t priority = arraysize(kDefaultWidgetEntryPage);
  std::string source;

  for (base::FilePath file = iter.Next(); !file.empty(); file = iter.Next()) {
    for (size_t i = 0; i < arraysize(kDefaultWidgetEntryPage); ++i) {
      if (file.BaseName().MaybeAsASCII() == kDefaultWidgetEntryPage[i] &&
          i < priority) {
        source = kDefaultWidgetEntryPage[i];
        priority = i;
      }
    }
  }

  return source.empty() ? GURL() : data->GetResourceURL(source);
}

}  // namespace

namespace application {

scoped_ptr<Application> Application::Create(
    scoped_refptr<ApplicationData> data,
    RuntimeContext* context) {
#if defined(OS_TIZEN)
  return make_scoped_ptr<Application>(new ApplicationTizen(data, context));
#else
  return make_scoped_ptr(new Application(data, context));
#endif
}

Application::Application(
    scoped_refptr<ApplicationData> data,
    RuntimeContext* runtime_context)
    : data_(data),
      render_process_host_(NULL),
      web_contents_(NULL),
      security_mode_enabled_(false),
      runtime_context_(runtime_context),
      observer_(NULL),
      ui_strategy_(new RuntimeDeferedUIStrategy),
      remote_debugging_enabled_(false),
      weak_factory_(this) {
  DCHECK(runtime_context_);
  DCHECK(data_.get());
}

Application::~Application() {
  Terminate();
  if (render_process_host_)
    render_process_host_->RemoveObserver(this);
}

template<>
GURL Application::GetStartURL<Manifest::TYPE_WIDGET>() {
#if defined(OS_TIZEN)
  if (data_->IsHostedApp()) {
    std::string source;
    data_->GetManifest()->GetString(widget_keys::kLaunchLocalPathKey, &source);
    GURL url = GURL(source);

    if (url.is_valid() && url.SchemeIsHTTPOrHTTPS())
      return url;
  }
#endif

  GURL url = GetAbsoluteURLFromKey(widget_keys::kLaunchLocalPathKey);
  if (url.is_valid())
    return url;

  LOG(WARNING) << "Failed to find start URL from the 'config.xml'"
               << "trying to find default entry page.";
  url = GetDefaultWidgetEntryPage(data_);
  if (url.is_valid())
    return url;

  LOG(WARNING) << "Failed to find a valid start URL in the manifest.";
  return GURL();
}

template<>
GURL Application::GetStartURL<Manifest::TYPE_MANIFEST>() {
  if (data_->IsHostedApp()) {
    std::string source;
    data_->GetManifest()->GetString(keys::kStartURLKey, &source);
    // Not trying to get a relative path for the "fake" application.
    return GURL(source);
  }

  GURL url = GetAbsoluteURLFromKey(keys::kStartURLKey);
  if (url.is_valid())
    return url;

  url = GetAbsoluteURLFromKey(keys::kLaunchLocalPathKey);
  if (url.is_valid())
    return url;

  url = GetAbsoluteURLFromKey(keys::kDeprecatedURLKey);
  if (url.is_valid()) {
    LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedURLKey
        << "' found. Please migrate to using '" << keys::kStartURLKey
        << "' instead.";
    return url;
  }

  LOG(WARNING) << "Failed to find a valid start URL in the manifest.";
  return GURL();
}

template<>
ui::WindowShowState Application::GetWindowShowState<Manifest::TYPE_WIDGET>(
    const LaunchParams& params) {
  if (params.force_fullscreen)
    return ui::SHOW_STATE_FULLSCREEN;

  const Manifest* manifest = data_->GetManifest();
  std::string view_modes_string;
  if (manifest->GetString(widget_keys::kViewModesKey, &view_modes_string)) {
    // FIXME: ATM only 'fullscreen' and 'windowed' values are supported.
    // If the first user prefererence is 'fullscreen', set window show state
    // FULLSCREEN, otherwise set the default window show state.
    std::vector<std::string> modes;
    base::SplitString(view_modes_string, ' ', &modes);
    if (!modes.empty() && modes[0] == "fullscreen")
      return ui::SHOW_STATE_FULLSCREEN;
  }

  return ui::SHOW_STATE_DEFAULT;
}

template<>
ui::WindowShowState Application::GetWindowShowState<Manifest::TYPE_MANIFEST>(
    const LaunchParams& params) {
  if (params.force_fullscreen)
    return ui::SHOW_STATE_FULLSCREEN;

  const Manifest* manifest = data_->GetManifest();
  std::string display_string;
  if (manifest->GetString(keys::kDisplay, &display_string)) {
    // FIXME: ATM only 'fullscreen' and 'standalone' (which is fallback value)
    // values are supported.
    if (display_string.find("fullscreen") != std::string::npos)
      return ui::SHOW_STATE_FULLSCREEN;
  }

  return ui::SHOW_STATE_DEFAULT;
}

bool Application::Launch(const LaunchParams& launch_params) {
  if (!runtimes_.empty()) {
    LOG(ERROR) << "Attempt to launch app with id " << id()
               << ", but it is already running.";
    return false;
  }

  CHECK(!render_process_host_);
  bool is_wgt = data_->manifest_type() == Manifest::TYPE_WIDGET;

  GURL url = is_wgt ? GetStartURL<Manifest::TYPE_WIDGET>() :
                      GetStartURL<Manifest::TYPE_MANIFEST>();
  if (!url.is_valid())
    return false;

  remote_debugging_enabled_ = launch_params.remote_debugging;

  Runtime* runtime = Runtime::Create(
      runtime_context_,
      this, content::SiteInstance::CreateForURL(runtime_context_, url));
  render_process_host_ = runtime->GetRenderProcessHost();
  render_process_host_->AddObserver(this);
  web_contents_ = runtime->web_contents();
  InitSecurityPolicy();
  runtime->LoadURL(url);

  NativeAppWindow::CreateParams params;
  params.net_wm_pid = launch_params.launcher_pid;
  params.state = is_wgt ?
      GetWindowShowState<Manifest::TYPE_WIDGET>(launch_params):
      GetWindowShowState<Manifest::TYPE_MANIFEST>(launch_params);
  window_show_params_.state = params.state;

  params.splash_screen_path = GetSplashScreenPath();

  ui_strategy_->Show(runtime, params);

  return true;
}

GURL Application::GetAbsoluteURLFromKey(const std::string& key) {
  const Manifest* manifest = data_->GetManifest();
  std::string source;

  if (!manifest->GetString(key, &source) || source.empty())
    return GURL();

  return data_->GetResourceURL(source);
}

void Application::Terminate() {
  std::set<Runtime*> to_be_closed(runtimes_);
  std::for_each(to_be_closed.begin(), to_be_closed.end(),
                std::mem_fun(&Runtime::Close));
}

int Application::GetRenderProcessHostID() const {
  DCHECK(render_process_host_);
  return render_process_host_->GetID();
}

void Application::OnRuntimeAdded(Runtime* runtime) {
  DCHECK(runtime);
  runtime->set_remote_debugging_enabled(remote_debugging_enabled_);
  if (!runtimes_.empty())
    ui_strategy_->Show(runtime, window_show_params_);
  runtimes_.insert(runtime);
}

void Application::OnRuntimeRemoved(Runtime* runtime) {
  DCHECK(runtime);
  runtimes_.erase(runtime);

  if (runtimes_.empty())
    base::MessageLoop::current()->PostTask(FROM_HERE,
        base::Bind(&Application::NotifyTermination,
                   weak_factory_.GetWeakPtr()));
}

void Application::RenderProcessExited(RenderProcessHost* host,
                                      base::ProcessHandle,
                                      base::TerminationStatus,
                                      int) {
  DCHECK(render_process_host_ == host);
  VLOG(1) << "RenderProcess id: " << host->GetID() << " is gone!";
  XWalkRunner::GetInstance()->OnRenderProcessHostGone(host);
}

void Application::RenderProcessHostDestroyed(RenderProcessHost* host) {
  DCHECK(render_process_host_ == host);
  render_process_host_ = NULL;
  web_contents_ = NULL;
}

void Application::NotifyTermination() {
  CHECK(!render_process_host_);
  if (observer_)
    observer_->OnApplicationTerminated(this);
}

bool Application::UseExtension(const std::string& extension_name) const {
  // TODO(Bai): Tells whether the application contains the specified extension
  return true;
}

bool Application::RegisterPermissions(const std::string& extension_name,
                                      const std::string& perm_table) {
  // TODO(Bai): Parse the permission table and fill in the name_perm_map_
  // The perm_table format is a simple JSON string, like
  // [{"permission_name":"echo","apis":["add","remove","get"]}]
  scoped_ptr<base::Value> root;
  root.reset(base::JSONReader().ReadToValue(perm_table));
  if (root.get() == NULL || !root->IsType(base::Value::TYPE_LIST))
    return false;

  base::ListValue* permission_list = static_cast<base::ListValue*>(root.get());
  if (permission_list->GetSize() == 0)
    return false;

  for (base::ListValue::const_iterator iter = permission_list->begin();
      iter != permission_list->end(); ++iter) {
    if (!(*iter)->IsType(base::Value::TYPE_DICTIONARY))
        return false;

    base::DictionaryValue* dict_val =
        static_cast<base::DictionaryValue*>(*iter);
    std::string permission_name;
    if (!dict_val->GetString("permission_name", &permission_name))
      return false;

    base::ListValue* api_list = NULL;
    if (!dict_val->GetList("apis", &api_list))
      return false;

    for (base::ListValue::const_iterator api_iter = api_list->begin();
        api_iter != api_list->end(); ++api_iter) {
      std::string api;
      if (!((*api_iter)->IsType(base::Value::TYPE_STRING)
          && (*api_iter)->GetAsString(&api)))
        return false;
      // register the permission and api
      name_perm_map_[api] = permission_name;
      DLOG(INFO) << "Permission Registered [PERM] " << permission_name
                 << " [API] " << api;
    }
  }

  return true;
}

std::string Application::GetRegisteredPermissionName(
    const std::string& extension_name,
    const std::string& api_name) const {
  std::map<std::string, std::string>::const_iterator iter =
      name_perm_map_.find(api_name);
  if (iter == name_perm_map_.end())
    return std::string("");
  return iter->second;
}

StoredPermission Application::GetPermission(PermissionType type,
                               const std::string& permission_name) const {
  if (type == SESSION_PERMISSION) {
    StoredPermissionMap::const_iterator iter =
        permission_map_.find(permission_name);
    if (iter == permission_map_.end())
      return UNDEFINED_STORED_PERM;
    return iter->second;
  }
  if (type == PERSISTENT_PERMISSION) {
    return data_->GetPermission(permission_name);
  }
  NOTREACHED();
  return UNDEFINED_STORED_PERM;
}

bool Application::SetPermission(PermissionType type,
                                const std::string& permission_name,
                                StoredPermission perm) {
  if (type == SESSION_PERMISSION) {
    permission_map_[permission_name] = perm;
    return true;
  }
  if (type == PERSISTENT_PERMISSION)
    return data_->SetPermission(permission_name, perm);

  NOTREACHED();
  return false;
}

void Application::InitSecurityPolicy() {
  // CSP policy takes precedence over WARP.
  if (data_->HasCSPDefined())
    security_policy_.reset(new SecurityPolicyCSP(this));
  else if (data_->manifest_type() == Manifest::TYPE_WIDGET)
    security_policy_.reset(new SecurityPolicyWARP(this));

  if (security_policy_)
    security_policy_->Enforce();
}

bool Application::CanRequestURL(const GURL& url) const {
  if (security_policy_)
    return security_policy_->IsAccessAllowed(url);
  return true;
}

base::FilePath Application::GetSplashScreenPath() {
  return base::FilePath();
}

}  // namespace application
}  // namespace xwalk
<commit_msg>Application: Add the check for return value.<commit_after>// Copyright (c) 2013 Intel Corporation. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "xwalk/application/browser/application.h"

#include <string>

#include "base/files/file_enumerator.h"
#include "base/json/json_reader.h"
#include "base/macros.h"
#include "base/message_loop/message_loop.h"
#include "base/stl_util.h"
#include "base/strings/string_split.h"
#include "base/threading/thread_restrictions.h"
#include "base/values.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/site_instance.h"
#include "net/base/net_util.h"
#include "xwalk/application/common/application_manifest_constants.h"
#include "xwalk/application/common/constants.h"
#include "xwalk/application/common/manifest_handlers/warp_handler.h"
#include "xwalk/runtime/browser/runtime.h"
#include "xwalk/runtime/browser/runtime_context.h"
#include "xwalk/runtime/browser/runtime_defered_ui_strategy.h"
#include "xwalk/runtime/browser/xwalk_runner.h"

#if defined(OS_TIZEN)
#include "xwalk/application/browser/application_tizen.h"
#endif

using content::RenderProcessHost;

namespace xwalk {

namespace keys = application_manifest_keys;
namespace widget_keys = application_widget_keys;

namespace {
const char* kDefaultWidgetEntryPage[] = {
"index.html",
"index.htm",
"index.svg",
"index.xhtml",
"index.xht"};

GURL GetDefaultWidgetEntryPage(
    scoped_refptr<xwalk::application::ApplicationData> data) {
  base::ThreadRestrictions::SetIOAllowed(true);
  base::FileEnumerator iter(
      data->path(), true,
      base::FileEnumerator::FILES,
      FILE_PATH_LITERAL("index.*"));
  size_t priority = arraysize(kDefaultWidgetEntryPage);
  std::string source;

  for (base::FilePath file = iter.Next(); !file.empty(); file = iter.Next()) {
    for (size_t i = 0; i < arraysize(kDefaultWidgetEntryPage); ++i) {
      if (file.BaseName().MaybeAsASCII() == kDefaultWidgetEntryPage[i] &&
          i < priority) {
        source = kDefaultWidgetEntryPage[i];
        priority = i;
      }
    }
  }

  return source.empty() ? GURL() : data->GetResourceURL(source);
}

}  // namespace

namespace application {

scoped_ptr<Application> Application::Create(
    scoped_refptr<ApplicationData> data,
    RuntimeContext* context) {
#if defined(OS_TIZEN)
  return make_scoped_ptr<Application>(new ApplicationTizen(data, context));
#else
  return make_scoped_ptr(new Application(data, context));
#endif
}

Application::Application(
    scoped_refptr<ApplicationData> data,
    RuntimeContext* runtime_context)
    : data_(data),
      render_process_host_(NULL),
      web_contents_(NULL),
      security_mode_enabled_(false),
      runtime_context_(runtime_context),
      observer_(NULL),
      ui_strategy_(new RuntimeDeferedUIStrategy),
      remote_debugging_enabled_(false),
      weak_factory_(this) {
  DCHECK(runtime_context_);
  DCHECK(data_.get());
}

Application::~Application() {
  Terminate();
  if (render_process_host_)
    render_process_host_->RemoveObserver(this);
}

template<>
GURL Application::GetStartURL<Manifest::TYPE_WIDGET>() {
#if defined(OS_TIZEN)
  if (data_->IsHostedApp()) {
    std::string source;
    GURL url;
    if (data_->GetManifest()->GetString(
        widget_keys::kLaunchLocalPathKey, &source)) {
      url = GURL(source);
    }

    if (url.is_valid() && url.SchemeIsHTTPOrHTTPS())
      return url;
  }
#endif

  GURL url = GetAbsoluteURLFromKey(widget_keys::kLaunchLocalPathKey);
  if (url.is_valid())
    return url;

  LOG(WARNING) << "Failed to find start URL from the 'config.xml'"
               << "trying to find default entry page.";
  url = GetDefaultWidgetEntryPage(data_);
  if (url.is_valid())
    return url;

  LOG(WARNING) << "Failed to find a valid start URL in the manifest.";
  return GURL();
}

template<>
GURL Application::GetStartURL<Manifest::TYPE_MANIFEST>() {
  if (data_->IsHostedApp()) {
    std::string source;
    // Not trying to get a relative path for the "fake" application.
    if (data_->GetManifest()->GetString(keys::kStartURLKey, &source))
      return GURL(source);
    return GURL();
  }

  GURL url = GetAbsoluteURLFromKey(keys::kStartURLKey);
  if (url.is_valid())
    return url;

  url = GetAbsoluteURLFromKey(keys::kLaunchLocalPathKey);
  if (url.is_valid())
    return url;

  url = GetAbsoluteURLFromKey(keys::kDeprecatedURLKey);
  if (url.is_valid()) {
    LOG(WARNING) << "Deprecated key '" << keys::kDeprecatedURLKey
        << "' found. Please migrate to using '" << keys::kStartURLKey
        << "' instead.";
    return url;
  }

  LOG(WARNING) << "Failed to find a valid start URL in the manifest.";
  return GURL();
}

template<>
ui::WindowShowState Application::GetWindowShowState<Manifest::TYPE_WIDGET>(
    const LaunchParams& params) {
  if (params.force_fullscreen)
    return ui::SHOW_STATE_FULLSCREEN;

  const Manifest* manifest = data_->GetManifest();
  std::string view_modes_string;
  if (manifest->GetString(widget_keys::kViewModesKey, &view_modes_string)) {
    // FIXME: ATM only 'fullscreen' and 'windowed' values are supported.
    // If the first user prefererence is 'fullscreen', set window show state
    // FULLSCREEN, otherwise set the default window show state.
    std::vector<std::string> modes;
    base::SplitString(view_modes_string, ' ', &modes);
    if (!modes.empty() && modes[0] == "fullscreen")
      return ui::SHOW_STATE_FULLSCREEN;
  }

  return ui::SHOW_STATE_DEFAULT;
}

template<>
ui::WindowShowState Application::GetWindowShowState<Manifest::TYPE_MANIFEST>(
    const LaunchParams& params) {
  if (params.force_fullscreen)
    return ui::SHOW_STATE_FULLSCREEN;

  const Manifest* manifest = data_->GetManifest();
  std::string display_string;
  if (manifest->GetString(keys::kDisplay, &display_string)) {
    // FIXME: ATM only 'fullscreen' and 'standalone' (which is fallback value)
    // values are supported.
    if (display_string.find("fullscreen") != std::string::npos)
      return ui::SHOW_STATE_FULLSCREEN;
  }

  return ui::SHOW_STATE_DEFAULT;
}

bool Application::Launch(const LaunchParams& launch_params) {
  if (!runtimes_.empty()) {
    LOG(ERROR) << "Attempt to launch app with id " << id()
               << ", but it is already running.";
    return false;
  }

  CHECK(!render_process_host_);
  bool is_wgt = data_->manifest_type() == Manifest::TYPE_WIDGET;

  GURL url = is_wgt ? GetStartURL<Manifest::TYPE_WIDGET>() :
                      GetStartURL<Manifest::TYPE_MANIFEST>();
  if (!url.is_valid())
    return false;

  remote_debugging_enabled_ = launch_params.remote_debugging;

  Runtime* runtime = Runtime::Create(
      runtime_context_,
      this, content::SiteInstance::CreateForURL(runtime_context_, url));
  render_process_host_ = runtime->GetRenderProcessHost();
  render_process_host_->AddObserver(this);
  web_contents_ = runtime->web_contents();
  InitSecurityPolicy();
  runtime->LoadURL(url);

  NativeAppWindow::CreateParams params;
  params.net_wm_pid = launch_params.launcher_pid;
  params.state = is_wgt ?
      GetWindowShowState<Manifest::TYPE_WIDGET>(launch_params):
      GetWindowShowState<Manifest::TYPE_MANIFEST>(launch_params);
  window_show_params_.state = params.state;

  params.splash_screen_path = GetSplashScreenPath();

  ui_strategy_->Show(runtime, params);

  return true;
}

GURL Application::GetAbsoluteURLFromKey(const std::string& key) {
  const Manifest* manifest = data_->GetManifest();
  std::string source;

  if (!manifest->GetString(key, &source) || source.empty())
    return GURL();

  return data_->GetResourceURL(source);
}

void Application::Terminate() {
  std::set<Runtime*> to_be_closed(runtimes_);
  std::for_each(to_be_closed.begin(), to_be_closed.end(),
                std::mem_fun(&Runtime::Close));
}

int Application::GetRenderProcessHostID() const {
  DCHECK(render_process_host_);
  return render_process_host_->GetID();
}

void Application::OnRuntimeAdded(Runtime* runtime) {
  DCHECK(runtime);
  runtime->set_remote_debugging_enabled(remote_debugging_enabled_);
  if (!runtimes_.empty())
    ui_strategy_->Show(runtime, window_show_params_);
  runtimes_.insert(runtime);
}

void Application::OnRuntimeRemoved(Runtime* runtime) {
  DCHECK(runtime);
  runtimes_.erase(runtime);

  if (runtimes_.empty())
    base::MessageLoop::current()->PostTask(FROM_HERE,
        base::Bind(&Application::NotifyTermination,
                   weak_factory_.GetWeakPtr()));
}

void Application::RenderProcessExited(RenderProcessHost* host,
                                      base::ProcessHandle,
                                      base::TerminationStatus,
                                      int) {
  DCHECK(render_process_host_ == host);
  VLOG(1) << "RenderProcess id: " << host->GetID() << " is gone!";
  XWalkRunner::GetInstance()->OnRenderProcessHostGone(host);
}

void Application::RenderProcessHostDestroyed(RenderProcessHost* host) {
  DCHECK(render_process_host_ == host);
  render_process_host_ = NULL;
  web_contents_ = NULL;
}

void Application::NotifyTermination() {
  CHECK(!render_process_host_);
  if (observer_)
    observer_->OnApplicationTerminated(this);
}

bool Application::UseExtension(const std::string& extension_name) const {
  // TODO(Bai): Tells whether the application contains the specified extension
  return true;
}

bool Application::RegisterPermissions(const std::string& extension_name,
                                      const std::string& perm_table) {
  // TODO(Bai): Parse the permission table and fill in the name_perm_map_
  // The perm_table format is a simple JSON string, like
  // [{"permission_name":"echo","apis":["add","remove","get"]}]
  scoped_ptr<base::Value> root;
  root.reset(base::JSONReader().ReadToValue(perm_table));
  if (root.get() == NULL || !root->IsType(base::Value::TYPE_LIST))
    return false;

  base::ListValue* permission_list = static_cast<base::ListValue*>(root.get());
  if (permission_list->GetSize() == 0)
    return false;

  for (base::ListValue::const_iterator iter = permission_list->begin();
      iter != permission_list->end(); ++iter) {
    if (!(*iter)->IsType(base::Value::TYPE_DICTIONARY))
        return false;

    base::DictionaryValue* dict_val =
        static_cast<base::DictionaryValue*>(*iter);
    std::string permission_name;
    if (!dict_val->GetString("permission_name", &permission_name))
      return false;

    base::ListValue* api_list = NULL;
    if (!dict_val->GetList("apis", &api_list))
      return false;

    for (base::ListValue::const_iterator api_iter = api_list->begin();
        api_iter != api_list->end(); ++api_iter) {
      std::string api;
      if (!((*api_iter)->IsType(base::Value::TYPE_STRING)
          && (*api_iter)->GetAsString(&api)))
        return false;
      // register the permission and api
      name_perm_map_[api] = permission_name;
      DLOG(INFO) << "Permission Registered [PERM] " << permission_name
                 << " [API] " << api;
    }
  }

  return true;
}

std::string Application::GetRegisteredPermissionName(
    const std::string& extension_name,
    const std::string& api_name) const {
  std::map<std::string, std::string>::const_iterator iter =
      name_perm_map_.find(api_name);
  if (iter == name_perm_map_.end())
    return std::string("");
  return iter->second;
}

StoredPermission Application::GetPermission(PermissionType type,
                               const std::string& permission_name) const {
  if (type == SESSION_PERMISSION) {
    StoredPermissionMap::const_iterator iter =
        permission_map_.find(permission_name);
    if (iter == permission_map_.end())
      return UNDEFINED_STORED_PERM;
    return iter->second;
  }
  if (type == PERSISTENT_PERMISSION) {
    return data_->GetPermission(permission_name);
  }
  NOTREACHED();
  return UNDEFINED_STORED_PERM;
}

bool Application::SetPermission(PermissionType type,
                                const std::string& permission_name,
                                StoredPermission perm) {
  if (type == SESSION_PERMISSION) {
    permission_map_[permission_name] = perm;
    return true;
  }
  if (type == PERSISTENT_PERMISSION)
    return data_->SetPermission(permission_name, perm);

  NOTREACHED();
  return false;
}

void Application::InitSecurityPolicy() {
  // CSP policy takes precedence over WARP.
  if (data_->HasCSPDefined())
    security_policy_.reset(new SecurityPolicyCSP(this));
  else if (data_->manifest_type() == Manifest::TYPE_WIDGET)
    security_policy_.reset(new SecurityPolicyWARP(this));

  if (security_policy_)
    security_policy_->Enforce();
}

bool Application::CanRequestURL(const GURL& url) const {
  if (security_policy_)
    return security_policy_->IsAccessAllowed(url);
  return true;
}

base::FilePath Application::GetSplashScreenPath() {
  return base::FilePath();
}

}  // namespace application
}  // namespace xwalk
<|endoftext|>


<commit_before>#include "guid.h"

#ifdef GUID_LIBUUID
#include <uuid/uuid.h>
#endif

#ifdef GUID_CFUUID
#include <CoreFoundation/CFUUID.h>
#endif

#ifdef GUID_WINDOWS
#include <objbase.h>
#endif

using namespace std;

// overload << so that it's easy to convert to a string
ostream &operator<<(ostream &s, const Guid &guid)
{
  return s << hex << setfill('0')
    << setw(2) << (int)guid._bytes[0]
    << setw(2) << (int)guid._bytes[1]
    << setw(2) << (int)guid._bytes[2]
    << setw(2) << (int)guid._bytes[3]
    << "-"
    << setw(2) << (int)guid._bytes[4]
    << setw(2) << (int)guid._bytes[5]
    << "-"
    << setw(2) << (int)guid._bytes[6]
    << setw(2) << (int)guid._bytes[7]
    << "-"
    << setw(2) << (int)guid._bytes[8]
    << setw(2) << (int)guid._bytes[9]
    << "-"
    << setw(2) << (int)guid._bytes[10]
    << setw(2) << (int)guid._bytes[11]
    << setw(2) << (int)guid._bytes[12]
    << setw(2) << (int)guid._bytes[13]
    << setw(2) << (int)guid._bytes[14]
    << setw(2) << (int)guid._bytes[15];
}

// create a guid from vector of bytes
Guid::Guid(const vector<unsigned char> &bytes)
{
  _bytes = bytes;
}

// create a guid from array of bytes
Guid::Guid(const unsigned char *bytes)
{
  _bytes.assign(bytes, bytes + 16);
}

// create a guid from string
Guid::Guid(const string &fromString)
{
  _bytes.clear();
  char byteHexString[3] = {0};

  bool lookingForFirstChar = true;

  for (const char &ch : fromString)
  {
    if (ch == '-')
      continue;

    if (lookingForFirstChar)
    {
      byteHexString[0] = ch;
      lookingForFirstChar = false;
    }
    else
    {
      byteHexString[1] = ch;
      unsigned long byte;
      byte = stoul(byteHexString, 0, 16);
      _bytes.push_back(byte);
      lookingForFirstChar = true;
    }
  }

}

// create empty guid
Guid::Guid()
{
  _bytes = vector<unsigned char>(16, 0);
}

// copy constructor
Guid::Guid(const Guid &other)
{
  _bytes = other._bytes;
}

// overload assignment operator
Guid &Guid::operator=(const Guid &other)
{
  _bytes = other._bytes;
  return *this;
}

// overload equality operator
bool Guid::operator==(const Guid &other) const
{
  return _bytes == other._bytes;
}

// overload inequality operator
bool Guid::operator!=(const Guid &other) const
{
  return !((*this) == other);
}

// This is the linux friendly implementation, but it coul work on other
// systems that have libuuid available
#ifdef GUID_LIBUUID
Guid generateGuid()
{
  uuid_t id;
  uuid_generate(id);
  return id;
}
#endif

// this is the mac and ios version
#ifdef GUID_CFUUID
struct __CFUUID;

Guid generateGuid()
{
  auto id = CFUUIDCreate(NULL);
  auto bytes = CFUUIDGetUUIDBytes(id);

  const unsigned char byteArray[16] =
  {
    bytes.byte0,
    bytes.byte1,
    bytes.byte2,
    bytes.byte3,
    bytes.byte4,
    bytes.byte5,
    bytes.byte6,
    bytes.byte7,
    bytes.byte8,
    bytes.byte9,
    bytes.byte10,
    bytes.byte11,
    bytes.byte12,
    bytes.byte13,
    bytes.byte14,
    bytes.byte15
  };
  return byteArray;
}
#endif

#ifdef GUID_WINDOWS
Guid generateGuid()
{
	GUID newId;
	CoCreateGuid(&newId);

	const unsigned char bytes[16] =
	{
		(newId.Data1 >> 24) & 0xff,
		(newId.Data1 >> 16) & 0xff,
		(newId.Data1 >> 8) & 0xff,
		(newId.Data1) & 0xff,

		(newId.Data2 >> 8) & 0xff,
		(newId.Data2) & 0xff,

		(newId.Data3 >> 8) & 0xff,
		(newId.Data3) & 0xff,

		newId.Data4[0],
		newId.Data4[1],
		newId.Data4[2],
		newId.Data4[3],
		newId.Data4[4],
		newId.Data4[5],
		newId.Data4[6],
		newId.Data4[7]
	};

	return bytes;
}
#endif
<commit_msg>Removed unneeded prototype for __CFUUID<commit_after>#include "guid.h"

#ifdef GUID_LIBUUID
#include <uuid/uuid.h>
#endif

#ifdef GUID_CFUUID
#include <CoreFoundation/CFUUID.h>
#endif

#ifdef GUID_WINDOWS
#include <objbase.h>
#endif

using namespace std;

// overload << so that it's easy to convert to a string
ostream &operator<<(ostream &s, const Guid &guid)
{
  return s << hex << setfill('0')
    << setw(2) << (int)guid._bytes[0]
    << setw(2) << (int)guid._bytes[1]
    << setw(2) << (int)guid._bytes[2]
    << setw(2) << (int)guid._bytes[3]
    << "-"
    << setw(2) << (int)guid._bytes[4]
    << setw(2) << (int)guid._bytes[5]
    << "-"
    << setw(2) << (int)guid._bytes[6]
    << setw(2) << (int)guid._bytes[7]
    << "-"
    << setw(2) << (int)guid._bytes[8]
    << setw(2) << (int)guid._bytes[9]
    << "-"
    << setw(2) << (int)guid._bytes[10]
    << setw(2) << (int)guid._bytes[11]
    << setw(2) << (int)guid._bytes[12]
    << setw(2) << (int)guid._bytes[13]
    << setw(2) << (int)guid._bytes[14]
    << setw(2) << (int)guid._bytes[15];
}

// create a guid from vector of bytes
Guid::Guid(const vector<unsigned char> &bytes)
{
  _bytes = bytes;
}

// create a guid from array of bytes
Guid::Guid(const unsigned char *bytes)
{
  _bytes.assign(bytes, bytes + 16);
}

// create a guid from string
Guid::Guid(const string &fromString)
{
  _bytes.clear();
  char byteHexString[3] = {0};

  bool lookingForFirstChar = true;

  for (const char &ch : fromString)
  {
    if (ch == '-')
      continue;

    if (lookingForFirstChar)
    {
      byteHexString[0] = ch;
      lookingForFirstChar = false;
    }
    else
    {
      byteHexString[1] = ch;
      unsigned long byte;
      byte = stoul(byteHexString, 0, 16);
      _bytes.push_back(byte);
      lookingForFirstChar = true;
    }
  }

}

// create empty guid
Guid::Guid()
{
  _bytes = vector<unsigned char>(16, 0);
}

// copy constructor
Guid::Guid(const Guid &other)
{
  _bytes = other._bytes;
}

// overload assignment operator
Guid &Guid::operator=(const Guid &other)
{
  _bytes = other._bytes;
  return *this;
}

// overload equality operator
bool Guid::operator==(const Guid &other) const
{
  return _bytes == other._bytes;
}

// overload inequality operator
bool Guid::operator!=(const Guid &other) const
{
  return !((*this) == other);
}

// This is the linux friendly implementation, but it coul work on other
// systems that have libuuid available
#ifdef GUID_LIBUUID
Guid generateGuid()
{
  uuid_t id;
  uuid_generate(id);
  return id;
}
#endif

// this is the mac and ios version
#ifdef GUID_CFUUID
Guid generateGuid()
{
  auto id = CFUUIDCreate(NULL);
  auto bytes = CFUUIDGetUUIDBytes(id);

  const unsigned char byteArray[16] =
  {
    bytes.byte0,
    bytes.byte1,
    bytes.byte2,
    bytes.byte3,
    bytes.byte4,
    bytes.byte5,
    bytes.byte6,
    bytes.byte7,
    bytes.byte8,
    bytes.byte9,
    bytes.byte10,
    bytes.byte11,
    bytes.byte12,
    bytes.byte13,
    bytes.byte14,
    bytes.byte15
  };
  return byteArray;
}
#endif

// obviously this is the windows version
#ifdef GUID_WINDOWS
Guid generateGuid()
{
	GUID newId;
	CoCreateGuid(&newId);

	const unsigned char bytes[16] =
	{
		(newId.Data1 >> 24) & 0xff,
		(newId.Data1 >> 16) & 0xff,
		(newId.Data1 >> 8) & 0xff,
		(newId.Data1) & 0xff,

		(newId.Data2 >> 8) & 0xff,
		(newId.Data2) & 0xff,

		(newId.Data3 >> 8) & 0xff,
		(newId.Data3) & 0xff,

		newId.Data4[0],
		newId.Data4[1],
		newId.Data4[2],
		newId.Data4[3],
		newId.Data4[4],
		newId.Data4[5],
		newId.Data4[6],
		newId.Data4[7]
	};

	return bytes;
}
#endif
<|endoftext|>


<commit_before>// gzip handling

#include <string>
#include <zlib.h>
#include "gzip.hpp"
#include "log.hpp"

using namespace std;

IO_Wrapper::IO_Wrapper( string filename ){
  fs = new ifstream( filename );
}

// access string getline to return next line in ifstream object
string IO_Wrapper::getline(){
  string line("");
  std::getline( *fs, line );
  return line;
}

Gzip::Gzip( string filename ): BUFF_SIZE(16384), buffer(""), filename(filename){
  fp = fopen( filename.c_str(), "rb" );

  /* allocate inflate state */
  zs.zalloc = Z_NULL;
  zs.zfree = Z_NULL;
  zs.opaque = Z_NULL;
  zs.avail_in = 0;
  zs.next_in = Z_NULL;
  status = inflateInit2(&zs, 16+MAX_WBITS);

  if (status != Z_OK)
    zerr();
}

/* report a zlib or i/o error */
void Gzip::zerr(){
  char log_buff[1000];

  switch (status) {
    case Z_ERRNO:
      fprintf( stderr, "zlib: error reading file: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: error reading file: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_STREAM_ERROR:
      fprintf( stderr, "zlib: invalid compression level: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: invalid compression level: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_DATA_ERROR:
      fprintf( stderr, "zlib: invalid or incomplete deflate data: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: invalid or incomplete deflate data: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_MEM_ERROR:
      fprintf( stderr, "zlib: out of memory: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: out of memory: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_VERSION_ERROR:
      fprintf( stderr, "zlib: version mismatch: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: version mismatch: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
  }
}

// append next set of data to buffer
void Gzip::fill_buffer(){
  unsigned char in[BUFF_SIZE];
  unsigned char out[BUFF_SIZE];
  int next_pos = 0;

  // read in data from gzipd file
  zs.avail_in = fread(in, 1, BUFF_SIZE, fp);

  // handle read errors
  if (ferror(fp)) {
    (void)inflateEnd(&zs);
    status = Z_ERRNO;
    return;
  }

  // handle data error
  if (zs.avail_in == 0){
    status = Z_DATA_ERROR;
    return;
  }

  // prep z_stream members
  zs.next_in = in;
  zs.avail_out = BUFF_SIZE;
  zs.next_out = out;

  // decompress data
  status = inflate(&zs, Z_NO_FLUSH);

  // check for errors
  switch (status) {
    case Z_NEED_DICT:
      status = Z_DATA_ERROR;     /* and fall through */
    case Z_DATA_ERROR:
    case Z_MEM_ERROR:
      (void)inflateEnd(&zs);
      return;
  }

  // append data to buffer
  buffer.append( (char*)out );
}

// return the next line in the gzip file
string Gzip::getline(){
  size_t next_pos = 0;
  string line( "" );

  // check if buffer has a full line in it, if not, fill_buffer
  while((next_pos = buffer.find( '\n' )) == string::npos && status == Z_OK ){
    fill_buffer();
  }

  // if last line in file, store results for return
  if( status == Z_STREAM_END && next_pos == string::npos ){
    line = buffer;
    buffer = "";

    (void)inflateEnd(&zs);
  }
  // protect against errors
  else if( status != Z_OK && status != Z_STREAM_END ){
    (void)inflateEnd(&zs);
    zerr();
    return "";
  }
  // parse out next line in buffer
  else{
    line = buffer.substr( 0, next_pos );
    buffer.erase( 0, next_pos+1 );
  }

  return line;
}
<commit_msg>Small changes to fix gzip. Still not fixed<commit_after>// gzip handling

#include <iostream>
#include <sstream>
#include <string>
#include <cstring>
#include <zlib.h>
#include "gzip.hpp"
#include "log.hpp"

using namespace std;

IO_Wrapper::IO_Wrapper( string filename ){
  fs = new ifstream( filename );
}

// access string getline to return next line in ifstream object
string IO_Wrapper::getline(){
  string line("");
  std::getline( *fs, line );
  return line;
}

Gzip::Gzip( string filename ): BUFF_SIZE(16384), buffer(""), filename(filename){
  fp = fopen( filename.c_str(), "rb" );

  /* allocate inflate state */
  zs.zalloc = Z_NULL;
  zs.zfree = Z_NULL;
  zs.opaque = Z_NULL;
  zs.avail_in = 0;
  zs.avail_out = BUFF_SIZE;
  zs.next_in = Z_NULL;
  status = inflateInit2(&zs, 32+MAX_WBITS);

  if (status != Z_OK)
    zerr();
}

/* report a zlib or i/o error */
void Gzip::zerr(){
  char log_buff[1000];

  switch (status) {
    case Z_ERRNO:
      fprintf( stderr, "zlib: error reading file: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: error reading file: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_STREAM_ERROR:
      fprintf( stderr, "zlib: invalid compression level: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: invalid compression level: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_DATA_ERROR:
      fprintf( stderr, "zlib: invalid or incomplete deflate data: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: invalid or incomplete deflate data: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_MEM_ERROR:
      fprintf( stderr, "zlib: out of memory: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: out of memory: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
      break;
    case Z_VERSION_ERROR:
      fprintf( stderr, "zlib: version mismatch: %s\n", filename.c_str() );
      sprintf( log_buff, "zlib: version mismatch: %s", filename.c_str() );
      Log::Inst()->log_it( log_buff );
  }
}

// append next set of data to buffer
void Gzip::fill_buffer(){
  unsigned char in[BUFF_SIZE];
  unsigned char out[BUFF_SIZE];
  int next_pos = 0;
  int new_data = 0;

  cout << "avail_out: " << zs.avail_out << endl;
  cout << "avail_in: " << zs.avail_in << endl;

  // read in data from gzipd file
  new_data = fread(in, 1, BUFF_SIZE-zs.avail_in, fp);
  zs.avail_in += new_data;

  cout << "ferror status: " << status << endl;

  // handle read errors
  if (ferror(fp)) {
    (void)inflateEnd(&zs);
    status = Z_ERRNO;
    return;
  }

  // handle data error
  if (zs.avail_in == 0){
    status = Z_DATA_ERROR;
    cout << "DATA_ERROR" << endl;
    return;
  }

  if( new_data == zs.avail_in ){
    memcpy( zs.next_in + zs.avail_in - new_data, &in, new_data );
  }
  else{
    zs.avail_in += new_data;

  cout << "predecompress status: " << status << endl;

  // prep z_stream members
  zs.avail_out = BUFF_SIZE;
  zs.next_out = out;

  // decompress data
  status = inflate(&zs, Z_NO_FLUSH);
  cout << "decompress status: " << status << endl;
  cout << "avail_out: " << zs.avail_out << endl;
  cout << "avail_in: " << zs.avail_in << endl;

  // check for errors
  switch (status) {
    case Z_NEED_DICT:
      status = Z_DATA_ERROR;     /* and fall through */
    case Z_DATA_ERROR:
    case Z_MEM_ERROR:
      (void)inflateEnd(&zs);
      cout << "ERROR" << endl;
      return;
  }

  stringstream s;

  s << out;

  // append data to buffer
  buffer.append( s.str() );
}

// return the next line in the gzip file
string Gzip::getline(){
  size_t next_pos = 0;
  string line( "" );

  // check if buffer has a full line in it, if not, fill_buffer
  while((next_pos = buffer.find( '\n' )) == string::npos && status == Z_OK ){
    cout << "fill_buffer()" << endl;
    fill_buffer();
    cout << "status: " << status << endl;
  }

  // if last line in file, store results for return
  if( status == Z_STREAM_END && next_pos == string::npos ){
    line = buffer;
    buffer = "";

    (void)inflateEnd(&zs);
  }
  // protect against errors
  else if( status != Z_OK && status != Z_STREAM_END ){
    (void)inflateEnd(&zs);
    zerr();
    return "";
  }
  // parse out next line in buffer
  else{
    line = buffer.substr( 0, next_pos );
    buffer.erase( 0, next_pos+1 );
  }

  return line;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2017 Rene Herthel
 * Copyright (C) 2017 Jonas Fuhrmann
 *
 * This file is subject to the terms and conditions of the MIT License.
 * See the file LICENSE in the top level directory for more details.
 */

/**
 * @ingroup    height_measurement
 * @{
 *
 * @brief      Test function declaration of the HeightMeasurement component
 *
 * @author     Rene Herthel <rene.herthel@haw-hamburg.de>
 * @author     Jonas Fuhrmann <jonas.fuhrmann@haw-hamburg.de>
 */

#include "TestHeightMeasurement.h"

#include "HeightMeasurementHal.h"
#include "HeightContext.h"
#include "HWdefines.h"

#include <iostream>
#include <chrono>
#include <thread>

void TestHeightMeasurement::startTest() {
    std::cout<<"[TestHeightMeasurement] Start:"<<std::endl;

    HeightMeasurementHal hal;
    int16_t data = 0;
    hal.read(data);

    std::cout<<"[TestHeightMeasurement] Hal data: "<<(int)data<<std::endl;

    std::cout<<"[TestHeightMeasurement] Context: "<<(int)data<<std::endl;

    // Use the chid in the constructor.
    HeightContext context(9);

    context.process(HeightContext::START);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    context.process(HeightContext::HOLE_HEIGHT);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    context.process(HeightContext::SURFACE_HEIGHT);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    context.process(HeightContext::REF_HEIGHT);
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));

    std::cout<<"[TestHeightMeasurement] Done."<<std::endl;
}

/** @} */
<commit_msg>Some improvement of the test, but stil todo.<commit_after>/*
 * Copyright (C) 2017 Rene Herthel
 * Copyright (C) 2017 Jonas Fuhrmann
 *
 * This file is subject to the terms and conditions of the MIT License.
 * See the file LICENSE in the top level directory for more details.
 */

/**
 * @ingroup    height_measurement
 * @{
 *
 * @brief      Test function declaration of the HeightMeasurement component
 *
 * @author     Rene Herthel <rene.herthel@haw-hamburg.de>
 * @author     Jonas Fuhrmann <jonas.fuhrmann@haw-hamburg.de>
 */

#include "TestHeightMeasurement.h"

#include "HeightMeasurementHal.h"
#include "HeightContext.h"
#include "HeightMeasurementService.h"
#include "HWdefines.h"

#include <iostream>
#include <chrono>
#include <thread>

#define TEST_HEIGHT_HAL             (0)
#define TEST_HEIGHT_STATEMACHINE    (0)
#define TEST_HEIGHT_SERVICE         (1)
#define SLEEP_TIME                  (1000)

void TestHeightMeasurement::startTest() {
    std::cout<<"[TestHeightMeasurement] Start:"<<std::endl;

#if TEST_HEIGHT_HAL
    std::cout<<"[TestHeightMeasurement] Testing Hal."<<std::endl;
    HeightMeasurementHal hal;
    int16_t data = 0;
    hal.read(data);
    std::cout<<"[TestHeightMeasurement] Hal data: "<<(int)data<<std::endl;
#endif /* TEST_HEIGHT_HAL */

#if TEST_HEIGHT_STATEMACHINE
    std::cout<<"[TestHeightMeasurement] Testing context: "<<(int)data<<std::endl;
    // Use the chid in the constructor.
    HeightContext context(9); // Non available chid!
    context.process(HeightContext::START);
    std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
    context.process(HeightContext::HOLE_HEIGHT);
    std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
    context.process(HeightContext::SURFACE_HEIGHT);
    std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
    context.process(HeightContext::REF_HEIGHT);
    std::this_thread::sleep_for(std::chrono::milliseconds(SLEEP_TIME));
#endif /* TEST_HEIGHT_STATEMACHINE */

#if TEST_HEIGHT_SERVICE
    std::cout<<"[TestHeightMeasurement] Testing Service:"<<std::endl;
    // TODO HeightMeasurementService service(TODO);
#endif /* TEST_HEIGHT_SERVICE */

    std::cout<<"[TestHeightMeasurement] Done."<<std::endl;
}

/** @} */
<|endoftext|>


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

#include <Eigen/Core>
#include <glog/logging.h>
#include <gflags/gflags.h>
#include <theia/theia.h>
#include <string>
#include <vector>

#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#ifdef FREEGLUT
#include <GL/freeglut.h>
#else
#include <GLUT/glut.h>
#endif
#else
#ifdef _WIN32
#include <windows.h>
#endif
#define GL_GLEXT_PROTOTYPES 1
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif

DEFINE_string(reconstruction, "", "Reconstruction file to be viewed.");

// Containers for the data.
std::vector<theia::Camera> cameras;
std::vector<Eigen::Vector3d> world_points;
std::vector<int> num_views_for_track;

// Parameters for OpenGL.
int mouse_down_x[3], mouse_down_y[3];
float rot_x = 0.0f, rot_y = 0.0f;
float prev_x, prev_y;
float distance = 100.0;
Eigen::Vector3d origin = Eigen::Vector3d::Zero();
bool mouse_rotates = false, mouse_moves = false;
bool draw_cameras = true;
bool draw_axes = false;

float point_size = 1.0;
float normalized_focal_length = 1.0;
int min_num_views_for_track = 2;
void GetPerspectiveParams(double* aspect_ratio, double* fovy) {
  int width = 800;
  int height = 600;
  double focal_length = 600.0;
  *aspect_ratio = static_cast<double>(width) / static_cast<double>(height);
  *fovy = 2 * atan(height / (2.0 * focal_length)) * 180.0 / M_PI;
}

void ChangeSize(int w, int h) {
  // Prevent a divide by zero, when window is too short
  // (you cant make a window of zero width).
  if (h == 0) h = 1;

  // Use the Projection Matrix
  glMatrixMode(GL_PROJECTION);

  // Reset Matrix
  glLoadIdentity();

  // Set the viewport to be the entire window
  double aspect_ratio, fovy;
  GetPerspectiveParams(&aspect_ratio, &fovy);
  glViewport(0, 0, w, h);

  // Set the correct perspective.
  gluPerspective(fovy, aspect_ratio, 0.01f, 100000.0f);

  // Get Back to the Reconstructionview
  glMatrixMode(GL_MODELVIEW);
}

void DrawAxes(float length) {
  glPushAttrib(GL_POLYGON_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glDisable(GL_LIGHTING);

  glBegin(GL_LINES);
  glColor3f(1.0, 0.0, 0.0);
  glVertex3f(0, 0, 0);
  glVertex3f(length, 0, 0);

  glColor3f(0.0, 1.0, 0.0);
  glVertex3f(0, 0, 0);
  glVertex3f(0, length, 0);

  glColor3f(0.0, 0.0, 1.0);
  glVertex3f(0, 0, 0);
  glVertex3f(0, 0, length);
  glEnd();

  glPopAttrib();
}

void DrawCamera(const theia::Camera& camera) {
  glPushMatrix();
  Eigen::Matrix4d transformation_matrix;
  transformation_matrix.block<3, 3>(0, 0) =
      camera.GetOrientationAsRotationMatrix().transpose();
  transformation_matrix.col(3).head<3>() = camera.GetPosition();
  transformation_matrix(3, 3) = 1.0;

  // Apply world pose transformation.
  glMultMatrixd(reinterpret_cast<GLdouble*>(transformation_matrix.data()));

  // Draw Cameras.
  glColor3f(1.0, 0.0, 0.0);

  // Create the camera wireframe. If intrinsic parameters are not set then use
  // the focal length as a guess.

  // Use the camera calibration to display the cameras.
  Eigen::Matrix3d calibration;
  camera.GetCalibrationMatrix(&calibration);
  calibration /= camera.FocalLength();
  calibration(2, 2) = 1.0;

  const Eigen::Vector3d top_left =
      normalized_focal_length * (calibration * Eigen::Vector3d(-1, -1, 1));
  const Eigen::Vector3d top_right =
      normalized_focal_length * (calibration * Eigen::Vector3d(1, -1, 1));
  const Eigen::Vector3d bottom_right =
      normalized_focal_length * (calibration * Eigen::Vector3d(1, 1, 1));
  const Eigen::Vector3d bottom_left =
      normalized_focal_length * (calibration * Eigen::Vector3d(-1, 1, 1));

  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glBegin(GL_TRIANGLE_FAN);
  glVertex3f(0.0, 0.0, 0.0);
  glVertex3f(top_right[0], top_right[1], top_right[2]);
  glVertex3f(top_left[0], top_left[1], top_left[2]);
  glVertex3f(bottom_left[0], bottom_left[1], bottom_left[2]);
  glVertex3f(bottom_right[0], bottom_right[1], bottom_right[2]);
  glVertex3f(top_right[0], top_right[1], top_right[2]);
  glEnd();
  glPopMatrix();
}

void RenderScene() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();
  glTranslatef(-origin[0], -origin[1], -distance);
  glRotatef(180.0f + rot_x, 1.0f, 0.0f, 0.0f);
  glRotatef(-rot_y, 0.0f, 1.0f, 0.0f);
  glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

  if (draw_axes) {
    DrawAxes(1.0);
  }

  // Plot the point cloud.
  glDisable(GL_LIGHTING);
  glEnable(GL_MULTISAMPLE);
  glEnable(GL_BLEND);
  glEnable(GL_POINT_SMOOTH);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glPointSize(point_size);

  // the coordinates for calculating point attenuation:
  GLfloat point_size_coords[3];
  point_size_coords[0] = 1.0f;
  point_size_coords[1] = 0.055f;
  point_size_coords[2] = 0.0f;
  glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, point_size_coords);

  // Draw the points.
  glColor3f(0.01, 0.01, 0.01);
  glBegin(GL_POINTS);
  for (int i = 0; i < world_points.size(); i++) {
    if (num_views_for_track[i] < min_num_views_for_track) {
      continue;
    }
    glVertex3d(world_points[i].x(), world_points[i].y(), world_points[i].z());
  }
  glEnd();

  // Draw the cameras.
  if (draw_cameras) {
    for (int i = 0; i < cameras.size(); i++) {
      DrawCamera(cameras[i]);
    }
  }
  glutSwapBuffers();
}

void MouseButton(int button, int state, int x, int y) {
  // button down: save coordinates
  if (state == GLUT_DOWN && button <= 2) {
    mouse_down_x[button] = x;
    mouse_down_y[button] = y;
    prev_x = x;
    prev_y = y;

    if (button == GLUT_RIGHT_BUTTON) {
      mouse_rotates = true;
    } else if (button == GLUT_LEFT_BUTTON) {
      mouse_moves = true;
    }
    return;
  }

  if (state == GLUT_UP && button == GLUT_RIGHT_BUTTON) {
    mouse_rotates = false;
  }

  if (state == GLUT_UP && button == GLUT_LEFT_BUTTON) {
    mouse_moves = false;
  }

  // scroll event - wheel reports as button 3 (scroll up) and button 4 (scroll
  // down)
  if ((button == 3) || (button == 4)) {
    // Each wheel event reports like a button click, GLUT_DOWN then GLUT_UP
    if (state == GLUT_UP) return;  // Disregard redundant GLUT_UP events
    if (button == 3)
      distance /= 1.5f;
    else
      distance *= 1.5f;
  }
}

void MouseMove(int x, int y) {
  if (mouse_rotates) {
    const double rotate_factor = 0.5f;
    // notice x & y difference (i.e., changes in x are to rotate about y-axis)
    rot_x -= rotate_factor * (y - prev_y);
    rot_y -= rotate_factor * (x - prev_x);
    prev_x = x;
    prev_y = y;
  } else if (mouse_moves) {
    const double mouse_factor = 0.03f;
    origin.x() -= mouse_factor * (x - prev_x);
    origin.y() += mouse_factor * (y - prev_y);
    prev_x = x;
    prev_y = y;
  }
}

void Keyboard(unsigned char key, int x, int y) {
  switch (key) {
    case 'r':  // reset viewpoint
      distance = 100.0f;
      rot_x = 0.0f;
      rot_y = 0.0f;
      point_size = 1.0;
      origin = Eigen::Vector3d::Zero();
      break;
    case 'z':
      distance /= 1.2f;
      break;
    case 'Z':
      distance *= 1.2f;
      break;
    case 'p':
      point_size /= 1.2;
      break;
    case 'P':
      point_size *= 1.2;
      break;
    case 'f':
      normalized_focal_length /= 1.2;
      break;
    case 'F':
      normalized_focal_length *= 1.2;
      break;
    case 'c':
      draw_cameras = !draw_cameras;
      break;
    case 'a':
      draw_axes = !draw_axes;
      break;
    case 't':
      ++min_num_views_for_track;
      break;
    case 'T':
      --min_num_views_for_track;
      break;
  }
}

// initialize viewport etc.
void Init() {
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();

  double aspect_ratio, fovy;  // set the correct perspective.
  GetPerspectiveParams(&aspect_ratio, &fovy);
  gluPerspective(fovy, 1.0, .01, 100000.0);

  glMatrixMode(GL_MODELVIEW);
}

void CenterReconstruction() {
  Eigen::Vector3d mean_camera = Eigen::Vector3d::Zero();
  for (int i = 0; i < cameras.size(); i++) {
    mean_camera += cameras[i].GetPosition();
  }
  mean_camera /= static_cast<double>(cameras.size());

  for (int i = 0; i < cameras.size(); i++) {
    const Eigen::Vector3d old_position = cameras[i].GetPosition();
    cameras[i].SetPosition(old_position - mean_camera);
  }
  for (int i = 0; i < world_points.size(); i++) {
    world_points[i] -= mean_camera;
  }
}

int main(int argc, char* argv[]) {
  THEIA_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);

  // Output as a binary file.
  std::unique_ptr<theia::Reconstruction> reconstruction(
      new theia::Reconstruction());
  CHECK(ReadReconstruction(FLAGS_reconstruction, reconstruction.get()))
      << "Could not read reconstruction file.";

  // Set up camera drawing.
  cameras.reserve(reconstruction->NumViews());
  for (const theia::ViewId view_id : reconstruction->ViewIds()) {
    const auto* view = reconstruction->View(view_id);
    if (view == nullptr || !view->IsEstimated()) {
      continue;
    }
    cameras.emplace_back(view->Camera());
  }

  // Set up world points.
  world_points.reserve(reconstruction->NumTracks());
  for (const theia::TrackId track_id : reconstruction->TrackIds()) {
    const auto* track = reconstruction->Track(track_id);
    if (track == nullptr || !track->IsEstimated()) {
      continue;
    }
    world_points.emplace_back(track->Point().hnormalized());
    num_views_for_track.emplace_back(track->NumViews());
  }

  CenterReconstruction();

  reconstruction.release();

  // Set up opengl and glut.
  glutInit(&argc, argv);
  glutInitWindowPosition(600, 600);
  glutInitWindowSize(1200, 800);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow("Theia Reconstruction Viewer");

  // Set the camera
  gluLookAt(0.0f, 0.0f, -6.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

  // register callbacks
  glutDisplayFunc(RenderScene);
  glutReshapeFunc(ChangeSize);
  glutMouseFunc(MouseButton);
  glutMotionFunc(MouseMove);
  glutKeyboardFunc(Keyboard);
  glutIdleFunc(RenderScene);

  // enter GLUT event processing loop
  glutMainLoop();

  return 0;
}
<commit_msg>Improving view browsing. Now uses a proper trackball<commit_after>// Copyright (C) 2014 The Regents of the University of California (Regents).
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//
//     * Neither the name of The Regents or University of California nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
// Please contact the author of this library if you have any questions.
// Author: Chris Sweeney (cmsweeney@cs.ucsb.edu)

#include <Eigen/Core>
#include <glog/logging.h>
#include <gflags/gflags.h>
#include <theia/theia.h>
#include <string>
#include <vector>

#ifdef __APPLE__
#include <OpenGL/OpenGL.h>
#ifdef FREEGLUT
#include <GL/freeglut.h>
#else
#include <GLUT/glut.h>
#endif
#else
#ifdef _WIN32
#include <windows.h>
#endif
#define GL_GLEXT_PROTOTYPES 1
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glut.h>
#endif

DEFINE_string(reconstruction, "", "Reconstruction file to be viewed.");

// Containers for the data.
std::vector<theia::Camera> cameras;
std::vector<Eigen::Vector3d> world_points;
std::vector<int> num_views_for_track;

// Parameters for OpenGL.
int width = 1200;
int height = 800;
int mouse_down_x[3], mouse_down_y[3];
float rot_x = 0.0f, rot_y = 0.0f;
float prev_x, prev_y;
float distance = 1.0;
Eigen::Vector3d origin = Eigen::Vector3d::Zero();
bool mouse_rotates = false, mouse_moves = false;

bool draw_cameras = true;
bool draw_axes = false;
float point_size = 1.0;
float normalized_focal_length = 1.0;
int min_num_views_for_track = 3;

void GetPerspectiveParams(double* aspect_ratio, double* fovy) {
  double focal_length = 800.0;
  *aspect_ratio = static_cast<double>(width) / static_cast<double>(height);
  *fovy = 2 * atan(height / (2.0 * focal_length)) * 180.0 / M_PI;
}

void ChangeSize(int w, int h) {
  // Prevent a divide by zero, when window is too short
  // (you cant make a window of zero width).
  if (h == 0) h = 1;

  // Use the Projection Matrix
  glMatrixMode(GL_PROJECTION);

  // Reset Matrix
  glLoadIdentity();

  // Set the viewport to be the entire window
  double aspect_ratio, fovy;
  GetPerspectiveParams(&aspect_ratio, &fovy);
  glViewport(0, 0, w, h);

  // Set the correct perspective.
  gluPerspective(fovy, aspect_ratio, 0.001f, 100000.0f);

  // Get Back to the Reconstructionview
  glMatrixMode(GL_MODELVIEW);
}

void DrawAxes(float length) {
  glPushAttrib(GL_POLYGON_BIT | GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT);

  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glDisable(GL_LIGHTING);
  glLineWidth(5.0);
  glBegin(GL_LINES);
  glColor3f(1.0, 0.0, 0.0);
  glVertex3f(0, 0, 0);
  glVertex3f(length, 0, 0);

  glColor3f(0.0, 1.0, 0.0);
  glVertex3f(0, 0, 0);
  glVertex3f(0, length, 0);

  glColor3f(0.0, 0.0, 1.0);
  glVertex3f(0, 0, 0);
  glVertex3f(0, 0, length);
  glEnd();

  glPopAttrib();
  glLineWidth(1.0);
}

void DrawCamera(const theia::Camera& camera) {
  glPushMatrix();
  Eigen::Matrix4d transformation_matrix;
  transformation_matrix.block<3, 3>(0, 0) =
      camera.GetOrientationAsRotationMatrix().transpose();
  transformation_matrix.col(3).head<3>() = camera.GetPosition();
  transformation_matrix(3, 3) = 1.0;

  // Apply world pose transformation.
  glMultMatrixd(reinterpret_cast<GLdouble*>(transformation_matrix.data()));

  // Draw Cameras.
  glColor3f(1.0, 0.0, 0.0);

  // Create the camera wireframe. If intrinsic parameters are not set then use
  // the focal length as a guess.

  // Use the camera calibration to display the cameras.
  Eigen::Matrix3d calibration;
  camera.GetCalibrationMatrix(&calibration);
  calibration /= camera.FocalLength();
  calibration(2, 2) = 1.0;

  const Eigen::Vector3d top_left =
      normalized_focal_length * (calibration * Eigen::Vector3d(-1, -1, 1));
  const Eigen::Vector3d top_right =
      normalized_focal_length * (calibration * Eigen::Vector3d(1, -1, 1));
  const Eigen::Vector3d bottom_right =
      normalized_focal_length * (calibration * Eigen::Vector3d(1, 1, 1));
  const Eigen::Vector3d bottom_left =
      normalized_focal_length * (calibration * Eigen::Vector3d(-1, 1, 1));

  glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
  glBegin(GL_TRIANGLE_FAN);
  glVertex3f(0.0, 0.0, 0.0);
  glVertex3f(top_right[0], top_right[1], top_right[2]);
  glVertex3f(top_left[0], top_left[1], top_left[2]);
  glVertex3f(bottom_left[0], bottom_left[1], bottom_left[2]);
  glVertex3f(bottom_right[0], bottom_right[1], bottom_right[2]);
  glVertex3f(top_right[0], top_right[1], top_right[2]);
  glEnd();
  glPopMatrix();
}

void RenderScene() {
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glTranslatef(0.0, 0.0, -10);

  glRotatef(180.0f + rot_x, 1.0f, 0.0f, 0.0f);
  glRotatef(-rot_y, 0.0f, 1.0f, 0.0f);
  if (draw_axes) {
    DrawAxes(1.0);
  }

  glScalef(distance, distance, distance);

  glTranslatef(-origin[0], -origin[1], -origin[2]);
  glClearColor(1.0f, 1.0f, 1.0f, 0.0f);

  // Plot the point cloud.
  glDisable(GL_LIGHTING);
  glEnable(GL_MULTISAMPLE);
  glEnable(GL_BLEND);
  glEnable(GL_POINT_SMOOTH);
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

  glPointSize(point_size);

  // the coordinates for calculating point attenuation:
  GLfloat point_size_coords[3];
  point_size_coords[0] = 1.0f;
  point_size_coords[1] = 0.055f;
  point_size_coords[2] = 0.0f;
  glPointParameterfv(GL_POINT_DISTANCE_ATTENUATION, point_size_coords);

  // Draw the points.
  glColor3f(0.01, 0.01, 0.01);
  glBegin(GL_POINTS);
  for (int i = 0; i < world_points.size(); i++) {
    if (num_views_for_track[i] < min_num_views_for_track) {
      continue;
    }
    glVertex3d(world_points[i].x(), world_points[i].y(), world_points[i].z());
  }
  glEnd();

  // Draw the cameras.
  if (draw_cameras) {
    for (int i = 0; i < cameras.size(); i++) {
      DrawCamera(cameras[i]);
    }
  }

  glutSwapBuffers();
}

void MouseButton(int button, int state, int x, int y) {
  // button down: save coordinates
  if (state == GLUT_DOWN && button <= 2) {
    mouse_down_x[button] = x;
    mouse_down_y[button] = y;
    prev_x = x;
    prev_y = y;

    if (button == GLUT_RIGHT_BUTTON) {
      mouse_rotates = true;
    } else if (button == GLUT_LEFT_BUTTON) {
      mouse_moves = true;
    }
    return;
  }

  if (state == GLUT_UP && button == GLUT_RIGHT_BUTTON) {
    mouse_rotates = false;
  }

  if (state == GLUT_UP && button == GLUT_LEFT_BUTTON) {
    mouse_moves = false;
  }

  // scroll event - wheel reports as button 3 (scroll up) and button 4 (scroll
  // down)
  if ((button == 3) || (button == 4)) {
    // Each wheel event reports like a button click, GLUT_DOWN then GLUT_UP
    if (state == GLUT_UP) return;  // Disregard redundant GLUT_UP events
    if (button == 3)
      distance /= 1.5f;
    else
      distance *= 1.5f;
  }
}

void MouseMove(int x, int y) {
  if (mouse_rotates) {
    const double rotate_factor = 0.5f;
    // notice x & y difference (i.e., changes in x are to rotate about y-axis)
    rot_x -= rotate_factor * (y - prev_y);
    rot_y -= rotate_factor * (x - prev_x);
    prev_x = x;
    prev_y = y;
  } else if (mouse_moves) {
    const Eigen::Quaterniond inv_rot =
        Eigen::Quaterniond(Eigen::AngleAxisd(theia::DegToRad(180.f + rot_x),
                                             Eigen::Vector3d::UnitX()) *
                           Eigen::AngleAxisd(theia::DegToRad(-rot_y),
                                             Eigen::Vector3d::UnitY()));
    origin += inv_rot * Eigen::Vector3d(prev_x - x, y - prev_y, 0);
    prev_x = x;
    prev_y = y;
  }
}

void Keyboard(unsigned char key, int x, int y) {
  switch (key) {
    case 'r':  // reset viewpoint
      distance = 100.0f;
      rot_x = 0.0f;
      rot_y = 0.0f;
      point_size = 1.0;
      origin = Eigen::Vector3d::Zero();
      break;
    case 'z':
      distance /= 1.2f;
      break;
    case 'Z':
      distance *= 1.2f;
      break;
    case 'p':
      point_size /= 1.2;
      break;
    case 'P':
      point_size *= 1.2;
      break;
    case 'f':
      normalized_focal_length /= 1.2;
      break;
    case 'F':
      normalized_focal_length *= 1.2;
      break;
    case 'c':
      draw_cameras = !draw_cameras;
      break;
    case 'a':
      draw_axes = !draw_axes;
      break;
    case 't':
      ++min_num_views_for_track;
      break;
    case 'T':
      --min_num_views_for_track;
      break;
  }
}

void CenterReconstruction() {
  Eigen::Vector3d mean_camera = Eigen::Vector3d::Zero();
  for (int i = 0; i < cameras.size(); i++) {
    mean_camera += cameras[i].GetPosition();
  }
  mean_camera /= static_cast<double>(cameras.size());

  for (int i = 0; i < cameras.size(); i++) {
    const Eigen::Vector3d old_position = cameras[i].GetPosition();
    cameras[i].SetPosition(old_position - mean_camera);
  }
  for (int i = 0; i < world_points.size(); i++) {
    world_points[i] -= mean_camera;
  }
}

int main(int argc, char* argv[]) {
  THEIA_GFLAGS_NAMESPACE::ParseCommandLineFlags(&argc, &argv, true);
  google::InitGoogleLogging(argv[0]);

  // Output as a binary file.
  std::unique_ptr<theia::Reconstruction> reconstruction(
      new theia::Reconstruction());
  CHECK(ReadReconstruction(FLAGS_reconstruction, reconstruction.get()))
      << "Could not read reconstruction file.";

  // Set up camera drawing.
  cameras.reserve(reconstruction->NumViews());
  for (const theia::ViewId view_id : reconstruction->ViewIds()) {
    const auto* view = reconstruction->View(view_id);
    if (view == nullptr || !view->IsEstimated()) {
      continue;
    }
    cameras.emplace_back(view->Camera());
  }

  // Set up world points.
  world_points.reserve(reconstruction->NumTracks());
  for (const theia::TrackId track_id : reconstruction->TrackIds()) {
    const auto* track = reconstruction->Track(track_id);
    if (track == nullptr || !track->IsEstimated()) {
      continue;
    }
    world_points.emplace_back(track->Point().hnormalized());
    num_views_for_track.emplace_back(track->NumViews());
  }

  CenterReconstruction();

  reconstruction.release();

  // Set up opengl and glut.
  glutInit(&argc, argv);
  glutInitWindowPosition(600, 600);
  glutInitWindowSize(1200, 800);
  glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
  glutCreateWindow("Theia Reconstruction Viewer");

  // Set the camera
  gluLookAt(0.0f, 0.0f, -6.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f);

  // register callbacks
  glutDisplayFunc(RenderScene);
  glutReshapeFunc(ChangeSize);
  glutMouseFunc(MouseButton);
  glutMotionFunc(MouseMove);
  glutKeyboardFunc(Keyboard);
  glutIdleFunc(RenderScene);

  // enter GLUT event processing loop
  glutMainLoop();

  return 0;
}
<|endoftext|>