<commit_before>#include "webcam.hpp"
#include <chrono>

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

unsigned long long getMilliseconds() {
 return chrono::system_clock::now().time_since_epoch()/chrono::milliseconds(1);
}

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

/*****
 begin camera setup
*****/

 CvCapture* capture = 0;
 int width, height;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream config_file (".config");

 if (config_file.is_open()) {
// does not support corrupted .config

  string line;
  getline(config_file, line);
  istringstream(line)>>width;
  getline(config_file, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  config_file.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream config_file_out(".config");
  config_file_out << width;
  config_file_out << "\n";
  config_file_out << height;
  config_file_out << "\n";
  config_file_out.close();
 }

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

/*****
 end camera setup
*****/

/*****
 filter setup
*****/

 Mat acbg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated background
 Mat acbg_m(256, 256, CV_8UC1, Scalar(0));
// accumulated background mask

 Mat acfg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated foreground
 Mat acfg_t(256, 256, CV_8UC3, Scalar(0));
// accumulated foreground threshold

 Mat img_256_p(256, 256, CV_8UC3, Scalar(0,0,0));
// previous image
 Mat haar_t_p(256, 256, CV_8UC1, Scalar(1));
// previous possible locations for mouth

/*****
 end filter setup
*****/

/*****
 misc
*****/

 unsigned long long times[100];
 for (int i=0; i<100; i++)
  times[i] = 0;

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 unsigned long long timenow = getMilliseconds();

 bool keep_going = true;

 CascadeClassifier mouth_cascade;
 mouth_cascade.load("Mouth.xml");

/*****
 begin filter loop
*****/

 while (keep_going) {

  Mat image(cvQueryFrame(capture));
//  imshow("webcam", image);
// at some point preprocess by rotating according to OVR roll
// right now really annoying because of state variables

  Mat gray, img_256, gray_256;
  resize(image, img_256, Size(256, 256));
  cvtColor(image, gray, CV_RGB2GRAY);
  cvtColor(img_256, gray_256, CV_RGB2GRAY);

// this mask gets anything kind of dark (DK2) and dilates
// should work *great*
  Mat gr_m;
// gray mask
  equalizeHist(gray_256, gr_m);
  threshold(gr_m, gr_m, 215, 1, THRESH_BINARY);
  dilate(gr_m, gr_m, ellipticKernel(23));
  erode(gr_m, gr_m, ellipticKernel(45));

//  imshow("gray mask", gray_256.mul(1-gr_m));

  bitwise_or(acbg_m, gr_m, acbg_m);
//  imshow("accumulated bg mask", gray_256.mul(1-acbg_m));

// this mask watches for flow against accumulated bg
  Mat fl_m;
// flow mask
  absdiff(img_256, acbg, fl_m);
  cvtColor(fl_m, fl_m, CV_BGR2GRAY);
  fl_m = acbg_m.mul(fl_m);
  threshold(fl_m, fl_m, 45, 1, THRESH_BINARY_INV);
  erode(fl_m, fl_m, ellipticKernel(51));
//  imshow("flow mask", fl_m*255);

  Mat bg_m;
  bitwise_and(acbg_m, fl_m, bg_m);
  bitwise_or(gr_m, bg_m, bg_m);
//  imshow("bgm", bg_m*255);

// maybe do some morphological operations on bg_m?
// previously combined bg_m with its opening

// ugly way to compute:
// acbg = [acbg'.(1-bg_m)]+[((acbg'+img_256)/2).bg_m]
// find a nicer way later
// problem is masks are 1 channel while images are 3 channel

  Mat bg_m3;
  Mat tmp0[3];
  tmp0[0] = tmp0[1] = tmp0[2] = bg_m;
  merge(tmp0, 3, bg_m3);
//  imshow("bg_m3", bg_m3*255);
  acbg = acbg.mul(Scalar(1,1,1)-bg_m3) + (acbg/2+img_256/2).mul(bg_m3);
//  imshow("acbg", acbg);

//  imshow("bg mask", gray_256.mul(1-bg_m));

  Mat df_m;
// delta flow mask
  absdiff(img_256, img_256_p, df_m);
  cvtColor(df_m, df_m, CV_BGR2GRAY);
  threshold(df_m, df_m, 30, 1, THRESH_BINARY);
  int t1,t2;
  t1 = tracker1+1-(tracker1%2);
  if (t1<3) t1=3;
  if (t1>90) t1=91;
  t2 = tracker2+1-(tracker2%2);
  if (t2<3) t2=3;
  if (t2>90) t2=91;

  erode(df_m, df_m, ellipticKernel(t1, t2));
for (int j=0; j<tracker3; j++) {
  dilate(df_m, df_m, ellipticKernel(t1, t2));
  erode(df_m, df_m, ellipticKernel(t1, t2));
}

  imshow("delta flow mask", df_m*255);
  img_256_p = img_256.clone();

  Mat haar_m;
// bitwise_and(1 - bg_m, fg_m, haar_m);
  haar_m = 1 - bg_m;

// run haar classifier
  int scale = width/300;
  if (scale < 1)
   scale = 1;
// can't use 256x256 since haar isn't stretch invariant

  Mat thingy;
  resize(gray, thingy, Size(width/scale, height/scale));
  equalizeHist(thingy, thingy);
///////////////////
// need to change this after foreground stuff gets written

  vector<Rect> mouth_rects;
  resize(haar_m, haar_m, Size(width/scale, height/scale));

  thingy = thingy.mul(haar_m);
/////////////////

  mouth_cascade.detectMultiScale(thingy, mouth_rects, 1.1, 0, CV_HAAR_SCALE_IMAGE);
  Mat rect_image(height, width, CV_8UC1, Scalar(0));

  for (size_t i=0; i<mouth_rects.size(); i++) {
   Rect scaled(mouth_rects[i].x*scale, mouth_rects[i].y*scale, mouth_rects[i].width*scale,mouth_rects[i].height*scale);
   Mat new_rect(height, width, CV_8UC1, Scalar(0));
   rectangle(new_rect, scaled, Scalar(1), CV_FILLED);
   rect_image += new_rect;
  }

  double min_val, max_val;
  minMaxLoc(rect_image, &min_val, &max_val);

// or maybe equalize? this whole thing needs to be rewritten
// with the new fg and temporal coherence ideas

  Mat rect_thresh;
  threshold(rect_image, rect_thresh, max_val*0.9, 1, THRESH_BINARY);
  imshow("mouth", rect_thresh.mul(gray));

/*
  Moments m = moments(rect_thresh, 1);
  circle(image, Point(m.m10/m.m00,m.m01/m.m00),20,Scalar(128),30);
  imshow("centroid", image);
*/

  keep_going = (waitKey(1)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}

<commit_msg>hacking<commit_after>#include "webcam.hpp"
#include <chrono>

using namespace cv;
using namespace std;

Mat ellipticKernel(int width, int height = -1) {
 if (height==-1) {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,width), Point(width/2, width/2));
 } else {
  return getStructuringElement(MORPH_ELLIPSE,Size(width,height), Point(width/2, height/2));
 }
}

unsigned long long getMilliseconds() {
 return chrono::system_clock::now().time_since_epoch()/chrono::milliseconds(1);
}

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

/*****
 begin camera setup
*****/

 CvCapture* capture = 0;
 int width, height;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream config_file (".config");

 if (config_file.is_open()) {
// does not support corrupted .config

  string line;
  getline(config_file, line);
  istringstream(line)>>width;
  getline(config_file, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  config_file.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream config_file_out(".config");
  config_file_out << width;
  config_file_out << "\n";
  config_file_out << height;
  config_file_out << "\n";
  config_file_out.close();
 }

 for (int i = 0; i < 30; i++) {
  // capture some frames so exposure correction takes place
  cvQueryFrame(capture);
 }

/*****
 end camera setup
*****/

/*****
 filter setup
*****/

 Mat acbg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated background
 Mat acbg_m(256, 256, CV_8UC1, Scalar(0));
// accumulated background mask

 Mat acfg(256, 256, CV_8UC3, Scalar(0,0,0));
// accumulated foreground
 Mat acfg_t(256, 256, CV_8UC3, Scalar(0));
// accumulated foreground threshold

 Mat img_256_p(256, 256, CV_8UC3, Scalar(0,0,0));
// previous image
 Mat haar_t_p(256, 256, CV_8UC1, Scalar(1));
// previous possible locations for mouth

/*****
 end filter setup
*****/

/*****
 misc
*****/

 unsigned long long times[100];
 for (int i=0; i<100; i++)
  times[i] = 0;

 int tracker1, tracker2, tracker3;
 namedWindow("s",1);
 createTrackbar("1","s",&tracker1,100);
 createTrackbar("2","s",&tracker2,100);
 createTrackbar("3","s",&tracker3,100);

 unsigned long long timenow = getMilliseconds();

 bool keep_going = true;

 CascadeClassifier mouth_cascade;
 mouth_cascade.load("Mouth.xml");

/*****
 begin filter loop
*****/

 while (keep_going) {

  Mat image(cvQueryFrame(capture));
//  imshow("webcam", image);
// at some point preprocess by rotating according to OVR roll
// right now really annoying because of state variables

  Mat gray, img_256, gray_256;
  resize(image, img_256, Size(256, 256));
  cvtColor(image, gray, CV_RGB2GRAY);
  cvtColor(img_256, gray_256, CV_RGB2GRAY);

// this mask gets anything kind of dark (DK2) and dilates
// should work *great*
  Mat gr_m;
// gray mask
  equalizeHist(gray_256, gr_m);
  threshold(gr_m, gr_m, 215, 1, THRESH_BINARY);
  dilate(gr_m, gr_m, ellipticKernel(23));
  erode(gr_m, gr_m, ellipticKernel(45));

//  imshow("gray mask", gray_256.mul(1-gr_m));

  bitwise_or(acbg_m, gr_m, acbg_m);
//  imshow("accumulated bg mask", gray_256.mul(1-acbg_m));

// this mask watches for flow against accumulated bg
  Mat fl_m;
// flow mask
  absdiff(img_256, acbg, fl_m);
  cvtColor(fl_m, fl_m, CV_BGR2GRAY);
  fl_m = acbg_m.mul(fl_m);
  threshold(fl_m, fl_m, 45, 1, THRESH_BINARY_INV);
  erode(fl_m, fl_m, ellipticKernel(51));
//  imshow("flow mask", fl_m*255);

  Mat bg_m;
  bitwise_and(acbg_m, fl_m, bg_m);
  bitwise_or(gr_m, bg_m, bg_m);
//  imshow("bgm", bg_m*255);

// maybe do some morphological operations on bg_m?
// previously combined bg_m with its opening

// ugly way to compute:
// acbg = [acbg'.(1-bg_m)]+[((acbg'+img_256)/2).bg_m]
// find a nicer way later
// problem is masks are 1 channel while images are 3 channel

  Mat bg_m3;
  Mat tmp0[3];
  tmp0[0] = tmp0[1] = tmp0[2] = bg_m;
  merge(tmp0, 3, bg_m3);
//  imshow("bg_m3", bg_m3*255);
  acbg = acbg.mul(Scalar(1,1,1)-bg_m3) + (acbg/2+img_256/2).mul(bg_m3);
//  imshow("acbg", acbg);

//  imshow("bg mask", gray_256.mul(1-bg_m));

  Mat df_m;
// delta flow mask
  absdiff(img_256, img_256_p, df_m);
  cvtColor(df_m, df_m, CV_BGR2GRAY);
  threshold(df_m, df_m, 5, 1, THRESH_BINARY);
  int t1,t2;
  t1 = tracker1+1-(tracker1%2);
  if (t1<3) t1=3;
  if (t1>90) t1=91;
  t2 = tracker2+1-(tracker2%2);
  if (t2<3) t2=3;
  if (t2>90) t2=91;

  erode(df_m, df_m, ellipticKernel(t1, t2));
for (int j=0; j<tracker3; j++) {
  dilate(df_m, df_m, ellipticKernel(t1, t2));
  erode(df_m, df_m, ellipticKernel(t1, t2));
}

  imshow("delta flow mask", df_m*255);
  img_256_p = img_256.clone();

  Mat haar_m;
// bitwise_and(1 - bg_m, fg_m, haar_m);
  haar_m = 1 - bg_m;

// run haar classifier
  int scale = width/300;
  if (scale < 1)
   scale = 1;
// can't use 256x256 since haar isn't stretch invariant

  Mat thingy;
  resize(gray, thingy, Size(width/scale, height/scale));
  equalizeHist(thingy, thingy);
///////////////////
// need to change this after foreground stuff gets written

  vector<Rect> mouth_rects;
  resize(haar_m, haar_m, Size(width/scale, height/scale));

  thingy = thingy.mul(haar_m);
/////////////////

  mouth_cascade.detectMultiScale(thingy, mouth_rects, 1.1, 0, CV_HAAR_SCALE_IMAGE);
  Mat rect_image(height, width, CV_8UC1, Scalar(0));

  for (size_t i=0; i<mouth_rects.size(); i++) {
   Rect scaled(mouth_rects[i].x*scale, mouth_rects[i].y*scale, mouth_rects[i].width*scale,mouth_rects[i].height*scale);
   Mat new_rect(height, width, CV_8UC1, Scalar(0));
   rectangle(new_rect, scaled, Scalar(1), CV_FILLED);
   rect_image += new_rect;
  }

  double min_val, max_val;
  minMaxLoc(rect_image, &min_val, &max_val);

// or maybe equalize? this whole thing needs to be rewritten
// with the new fg and temporal coherence ideas

  Mat rect_thresh;
  threshold(rect_image, rect_thresh, max_val*0.9, 1, THRESH_BINARY);
  imshow("mouth", rect_thresh.mul(gray));

/*
  Moments m = moments(rect_thresh, 1);
  circle(image, Point(m.m10/m.m00,m.m01/m.m00),20,Scalar(128),30);
  imshow("centroid", image);
*/

  keep_going = (waitKey(1)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}

<|endoftext|>


<commit_before>#include "webcam.hpp"

using namespace cv;
using namespace std;

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

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
  //imshow("webcam", image);

// thresholds on dark regions

  Mat gray, blurred_gray, threshold_gray;
  cvtColor(image, gray, CV_BGR2GRAY);

  blur(gray, blurred_gray, Size(width/10,height/20));
  equalizeHist(blurred_gray, blurred_gray);
  bitwise_not(blurred_gray, blurred_gray);
  threshold(blurred_gray, threshold_gray, 210, 1, THRESH_BINARY);
  imshow("threshold", threshold_gray);

  Mat canny;
  equalizeHist(gray, gray);
  Canny(gray, canny, 50, 200, 3);
  imshow("canny", canny);
  vector<Vec4i> lines;
  HoughLinesP(canny, lines, 10, CV_PI/180, 150);
  for (size_t i = 0; i < lines.size(); i++) {
   line(image, Point(lines[i][0], lines[i][1]),
    Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8);
  }

  imshow("lola", image);
/*
  bitwise_not(gray,gray);
  Mat mask = threshold_gray.mul(gray);
  imshow("mask", mask);

  Moments lol = moments(mask, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);
*/
  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<commit_msg>hacking<commit_after>#include "webcam.hpp"

using namespace cv;
using namespace std;

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

 CvCapture* capture = 0;
 int width, height, fps;

 capture = cvCaptureFromCAM(0);

 if (!capture) {
  printf("No camera detected!");
  return -1;
 }

 ifstream configFile (".config");

 if (configFile.is_open()) {

  //probably want to support corrupted .config
  string line;
  getline(configFile, line);
  istringstream(line)>>width;
  getline(configFile, line);
  istringstream(line)>>height;
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, width);
  cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, height);

  configFile.close();

 } else {

  initResolutions();

  for (int i=36; i<150; i++) {
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH, resolutions[i].width);
   cvSetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT, resolutions[i].height);
  }

  width = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
  height = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);

  ofstream configFileOut(".config");
  configFileOut << width;
  configFileOut << "\n";
  configFileOut << height;
  configFileOut << "\n";
  configFileOut.close();
 }

 bool keepGoing = true;

// srand(890);//not interested in good randomness

 Mat image;
 Mat channel[3];

 while (keepGoing) {

  image = cvQueryFrame(capture);
  //imshow("webcam", image);

// thresholds on dark regions

  Mat gray, blurred_gray, threshold_gray;
  cvtColor(image, gray, CV_BGR2GRAY);

  blur(gray, blurred_gray, Size(width/10,height/20));
  equalizeHist(blurred_gray, blurred_gray);
  bitwise_not(blurred_gray, blurred_gray);
  threshold(blurred_gray, threshold_gray, 210, 1, THRESH_BINARY);
  imshow("threshold", threshold_gray);

  Mat canny;
  Canny(gray, canny, 30, 40, 3);
  imshow("canny", canny);
  vector<Vec4i> lines;
  HoughLinesP(canny, lines, 10, CV_PI/180, 150);
  for (size_t i = 0; i < lines.size(); i++) {
   line(image, Point(lines[i][0], lines[i][1]),
    Point(lines[i][2], lines[i][3]), Scalar(0,0,255), 3, 8);
  }

  imshow("lola", image);
/*
  bitwise_not(gray,gray);
  Mat mask = threshold_gray.mul(gray);
  imshow("mask", mask);

  Moments lol = moments(mask, 1);
  circle(image, Point(lol.m10/lol.m00,lol.m01/lol.m00),20,Scalar(128),30);
  imshow("leimage", image);
*/
  keepGoing = (waitKey(25)<0);

 }

 cvReleaseCapture(&capture);

 return 0;
}
<|endoftext|>


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

#include "paddle/phi/backends/c_comm_lib.h"

namespace phi {
// Even this source file does not contains any code, it is better to keep this
// source file for cmake dependency.
}  // namespace phi
<commit_msg>[CustomDevice] remove unused file (#44358)<commit_after><|endoftext|>


<commit_before>/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-7-7 20:57:37
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 1000000000000007;

typedef tuple<bool, ll> I;
typedef tuple<int, ll> P;
int n, m;
vector<P> V[100010];
I info[100010];
I nil = I(true, infty);
set<ll> value;

int main()
{
  cin >> n >> m;
  for (auto i = 0; i < m; i++)
  {
    int u, v;
    ll s;
    cin >> u >> v >> s;
    u--;
    v--;
    V[u].push_back(P(v, s));
    V[v].push_back(P(u, s));
  }
  fill(info, info + 100010, nil);
  info[0] = I(true, 0);
  queue<int> Q;
  Q.push(0);
  bool visited[100010];
  fill(visited, visited + 100010, false);
  while (!Q.empty())
  {
    int x = Q.front();
    Q.pop();
    if (!visited[x])
    {
      visited[x] = true;
      bool pm = get<0>(info[x]);
      ll v = get<1>(info[x]);
      for (auto e : V[x])
      {
        int y = get<0>(e);
        ll w = get<1>(e);
        if (info[y] == nil)
        {
          info[y] = I(!pm, w - v);
          Q.push(y);
        }
        else
        {
          bool pm2 = get<0>(info[y]);
          ll v2 = get<1>(info[y]);
          if (pm == pm2)
          {
            ll tmp = w - (v + v2);
            if (tmp % 2 != 0)
            {
              cout << 0 << endl;
              return 0;
            }
            tmp = tmp / 2;
            if (!pm)
            {
              tmp = -tmp;
            }
            if (tmp > 0)
            {
              value.insert(tmp);
              if ((int)value.size() > 1)
              {
                cout << 0 << endl;
                return 0;
              }
            }
          }
          else
          {
            if (info[y] != I(!pm, w - v))
            {
              cout << 0 << endl;
              return 0;
            }
          }
        }
      }
    }
  }
  ll p_mini = infty;
  ll m_mini = infty;
  if ((int)value.size() == 1)
  {
    cout << 1 << endl;
    return 0;
  }
  for (auto i = 0; i < n; i++)
  {
    bool pm = get<0>(info[i]);
    ll v = get<1>(info[i]);
    // cerr << "info[" << i << "] = (" << pm << ", " << v << ")" << endl;
    if (pm)
    {
      p_mini = min(p_mini, v);
    }
    else
    {
      m_mini = min(m_mini, v);
    }
  }
  // cerr << p_mini << " " << m_mini << endl;
  ll ans;
  if (p_mini >= 0)
  {
    ans = m_mini - 1;
  }
  else
  {
    ans = m_mini + p_mini - 1;
  }
  cout << max(0ll, ans) << endl;
}<commit_msg>submit E.cpp to 'E - + Graph' (soundhound2018-summer-qual) [C++14 (GCC 5.4.1)]<commit_after>/**
 * File    : E.cpp
 * Author  : Kazune Takahashi
 * Created : 2018-7-7 20:57:37
 * Powered by Visual Studio Code
 */

#include <iostream>
#include <iomanip>   // << fixed << setprecision(xxx)
#include <algorithm> // do { } while ( next_permutation(A, A+xxx) ) ;
#include <vector>
#include <string> // to_string(nnn) // substr(m, n) // stoi(nnn)
#include <complex>
#include <tuple>
#include <queue>
#include <stack>
#include <map> // if (M.find(key) != M.end()) { }
#include <set>
#include <functional>
#include <random> // auto rd = bind(uniform_int_distribution<int>(0, 9), mt19937(19920725));
#include <chrono> // std::chrono::system_clock::time_point start_time, end_time;
// start = std::chrono::system_clock::now();
// double elapsed = std::chrono::duration_cast<std::chrono::milliseconds>(end_time-start_time).count();
#include <cctype>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
using namespace std;

#define DEBUG 0 // change 0 -> 1 if we need debug.

typedef long long ll;

// const int dx[4] = {1, 0, -1, 0};
// const int dy[4] = {0, 1, 0, -1};

// const int C = 1e6+10;
const ll infty = 1000000000000007;

typedef tuple<bool, ll> I;
typedef tuple<int, ll> P;
int n, m;
vector<P> V[100010];
I info[100010];
I nil = I(true, infty);
set<ll> value;

int main()
{
  cin >> n >> m;
  for (auto i = 0; i < m; i++)
  {
    int u, v;
    ll s;
    cin >> u >> v >> s;
    u--;
    v--;
    V[u].push_back(P(v, s));
    V[v].push_back(P(u, s));
  }
  fill(info, info + 100010, nil);
  info[0] = I(true, 0);
  queue<int> Q;
  Q.push(0);
  bool visited[100010];
  fill(visited, visited + 100010, false);
  while (!Q.empty())
  {
    int x = Q.front();
    Q.pop();
    if (!visited[x])
    {
      visited[x] = true;
      bool pm = get<0>(info[x]);
      ll v = get<1>(info[x]);
      for (auto e : V[x])
      {
        int y = get<0>(e);
        ll w = get<1>(e);
        if (info[y] == nil)
        {
          info[y] = I(!pm, w - v);
          Q.push(y);
        }
        else
        {
          bool pm2 = get<0>(info[y]);
          ll v2 = get<1>(info[y]);
          if (pm == pm2)
          {
            ll tmp = w - (v + v2);
            if (tmp % 2 != 0)
            {
              cout << 0 << endl;
              return 0;
            }
            tmp = tmp / 2;
            if (!pm)
            {
              tmp = -tmp;
            }
            if (tmp > 0)
            {
              value.insert(tmp);
              if ((int)value.size() > 1)
              {
                cout << 0 << endl;
                return 0;
              }
            }
          }
          else
          {
            if (info[y] != I(!pm, w - v))
            {
              cout << 0 << endl;
              return 0;
            }
          }
        }
      }
    }
  }
  ll p_mini = infty;
  ll m_mini = infty;
  for (auto i = 0; i < n; i++)
  {
    bool pm = get<0>(info[i]);
    ll v = get<1>(info[i]);
    // cerr << "info[" << i << "] = (" << pm << ", " << v << ")" << endl;
    if (pm)
    {
      p_mini = min(p_mini, v);
    }
    else
    {
      m_mini = min(m_mini, v);
    }
  }
  if ((int)value.size() == 1)
  {
    int x = *value.begin();
    if (-p_mini <= x && x <= m_mini)
    {
      cout << 1 << endl;
      return 0;
    }
    else
    {
      cout << 0 << endl;
      return 0;
    }
  }
  // cerr << p_mini << " " << m_mini << endl;
  ll ans;
  if (p_mini >= 0)
  {
    ans = m_mini - 1;
  }
  else
  {
    ans = m_mini + p_mini - 1;
  }
  cout << max(0ll, ans) << endl;
}<|endoftext|>


<commit_before>#include <Arduino.h>
#include <Wire.h>
#include <UnoWiFiDevEd.h>
#include <DHT.h>

#define CONNECTOR "mqtt"
// MQTT topic on which we will publish
#define TOPIC "arduino/dht11"

// Last millis that we sent an update
unsigned long lastupdate = 0;

// DHT connected to pin 5
DHT dht(5, DHT11);

void setup(void){
	Serial.begin(115200);
	Serial.println(F("TrojanC - Learn Arduino:: mqtt-dht11"));
	Ciao.begin();
	dht.begin();
}

void loop(void){
	// If we updated 2 seconds ago
	if(((unsigned long)(millis() - lastupdate)) >= 2000){
		lastupdate = millis();
		float temperature = dht.readTemperature();
		Serial.print(F("Temperature: "));Serial.println(temperature);
		Ciao.write(CONNECTOR, TOPIC, String(temperature));
	}
}
<commit_msg>Updates to example<commit_after>#include <Arduino.h>
#include <Wire.h>
#include <UnoWiFiDevEd.h>
#include <DHT.h>

#define CONNECTOR "mqtt"
// MQTT topic on which we will publish
#define TOPIC "trojanc/learn-arduino/mqtt-dht11"

// Last millis that we sent an update
unsigned long lastupdate = 0;

// DHT connected to pin 5
DHT dht(5, DHT11);

void setup(void){
	Serial.begin(115200);
	Serial.println(F("TrojanC - Learn Arduino:: mqtt-dht11"));
	Ciao.begin();
	dht.begin();
}

void loop(void){
	// If we updated 2 seconds ago
	if(((unsigned long)(millis() - lastupdate)) >= 2000){
		lastupdate = millis();
		float temperature = dht.readTemperature();
		Serial.print(F("Temperature: "));Serial.println(temperature);
		Ciao.write(CONNECTOR, TOPIC, String(temperature));
	}
}
<|endoftext|>


<commit_before>/***********************************************************************
 row.cpp - Implements the Row class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "row.h"
#include "result.h"
#include "exceptions.h"

namespace mysqlpp {

Row::Row(const MYSQL_ROW& d, const ResUse* r,
		unsigned long* jj, bool te) :
OptionalExceptions(te),
res_(r),
initialized_(false)
{
	if (!d || !r) {
		if (throw_exceptions()) {
			throw BadQuery("ROW or RES is NULL");
		}
		else {
			return;
		}
	}
	data_.clear();
	is_nulls_.clear();
	initialized_ = true;
	for (unsigned int i = 0; i < size(); i++) {
		data_.insert(data_.end(),
				(d[i] ?  std::string(d[i], jj[i]) : std::string("NULL")));
		is_nulls_.insert(is_nulls_.end(), d[i] ? false : true);
	}
}

Row::~Row()
{
	data_.clear();
	is_nulls_.clear();
	initialized_ = false;
}

Row::size_type Row::size() const
{
	return res_->num_fields();
}

const ColData Row::at(size_type i) const
{
	if (initialized_) {
		return ColData(data_.at(i).c_str(), res_->types(i), is_nulls_[i]);
	}
	else {
		if (throw_exceptions())
			throw std::out_of_range("Row not initialized");
		else
			return ColData();
	}
}

const ColData Row::operator [](const char* field) const
{
	size_type si = res_->field_num(std::string(field));
	if (si < size()) {
		return at(si);
	}
	else {
		throw BadFieldName(field);
	}
}

value_list_ba<FieldNames, do_nothing_type0>
Row::field_list(const char* d) const
{
	return value_list_ba<FieldNames, do_nothing_type0>
			(parent().names(), d, do_nothing);
}

template <class Manip>
value_list_ba<FieldNames, Manip>
Row::field_list(const char *d, Manip m) const
{
	return value_list_ba<FieldNames, Manip>(parent().names(), d, m);
}

template <class Manip>
value_list_b<FieldNames, Manip>
Row::field_list(const char *d, Manip m, const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const char* d, const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, d, quote);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, ",", quote);
}

template <class Manip> value_list_b<FieldNames, Manip>
Row::field_list(const char* d, Manip m, bool t0, bool t1, bool t2,
		bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
		bool ta, bool tb, bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const char *d, bool t0, bool t1, bool t2, bool t3,
		bool t4, bool t5, bool t6, bool t7, bool t8, bool t9, bool ta,
		bool tb, bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, d, quote);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(bool t0, bool t1, bool t2, bool t3, bool t4, bool t5,
		bool t6, bool t7, bool t8, bool t9, bool ta, bool tb,
		bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, ",", quote);
}

equal_list_ba<FieldNames, Row, quote_type0>
Row::equal_list(const char* d, const char* e) const
{
	return equal_list_ba<FieldNames, Row, quote_type0>(
			parent().names(), *this, d, e, quote);
}

template <class Manip>
equal_list_ba<FieldNames, Row, Manip>
Row::equal_list(const char* d, const char* e, Manip m) const
{
	return equal_list_ba<FieldNames, Row, Manip>(
			parent().names(), *this, d, e, m);
}

} // end namespace mysqlpp

<commit_msg>Row::at() now uses the ColData ctor with an explicit length parameter when creating the object it returns.  This fixes yet another place where we can be bit by query results containing nulls.  Probably isn't the last one, though.<commit_after>/***********************************************************************
 row.cpp - Implements the Row class.

 Copyright (c) 1998 by Kevin Atkinson, (c) 1999, 2000 and 2001 by
 MySQL AB, and (c) 2004, 2005 by Educational Technology Resources, Inc.
 Others may also hold copyrights on code in this file.  See the CREDITS
 file in the top directory of the distribution for details.

 This file is part of MySQL++.

 MySQL++ is free software; you can redistribute it and/or modify it
 under the terms of the GNU Lesser General Public License as published
 by the Free Software Foundation; either version 2.1 of the License, or
 (at your option) any later version.

 MySQL++ is distributed in the hope that it will be useful, but WITHOUT
 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
 License for more details.

 You should have received a copy of the GNU Lesser General Public
 License along with MySQL++; if not, write to the Free Software
 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
 USA
***********************************************************************/

#include "row.h"
#include "result.h"
#include "exceptions.h"

namespace mysqlpp {

Row::Row(const MYSQL_ROW& d, const ResUse* r,
		unsigned long* jj, bool te) :
OptionalExceptions(te),
res_(r),
initialized_(false)
{
	if (!d || !r) {
		if (throw_exceptions()) {
			throw BadQuery("ROW or RES is NULL");
		}
		else {
			return;
		}
	}
	data_.clear();
	is_nulls_.clear();
	initialized_ = true;
	for (unsigned int i = 0; i < size(); i++) {
		data_.insert(data_.end(),
				(d[i] ?  std::string(d[i], jj[i]) : std::string("NULL")));
		is_nulls_.insert(is_nulls_.end(), d[i] ? false : true);
	}
}

Row::~Row()
{
	data_.clear();
	is_nulls_.clear();
	initialized_ = false;
}

Row::size_type Row::size() const
{
	return res_->num_fields();
}

const ColData Row::at(size_type i) const
{
	if (initialized_) {
		const std::string& s = data_.at(i);
		return ColData(s.c_str(), s.length(), res_->types(i),
				is_nulls_[i]);
	}
	else {
		if (throw_exceptions())
			throw std::out_of_range("Row not initialized");
		else
			return ColData();
	}
}

const ColData Row::operator [](const char* field) const
{
	size_type si = res_->field_num(std::string(field));
	if (si < size()) {
		return at(si);
	}
	else {
		throw BadFieldName(field);
	}
}

value_list_ba<FieldNames, do_nothing_type0>
Row::field_list(const char* d) const
{
	return value_list_ba<FieldNames, do_nothing_type0>
			(parent().names(), d, do_nothing);
}

template <class Manip>
value_list_ba<FieldNames, Manip>
Row::field_list(const char *d, Manip m) const
{
	return value_list_ba<FieldNames, Manip>(parent().names(), d, m);
}

template <class Manip>
value_list_b<FieldNames, Manip>
Row::field_list(const char *d, Manip m, const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const char* d, const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, d, quote);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const std::vector<bool>& vb) const
{
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, ",", quote);
}

template <class Manip> value_list_b<FieldNames, Manip>
Row::field_list(const char* d, Manip m, bool t0, bool t1, bool t2,
		bool t3, bool t4, bool t5, bool t6, bool t7, bool t8, bool t9,
		bool ta, bool tb, bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, Manip>(parent().names(), vb, d, m);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(const char *d, bool t0, bool t1, bool t2, bool t3,
		bool t4, bool t5, bool t6, bool t7, bool t8, bool t9, bool ta,
		bool tb, bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, d, quote);
}

value_list_b<FieldNames, quote_type0>
Row::field_list(bool t0, bool t1, bool t2, bool t3, bool t4, bool t5,
		bool t6, bool t7, bool t8, bool t9, bool ta, bool tb,
		bool tc) const
{
	std::vector<bool> vb;
	create_vector(parent().names().size(), vb, t0, t1, t2, t3, t4,
			t5, t6, t7, t8, t9, ta, tb, tc);
	return value_list_b<FieldNames, quote_type0>(parent().names(),
			vb, ",", quote);
}

equal_list_ba<FieldNames, Row, quote_type0>
Row::equal_list(const char* d, const char* e) const
{
	return equal_list_ba<FieldNames, Row, quote_type0>(
			parent().names(), *this, d, e, quote);
}

template <class Manip>
equal_list_ba<FieldNames, Row, Manip>
Row::equal_list(const char* d, const char* e, Manip m) const
{
	return equal_list_ba<FieldNames, Row, Manip>(
			parent().names(), *this, d, e, m);
}

} // end namespace mysqlpp

<|endoftext|>


<commit_before>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperElevationParametersHandler.h"
#include "otbDEMHandler.h"

namespace otb
{
namespace Wrapper
{

void ElevationParametersHandler::AddElevationParameters(Application::Pointer app,
                                                         const std::string & key)
{
  app->AddParameter(ParameterType_Group, key, "Elevation management");
  app->SetParameterDescription(key,
                               "This group of parameters allows to manage elevation values. Supported formats are SRTM, DTED or any geotiff processed by the DEM import application");

  // DEM directory
  std::ostringstream oss;
  oss << key<<".dem";
  app->AddParameter(ParameterType_Directory, oss.str(), "DEM directory");
  app->SetParameterDescription(oss.str(),
                               "This parameter allows to select a directory containing Digital Elevation Model tiles");
  app->MandatoryOff(oss.str());

  std::string demDirFromConfig = otb::ConfigurationFile::GetInstance()->GetDEMDirectory();

  if(demDirFromConfig!="")
    {
    app->SetParameterString(oss.str(), otb::ConfigurationFile::GetInstance()->GetDEMDirectory());
    app->EnableParameter(oss.str());
    }
  else
    {
    app->DisableParameter(oss.str());
    }

   // Geoid file
  oss.str("");
  oss << key<<".geoid";
  app->AddParameter(ParameterType_InputFilename, oss.str(), "Geoid File");
  app->SetParameterDescription(oss.str(),"Use a geoid grid to get the height above the ellipsoid in case there is no DEM available, no coverage for some points or pixels with no_data in the DEM tiles.");
  app->MandatoryOff(oss.str());

  std::string geoidFromConfig = otb::ConfigurationFile::GetInstance()->GetGeoidFile();

  if(geoidFromConfig!="")
    {
    app->SetParameterString(oss.str(),geoidFromConfig );
    app->EnableParameter(oss.str());
    }
  else
    {
    app->DisableParameter(oss.str());
    }

  // Average elevation
  oss.str("");
  oss << key <<".default";
  app->AddParameter(ParameterType_Float, oss.str(), "Default elevation");
  app->SetParameterDescription(oss.str(),"This parameter allows to set the default height above ellipsoid when there is no DEM available, no coverage for some points or pixels with no_data in the DEM tiles, and no geoid file has been set. This is also used by some application as an average elevation value.");
  app->SetDefaultParameterFloat(oss.str(), 0.);

 // TODO : not implemented yet
 //   // Tiff image
 //   oss << ".tiff";
 //   app->AddChoice(oss.str(), "Tiff file");
 //   app->AddParameter(ParameterType_InputImage, oss.str(), "Tiff file");
 //   app->SetParameterDescription(oss.str(),"Tiff file used to get elevation for each location in the image");

}

void ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(const Application::Pointer app, const std::string& key)
{
  // Set default elevation
  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(GetDefaultElevation(app,key));

  std::ostringstream oss;
  oss<<"Elevation management: setting default height above ellipsoid to  " << GetDefaultElevation(app,key) << " meters"<<std::endl;

  app->GetLogger()->Info(oss.str());

  // Set geoid if available
  if(IsGeoidUsed(app,key))
    {
    oss.str("");
    oss<<"Elevation management: using geoid file ("<<GetGeoidFile(app,key)<<")"<<std::endl;
    otb::DEMHandler::Instance()->OpenGeoidFile(GetGeoidFile(app,key));
    app->GetLogger()->Info(oss.str());
    }

  // Set DEM directory if available
  if(IsDEMUsed(app,key))
    {
    oss.str("");
    oss<<"Elevation management: using DEM directory ("<<GetDEMDirectory(app,key)<<")"<<std::endl;
    otb::DEMHandler::Instance()->OpenDEMDirectory(GetDEMDirectory(app,key));
    app->GetLogger()->Info(oss.str());
    }
}

/**
 *
 * Get the Average elevation value
 */
float
ElevationParametersHandler::GetDefaultElevation(const Application::Pointer app, const std::string& key)
{
  std::ostringstream oss;
  oss << key <<".default";
  return app->GetParameterFloat(oss.str());
}

/**
 * Get the Geoid file
 */
const std::string
ElevationParametersHandler::GetGeoidFile(const Application::Pointer app, const std::string& key)
{
  std::ostringstream oss;
  oss << key <<".geoid";
  if (IsGeoidUsed(app, key))
    {
    return app->GetParameterString(oss.str());
    }

  return "";
}

/**
 * Is Geoid used
 */
bool
ElevationParametersHandler::IsGeoidUsed(const Application::Pointer app, const std::string& key)
{
  std::ostringstream geoidKey;
  geoidKey<< key<<".geoid";

  return app->IsParameterEnabled(geoidKey.str()) && app->HasValue(geoidKey.str());
}

/**
 *
 * Is Geoid used
 */
bool
ElevationParametersHandler::IsDEMUsed(const Application::Pointer app, const std::string& key)
{
  std::ostringstream geoidKey;
  geoidKey<< key<<".dem";

  return app->IsParameterEnabled(geoidKey.str()) && app->HasValue(geoidKey.str());
}

const std::string
ElevationParametersHandler::GetDEMDirectory(const Application::Pointer app, const std::string& key)
{
  std::ostringstream oss;
  oss << key <<".dem";
  if (IsDEMUsed(app, key))
    {
    return app->GetParameterString(oss.str());
    }

  return "";
}

}// End namespace Wrapper
}// End namespace otb
<commit_msg>DOC: add link to geoid file in elevation parameters handler description<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "otbWrapperElevationParametersHandler.h"
#include "otbDEMHandler.h"

namespace otb
{
namespace Wrapper
{

void ElevationParametersHandler::AddElevationParameters(Application::Pointer app,
                                                         const std::string & key)
{
  app->AddParameter(ParameterType_Group, key, "Elevation management");
  app->SetParameterDescription(key,
                               "This group of parameters allows to manage elevation values. Supported formats are SRTM, DTED or any geotiff processed by the DEM import application");

  // DEM directory
  std::ostringstream oss;
  oss << key<<".dem";
  app->AddParameter(ParameterType_Directory, oss.str(), "DEM directory");
  app->SetParameterDescription(oss.str(),
                               "This parameter allows to select a directory containing Digital Elevation Model tiles");
  app->MandatoryOff(oss.str());

  std::string demDirFromConfig = otb::ConfigurationFile::GetInstance()->GetDEMDirectory();

  if(demDirFromConfig!="")
    {
    app->SetParameterString(oss.str(), otb::ConfigurationFile::GetInstance()->GetDEMDirectory());
    app->EnableParameter(oss.str());
    }
  else
    {
    app->DisableParameter(oss.str());
    }

   // Geoid file
  oss.str("");
  oss << key<<".geoid";
  app->AddParameter(ParameterType_InputFilename, oss.str(), "Geoid File");
  app->SetParameterDescription(oss.str(),"Use a geoid grid to get the height above the ellipsoid in case there is no DEM available, no coverage for some points or pixels with no_data in the DEM tiles. A version of the geoid can be found on the OTB website (http://hg.orfeo-toolbox.org/OTB-Data/raw-file/404aa6e4b3e0/Input/DEM/egm96.grd).");
  app->MandatoryOff(oss.str());

  std::string geoidFromConfig = otb::ConfigurationFile::GetInstance()->GetGeoidFile();

  if(geoidFromConfig!="")
    {
    app->SetParameterString(oss.str(),geoidFromConfig );
    app->EnableParameter(oss.str());
    }
  else
    {
    app->DisableParameter(oss.str());
    }

  // Average elevation
  oss.str("");
  oss << key <<".default";
  app->AddParameter(ParameterType_Float, oss.str(), "Default elevation");
  app->SetParameterDescription(oss.str(),"This parameter allows to set the default height above ellipsoid when there is no DEM available, no coverage for some points or pixels with no_data in the DEM tiles, and no geoid file has been set. This is also used by some application as an average elevation value.");
  app->SetDefaultParameterFloat(oss.str(), 0.);

 // TODO : not implemented yet
 //   // Tiff image
 //   oss << ".tiff";
 //   app->AddChoice(oss.str(), "Tiff file");
 //   app->AddParameter(ParameterType_InputImage, oss.str(), "Tiff file");
 //   app->SetParameterDescription(oss.str(),"Tiff file used to get elevation for each location in the image");

}

void ElevationParametersHandler::SetupDEMHandlerFromElevationParameters(const Application::Pointer app, const std::string& key)
{
  // Set default elevation
  otb::DEMHandler::Instance()->SetDefaultHeightAboveEllipsoid(GetDefaultElevation(app,key));

  std::ostringstream oss;
  oss<<"Elevation management: setting default height above ellipsoid to  " << GetDefaultElevation(app,key) << " meters"<<std::endl;

  app->GetLogger()->Info(oss.str());

  // Set geoid if available
  if(IsGeoidUsed(app,key))
    {
    oss.str("");
    oss<<"Elevation management: using geoid file ("<<GetGeoidFile(app,key)<<")"<<std::endl;
    otb::DEMHandler::Instance()->OpenGeoidFile(GetGeoidFile(app,key));
    app->GetLogger()->Info(oss.str());
    }

  // Set DEM directory if available
  if(IsDEMUsed(app,key))
    {
    oss.str("");
    oss<<"Elevation management: using DEM directory ("<<GetDEMDirectory(app,key)<<")"<<std::endl;
    otb::DEMHandler::Instance()->OpenDEMDirectory(GetDEMDirectory(app,key));
    app->GetLogger()->Info(oss.str());
    }
}

/**
 *
 * Get the Average elevation value
 */
float
ElevationParametersHandler::GetDefaultElevation(const Application::Pointer app, const std::string& key)
{
  std::ostringstream oss;
  oss << key <<".default";
  return app->GetParameterFloat(oss.str());
}

/**
 * Get the Geoid file
 */
const std::string
ElevationParametersHandler::GetGeoidFile(const Application::Pointer app, const std::string& key)
{
  std::ostringstream oss;
  oss << key <<".geoid";
  if (IsGeoidUsed(app, key))
    {
    return app->GetParameterString(oss.str());
    }

  return "";
}

/**
 * Is Geoid used
 */
bool
ElevationParametersHandler::IsGeoidUsed(const Application::Pointer app, const std::string& key)
{
  std::ostringstream geoidKey;
  geoidKey<< key<<".geoid";

  return app->IsParameterEnabled(geoidKey.str()) && app->HasValue(geoidKey.str());
}

/**
 *
 * Is Geoid used
 */
bool
ElevationParametersHandler::IsDEMUsed(const Application::Pointer app, const std::string& key)
{
  std::ostringstream geoidKey;
  geoidKey<< key<<".dem";

  return app->IsParameterEnabled(geoidKey.str()) && app->HasValue(geoidKey.str());
}

const std::string
ElevationParametersHandler::GetDEMDirectory(const Application::Pointer app, const std::string& key)
{
  std::ostringstream oss;
  oss << key <<".dem";
  if (IsDEMUsed(app, key))
    {
    return app->GetParameterString(oss.str());
    }

  return "";
}

}// End namespace Wrapper
}// End namespace otb
<|endoftext|>


<commit_before><commit_msg>planning: add conf enabled check for creep stage<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/dbus/dbus_manager.h"

#include <glib.h>
#include <string>
#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "dbus/bus.h"

namespace xwalk {

DBusManager::DBusManager() {}

DBusManager::~DBusManager() {
  if (session_bus_)
    session_bus_->ShutdownOnDBusThreadAndBlock();
}

scoped_refptr<dbus::Bus> DBusManager::session_bus() {
  if (!session_bus_) {
    base::Thread::Options thread_options;
    thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
    std::string thread_name = "Crosswalk D-Bus thread";
    dbus_thread_.reset(new base::Thread(thread_name.c_str()));
    dbus_thread_->StartWithOptions(thread_options);

    dbus::Bus::Options options;
    options.dbus_task_runner = dbus_thread_->message_loop_proxy();

    // On Tizen 2.x DBUS_SESSION_ADDRESS points to a wrong path, so we set
    // the correct one here.
    options.bus_type = dbus::Bus::CUSTOM_ADDRESS;
    options.address = base::StringPrintf(
        "unix:path=/run/user/%s/dbus/user_bus_socket", g_get_user_name());

    session_bus_ = new dbus::Bus(options);
  }

  return session_bus_;
}

}  // namespace xwalk
<commit_msg>[Tizen][Runtime] Fix session bus issue under service mode.<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/dbus/dbus_manager.h"

#include <glib.h>
#include <string>
#include "base/bind.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread.h"
#include "dbus/bus.h"

namespace xwalk {

DBusManager::DBusManager() {}

DBusManager::~DBusManager() {
  if (session_bus_)
    session_bus_->ShutdownOnDBusThreadAndBlock();
}

scoped_refptr<dbus::Bus> DBusManager::session_bus() {
  if (!session_bus_) {
    base::Thread::Options thread_options;
    thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
    std::string thread_name = "Crosswalk D-Bus thread";
    dbus_thread_.reset(new base::Thread(thread_name.c_str()));
    dbus_thread_->StartWithOptions(thread_options);

    dbus::Bus::Options options;
    options.dbus_task_runner = dbus_thread_->message_loop_proxy();

    session_bus_ = new dbus::Bus(options);
  }

  return session_bus_;
}

}  // namespace xwalk
<|endoftext|>


<commit_before><commit_msg>coverity#1296215 Dereference before null check<commit_after><|endoftext|>


<commit_before>/*
  Copyright (C) 2007 by Mike Gist

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "cstool/unusedresourcehelper.h"
#include "csutil/csobject.h"
#include "iengine/collection.h"
#include "iengine/engine.h"
#include "iengine/material.h"
#include "iengine/texture.h"

namespace CS
{
  namespace Utility
  {
    namespace UnusedResourceHelper
    {
      namespace Implementation
      {
        static inline void UnloadHelper(iObject* object, iEngine* engine)
        {
          csObject* obj = (csObject*)object;

          size_t realRefCount = obj->GetRefCount() - obj->GetInternalRefCount();
          if(realRefCount == 1)
          {
            csRef<iCollectionArray> colArr = engine->GetCollections();
            for(size_t i=0; i<colArr->GetSize(); i++)
            {
              colArr->Get(i)->Remove(object);
            }
          }
        }
      } // namespace Implementation

      void UnloadUnusedMaterials(iEngine* engine,
        const csWeakRefArray<iMaterialWrapper>& materials)
      {
        for(size_t i=0; i<materials.GetSize(); i++)
        {
          csWeakRef<iMaterialWrapper> mw = materials[i];
          if (!mw) continue;
          Implementation::UnloadHelper(mw->QueryObject(), engine);
        }
      }

      void UnloadUnusedTextures(iEngine* engine,
        const csWeakRefArray<iTextureWrapper>& textures)
      {
        for(size_t i=0; i<textures.GetSize(); i++)
        {
          csWeakRef<iTextureWrapper> tw = textures[i];
          if (!tw) continue;
          Implementation::UnloadHelper(tw->QueryObject(), engine);
        }
      }
    }
  }
}
<commit_msg>- Mike Gist fixed a crash in UnloadHelper.<commit_after>/*
  Copyright (C) 2007 by Mike Gist

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Library General Public
  License as published by the Free Software Foundation; either
  version 2 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Library General Public License for more details.

  You should have received a copy of the GNU Library General Public
  License along with this library; if not, write to the Free
  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "cstool/unusedresourcehelper.h"
#include "csutil/csobject.h"
#include "iengine/collection.h"
#include "iengine/engine.h"
#include "iengine/material.h"
#include "iengine/texture.h"

namespace CS
{
  namespace Utility
  {
    namespace UnusedResourceHelper
    {
      namespace Implementation
      {
        static inline void UnloadHelper(iObject* object, iEngine* engine)
        {
          csWeakRef<csObject> obj = (csObject*)object;

          size_t realRefCount = obj->GetRefCount() - obj->GetInternalRefCount();
          if(realRefCount == 1)
          {
            csRef<iCollectionArray> colArr = engine->GetCollections();
            for(size_t i=0; i<colArr->GetSize() && obj.IsValid(); i++)
            {
              colArr->Get(i)->Remove(object);
            }
          }
        }
      } // namespace Implementation

      void UnloadUnusedMaterials(iEngine* engine,
        const csWeakRefArray<iMaterialWrapper>& materials)
      {
        for(size_t i=0; i<materials.GetSize(); i++)
        {
          csWeakRef<iMaterialWrapper> mw = materials[i];
          if (!mw) continue;
          Implementation::UnloadHelper(mw->QueryObject(), engine);
        }
      }

      void UnloadUnusedTextures(iEngine* engine,
        const csWeakRefArray<iTextureWrapper>& textures)
      {
        for(size_t i=0; i<textures.GetSize(); i++)
        {
          csWeakRef<iTextureWrapper> tw = textures[i];
          if (!tw) continue;
          Implementation::UnloadHelper(tw->QueryObject(), engine);
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

// This file comes from a 3rd party and has been adapted to fit into the VAST
// code base. Details about the original file:
//
// - URL:        https://gist.github.com/foonathan/daad3fffaf5dd7cd7a5bbabd6ccd8c1b
// - Author:     Jonathan Müller
// - Details:    https://foonathan.net/blog/2017/12/21/visitors.html

#pragma once

#include <typeinfo>
#include <type_traits>

#include <caf/optional.hpp>
#include <caf/detail/type_traits.hpp>

#include "vast/detail/overload.hpp"

namespace vast {

/// The base class for polymorphic visitors.
template <class Result, class CommonBase>
class polymorphic_visitor {
public:
  template <class T>
  caf::optional<Result> operator()(const T& x) {
    static_assert(std::is_base_of_v<CommonBase, T>);
    return do_visit(&x);
  }

protected:
  virtual caf::optional<Result> do_visit(const CommonBase* ptr) = 0;

  ~polymorphic_visitor() {
    // nop
  }
};

namespace detail {

template <class F>
using fun_res_t =
  typename caf::detail::get_callable_trait<F>::result_type;

template <class F>
struct fun_arg {
  using arg_types = typename caf::detail::get_callable_trait<F>::arg_types;
  static_assert(caf::detail::tl_size<arg_types>::value == 1);
  using type = std::decay_t<caf::detail::tl_head_t<arg_types>>;
};

template <class F>
using fun_arg_t = typename fun_arg<F>::type;

template <class Result, class CommonBase, class F, class... Ts>
class fun final : public polymorphic_visitor<Result, CommonBase> {
public:
  using result_t = std::conditional_t<std::is_same_v<void, Result>,
                                      caf::unit_t, Result>;

  explicit fun(F f) : f_(std::move(f)) {
    // nop
  }

protected:
  template <class T>
  bool try_visit(caf::optional<result_t>& result, const CommonBase* ptr) {
    auto invoke = [&](const T* dptr) {
      if constexpr (std::is_same_v<void, Result>)
        f_(*dptr);
      else
        result = f_(*dptr);
    };
    if constexpr (std::is_final_v<T>) {
      if (typeid(*ptr) == typeid(T)) {
        invoke(static_cast<const T*>(ptr));
        return true;
      }
    } else {
      auto dptr = dynamic_cast<const T*>(ptr);
      if (dptr != nullptr) {
        invoke(dptr);
        return true;
      }
    }
    return false;
  }

  caf::optional<Result> do_visit(const CommonBase* ptr) override {
    caf::optional<result_t> result;
    (try_visit<Ts>(result, ptr) || ...);
    return result;
  }

  F f_;
};

} // namespace detail

/// Constructs a visitor from a list of unary functions. All functions must
/// take an argument that is-a `CommonBase`.
/// @relates polymorphic_visitor
template <class CommonBase, class F, class... Fs>
static auto make_polymorphic_visitor(F f, Fs... fs) {
  using namespace detail;
  using result_type = fun_res_t<F>;
  // All lambdas must return the same type.
  static_assert((std::is_same_v<result_type, fun_res_t<Fs>> && ...));
  // All lambdas must take one argument that's a subtype of CommonBase.
  static_assert(std::is_base_of_v<CommonBase, fun_arg_t<F>>);
  static_assert((std::is_base_of_v<CommonBase, fun_arg_t<Fs>> && ...));
  auto lambda = overload(std::move(f), std::move(fs)...);
  using visitor_type = fun<result_type, CommonBase, decltype(lambda),
                                      fun_arg_t<F>, fun_arg_t<Fs>...>;
  return visitor_type{std::move(lambda)};
}

} // namespace vast
<commit_msg>Give visitor implementation a proper name<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

// This file comes from a 3rd party and has been adapted to fit into the VAST
// code base. Details about the original file:
//
// - URL:        https://gist.github.com/foonathan/daad3fffaf5dd7cd7a5bbabd6ccd8c1b
// - Author:     Jonathan Müller
// - Details:    https://foonathan.net/blog/2017/12/21/visitors.html

#pragma once

#include <typeinfo>
#include <type_traits>

#include <caf/optional.hpp>
#include <caf/detail/type_traits.hpp>

#include "vast/detail/overload.hpp"

namespace vast {

/// The base class for polymorphic visitors.
template <class Result, class CommonBase>
class polymorphic_visitor {
public:
  template <class T>
  caf::optional<Result> operator()(const T& x) {
    static_assert(std::is_base_of_v<CommonBase, T>);
    return do_visit(&x);
  }

protected:
  virtual caf::optional<Result> do_visit(const CommonBase* ptr) = 0;

  ~polymorphic_visitor() {
    // nop
  }
};

namespace detail {

template <class F>
using fun_res_t =
  typename caf::detail::get_callable_trait<F>::result_type;

template <class F>
struct fun_arg {
  using arg_types = typename caf::detail::get_callable_trait<F>::arg_types;
  static_assert(caf::detail::tl_size<arg_types>::value == 1);
  using type = std::decay_t<caf::detail::tl_head_t<arg_types>>;
};

template <class F>
using fun_arg_t = typename fun_arg<F>::type;

template <class Result, class CommonBase, class F, class... Ts>
class polymorphic_visitor_impl final : public polymorphic_visitor<Result, CommonBase> {
public:
  using result_t = std::conditional_t<std::is_same_v<void, Result>,
                                      caf::unit_t, Result>;

  explicit polymorphic_visitor_impl(F f) : f_(std::move(f)) {
    // nop
  }

protected:
  template <class T>
  bool try_visit(caf::optional<result_t>& result, const CommonBase* ptr) {
    auto invoke = [&](const T* dptr) {
      if constexpr (std::is_same_v<void, Result>)
        f_(*dptr);
      else
        result = f_(*dptr);
    };
    if constexpr (std::is_final_v<T>) {
      if (typeid(*ptr) == typeid(T)) {
        invoke(static_cast<const T*>(ptr));
        return true;
      }
    } else {
      auto dptr = dynamic_cast<const T*>(ptr);
      if (dptr != nullptr) {
        invoke(dptr);
        return true;
      }
    }
    return false;
  }

  caf::optional<Result> do_visit(const CommonBase* ptr) override {
    caf::optional<result_t> result;
    (try_visit<Ts>(result, ptr) || ...);
    return result;
  }

  F f_;
};

} // namespace detail

/// Constructs a visitor from a list of unary functions. All functions must
/// take an argument that is-a `CommonBase`.
/// @relates polymorphic_visitor
template <class CommonBase, class F, class... Fs>
static auto make_polymorphic_visitor(F f, Fs... fs) {
  using namespace detail;
  using result_type = fun_res_t<F>;
  // All lambdas must return the same type.
  static_assert((std::is_same_v<result_type, fun_res_t<Fs>> && ...));
  // All lambdas must take one argument that's a subtype of CommonBase.
  static_assert(std::is_base_of_v<CommonBase, fun_arg_t<F>>);
  static_assert((std::is_base_of_v<CommonBase, fun_arg_t<Fs>> && ...));
  auto lambda = overload(std::move(f), std::move(fs)...);
  using visitor_type = polymorphic_visitor_impl<
    result_type, CommonBase, decltype(lambda), fun_arg_t<F>, fun_arg_t<Fs>...
  >;
  return visitor_type{std::move(lambda)};
}

} // namespace vast
<|endoftext|>


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

#include "Ip.h"
#include <Module.h>
#include <Log.h>

// protocols we use in IP
#include "Ethernet.h"
#include "Arp.h"

// child protocols of IP
#include "Icmp.h"
#include "Udp.h"
#include "Tcp.h"

#include "NetManager.h"
#include "RawManager.h"
#include "Endpoint.h"

#include "RoutingTable.h"

Ip Ip::ipInstance;

Ip::Ip() :
  m_NextIdLock(), m_IpId(0), m_Fragments()
{
}

Ip::~Ip()
{
}

bool Ip::send(IpAddress dest, IpAddress from, uint8_t type, size_t nBytes, uintptr_t packet, Network *pCard)
{
  IpAddress realDest = dest;

  // Grab the address to send to (as well as the NIC to send with)
  if(!pCard)
  {
    pCard = RoutingTable::instance().DetermineRoute(&realDest);
    if(!pCard)
    {
      WARNING("IPv4: Couldn't find a route for destination '" << dest.toString() << "'.");
      return false;
    }
  }
  if(!pCard->isConnected())
    return false; // NIC isn't active

  // Fill in the from address if it's not valid. Note that some protocols
  // can't do this as they need the source address in the checksum.
  if(from == Network::convertToIpv4(0, 0, 0, 0))
  {
    StationInfo me = pCard->getStationInfo();
    from = me.ipv4;
  }

  // Allocate space for the new packet with an IP header
  size_t newSize = nBytes + sizeof(ipHeader);
  uint8_t* newPacket = new uint8_t[newSize];
  uintptr_t packAddr = reinterpret_cast<uintptr_t>(newPacket);

  // Grab a pointer for the ip header
  ipHeader* header = reinterpret_cast<ipHeader*>(newPacket);
  memset(header, 0, sizeof(ipHeader));

  // Compose the IPv4 packet header
  header->id = Ip::instance().getNextId();

  header->ipDest = dest.getIp();
  header->ipSrc = from.getIp();

  header->len = HOST_TO_BIG16(sizeof(ipHeader) + nBytes);

  header->type = type;

  header->ttl = 128;

  header->ipver = 4; // IPv4, offset is 5 DWORDs
  header->header_len = 5;

  header->checksum = 0;
  header->checksum = Network::calculateChecksum(packAddr, sizeof(ipHeader));

  // copy the payload into the packet
  memcpy(reinterpret_cast<void*>(packAddr + sizeof(ipHeader)), reinterpret_cast<void*>(packet), nBytes);

  // Get the address to send to
  /// \todo Perhaps flag this so if we don't want to automatically resolve the MAC
  ///       it doesn't happen?
  MacAddress destMac;
  bool macValid = true;
  if(dest == 0xffffffff)
    destMac.setMac(0xff);
  else
    macValid = Arp::instance().getFromCache(realDest, true, &destMac, pCard);
  if(macValid)
    Ethernet::send(newSize, packAddr, pCard, destMac, ETH_IP);

  delete [] newPacket;
  return macValid;
}

void Ip::receive(size_t nBytes, uintptr_t packet, Network* pCard, uint32_t offset)
{
  // Verify the inputs. Drivers may directly dump this information on us so
  // we cannot ever be too sure.
  if(!packet || !nBytes || !pCard)
      return;

  // grab the header
  ipHeader* header = reinterpret_cast<ipHeader*>(packet + offset);

  // Store the addresses for the packet data
  uintptr_t packetAddress = packet + offset;
  size_t packetSize = nBytes - offset;
  bool wasFragment = false;

  // Find the offset of the data section of this packet
  size_t dataOffset = offset;
  offset += header->header_len * 4;

  // Verify the checksum
  uint16_t checksum = header->checksum;
  header->checksum = 0;
  uint16_t calcChecksum = Network::calculateChecksum(reinterpret_cast<uintptr_t>(header), sizeof(ipHeader));
  header->checksum = checksum;
  if(checksum == calcChecksum)
  {
    IpAddress from(header->ipSrc);
    Endpoint::RemoteEndpoint remoteHost;
    remoteHost.ip = from;

    // Determine if the packet is part of a fragment
    if((header->frag_offset != 0) || (header->flags & IP_FLAG_MF))
    {
        // Find the size of the data section of this packet
        size_t dataLength = nBytes - offset;
        dataLength -= header->header_len * 4;

        // Grab the fragment block for this combination of IP and ID
        Ipv4Identifier id(BIG_TO_HOST16(header->id), from);
        fragmentWrapper *p = m_Fragments.lookup(id);

        // Do we need to create a new wrapper?
        if(!p)
        {
            p = new fragmentWrapper;
            m_Fragments.insert(id, p);
        }

        // Insert this fragment to the list
        if(dataLength)
        {
            char *buff = new char[dataLength];
            memcpy(buff, reinterpret_cast<void*>(packet + offset + dataOffset), dataLength);

            fragment *f = new fragment;
            f->data = buff;
            f->length = dataLength;
            p->fragments.insert(BIG_TO_HOST16(header->frag_offset), f);
        }

        // Was this the last one?
        if(header->frag_offset && !(header->flags & IP_FLAG_MF))
        {
            // Yes, collate the fragments and send to the upper layers
            size_t copyOffset = (header->header_len * 4);
            size_t fullLength = BIG_TO_HOST16(header->frag_offset) + dataLength + copyOffset;
            char *buff = new char[fullLength];

            // Iterate through the fragment list, copying data into the buffer as we go
            for(Tree<size_t, fragment*>::Iterator it = p->fragments.begin();
                it!= p->fragments.end();
                it++)
            {
                // Copy this one in
                size_t offset = it.key();
                fragment *f = it.value();
                if(f)
                {
                    char *data = f->data;
                    if(data && offset < fullLength)
                    {
                        memcpy(buff + (copyOffset + offset), data, f->length);
                        delete data;
                    }
                    delete f;
                }
            }

            // Dump the header into the packet now
            memcpy(buff, header, header->header_len * 4);

            // Clean up now that we're done
            delete p;
            m_Fragments.remove(id);

            // Fall through to the handling of a conventional packet
            packetAddress = reinterpret_cast<uintptr_t>(buff);
            packetSize = fullLength;
            wasFragment = true;
        }
        else
        {
            // Do not handle an incomplete packet, wait for another one to arrive
            return;
        }
    }
    else
    {
        wasFragment = false;
    }

    switch(header->type)
    {
      case IP_ICMP:
        // NOTICE("IP: ICMP packet");

        /// \todo fix
        // RawManager::instance().receive(packet + offset, nBytes - offset, &remoteHost, IPPROTO_ICMP, pCard);

        // icmp needs the ip header as well
        Icmp::instance().receive(from, nBytes, packetAddress, pCard, 0);
        break;

      case IP_UDP:
        // NOTICE("IP: UDP packet");

        /// \todo fix
        //RawManager::instance().receive(packet + offset, nBytes - offset, &remoteHost, IPPROTO_UDP, pCard);

        // udp needs the ip header as well
        Udp::instance().receive(from, nBytes, packetAddress, pCard, 0);
        break;

      case IP_TCP:
        // NOTICE("IP: TCP packet");

        /// \todo fix
        //RawManager::instance().receive(packet + offset, nBytes - offset, &remoteHost, IPPROTO_TCP, pCard);

        // tcp needs the ip header as well
        Tcp::instance().receive(from, nBytes, packetAddress, pCard, 0);
        break;

      default:
        NOTICE("IP: Unknown packet type");
        break;
    }

    if(wasFragment)
    {
        delete reinterpret_cast<char*>(packetAddress);
    }
  }
  else
    NOTICE("IP: Checksum invalid!");
}
<commit_msg>Added the RawManager stuff back to the IPv4 code after I verified that it wasn't broken by the previous commit.<commit_after>/*
 * Copyright (c) 2008 James Molloy, Jörg Pfähler, Matthew Iselin
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "Ip.h"
#include <Module.h>
#include <Log.h>

// protocols we use in IP
#include "Ethernet.h"
#include "Arp.h"

// child protocols of IP
#include "Icmp.h"
#include "Udp.h"
#include "Tcp.h"

#include "NetManager.h"
#include "RawManager.h"
#include "Endpoint.h"

#include "RoutingTable.h"

Ip Ip::ipInstance;

Ip::Ip() :
  m_NextIdLock(), m_IpId(0), m_Fragments()
{
}

Ip::~Ip()
{
}

bool Ip::send(IpAddress dest, IpAddress from, uint8_t type, size_t nBytes, uintptr_t packet, Network *pCard)
{
  IpAddress realDest = dest;

  // Grab the address to send to (as well as the NIC to send with)
  if(!pCard)
  {
    pCard = RoutingTable::instance().DetermineRoute(&realDest);
    if(!pCard)
    {
      WARNING("IPv4: Couldn't find a route for destination '" << dest.toString() << "'.");
      return false;
    }
  }
  if(!pCard->isConnected())
    return false; // NIC isn't active

  // Fill in the from address if it's not valid. Note that some protocols
  // can't do this as they need the source address in the checksum.
  if(from == Network::convertToIpv4(0, 0, 0, 0))
  {
    StationInfo me = pCard->getStationInfo();
    from = me.ipv4;
  }

  // Allocate space for the new packet with an IP header
  size_t newSize = nBytes + sizeof(ipHeader);
  uint8_t* newPacket = new uint8_t[newSize];
  uintptr_t packAddr = reinterpret_cast<uintptr_t>(newPacket);

  // Grab a pointer for the ip header
  ipHeader* header = reinterpret_cast<ipHeader*>(newPacket);
  memset(header, 0, sizeof(ipHeader));

  // Compose the IPv4 packet header
  header->id = Ip::instance().getNextId();

  header->ipDest = dest.getIp();
  header->ipSrc = from.getIp();

  header->len = HOST_TO_BIG16(sizeof(ipHeader) + nBytes);

  header->type = type;

  header->ttl = 128;

  header->ipver = 4; // IPv4, offset is 5 DWORDs
  header->header_len = 5;

  header->checksum = 0;
  header->checksum = Network::calculateChecksum(packAddr, sizeof(ipHeader));

  // copy the payload into the packet
  memcpy(reinterpret_cast<void*>(packAddr + sizeof(ipHeader)), reinterpret_cast<void*>(packet), nBytes);

  // Get the address to send to
  /// \todo Perhaps flag this so if we don't want to automatically resolve the MAC
  ///       it doesn't happen?
  MacAddress destMac;
  bool macValid = true;
  if(dest == 0xffffffff)
    destMac.setMac(0xff);
  else
    macValid = Arp::instance().getFromCache(realDest, true, &destMac, pCard);
  if(macValid)
    Ethernet::send(newSize, packAddr, pCard, destMac, ETH_IP);

  delete [] newPacket;
  return macValid;
}

void Ip::receive(size_t nBytes, uintptr_t packet, Network* pCard, uint32_t offset)
{
  // Verify the inputs. Drivers may directly dump this information on us so
  // we cannot ever be too sure.
  if(!packet || !nBytes || !pCard)
      return;

  // grab the header
  ipHeader* header = reinterpret_cast<ipHeader*>(packet + offset);

  // Store the addresses for the packet data
  uintptr_t packetAddress = packet + offset;
  size_t packetSize = nBytes - offset;
  bool wasFragment = false;

  // Verify the checksum
  uint16_t checksum = header->checksum;
  header->checksum = 0;
  uint16_t calcChecksum = Network::calculateChecksum(reinterpret_cast<uintptr_t>(header), sizeof(ipHeader));
  header->checksum = checksum;
  if(checksum == calcChecksum)
  {
    IpAddress from(header->ipSrc);
    Endpoint::RemoteEndpoint remoteHost;
    remoteHost.ip = from;

    // Determine if the packet is part of a fragment
    if((header->frag_offset != 0) || (header->flags & IP_FLAG_MF))
    {
        // Find the size of the data section of this packet
        size_t dataLength = nBytes - offset;
        dataLength -= header->header_len * 4;

        // Find the offset of the data section of this packet
        size_t dataOffset = offset;
        offset += header->header_len * 4;

        // Grab the fragment block for this combination of IP and ID
        Ipv4Identifier id(BIG_TO_HOST16(header->id), from);
        fragmentWrapper *p = m_Fragments.lookup(id);

        // Do we need to create a new wrapper?
        if(!p)
        {
            p = new fragmentWrapper;
            m_Fragments.insert(id, p);
        }

        // Insert this fragment to the list
        if(dataLength)
        {
            char *buff = new char[dataLength];
            memcpy(buff, reinterpret_cast<void*>(packet + offset + dataOffset), dataLength);

            fragment *f = new fragment;
            f->data = buff;
            f->length = dataLength;
            p->fragments.insert(BIG_TO_HOST16(header->frag_offset), f);
        }

        // Was this the last one?
        if(header->frag_offset && !(header->flags & IP_FLAG_MF))
        {
            // Yes, collate the fragments and send to the upper layers
            size_t copyOffset = (header->header_len * 4);
            size_t fullLength = BIG_TO_HOST16(header->frag_offset) + dataLength + copyOffset;
            char *buff = new char[fullLength];

            // Iterate through the fragment list, copying data into the buffer as we go
            for(Tree<size_t, fragment*>::Iterator it = p->fragments.begin();
                it!= p->fragments.end();
                it++)
            {
                // Copy this one in
                size_t offset = it.key();
                fragment *f = it.value();
                if(f)
                {
                    char *data = f->data;
                    if(data && offset < fullLength)
                    {
                        memcpy(buff + (copyOffset + offset), data, f->length);
                        delete data;
                    }
                    delete f;
                }
            }

            // Dump the header into the packet now
            memcpy(buff, header, header->header_len * 4);

            // Clean up now that we're done
            delete p;
            m_Fragments.remove(id);

            // Fall through to the handling of a conventional packet
            packetAddress = reinterpret_cast<uintptr_t>(buff);
            packetSize = fullLength;
            wasFragment = true;
        }
        else
        {
            // Do not handle an incomplete packet, wait for another one to arrive
            return;
        }
    }
    else
    {
        wasFragment = false;
    }

    switch(header->type)
    {
      case IP_ICMP:
        // NOTICE("IP: ICMP packet");

        /// \todo fix
        RawManager::instance().receive(packetAddress, nBytes - offset, &remoteHost, IPPROTO_ICMP, pCard);

        // icmp needs the ip header as well
        Icmp::instance().receive(from, nBytes, packetAddress, pCard, 0);
        break;

      case IP_UDP:
        // NOTICE("IP: UDP packet");

        RawManager::instance().receive(packetAddress, nBytes - offset, &remoteHost, IPPROTO_UDP, pCard);

        // udp needs the ip header as well
        Udp::instance().receive(from, nBytes, packetAddress, pCard, 0);
        break;

      case IP_TCP:
        // NOTICE("IP: TCP packet");

        RawManager::instance().receive(packetAddress, nBytes - offset, &remoteHost, IPPROTO_TCP, pCard);

        // tcp needs the ip header as well
        Tcp::instance().receive(from, nBytes, packetAddress, pCard, 0);
        break;

      default:
        NOTICE("IP: Unknown packet type");
        break;
    }

    if(wasFragment)
    {
        delete reinterpret_cast<char*>(packetAddress);
    }
  }
  else
    NOTICE("IP: Checksum invalid!");
}
<|endoftext|>