<commit_before>#include "triangle.hpp"
#include <algorithm>

Triangle::Triangle():
Shape(),
ecke1_{1.0f,0.0f,-2.0f},
ecke2_{-1.0f,0.0f,-2.0f},
ecke3_{0.0f,1.0f,-2.0f}
{}

Triangle::Triangle(glm::vec3 const& ecke1, glm::vec3 const& ecke2, glm::vec3 const& ecke3):
Shape(),
/*ecke1_{ecke1.x,ecke1.y,ecke1.z},
ecke2_{ecke2.x,ecke2.y,ecke2.z},
ecke3_{ecke3.x,ecke3.y,ecke3.z}*/
ecke1_{ecke1},
ecke2_{ecke2},
ecke3_{ecke3}
{}

Triangle::Triangle(glm::vec3 const& ecke1, glm::vec3 const& ecke2, glm::vec3 const& ecke3, std::string const& name, Material const& mat):
Shape(name, mat),
/*ecke1_{ecke1.x,ecke1.y,ecke1.z},
ecke2_{ecke2.x,ecke2.y,ecke2.z},
ecke3_{ecke3.x,ecke3.y,ecke3.z}*/
ecke1_{ecke1},
ecke2_{ecke2},
ecke3_{ecke3}
{}

std::ostream& Triangle::print(std::ostream& os) const{
	Shape::print(os);
 os << "Punkt 1: ("<<ecke1_.x
	  << ", "<<ecke1_.y
    << ", "<<ecke1_.z
    << "Punkt 2: ("<< ecke2_.x
    << ", "<<ecke2_.y
    << ", "<<ecke2_.z
    << "Punkt 3: ("<< ecke3_.x
    << ", "<<ecke3_.y
    << ", "<<ecke3_.z
    << "\n";
}

/*Hit Triangle::intersect(Ray const& ray) {
  Hit defaulthit;
  return defaulthit;
}*/

Hit Triangle::intersect(Ray const& ray) {
  Hit impact;
  Hit noimpact;
  glm::vec3 e1,e2;
  glm::vec3 P,Q,T;
  float det, inv_det, u, v;
  float t;
  float bias = 0.00009;

  e1 = sub(ecke2_,ecke1_);
  e2 = sub(ecke3_,ecke1_);

  P = crossp(ray.direction,e2);
  det = skalar(e1,P);
  if(det > -bias && det < bias)return noimpact;
  inv_det = 1.0f / det;
  T = ray.origin-ecke1_;
  u = skalar(T,P) * inv_det;
  if(u < 0.0f || u > 1.0f)return noimpact;
  Q = crossp(T,e1);
  v = skalar(ray.direction,Q) * inv_det;
  if (v < 0.0 || u + v > 1.0)return noimpact;
  t = skalar(e2,Q) * inv_det;

  if (t > bias)
  {
    float distance = t;
    impact.distance_=t;
    impact.target_  = ray.origin + (distance * glm::normalize(ray.direction));
    glm::vec3 norm = crossp(ecke1_-ecke2_,ecke1_-ecke3_);
    glm::normalize(norm);
    impact.hit_=true;
    impact.normal_=norm;
    impact.sptr_=this;
    //std::cout << "t: " << t << "\n";
    return impact;
    std::cout << "ende";
    //std::cout << norm.x << norm.y << norm.z;
    //taken from https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
  }

  return noimpact;

 /* Hit HelloHitty;
  glm::vec3 norm = crossp(ecke1_-ecke2_,ecke1_-ecke3_);
  //glm::normalize(norm);
  float d = skalar(norm , ray.direction);
  if(d != 0)
  {
    float distance = (-(norm.x*(ray.origin.x - ecke1_.x))-(norm.y*(ray.origin.y - ecke1_.y))
      -(norm.z*(ray.origin.z - ecke1_.z))) / d;
    if(distance > 0)
    {
      HelloHitty.target_  = ray.origin + (distance * ray.direction);
      {
        if(skalar(ecke3_-ecke1_, ecke1_ - HelloHitty.target_) <= skalar(ecke3_ - ecke1_, ecke2_ - ecke1_) and skalar(ecke1_-ecke2_, ecke2_ - HelloHitty.target_) <= skalar(ecke1_ - ecke2_, ecke3_ - ecke2_) and skalar(ecke2_-ecke3_, ecke3_ - HelloHitty.target_) <= skalar(ecke2_ - ecke3_, ecke1_ - ecke3_) )
        {
        HelloHitty.hit_ = true;
        HelloHitty.normal_ = norm;
        HelloHitty.sptr_ = this;
        HelloHitty.distance_= distance; // glm::length(HelloHitty.target_ - ray.origin);
        }
      }
    }
  }
  return HelloHitty;*/
  /*glm::vec3 sub21{0.0f,0.0f,0.0f};
  sub21.x = ecke2_.x - ecke1_.x;
  sub21.y = ecke2_.y - ecke1_.y;
  sub21.z = ecke2_.z - ecke1_.z;

  glm::vec3 sub31{0.0f,0.0f,0.0f};
  sub31.x = ecke3_.x - ecke1_.x;
  sub31.y = ecke3_.y - ecke1_.y;
  sub31.z = ecke3_.z - ecke1_.z;

  glm::vec3 N = crossp(sub21,sub31);
  float A = betrag(N);
  Hit HelloHitty;
  float NdotprodwithRaydir = skalar(N, ray.direction);
  if (fabs(NdotprodwithRaydir) < 0.005)return HelloHitty;

  float d = skalar(N,ecke1_);
  float t = (skalar(N,ray.origin)+d) / NdotprodwithRaydir;
  glm::vec3 p = ray.origin + t * ray.direction;
  glm::vec3 C{0.0f,0.0f,0.0f};

  //ecke 1
  glm::vec3 eckeone = ecke2_-ecke1_;
  glm::vec3 vpone = p - ecke1_;
  C=crossp(ecke1_,vpone);
  if(skalar(N,C)<0)return HelloHitty;

  //ecke 2
  glm::vec3 ecketwo = ecke3_-ecke2_;
  glm::vec3 vptwo = p - ecke2_;
  C=crossp(ecke2_,vptwo);
  if(skalar(N,C)<0)return HelloHitty;

  //ecke 3
  glm::vec3 eckethree = ecke1_-ecke3_;
  glm::vec3 vpthree = p - ecke3_;
  C=crossp(ecke3_,vpthree);
  if(skalar(N,C)<0)return HelloHitty;
  glm::vec3 target= ray.origin + glm::normalize(ray.direction) * t;

  glm::vec3 normale= glm::normalize(crossp(sub21,sub31));
  Hit trifft;
  trifft.hit_=true;
  trifft.distance_=t;
  trifft.target_=target;
  trifft.normal_=normale;
  trifft.sptr_=this;
  return trifft;*/

}
/*bool rayTriangleIntersect(
    const Vec3f &orig, const Vec3f &dir,
    const Vec3f &v0, const Vec3f &v1, const Vec3f &v2,
    float &t)
{
    // compute plane's normal
    Vec3f v0v1 = v1 - v0;
    Vec3f v0v2 = v2 - v0;
    // no need to normalize
    Vec3f N = v0v1.crossProduct(v0v2); // N
    float area2 = N.length();

    // Step 1: finding P

    // check if ray and plane are parallel ?
    float NdotRayDirection = N.dotProduct(dir);
    if (fabs(NdotRayDirection) < kEpsilon) // almost 0
        return false; // they are parallel so they don't intersect !

    // compute d parameter using equation 2
    float d = N.dotProduct(v0);

    // compute t (equation 3)
    t = (N.dotProduct(orig) + d) / NdotRayDirection;
    // check if the triangle is in behind the ray
    if (t < 0) return false; // the triangle is behind

    // compute the intersection point using equation 1
    Vec3f P = orig + t * dir;

    // Step 2: inside-outside test
    Vec3f C; // vector perpendicular to triangle's plane

    // edge 0
    Vec3f edge0 = v1 - v0;
    Vec3f vp0 = P - v0;
    C = edge0.crossProduct(vp0);
    if (N.dotProduct(C) < 0) return false; // P is on the right side

    // edge 1
    Vec3f edge1 = v2 - v1;
    Vec3f vp1 = P - v1;
    C = edge1.crossProduct(vp1);
    if (N.dotProduct(C) < 0)  return false; // P is on the right side

    // edge 2
    Vec3f edge2 = v0 - v2;
    Vec3f vecke2_ = P - v2;
    C = edge2.crossProduct(vecke2_);
    if (N.dotProduct(C) < 0) return false; // P is on the right side;

    return true; // this ray hits the triangle
} */<commit_msg>there you go normalized normal vector<commit_after>#include "triangle.hpp"
#include <algorithm>

Triangle::Triangle():
Shape(),
ecke1_{1.0f,0.0f,-2.0f},
ecke2_{-1.0f,0.0f,-2.0f},
ecke3_{0.0f,1.0f,-2.0f}
{}

Triangle::Triangle(glm::vec3 const& ecke1, glm::vec3 const& ecke2, glm::vec3 const& ecke3):
Shape(),
/*ecke1_{ecke1.x,ecke1.y,ecke1.z},
ecke2_{ecke2.x,ecke2.y,ecke2.z},
ecke3_{ecke3.x,ecke3.y,ecke3.z}*/
ecke1_{ecke1},
ecke2_{ecke2},
ecke3_{ecke3}
{}

Triangle::Triangle(glm::vec3 const& ecke1, glm::vec3 const& ecke2, glm::vec3 const& ecke3, std::string const& name, Material const& mat):
Shape(name, mat),
/*ecke1_{ecke1.x,ecke1.y,ecke1.z},
ecke2_{ecke2.x,ecke2.y,ecke2.z},
ecke3_{ecke3.x,ecke3.y,ecke3.z}*/
ecke1_{ecke1},
ecke2_{ecke2},
ecke3_{ecke3}
{}

std::ostream& Triangle::print(std::ostream& os) const{
	Shape::print(os);
 os << "Punkt 1: ("<<ecke1_.x
	  << ", "<<ecke1_.y
    << ", "<<ecke1_.z
    << "Punkt 2: ("<< ecke2_.x
    << ", "<<ecke2_.y
    << ", "<<ecke2_.z
    << "Punkt 3: ("<< ecke3_.x
    << ", "<<ecke3_.y
    << ", "<<ecke3_.z
    << "\n";
}

/*Hit Triangle::intersect(Ray const& ray) {
  Hit defaulthit;
  return defaulthit;
}*/

Hit Triangle::intersect(Ray const& ray) {
  Hit impact;
  Hit noimpact;
  glm::vec3 e1,e2;
  glm::vec3 P,Q,T;
  float det, inv_det, u, v;
  float t;
  float bias = 0.00009;

  e1 = sub(ecke2_,ecke1_);
  e2 = sub(ecke3_,ecke1_);

  P = crossp(ray.direction,e2);
  det = skalar(e1,P);
  if(det > -bias && det < bias)return noimpact;
  inv_det = 1.0f / det;
  T = ray.origin-ecke1_;
  u = skalar(T,P) * inv_det;
  if(u < 0.0f || u > 1.0f)return noimpact;
  Q = crossp(T,e1);
  v = skalar(ray.direction,Q) * inv_det;
  if (v < 0.0 || u + v > 1.0)return noimpact;
  t = skalar(e2,Q) * inv_det;

  if (t > bias)
  {
    float distance = t;
    impact.distance_=t;
    impact.target_  = ray.origin + (distance * glm::normalize(ray.direction));
    glm::vec3 norm = crossp(ecke1_-ecke2_,ecke1_-ecke3_);
    norm = glm::normalize(norm);
    impact.hit_=true;
    impact.normal_=norm;
    impact.sptr_=this;
    //std::cout << "t: " << t << "\n";
    return impact;
    std::cout << "ende";
    //std::cout << norm.x << norm.y << norm.z;
    //taken from https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
  }

  return noimpact;

 /* Hit HelloHitty;
  glm::vec3 norm = crossp(ecke1_-ecke2_,ecke1_-ecke3_);
  //glm::normalize(norm);
  float d = skalar(norm , ray.direction);
  if(d != 0)
  {
    float distance = (-(norm.x*(ray.origin.x - ecke1_.x))-(norm.y*(ray.origin.y - ecke1_.y))
      -(norm.z*(ray.origin.z - ecke1_.z))) / d;
    if(distance > 0)
    {
      HelloHitty.target_  = ray.origin + (distance * ray.direction);
      {
        if(skalar(ecke3_-ecke1_, ecke1_ - HelloHitty.target_) <= skalar(ecke3_ - ecke1_, ecke2_ - ecke1_) and skalar(ecke1_-ecke2_, ecke2_ - HelloHitty.target_) <= skalar(ecke1_ - ecke2_, ecke3_ - ecke2_) and skalar(ecke2_-ecke3_, ecke3_ - HelloHitty.target_) <= skalar(ecke2_ - ecke3_, ecke1_ - ecke3_) )
        {
        HelloHitty.hit_ = true;
        HelloHitty.normal_ = norm;
        HelloHitty.sptr_ = this;
        HelloHitty.distance_= distance; // glm::length(HelloHitty.target_ - ray.origin);
        }
      }
    }
  }
  return HelloHitty;*/
  /*glm::vec3 sub21{0.0f,0.0f,0.0f};
  sub21.x = ecke2_.x - ecke1_.x;
  sub21.y = ecke2_.y - ecke1_.y;
  sub21.z = ecke2_.z - ecke1_.z;

  glm::vec3 sub31{0.0f,0.0f,0.0f};
  sub31.x = ecke3_.x - ecke1_.x;
  sub31.y = ecke3_.y - ecke1_.y;
  sub31.z = ecke3_.z - ecke1_.z;

  glm::vec3 N = crossp(sub21,sub31);
  float A = betrag(N);
  Hit HelloHitty;
  float NdotprodwithRaydir = skalar(N, ray.direction);
  if (fabs(NdotprodwithRaydir) < 0.005)return HelloHitty;

  float d = skalar(N,ecke1_);
  float t = (skalar(N,ray.origin)+d) / NdotprodwithRaydir;
  glm::vec3 p = ray.origin + t * ray.direction;
  glm::vec3 C{0.0f,0.0f,0.0f};

  //ecke 1
  glm::vec3 eckeone = ecke2_-ecke1_;
  glm::vec3 vpone = p - ecke1_;
  C=crossp(ecke1_,vpone);
  if(skalar(N,C)<0)return HelloHitty;

  //ecke 2
  glm::vec3 ecketwo = ecke3_-ecke2_;
  glm::vec3 vptwo = p - ecke2_;
  C=crossp(ecke2_,vptwo);
  if(skalar(N,C)<0)return HelloHitty;

  //ecke 3
  glm::vec3 eckethree = ecke1_-ecke3_;
  glm::vec3 vpthree = p - ecke3_;
  C=crossp(ecke3_,vpthree);
  if(skalar(N,C)<0)return HelloHitty;
  glm::vec3 target= ray.origin + glm::normalize(ray.direction) * t;

  glm::vec3 normale= glm::normalize(crossp(sub21,sub31));
  Hit trifft;
  trifft.hit_=true;
  trifft.distance_=t;
  trifft.target_=target;
  trifft.normal_=normale;
  trifft.sptr_=this;
  return trifft;*/

}
/*bool rayTriangleIntersect(
    const Vec3f &orig, const Vec3f &dir,
    const Vec3f &v0, const Vec3f &v1, const Vec3f &v2,
    float &t)
{
    // compute plane's normal
    Vec3f v0v1 = v1 - v0;
    Vec3f v0v2 = v2 - v0;
    // no need to normalize
    Vec3f N = v0v1.crossProduct(v0v2); // N
    float area2 = N.length();

    // Step 1: finding P

    // check if ray and plane are parallel ?
    float NdotRayDirection = N.dotProduct(dir);
    if (fabs(NdotRayDirection) < kEpsilon) // almost 0
        return false; // they are parallel so they don't intersect !

    // compute d parameter using equation 2
    float d = N.dotProduct(v0);

    // compute t (equation 3)
    t = (N.dotProduct(orig) + d) / NdotRayDirection;
    // check if the triangle is in behind the ray
    if (t < 0) return false; // the triangle is behind

    // compute the intersection point using equation 1
    Vec3f P = orig + t * dir;

    // Step 2: inside-outside test
    Vec3f C; // vector perpendicular to triangle's plane

    // edge 0
    Vec3f edge0 = v1 - v0;
    Vec3f vp0 = P - v0;
    C = edge0.crossProduct(vp0);
    if (N.dotProduct(C) < 0) return false; // P is on the right side

    // edge 1
    Vec3f edge1 = v2 - v1;
    Vec3f vp1 = P - v1;
    C = edge1.crossProduct(vp1);
    if (N.dotProduct(C) < 0)  return false; // P is on the right side

    // edge 2
    Vec3f edge2 = v0 - v2;
    Vec3f vecke2_ = P - v2;
    C = edge2.crossProduct(vecke2_);
    if (N.dotProduct(C) < 0) return false; // P is on the right side;

    return true; // this ray hits the triangle
} */<|endoftext|>


<commit_before>
#include <pgdb2.h>

int main (int argc, char *argv[])
{
	pagedb::Options opts;
	opts.f_read = true;
	opts.f_write = true;
	opts.f_create = true;

	pagedb::DB db("foo.db", opts);

	return 0;
}

<commit_msg>[test] basic: test for constructor failure upon non-existent db<commit_after>
#include <pgdb2.h>
#include <stdexcept>
#include <assert.h>

int main (int argc, char *argv[])
{
	pagedb::Options opts;
	opts.f_read = true;
	opts.f_write = false;
	opts.f_create = false;

	// TEST: fail, b/c foo.db does not exist
	bool saw_err = false;
	try {
		pagedb::DB db("foo.db", opts);
	}
	catch (const std::runtime_error& error) {
		saw_err = true;
	}
	catch (...) {
		assert(0);
	}
	assert(saw_err == true);

	// TEST: open/close foo.db
	opts.f_read = true;
	opts.f_write = true;
	opts.f_create = true;

	try {
		pagedb::DB db("foo.db", opts);
	}
	catch (...) {
		assert(0);
	}

	return 0;
}

<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2015 University of Groningen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include "VRPNInputPrivatePCH.h"
#include "VRPNInputDeviceManager.h"
#if PLATFORM_WINDOWS
	#include "AllowWindowsPlatformTypes.h"
		#include "vrpn_Tracker.h"
		#include "vrpn_Button.h"
	#include "HideWindowsPlatformTypes.h"
#elif PLATFORM_LINUX
	#include "vrpn_Tracker.h"
	#include "vrpn_Button.h"
#endif
DEFINE_LOG_CATEGORY(LogVRPNInputDevice);

class FVRPNInputPlugin : public IInputDeviceModule
{
public:
	/*
	* We override this so we can init the keys before the blueprints are compiled on editor startup
	* if we do not do this here we will get warnings in blueprints.
	*/
	virtual void StartupModule() override {
		IModularFeatures::Get().RegisterModularFeature(GetModularFeatureName(), this);

		UE_LOG(LogVRPNInputDevice, Log, TEXT("Locating VRPN config file."));
		FString ConfigFile;
		if(!FParse::Value(FCommandLine::Get(), TEXT("VRPNConfigFile="), ConfigFile))
		{
			UE_LOG(LogVRPNInputDevice, Warning, TEXT("Could not find VRPN configuration file: %s."), *ConfigFile);
			return;
		}
		if(!FPaths::FileExists(ConfigFile))
		{
			return;
			UE_LOG(LogVRPNInputDevice, Warning, TEXT("Could not find VRPN configuration file: %s."), *ConfigFile);
		}

		FString EnabledDevices;
		TArray<FString> EnabledDevicesArray;
		FParse::Value(FCommandLine::Get(), TEXT("VRPNEnabledDevices="), EnabledDevices);
		EnabledDevices.ParseIntoArray(&EnabledDevicesArray, TEXT(","), false);

		TArray<FString> SectionNames;
		GConfig->GetSectionNames(ConfigFile,SectionNames);
		for(FString &SectionNameString : SectionNames)
		{
			// Tracker name is the section name itself
			FConfigSection* TrackerConfig = GConfig->GetSectionPrivate(*SectionNameString, false, true, ConfigFile);

			FString *TrackerTypeString = TrackerConfig->Find(FName(TEXT("Type")));
			if(TrackerTypeString == nullptr)
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: expected to find Type of type String in section [%s]. Skipping this section."), *ConfigFile, *SectionNameString);
				continue;
			}

			FString *TrackerAdressString = TrackerConfig->Find(FName(TEXT("Address")));
			if(TrackerAdressString == nullptr)
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: expected to find Address of type String in section [%s]. Skipping this section."), *ConfigFile, *SectionNameString);
				continue;
			}

			IVRPNInputDevice *InputDevice = nullptr;
			bool bEnabled = EnabledDevicesArray.Num() == 0 ||EnabledDevicesArray.Contains(SectionNameString);
			if(TrackerTypeString->Compare("Tracker") == 0)
			{
				UE_LOG(LogVRPNInputDevice, Log, TEXT("Creating VRPNTrackerInputDevice %s on adress %s."), *SectionNameString, *(*TrackerAdressString));
				InputDevice = new VRPNTrackerInputDevice(*TrackerAdressString, bEnabled);
			} else if(TrackerTypeString->Compare("Button") == 0)
			{
				UE_LOG(LogVRPNInputDevice, Log, TEXT("Creating VRPNButtonInputDevice %s on adress %s."), *SectionNameString, *(*TrackerAdressString));
				InputDevice = new VRPNButtonInputDevice(*TrackerAdressString, bEnabled);
			} else
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: Type should be Tracker or Button but found %s in section %s. Skipping this section."), *ConfigFile, *(*TrackerTypeString), *SectionNameString);
				continue;
			}
			if(!InputDevice->ParseConfig(TrackerConfig))
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: Could not parse config %s.."), *ConfigFile, *SectionNameString);
				continue;
			}
			if(!DeviceManager.IsValid())
			{
				UE_LOG(LogVRPNInputDevice, Log, TEXT("Create VRPN Input Manager."));
				DeviceManager = TSharedPtr< FVRPNInputDeviceManager >(new FVRPNInputDeviceManager());
			}
			DeviceManager->AddInputDevice(InputDevice);
		}

	}

	/** IPsudoControllerInterface implementation */
	virtual TSharedPtr< class IInputDevice > CreateInputDevice(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler) override {
		if(!DeviceManager.IsValid())
		{
			UE_LOG(LogVRPNInputDevice, Log, TEXT("Create VRPN Input Manager"));
			DeviceManager = TSharedPtr< FVRPNInputDeviceManager >(new FVRPNInputDeviceManager());
		}

		return DeviceManager;
	}

	virtual void ShutdownModule() override {
		DeviceManager = nullptr;
	}

	TSharedPtr< class FVRPNInputDeviceManager > DeviceManager;
};

IMPLEMENT_MODULE(FVRPNInputPlugin, VRPNInput)

FVRPNInputDeviceManager::FVRPNInputDeviceManager() {
}

FVRPNInputDeviceManager::~FVRPNInputDeviceManager() {
	for(IVRPNInputDevice* InputDevice: VRPNInputDevices)
	{
		delete InputDevice;
	}
}

void FVRPNInputDeviceManager::SendControllerEvents() {
	for(IVRPNInputDevice* InputDevice: VRPNInputDevices)
	{
		InputDevice->Update();
	}
}
<commit_msg>Compile fix against API change in Unreal Engine 4.8 release.<commit_after>/*
The MIT License (MIT)

Copyright (c) 2015 University of Groningen

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

#include "VRPNInputPrivatePCH.h"
#include "VRPNInputDeviceManager.h"
#if PLATFORM_WINDOWS
	#include "AllowWindowsPlatformTypes.h"
		#include "vrpn_Tracker.h"
		#include "vrpn_Button.h"
	#include "HideWindowsPlatformTypes.h"
#elif PLATFORM_LINUX
	#include "vrpn_Tracker.h"
	#include "vrpn_Button.h"
#endif
DEFINE_LOG_CATEGORY(LogVRPNInputDevice);

class FVRPNInputPlugin : public IInputDeviceModule
{
public:
	/*
	* We override this so we can init the keys before the blueprints are compiled on editor startup
	* if we do not do this here we will get warnings in blueprints.
	*/
	virtual void StartupModule() override {
		IModularFeatures::Get().RegisterModularFeature(GetModularFeatureName(), this);

		UE_LOG(LogVRPNInputDevice, Log, TEXT("Locating VRPN config file."));
		FString ConfigFile;
		if(!FParse::Value(FCommandLine::Get(), TEXT("VRPNConfigFile="), ConfigFile))
		{
			UE_LOG(LogVRPNInputDevice, Warning, TEXT("Could not find VRPN configuration file: %s."), *ConfigFile);
			return;
		}
		if(!FPaths::FileExists(ConfigFile))
		{
			return;
			UE_LOG(LogVRPNInputDevice, Warning, TEXT("Could not find VRPN configuration file: %s."), *ConfigFile);
		}

		FString EnabledDevices;
		TArray<FString> EnabledDevicesArray;
		FParse::Value(FCommandLine::Get(), TEXT("VRPNEnabledDevices="), EnabledDevices);
		EnabledDevices.ParseIntoArray(EnabledDevicesArray, TEXT(","), false);

		TArray<FString> SectionNames;
		GConfig->GetSectionNames(ConfigFile,SectionNames);
		for(FString &SectionNameString : SectionNames)
		{
			// Tracker name is the section name itself
			FConfigSection* TrackerConfig = GConfig->GetSectionPrivate(*SectionNameString, false, true, ConfigFile);

			FString *TrackerTypeString = TrackerConfig->Find(FName(TEXT("Type")));
			if(TrackerTypeString == nullptr)
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: expected to find Type of type String in section [%s]. Skipping this section."), *ConfigFile, *SectionNameString);
				continue;
			}

			FString *TrackerAdressString = TrackerConfig->Find(FName(TEXT("Address")));
			if(TrackerAdressString == nullptr)
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: expected to find Address of type String in section [%s]. Skipping this section."), *ConfigFile, *SectionNameString);
				continue;
			}

			IVRPNInputDevice *InputDevice = nullptr;
			bool bEnabled = EnabledDevicesArray.Num() == 0 ||EnabledDevicesArray.Contains(SectionNameString);
			if(TrackerTypeString->Compare("Tracker") == 0)
			{
				UE_LOG(LogVRPNInputDevice, Log, TEXT("Creating VRPNTrackerInputDevice %s on adress %s."), *SectionNameString, *(*TrackerAdressString));
				InputDevice = new VRPNTrackerInputDevice(*TrackerAdressString, bEnabled);
			} else if(TrackerTypeString->Compare("Button") == 0)
			{
				UE_LOG(LogVRPNInputDevice, Log, TEXT("Creating VRPNButtonInputDevice %s on adress %s."), *SectionNameString, *(*TrackerAdressString));
				InputDevice = new VRPNButtonInputDevice(*TrackerAdressString, bEnabled);
			} else
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: Type should be Tracker or Button but found %s in section %s. Skipping this section."), *ConfigFile, *(*TrackerTypeString), *SectionNameString);
				continue;
			}
			if(!InputDevice->ParseConfig(TrackerConfig))
			{
				UE_LOG(LogVRPNInputDevice, Warning, TEXT("Tracker config file %s: Could not parse config %s.."), *ConfigFile, *SectionNameString);
				continue;
			}
			if(!DeviceManager.IsValid())
			{
				UE_LOG(LogVRPNInputDevice, Log, TEXT("Create VRPN Input Manager."));
				DeviceManager = TSharedPtr< FVRPNInputDeviceManager >(new FVRPNInputDeviceManager());
			}
			DeviceManager->AddInputDevice(InputDevice);
		}

	}

	/** IPsudoControllerInterface implementation */
	virtual TSharedPtr< class IInputDevice > CreateInputDevice(const TSharedRef< FGenericApplicationMessageHandler >& InMessageHandler) override {
		if(!DeviceManager.IsValid())
		{
			UE_LOG(LogVRPNInputDevice, Log, TEXT("Create VRPN Input Manager"));
			DeviceManager = TSharedPtr< FVRPNInputDeviceManager >(new FVRPNInputDeviceManager());
		}

		return DeviceManager;
	}

	virtual void ShutdownModule() override {
		DeviceManager = nullptr;
	}

	TSharedPtr< class FVRPNInputDeviceManager > DeviceManager;
};

IMPLEMENT_MODULE(FVRPNInputPlugin, VRPNInput)

FVRPNInputDeviceManager::FVRPNInputDeviceManager() {
}

FVRPNInputDeviceManager::~FVRPNInputDeviceManager() {
	for(IVRPNInputDevice* InputDevice: VRPNInputDevices)
	{
		delete InputDevice;
	}
}

void FVRPNInputDeviceManager::SendControllerEvents() {
	for(IVRPNInputDevice* InputDevice: VRPNInputDevices)
	{
		InputDevice->Update();
	}
}
<|endoftext|>


<commit_before>//! @file communicator.hpp
//! @brief Public interface for Communicator.
//!
//! @author Peter Georg
#ifndef pMR_BACKENDS_MPI_COMMUNICATOR_H
#define pMR_BACKENDS_MPI_COMMUNICATOR_H

#include <memory>
#include <vector>
extern "C"
{
#include <mpi.h>
}
#include "target.hpp"

namespace pMR
{
    //! @brief Backend-agnostic Communicator.
    class Communicator
    {
        public:
            //! @brief Convert MPI Communicator to backend-agnostic
            //!     Communicator.
            //! @param communicator MPI Communicator
            Communicator(MPI_Comm const communicator);
            //! @brief Creates a cartesian Communicator with topoloy.size()
            //!     dimensions.
            //! @param communicator MPI Communicator to use as base for new
            //!     cartesian Communicator.
            //! @param topology Number of processes in each dimension. Special
            //!     value 0 indicates to auto detect a best fit for that
            //!     dimension.
            //! @param periodic Wether a dimension is periodic or not.
            Communicator(MPI_Comm const communicator,
                    std::vector<int> const &topology,
                    std::vector<int> const &periodic);
            ~Communicator() = default;
            //! @brief Get the number of dimensions of the communicator.
            //! @return Number of dimensions.
            int dimensions() const;
            //! @brief The overall size of the communicator.
            //! @return Overall size of the communicator.
            int size() const;
            //! @brief Number of processes in specified dimension.
            //! @param dimension Dimension.
            //! @return Number of processes.
            int size(int const dimension) const;
            //! @brief Check if specified dimension is perodic.
            //! @param dimension Dimension.
            //! @return true if dimension is periodic, false otherwise.
            bool isPeriodic(int const dimension) const;
            //! @brief Get own coordinate of specified dimension.
            //! @param dimension Dimension.
            //! @return Own coordinate.
            int ID() const;
            //! @brief Get own identification number unique within this
            //!     communicator.
            //! @return Own ID.
            int coordinate(int const dimension) const;
            //! @brief Get the neighbor in specified dimension, direction and
            //!     displacement.
            //! @param dimension Dimension.
            //! @param displacement Direction (>0: upwards, <0: downwards) and
            //!     displacement.
            //! @return Target representing requested neighbor.
            //! @note In case of a non-circular shift the neighbor might be
            //!     null, check the target for further information.
            Target getNeighbor(int const dimension,
                    int const displacement) const;
            //! @brief Get target by ID.
            //! @param ID ID.
            //! @return Target with requested ID.
            //! @note Returns target loop in case ID is own ID.
            //! @note Returns targel null in case of negative ID.
            Target getTarget(int const ID) const;
            MPI_Comm get() const;
            //! @brief Get the communicator's topology.
            //! @return Vector of length dimensions containing the number of
            //!     processes in each dimension.
            std::vector<int> topology() const;
            //! @brief Get the communicator's topology periodicity.
            //! @return Vector of length dimensions containing 0 or 1
            //!     indicating wether dimensions is periodic or not.
            std::vector<int> periodic() const;
        private:
            MPI_Comm mCommunicator;
            int mID;
            int mSize;
            std::vector<int> mCoordinates;
            std::vector<int> mTopology;
            std::vector<int> mPeriodic;
            bool mCartesian = false;
    };
}
#endif // pMR_BACKENDS_MPI_COMMUNICATOR_H
<commit_msg>Fix documentation<commit_after>//! @file communicator.hpp
//! @brief Public interface for Communicator.
//!
//! @author Peter Georg
#ifndef pMR_BACKENDS_MPI_COMMUNICATOR_H
#define pMR_BACKENDS_MPI_COMMUNICATOR_H

#include <memory>
#include <vector>
extern "C"
{
#include <mpi.h>
}
#include "target.hpp"

namespace pMR
{
    //! @brief Backend-agnostic Communicator.
    class Communicator
    {
        public:
            //! @brief Convert MPI Communicator to backend-agnostic
            //!     Communicator.
            //! @param communicator MPI Communicator
            Communicator(MPI_Comm const communicator);
            //! @brief Creates a cartesian Communicator with topoloy.size()
            //!     dimensions.
            //! @param communicator MPI Communicator to use as base for new
            //!     cartesian Communicator.
            //! @param topology Number of processes in each dimension. Special
            //!     value 0 indicates to auto detect a best fit for that
            //!     dimension.
            //! @param periodic Wether a dimension is periodic or not.
            Communicator(MPI_Comm const communicator,
                    std::vector<int> const &topology,
                    std::vector<int> const &periodic);
            ~Communicator() = default;
            //! @brief Get the number of dimensions of the communicator.
            //! @return Number of dimensions.
            int dimensions() const;
            //! @brief The overall size of the communicator.
            //! @return Overall size of the communicator.
            int size() const;
            //! @brief Number of processes in specified dimension.
            //! @param dimension Dimension.
            //! @return Number of processes.
            int size(int const dimension) const;
            //! @brief Check if specified dimension is perodic.
            //! @param dimension Dimension.
            //! @return true if dimension is periodic, false otherwise.
            bool isPeriodic(int const dimension) const;
            //! @brief Get own identification number unique within this
            //!     communicator.
            //! @return Own ID.
            int ID() const;
            //! @brief Get own coordinate of specified dimension.
            //! @param dimension Dimension.
            //! @return Own coordinate.
            int coordinate(int const dimension) const;
            //! @brief Get the neighbor in specified dimension, direction and
            //!     displacement.
            //! @param dimension Dimension.
            //! @param displacement Direction (>0: upwards, <0: downwards) and
            //!     displacement.
            //! @return Target representing requested neighbor.
            //! @note In case of a non-circular shift the neighbor might be
            //!     null, check the target for further information.
            Target getNeighbor(int const dimension,
                    int const displacement) const;
            //! @brief Get target by ID.
            //! @param ID ID.
            //! @return Target with requested ID.
            //! @note Returns target loop in case ID is own ID.
            //! @note Returns targel null in case of negative ID.
            Target getTarget(int const ID) const;
            MPI_Comm get() const;
            //! @brief Get the communicator's topology.
            //! @return Vector of length dimensions containing the number of
            //!     processes in each dimension.
            std::vector<int> topology() const;
            //! @brief Get the communicator's topology periodicity.
            //! @return Vector of length dimensions containing 0 or 1
            //!     indicating wether dimensions is periodic or not.
            std::vector<int> periodic() const;
        private:
            MPI_Comm mCommunicator;
            int mID;
            int mSize;
            std::vector<int> mCoordinates;
            std::vector<int> mTopology;
            std::vector<int> mPeriodic;
            bool mCartesian = false;
    };
}
#endif // pMR_BACKENDS_MPI_COMMUNICATOR_H
<|endoftext|>


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

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "propacc.hxx"

#include <tools/urlobj.hxx>
#include <tools/errcode.hxx>
#include <svtools/svarray.hxx>
#include <sbstar.hxx>
#include <sbunoobj.hxx>

using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace cppu;
using namespace rtl;

//========================================================================

// Deklaration Konvertierung von Sbx nach Uno mit bekannter Zielklasse
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );

//========================================================================

#ifdef WNT
#define CDECL _cdecl
#endif
#if defined(UNX)
#define CDECL
#endif

int CDECL SbCompare_PropertyValues_Impl( const void *arg1, const void *arg2 )
{
   return ((PropertyValue*)arg1)->Name.compareTo( ((PropertyValue*)arg2)->Name );
}

extern "C" int CDECL SbCompare_UString_PropertyValue_Impl( const void *arg1, const void *arg2 )
{
    const OUString *pArg1 = (OUString*) arg1;
    const PropertyValue **pArg2 = (const PropertyValue**) arg2;
    return pArg1->compareTo( (*pArg2)->Name );
}

int CDECL SbCompare_Properties_Impl( const void *arg1, const void *arg2 )
{
   return ((Property*)arg1)->Name.compareTo( ((Property*)arg2)->Name );
}

extern "C" int CDECL SbCompare_UString_Property_Impl( const void *arg1, const void *arg2 )
{
    const OUString *pArg1 = (OUString*) arg1;
    const Property *pArg2 = (Property*) arg2;
    return pArg1->compareTo( pArg2->Name );
}

//----------------------------------------------------------------------------

SbPropertyValues::SbPropertyValues()
{
}

//----------------------------------------------------------------------------

SbPropertyValues::~SbPropertyValues()
{
    _xInfo = Reference< XPropertySetInfo >();

    for ( USHORT n = 0; n < _aPropVals.Count(); ++n )
        delete _aPropVals.GetObject( n );
}

//----------------------------------------------------------------------------

Reference< XPropertySetInfo > SbPropertyValues::getPropertySetInfo(void) throw( RuntimeException )
{
    // create on demand?
    if ( !_xInfo.is() )
    {
        SbPropertySetInfo *pInfo = new SbPropertySetInfo( _aPropVals );
        ((SbPropertyValues*)this)->_xInfo = (XPropertySetInfo*)pInfo;
    }
    return _xInfo;
}

//-------------------------------------------------------------------------

INT32 SbPropertyValues::GetIndex_Impl( const OUString &rPropName ) const
{
    PropertyValue **ppPV;
    ppPV = (PropertyValue **)
            bsearch( &rPropName, _aPropVals.GetData(), _aPropVals.Count(),
                      sizeof( PropertyValue* ),
                      SbCompare_UString_PropertyValue_Impl );
    return ppPV ? ( (ppPV-_aPropVals.GetData()) / sizeof(ppPV) ) : USHRT_MAX;
}

//----------------------------------------------------------------------------

void SbPropertyValues::setPropertyValue(
                    const OUString& aPropertyName,
                    const Any& aValue)
                    throw (::com::sun::star::beans::UnknownPropertyException,
                    ::com::sun::star::beans::PropertyVetoException,
                    ::com::sun::star::lang::IllegalArgumentException,
                    ::com::sun::star::lang::WrappedTargetException,
                    ::com::sun::star::uno::RuntimeException)
{
    INT32 nIndex = GetIndex_Impl( aPropertyName );
    PropertyValue *pPropVal = _aPropVals.GetObject(
        sal::static_int_cast< USHORT >(nIndex));
    pPropVal->Value = aValue;
}

//----------------------------------------------------------------------------

Any SbPropertyValues::getPropertyValue(
                    const OUString& aPropertyName)
                    throw(::com::sun::star::beans::UnknownPropertyException,
                    ::com::sun::star::lang::WrappedTargetException,
                    ::com::sun::star::uno::RuntimeException)
{
    INT32 nIndex = GetIndex_Impl( aPropertyName );
    if ( nIndex != USHRT_MAX )
        return _aPropVals.GetObject(
            sal::static_int_cast< USHORT >(nIndex))->Value;
    return Any();
}

//----------------------------------------------------------------------------

void SbPropertyValues::addPropertyChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XPropertyChangeListener >& )
                    throw ()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::removePropertyChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XPropertyChangeListener >& )
                    throw ()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::addVetoableChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XVetoableChangeListener >& )
                    throw()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::removeVetoableChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XVetoableChangeListener >& )
                    throw()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

Sequence< PropertyValue > SbPropertyValues::getPropertyValues(void) throw (::com::sun::star::uno::RuntimeException)
{
    Sequence<PropertyValue> aRet( _aPropVals.Count());
    for ( USHORT n = 0; n < _aPropVals.Count(); ++n )
        aRet.getArray()[n] = *_aPropVals.GetObject(n);
    return aRet;
}

//----------------------------------------------------------------------------

void SbPropertyValues::setPropertyValues(const Sequence< PropertyValue >& rPropertyValues )
                     throw (::com::sun::star::beans::UnknownPropertyException,
                     ::com::sun::star::beans::PropertyVetoException,
                     ::com::sun::star::lang::IllegalArgumentException,
                     ::com::sun::star::lang::WrappedTargetException,
                     ::com::sun::star::uno::RuntimeException)
{
    if ( _aPropVals.Count() )
        throw PropertyExistException();

    const PropertyValue *pPropVals = rPropertyValues.getConstArray();
    for ( sal_Int16 n = 0; n < rPropertyValues.getLength(); ++n )
    {
        PropertyValue *pPropVal = new PropertyValue(pPropVals[n]);
        _aPropVals.Insert( pPropVal, n );
    }
}

//============================================================================
//PropertySetInfoImpl

PropertySetInfoImpl::PropertySetInfoImpl()
{
}

INT32 PropertySetInfoImpl::GetIndex_Impl( const OUString &rPropName ) const
{
    Property *pP;
    pP = (Property*)
            bsearch( &rPropName, _aProps.getConstArray(), _aProps.getLength(),
                      sizeof( Property ),
                      SbCompare_UString_Property_Impl );
    return pP ? sal::static_int_cast<INT32>( (pP-_aProps.getConstArray()) / sizeof(pP) ) : -1;
}

Sequence< Property > PropertySetInfoImpl::getProperties(void) throw()
{
    return _aProps;
}

Property PropertySetInfoImpl::getPropertyByName(const OUString& Name) throw( RuntimeException )
{
    sal_Int32 nIndex = GetIndex_Impl( Name );
    if( USHRT_MAX != nIndex )
        return _aProps.getConstArray()[ nIndex ];
    return Property();
}

sal_Bool PropertySetInfoImpl::hasPropertyByName(const OUString& Name) throw( RuntimeException )
{
    sal_Int32 nIndex = GetIndex_Impl( Name );
    return USHRT_MAX != nIndex;
}

//============================================================================

SbPropertySetInfo::SbPropertySetInfo()
{
}

//----------------------------------------------------------------------------

SbPropertySetInfo::SbPropertySetInfo( const SbPropertyValueArr_Impl &rPropVals )
{
    aImpl._aProps.realloc( rPropVals.Count() );
    for ( USHORT n = 0; n < rPropVals.Count(); ++n )
    {
        Property &rProp = aImpl._aProps.getArray()[n];
        const PropertyValue &rPropVal = *rPropVals.GetObject(n);
        rProp.Name = rPropVal.Name;
        rProp.Handle = rPropVal.Handle;
        rProp.Type = getCppuVoidType();
        rProp.Attributes = 0;
    }
}

//----------------------------------------------------------------------------

SbPropertySetInfo::~SbPropertySetInfo()
{
}

//-------------------------------------------------------------------------

Sequence< Property > SbPropertySetInfo::getProperties(void) throw( RuntimeException )
{
    return aImpl.getProperties();
}

Property SbPropertySetInfo::getPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.getPropertyByName( Name );
}

BOOL SbPropertySetInfo::hasPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.hasPropertyByName( Name );
}

//----------------------------------------------------------------------------

SbPropertyContainer::SbPropertyContainer()
{
}

//----------------------------------------------------------------------------

SbPropertyContainer::~SbPropertyContainer()
{
}

//----------------------------------------------------------------------------
void SbPropertyContainer::addProperty(const OUString& Name,
                                      INT16 Attributes,
                                      const Any& DefaultValue)
    throw(  PropertyExistException, IllegalTypeException,
            IllegalArgumentException, RuntimeException )
{
    (void)Name;
    (void)Attributes;
    (void)DefaultValue;
}

//----------------------------------------------------------------------------
void SbPropertyContainer::removeProperty(const OUString& Name)
    throw( UnknownPropertyException, RuntimeException )
{
    (void)Name;
}

//----------------------------------------------------------------------------
// XPropertySetInfo
Sequence< Property > SbPropertyContainer::getProperties(void) throw ()
{
    return aImpl.getProperties();
}

Property SbPropertyContainer::getPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.getPropertyByName( Name );
}

BOOL SbPropertyContainer::hasPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.hasPropertyByName( Name );
}

//----------------------------------------------------------------------------

Sequence< PropertyValue > SbPropertyContainer::getPropertyValues(void)
{
    return Sequence<PropertyValue>();
}

//----------------------------------------------------------------------------

void SbPropertyContainer::setPropertyValues(const Sequence< PropertyValue >& PropertyValues_)
{
    (void)PropertyValues_;
}

//----------------------------------------------------------------------------

void RTL_Impl_CreatePropertySet( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite )
{
    (void)pBasic;
    (void)bWrite;

    // Wir brauchen mindestens 1 Parameter
    if ( rPar.Count() < 2 )
    {
        StarBASIC::Error( SbERR_BAD_ARGUMENT );
        return;
    }

    // Klassen-Name der struct holen
    String aServiceName( RTL_CONSTASCII_USTRINGPARAM("stardiv.uno.beans.PropertySet") );

#if 0
    // Service suchen und instanzieren
    Reference< XMultiServiceFactory > xServiceManager = getProcessServiceFactory();
    Reference< XInterface > xInterface;
    if( xProv.is() )
        xInterface = xProv->newInstance();
#else
    Reference< XInterface > xInterface = (OWeakObject*) new SbPropertyValues();
#endif

    SbxVariableRef refVar = rPar.Get(0);
    if( xInterface.is() )
    {
        // PropertyValues setzen
        Any aArgAsAny = sbxToUnoValue( rPar.Get(1),
                getCppuType( (Sequence<PropertyValue>*)0 ) );
        Sequence<PropertyValue> *pArg =
                (Sequence<PropertyValue>*) aArgAsAny.getValue();
        Reference< XPropertyAccess > xPropAcc = Reference< XPropertyAccess >::query( xInterface );
        xPropAcc->setPropertyValues( *pArg );

        // SbUnoObject daraus basteln und zurueckliefern
        Any aAny;
        aAny <<= xInterface;
        SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
        if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
        {
            // Objekt zurueckliefern
            refVar->PutObject( (SbUnoObject*)xUnoObj );
            return;
        }
    }

    // Objekt konnte nicht erzeugt werden
    refVar->PutObject( NULL );
}

<commit_msg>INTEGRATION: CWS bgdlremove (1.11.68); FILE MERGED 2007/05/25 10:45:36 kso 1.11.68.1: #i76911# - ucbhelper no longer uses vos::ORef but rtl::Reference.<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: propacc.cxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: ihi $ $Date: 2007-06-05 15:10:29 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_basic.hxx"

#include "propacc.hxx"

#include <tools/urlobj.hxx>
#include <tools/errcode.hxx>
#include <svtools/svarray.hxx>
#include <sbstar.hxx>
#include <sbunoobj.hxx>

using com::sun::star::uno::Reference;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace cppu;
using namespace rtl;

//========================================================================

// Deklaration Konvertierung von Sbx nach Uno mit bekannter Zielklasse
Any sbxToUnoValue( SbxVariable* pVar, const Type& rType, Property* pUnoProperty = NULL );

//========================================================================

#ifdef WNT
#define CDECL _cdecl
#endif
#if defined(UNX)
#define CDECL
#endif

int CDECL SbCompare_PropertyValues_Impl( const void *arg1, const void *arg2 )
{
   return ((PropertyValue*)arg1)->Name.compareTo( ((PropertyValue*)arg2)->Name );
}

extern "C" int CDECL SbCompare_UString_PropertyValue_Impl( const void *arg1, const void *arg2 )
{
    const OUString *pArg1 = (OUString*) arg1;
    const PropertyValue **pArg2 = (const PropertyValue**) arg2;
    return pArg1->compareTo( (*pArg2)->Name );
}

int CDECL SbCompare_Properties_Impl( const void *arg1, const void *arg2 )
{
   return ((Property*)arg1)->Name.compareTo( ((Property*)arg2)->Name );
}

extern "C" int CDECL SbCompare_UString_Property_Impl( const void *arg1, const void *arg2 )
{
    const OUString *pArg1 = (OUString*) arg1;
    const Property *pArg2 = (Property*) arg2;
    return pArg1->compareTo( pArg2->Name );
}

//----------------------------------------------------------------------------

SbPropertyValues::SbPropertyValues()
{
}

//----------------------------------------------------------------------------

SbPropertyValues::~SbPropertyValues()
{
    _xInfo = Reference< XPropertySetInfo >();

    for ( USHORT n = 0; n < _aPropVals.Count(); ++n )
        delete _aPropVals.GetObject( n );
}

//----------------------------------------------------------------------------

Reference< XPropertySetInfo > SbPropertyValues::getPropertySetInfo(void) throw( RuntimeException )
{
    // create on demand?
    if ( !_xInfo.is() )
    {
        SbPropertySetInfo *pInfo = new SbPropertySetInfo( _aPropVals );
        ((SbPropertyValues*)this)->_xInfo = (XPropertySetInfo*)pInfo;
    }
    return _xInfo;
}

//-------------------------------------------------------------------------

INT32 SbPropertyValues::GetIndex_Impl( const OUString &rPropName ) const
{
    PropertyValue **ppPV;
    ppPV = (PropertyValue **)
            bsearch( &rPropName, _aPropVals.GetData(), _aPropVals.Count(),
                      sizeof( PropertyValue* ),
                      SbCompare_UString_PropertyValue_Impl );
    return ppPV ? ( (ppPV-_aPropVals.GetData()) / sizeof(ppPV) ) : USHRT_MAX;
}

//----------------------------------------------------------------------------

void SbPropertyValues::setPropertyValue(
                    const OUString& aPropertyName,
                    const Any& aValue)
                    throw (::com::sun::star::beans::UnknownPropertyException,
                    ::com::sun::star::beans::PropertyVetoException,
                    ::com::sun::star::lang::IllegalArgumentException,
                    ::com::sun::star::lang::WrappedTargetException,
                    ::com::sun::star::uno::RuntimeException)
{
    INT32 nIndex = GetIndex_Impl( aPropertyName );
    PropertyValue *pPropVal = _aPropVals.GetObject(
        sal::static_int_cast< USHORT >(nIndex));
    pPropVal->Value = aValue;
}

//----------------------------------------------------------------------------

Any SbPropertyValues::getPropertyValue(
                    const OUString& aPropertyName)
                    throw(::com::sun::star::beans::UnknownPropertyException,
                    ::com::sun::star::lang::WrappedTargetException,
                    ::com::sun::star::uno::RuntimeException)
{
    INT32 nIndex = GetIndex_Impl( aPropertyName );
    if ( nIndex != USHRT_MAX )
        return _aPropVals.GetObject(
            sal::static_int_cast< USHORT >(nIndex))->Value;
    return Any();
}

//----------------------------------------------------------------------------

void SbPropertyValues::addPropertyChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XPropertyChangeListener >& )
                    throw ()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::removePropertyChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XPropertyChangeListener >& )
                    throw ()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::addVetoableChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XVetoableChangeListener >& )
                    throw()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

void SbPropertyValues::removeVetoableChangeListener(
                    const OUString& aPropertyName,
                    const Reference< XVetoableChangeListener >& )
                    throw()
{
    (void)aPropertyName;
}

//----------------------------------------------------------------------------

Sequence< PropertyValue > SbPropertyValues::getPropertyValues(void) throw (::com::sun::star::uno::RuntimeException)
{
    Sequence<PropertyValue> aRet( _aPropVals.Count());
    for ( USHORT n = 0; n < _aPropVals.Count(); ++n )
        aRet.getArray()[n] = *_aPropVals.GetObject(n);
    return aRet;
}

//----------------------------------------------------------------------------

void SbPropertyValues::setPropertyValues(const Sequence< PropertyValue >& rPropertyValues )
                     throw (::com::sun::star::beans::UnknownPropertyException,
                     ::com::sun::star::beans::PropertyVetoException,
                     ::com::sun::star::lang::IllegalArgumentException,
                     ::com::sun::star::lang::WrappedTargetException,
                     ::com::sun::star::uno::RuntimeException)
{
    if ( _aPropVals.Count() )
        throw PropertyExistException();

    const PropertyValue *pPropVals = rPropertyValues.getConstArray();
    for ( sal_Int16 n = 0; n < rPropertyValues.getLength(); ++n )
    {
        PropertyValue *pPropVal = new PropertyValue(pPropVals[n]);
        _aPropVals.Insert( pPropVal, n );
    }
}

//============================================================================
//PropertySetInfoImpl

PropertySetInfoImpl::PropertySetInfoImpl()
{
}

INT32 PropertySetInfoImpl::GetIndex_Impl( const OUString &rPropName ) const
{
    Property *pP;
    pP = (Property*)
            bsearch( &rPropName, _aProps.getConstArray(), _aProps.getLength(),
                      sizeof( Property ),
                      SbCompare_UString_Property_Impl );
    return pP ? sal::static_int_cast<INT32>( (pP-_aProps.getConstArray()) / sizeof(pP) ) : -1;
}

Sequence< Property > PropertySetInfoImpl::getProperties(void) throw()
{
    return _aProps;
}

Property PropertySetInfoImpl::getPropertyByName(const OUString& Name) throw( RuntimeException )
{
    sal_Int32 nIndex = GetIndex_Impl( Name );
    if( USHRT_MAX != nIndex )
        return _aProps.getConstArray()[ nIndex ];
    return Property();
}

sal_Bool PropertySetInfoImpl::hasPropertyByName(const OUString& Name) throw( RuntimeException )
{
    sal_Int32 nIndex = GetIndex_Impl( Name );
    return USHRT_MAX != nIndex;
}

//============================================================================

SbPropertySetInfo::SbPropertySetInfo()
{
}

//----------------------------------------------------------------------------

SbPropertySetInfo::SbPropertySetInfo( const SbPropertyValueArr_Impl &rPropVals )
{
    aImpl._aProps.realloc( rPropVals.Count() );
    for ( USHORT n = 0; n < rPropVals.Count(); ++n )
    {
        Property &rProp = aImpl._aProps.getArray()[n];
        const PropertyValue &rPropVal = *rPropVals.GetObject(n);
        rProp.Name = rPropVal.Name;
        rProp.Handle = rPropVal.Handle;
        rProp.Type = getCppuVoidType();
        rProp.Attributes = 0;
    }
}

//----------------------------------------------------------------------------

SbPropertySetInfo::~SbPropertySetInfo()
{
}

//-------------------------------------------------------------------------

Sequence< Property > SbPropertySetInfo::getProperties(void) throw( RuntimeException )
{
    return aImpl.getProperties();
}

Property SbPropertySetInfo::getPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.getPropertyByName( Name );
}

BOOL SbPropertySetInfo::hasPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.hasPropertyByName( Name );
}

//----------------------------------------------------------------------------

SbPropertyContainer::SbPropertyContainer()
{
}

//----------------------------------------------------------------------------

SbPropertyContainer::~SbPropertyContainer()
{
}

//----------------------------------------------------------------------------
void SbPropertyContainer::addProperty(const OUString& Name,
                                      INT16 Attributes,
                                      const Any& DefaultValue)
    throw(  PropertyExistException, IllegalTypeException,
            IllegalArgumentException, RuntimeException )
{
    (void)Name;
    (void)Attributes;
    (void)DefaultValue;
}

//----------------------------------------------------------------------------
void SbPropertyContainer::removeProperty(const OUString& Name)
    throw( UnknownPropertyException, RuntimeException )
{
    (void)Name;
}

//----------------------------------------------------------------------------
// XPropertySetInfo
Sequence< Property > SbPropertyContainer::getProperties(void) throw ()
{
    return aImpl.getProperties();
}

Property SbPropertyContainer::getPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.getPropertyByName( Name );
}

BOOL SbPropertyContainer::hasPropertyByName(const OUString& Name)
    throw( RuntimeException )
{
    return aImpl.hasPropertyByName( Name );
}

//----------------------------------------------------------------------------

Sequence< PropertyValue > SbPropertyContainer::getPropertyValues(void)
{
    return Sequence<PropertyValue>();
}

//----------------------------------------------------------------------------

void SbPropertyContainer::setPropertyValues(const Sequence< PropertyValue >& PropertyValues_)
{
    (void)PropertyValues_;
}

//----------------------------------------------------------------------------

void RTL_Impl_CreatePropertySet( StarBASIC* pBasic, SbxArray& rPar, BOOL bWrite )
{
    (void)pBasic;
    (void)bWrite;

    // Wir brauchen mindestens 1 Parameter
    if ( rPar.Count() < 2 )
    {
        StarBASIC::Error( SbERR_BAD_ARGUMENT );
        return;
    }

    // Klassen-Name der struct holen
    String aServiceName( RTL_CONSTASCII_USTRINGPARAM("stardiv.uno.beans.PropertySet") );

#if 0
    // Service suchen und instanzieren
    Reference< XMultiServiceFactory > xServiceManager = getProcessServiceFactory();
    Reference< XInterface > xInterface;
    if( xProv.is() )
        xInterface = xProv->newInstance();
#else
    Reference< XInterface > xInterface = (OWeakObject*) new SbPropertyValues();
#endif

    SbxVariableRef refVar = rPar.Get(0);
    if( xInterface.is() )
    {
        // PropertyValues setzen
        Any aArgAsAny = sbxToUnoValue( rPar.Get(1),
                getCppuType( (Sequence<PropertyValue>*)0 ) );
        Sequence<PropertyValue> *pArg =
                (Sequence<PropertyValue>*) aArgAsAny.getValue();
        Reference< XPropertyAccess > xPropAcc = Reference< XPropertyAccess >::query( xInterface );
        xPropAcc->setPropertyValues( *pArg );

        // SbUnoObject daraus basteln und zurueckliefern
        Any aAny;
        aAny <<= xInterface;
        SbUnoObjectRef xUnoObj = new SbUnoObject( aServiceName, aAny );
        if( xUnoObj->getUnoAny().getValueType().getTypeClass() != TypeClass_VOID )
        {
            // Objekt zurueckliefern
            refVar->PutObject( (SbUnoObject*)xUnoObj );
            return;
        }
    }

    // Objekt konnte nicht erzeugt werden
    refVar->PutObject( NULL );
}

<|endoftext|>


<commit_before>/*
 * vvms.cpp
 *
 *  Created on: Nov 20, 2012
 *	  Author: partio
 */

#include "vvms.h"
#include <iostream>
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "fetcher.h"
#include "writer.h"
#include "neons.h"
#include "pcuda.h"

#undef HIMAN_AUXILIARY_INCLUDE

#ifdef DEBUG
#include "timer_factory.h"
#endif

using namespace std;
using namespace himan::plugin;

#include "cuda_extern.h"

vvms::vvms() : itsUseCuda(false), itsCudaDeviceCount(0)
{
	itsClearTextFormula = "w = -(ver) * 287 * T * (9.81*p)";

	itsLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("vvms"));

}

void vvms::Process(std::shared_ptr<const plugin_configuration> conf)
{

	shared_ptr<plugin::pcuda> c = dynamic_pointer_cast<plugin::pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

	if (c->HaveCuda())
	{
		string msg = "I possess the powers of CUDA";

		if (!conf->UseCuda())
		{
			msg += ", but I won't use them";
		}
		else
		{
			msg += ", and I'm not afraid to use them";
			itsUseCuda = true;
		}

		itsLogger->Info(msg);

		itsCudaDeviceCount = c->DeviceCount();

	}

	// Get number of threads to use

	unsigned short threadCount = ThreadCount(conf->ThreadCount());

	if (conf->StatisticsEnabled())
	{
		conf->Statistics()->UsedThreadCount(threadCount);
		conf->Statistics()->UsedGPUCount(itsCudaDeviceCount);
	}

	boost::thread_group g;

	shared_ptr<info> targetInfo = conf->Info();

	/*
	 * Set target parameter to potential temperature
	 *
	 * We need to specify grib and querydata parameter information
	 * since we don't know which one will be the output format.
	 * (todo: we could check from conf but why bother?)
	 *
	 */

	vector<param> theParams;

	param theRequestedParam ("VV-MS", 143);

	// GRIB 2

	theRequestedParam.GribDiscipline(0);
	theRequestedParam.GribCategory(2);
	theRequestedParam.GribParameter(9);

	// GRIB 1

	if (conf->OutputFileType() == kGRIB1)
	{
		shared_ptr<neons> n = dynamic_pointer_cast<neons> (plugin_factory::Instance()->Plugin("neons"));

		long parm_id = n->NeonsDB().GetGridParameterId(targetInfo->Producer().TableVersion(), theRequestedParam.Name());
		theRequestedParam.GribIndicatorOfParameter(parm_id);
		theRequestedParam.GribTableVersion(targetInfo->Producer().TableVersion());

	}

	theParams.push_back(theRequestedParam);

	targetInfo->Params(theParams);

	/*
	 * Create data structures.
	 */

	targetInfo->Create();

	/*
	 * Initialize parent class functions for dimension handling
	 */

	Dimension(conf->LeadingDimension());
	FeederInfo(shared_ptr<info> (new info(*targetInfo)));
	FeederInfo()->Param(theRequestedParam);

	/*
	 * Each thread will have a copy of the target info.
	 */

	vector<shared_ptr<info> > targetInfos;

	targetInfos.resize(threadCount);

	for (size_t i = 0; i < threadCount; i++)
	{

		itsLogger->Info("Thread " + boost::lexical_cast<string> (i + 1) + " starting");

		targetInfos[i] = shared_ptr<info> (new info(*targetInfo));

		boost::thread* t = new boost::thread(&vvms::Run,
							 this,
							 targetInfos[i],
							 conf,
							 i + 1);

		g.add_thread(t);

	}

	g.join_all();

	if (conf->FileWriteOption() == kSingleFile)
	{

		shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

		string theOutputFile = conf->ConfigurationFile();

		theWriter->ToFile(targetInfo, conf, theOutputFile);

	}
}

void vvms::Run(shared_ptr<info> myTargetInfo,
			   shared_ptr<const plugin_configuration> conf,
			   unsigned short threadIndex)
{

	while (AdjustLeadingDimension(myTargetInfo))
	{
		Calculate(myTargetInfo, conf, threadIndex);
	}

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void vvms::Calculate(shared_ptr<info> myTargetInfo,
					 shared_ptr<const plugin_configuration> conf,
					 unsigned short threadIndex)
{

	shared_ptr<fetcher> theFetcher = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

	// Required source parameters

	param TParam("T-K");
	param PParam("P-PA");
	param VVParam("VV-PAS");

	unique_ptr<logger> myThreadedLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("vvmsThread #" + boost::lexical_cast<string> (threadIndex)));

	ResetNonLeadingDimension(myTargetInfo);

	myTargetInfo->FirstParam();

	while (AdjustNonLeadingDimension(myTargetInfo))
	{

		myThreadedLogger->Info("Calculating time " + myTargetInfo->Time().ValidDateTime()->String("%Y%m%d%H%M") +
								" level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));

		double PScale = 1;
		double TBase = 0;

		/*
		 * If vvms is calculated for pressure levels, the P value
		 * equals to level value. Otherwise we have to fetch P
		 * separately.
		 */

		shared_ptr<info> PInfo;
		shared_ptr<info> VVInfo;
		shared_ptr<info> TInfo;

		shared_ptr<NFmiGrid> PGrid;

		bool isPressureLevel = (myTargetInfo->Level().Type() == kPressure);

		try
		{
			VVInfo = theFetcher->Fetch(conf,
						  myTargetInfo->Time(),
						  myTargetInfo->Level(),
						  VVParam);

			TInfo = theFetcher->Fetch(conf,
						 myTargetInfo->Time(),
						 myTargetInfo->Level(),
						 TParam);

			if (!isPressureLevel)
			{
				// Source info for P
				PInfo = theFetcher->Fetch(conf,
							  myTargetInfo->Time(),
							  myTargetInfo->Level(),
							  PParam);

				if (PInfo->Param().Unit() == kHPa)
				{
					PScale = 100;
				}

				PGrid = shared_ptr<NFmiGrid> (PInfo->Grid()->ToNewbaseGrid());
			}
		}
		catch (HPExceptionType e)
		{
			switch (e)
			{
				case kFileDataNotFound:
					itsLogger->Info("Skipping step " + boost::lexical_cast<string> (myTargetInfo->Time().Step()) + ", level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));
					myTargetInfo->Data()->Fill(kFloatMissing); // Fill data with missing value

					if (conf->StatisticsEnabled())
					{
						conf->Statistics()->AddToMissingCount(myTargetInfo->Grid()->Size());
						conf->Statistics()->AddToValueCount(myTargetInfo->Grid()->Size());
					}

					continue;
					break;

				default:
					throw runtime_error(ClassName() + ": Unable to proceed");
					break;
			}
		}

		unique_ptr<timer> processTimer = unique_ptr<timer> (timer_factory::Instance()->GetTimer());

		if (conf->StatisticsEnabled())
		{
			processTimer->Start();
		}

		if (TInfo->Param().Unit() == kC)
		{
			TBase = 273.15;
		}

		shared_ptr<NFmiGrid> targetGrid(myTargetInfo->Grid()->ToNewbaseGrid());
		shared_ptr<NFmiGrid> TGrid(TInfo->Grid()->ToNewbaseGrid());
		shared_ptr<NFmiGrid> VVGrid(VVInfo->Grid()->ToNewbaseGrid());

		int missingCount = 0;
		int count = 0;

		bool equalGrids = (*myTargetInfo->Grid() == *TInfo->Grid() &&
							*myTargetInfo->Grid() == *VVInfo->Grid() &&
						   (isPressureLevel || *myTargetInfo->Grid() == *PInfo->Grid()));

		string deviceType;

		if (itsUseCuda && equalGrids && threadIndex <= itsCudaDeviceCount)
		{
			deviceType = "GPU";

			size_t N = TGrid->Size();

			float* VVout = new float[N];
			double *infoData = new double[N];

			if (!isPressureLevel)
			{
				vvms_cuda::DoCuda(TGrid->DataPool()->Data(), TBase, PGrid->DataPool()->Data(), PScale, VVGrid->DataPool()->Data(), VVout, N, 0, threadIndex-1);
			}
			else
			{
				vvms_cuda::DoCuda(TGrid->DataPool()->Data(), TBase, 0, 0, VVGrid->DataPool()->Data(), VVout, N, 100 * myTargetInfo->Level().Value(), threadIndex-1);
			}

			for (size_t i = 0; i < N; i++)
			{
				infoData[i] = static_cast<double> (VVout[i]);

				if (infoData[i] == kFloatMissing)
				{
					missingCount++;
				}

				count++;
			}

			myTargetInfo->Data()->Set(infoData, N);

			delete [] infoData;
			delete [] VVout;

		}
		else
		{
			deviceType = "CPU";

			assert(targetGrid->Size() == myTargetInfo->Data()->Size());

			myTargetInfo->ResetLocation();

			targetGrid->Reset();

			while (myTargetInfo->NextLocation() && targetGrid->Next())
			{
				count++;

				double T = kFloatMissing;
				double P = kFloatMissing;
				double VV = kFloatMissing;

				InterpolateToPoint(targetGrid, TGrid, equalGrids, T);
				InterpolateToPoint(targetGrid, VVGrid, equalGrids, VV);

				if (isPressureLevel)
				{
					P = 100 * myTargetInfo->Level().Value();
				}
				else
				{
				 	InterpolateToPoint(targetGrid, PGrid, equalGrids, P);
				}

				if (T == kFloatMissing || P == kFloatMissing || VV == kFloatMissing)
				{
					missingCount++;

					myTargetInfo->Value(kFloatMissing);
					continue;
				}

				double VVms = 287 * -VV * (T + TBase) / (9.81 * P * PScale);

				if (!myTargetInfo->Value(VVms))
				{
					throw runtime_error(ClassName() + ": Failed to set value to matrix");
				}

			}
		}

		if (conf->StatisticsEnabled())
		{
			processTimer->Stop();
			conf->Statistics()->AddToProcessingTime(processTimer->GetTime());

#ifdef DEBUG
			itsLogger->Debug("Calculation took " + boost::lexical_cast<string> (processTimer->GetTime()) + " microseconds on "  + deviceType);
#endif

			conf->Statistics()->AddToMissingCount(missingCount);
			conf->Statistics()->AddToValueCount(count);

		}

		/*
		 * Now we are done for this level
		 *
		 * Clone info-instance to writer since it might change our descriptor places
		 */

		myThreadedLogger->Info("Missing values: " + boost::lexical_cast<string> (missingCount) + "/" + boost::lexical_cast<string> (count));

		if (conf->FileWriteOption() == kNeons || conf->FileWriteOption() == kMultipleFiles)
		{
			shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

			theWriter->ToFile(shared_ptr<info> (new info(*myTargetInfo)), conf);
		}
	}
}
<commit_msg>changes<commit_after>/*
 * vvms.cpp
 *
 *  Created on: Nov 20, 2012
 *	  Author: partio
 */

#include "vvms.h"
#include <iostream>
#include "plugin_factory.h"
#include "logger_factory.h"
#include <boost/lexical_cast.hpp>

#define HIMAN_AUXILIARY_INCLUDE

#include "fetcher.h"
#include "writer.h"
#include "neons.h"
#include "pcuda.h"

#undef HIMAN_AUXILIARY_INCLUDE

#ifdef DEBUG
#include "timer_factory.h"
#endif

using namespace std;
using namespace himan::plugin;

#include "vvms_cuda.h"

vvms::vvms() : itsUseCuda(false), itsCudaDeviceCount(0)
{
	itsClearTextFormula = "w = -(ver) * 287 * T * (9.81*p)";

	itsLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("vvms"));

}

void vvms::Process(std::shared_ptr<const plugin_configuration> conf)
{

	shared_ptr<plugin::pcuda> c = dynamic_pointer_cast<plugin::pcuda> (plugin_factory::Instance()->Plugin("pcuda"));

	if (c->HaveCuda())
	{
		string msg = "I possess the powers of CUDA";

		if (!conf->UseCuda())
		{
			msg += ", but I won't use them";
		}
		else
		{
			msg += ", and I'm not afraid to use them";
			itsUseCuda = true;
		}

		itsLogger->Info(msg);

		itsCudaDeviceCount = c->DeviceCount();

	}

	// Get number of threads to use

	unsigned short threadCount = ThreadCount(conf->ThreadCount());

	if (conf->StatisticsEnabled())
	{
		conf->Statistics()->UsedThreadCount(threadCount);
		conf->Statistics()->UsedGPUCount(itsCudaDeviceCount);
	}

	boost::thread_group g;

	shared_ptr<info> targetInfo = conf->Info();

	/*
	 * Set target parameter to potential temperature
	 *
	 * We need to specify grib and querydata parameter information
	 * since we don't know which one will be the output format.
	 * (todo: we could check from conf but why bother?)
	 *
	 */

	vector<param> theParams;

	param theRequestedParam ("VV-MS", 143);

	// GRIB 2

	theRequestedParam.GribDiscipline(0);
	theRequestedParam.GribCategory(2);
	theRequestedParam.GribParameter(9);

	// GRIB 1

	if (conf->OutputFileType() == kGRIB1)
	{
		shared_ptr<neons> n = dynamic_pointer_cast<neons> (plugin_factory::Instance()->Plugin("neons"));

		long parm_id = n->NeonsDB().GetGridParameterId(targetInfo->Producer().TableVersion(), theRequestedParam.Name());
		theRequestedParam.GribIndicatorOfParameter(parm_id);
		theRequestedParam.GribTableVersion(targetInfo->Producer().TableVersion());

	}

	theParams.push_back(theRequestedParam);

	targetInfo->Params(theParams);

	/*
	 * Create data structures.
	 */

	targetInfo->Create();

	/*
	 * Initialize parent class functions for dimension handling
	 */

	Dimension(conf->LeadingDimension());
	FeederInfo(shared_ptr<info> (new info(*targetInfo)));
	FeederInfo()->Param(theRequestedParam);

	/*
	 * Each thread will have a copy of the target info.
	 */

	vector<shared_ptr<info> > targetInfos;

	targetInfos.resize(threadCount);

	for (size_t i = 0; i < threadCount; i++)
	{

		itsLogger->Info("Thread " + boost::lexical_cast<string> (i + 1) + " starting");

		targetInfos[i] = shared_ptr<info> (new info(*targetInfo));

		boost::thread* t = new boost::thread(&vvms::Run,
							 this,
							 targetInfos[i],
							 conf,
							 i + 1);

		g.add_thread(t);

	}

	g.join_all();

	if (conf->FileWriteOption() == kSingleFile)
	{

		shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

		string theOutputFile = conf->ConfigurationFile();

		theWriter->ToFile(targetInfo, conf, theOutputFile);

	}
}

void vvms::Run(shared_ptr<info> myTargetInfo,
			   shared_ptr<const plugin_configuration> conf,
			   unsigned short threadIndex)
{

	while (AdjustLeadingDimension(myTargetInfo))
	{
		Calculate(myTargetInfo, conf, threadIndex);
	}

}

/*
 * Calculate()
 *
 * This function does the actual calculation.
 */

void vvms::Calculate(shared_ptr<info> myTargetInfo,
					 shared_ptr<const plugin_configuration> conf,
					 unsigned short threadIndex)
{

	shared_ptr<fetcher> theFetcher = dynamic_pointer_cast <fetcher> (plugin_factory::Instance()->Plugin("fetcher"));

	// Required source parameters

	param TParam("T-K");
	param PParam("P-PA");
	param VVParam("VV-PAS");

	unique_ptr<logger> myThreadedLogger = std::unique_ptr<logger> (logger_factory::Instance()->GetLog("vvmsThread #" + boost::lexical_cast<string> (threadIndex)));

	ResetNonLeadingDimension(myTargetInfo);

	myTargetInfo->FirstParam();

	bool useCudaInThisThread = itsUseCuda && threadIndex <= itsCudaDeviceCount;

	while (AdjustNonLeadingDimension(myTargetInfo))
	{

		myThreadedLogger->Info("Calculating time " + myTargetInfo->Time().ValidDateTime()->String("%Y%m%d%H%M") +
								" level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));

		double PScale = 1;
		double TBase = 0;

		/*
		 * If vvms is calculated for pressure levels, the P value
		 * equals to level value. Otherwise we have to fetch P
		 * separately.
		 */

		shared_ptr<info> PInfo;
		shared_ptr<info> VVInfo;
		shared_ptr<info> TInfo;

		shared_ptr<NFmiGrid> PGrid;

		bool isPressureLevel = (myTargetInfo->Level().Type() == kPressure);
		cout << threadIndex << " " << useCudaInThisThread << endl;
		try
		{
			VVInfo = theFetcher->Fetch(conf,
						  myTargetInfo->Time(),
						  myTargetInfo->Level(),
						  VVParam,
						  useCudaInThisThread);

			TInfo = theFetcher->Fetch(conf,
						 myTargetInfo->Time(),
						 myTargetInfo->Level(),
						 TParam);

			if (!isPressureLevel)
			{
				// Source info for P
				PInfo = theFetcher->Fetch(conf,
							  myTargetInfo->Time(),
							  myTargetInfo->Level(),
							  PParam);

				if (PInfo->Param().Unit() == kHPa)
				{
					PScale = 100;
				}

				PGrid = shared_ptr<NFmiGrid> (PInfo->Grid()->ToNewbaseGrid());
			}
		}
		catch (HPExceptionType e)
		{
			switch (e)
			{
				case kFileDataNotFound:
					itsLogger->Info("Skipping step " + boost::lexical_cast<string> (myTargetInfo->Time().Step()) + ", level " + boost::lexical_cast<string> (myTargetInfo->Level().Value()));
					myTargetInfo->Data()->Fill(kFloatMissing); // Fill data with missing value

					if (conf->StatisticsEnabled())
					{
						conf->Statistics()->AddToMissingCount(myTargetInfo->Grid()->Size());
						conf->Statistics()->AddToValueCount(myTargetInfo->Grid()->Size());
					}

					continue;
					break;

				default:
					throw runtime_error(ClassName() + ": Unable to proceed");
					break;
			}
		}

		unique_ptr<timer> processTimer = unique_ptr<timer> (timer_factory::Instance()->GetTimer());

		if (conf->StatisticsEnabled())
		{
			processTimer->Start();
		}

		if (TInfo->Param().Unit() == kC)
		{
			TBase = 273.15;
		}

		int missingCount = 0;
		int count = 0;

		bool equalGrids = (*myTargetInfo->Grid() == *TInfo->Grid() &&
							*myTargetInfo->Grid() == *VVInfo->Grid() &&
						   (isPressureLevel || *myTargetInfo->Grid() == *PInfo->Grid()));

		string deviceType;

		if (useCudaInThisThread && equalGrids)
		{
			deviceType = "GPU";

			vvms_cuda::vvms_cuda_options opts;

			opts.isConstantPressure = isPressureLevel;
			opts.TBase = TBase;
			opts.PScale = PScale;
			opts.cudaDeviceIndex = threadIndex-1;

			opts.N = TInfo->Grid()->Size();

			if (TInfo->Grid()->DataIsPacked())
			{
				assert(TInfo->Grid()->PackedData()->ClassName() == "simple_packed");

				opts.NPacked = TInfo->Grid()->PackedData()->Size();

				opts.TInPacked = dynamic_pointer_cast<simple_packed> (TInfo->Grid()->PackedData())->Values();
				opts.VVInPacked = dynamic_pointer_cast<simple_packed> (VVInfo->Grid()->PackedData())->Values();

				if (!opts.isConstantPressure)
				{
					opts.PInPacked = dynamic_pointer_cast<simple_packed> (PInfo->Grid()->PackedData())->Values();
				}

				opts.isPackedData = true;
			}
			else
			{
				opts.TIn = TInfo->Grid()->Data()->Values();
				opts.VVIn = VVInfo->Grid()->Data()->Values();

				if (!opts.isConstantPressure)
				{
					opts.PIn = PInfo->Grid()->Data()->Values();
				}

				opts.isPackedData = false;

			}

			if (opts.isConstantPressure)
			{
				opts.PConst = myTargetInfo->Level().Value() * 100; // Pa
			}

			cudaMallocHost(reinterpret_cast<void**> (&opts.VVOut), opts.N * sizeof(double));

			vvms_cuda::DoCuda(opts);

			assert(TInfo->Grid()->ScanningMode() == VVInfo->Grid()->ScanningMode() && (isPressureLevel || VVInfo->Grid()->ScanningMode() == PInfo->Grid()->ScanningMode()));

			if (TInfo->Grid()->ScanningMode() != myTargetInfo->Grid()->ScanningMode())
			{
				HPScanningMode originalMode = myTargetInfo->Grid()->ScanningMode();

				myTargetInfo->Grid()->ScanningMode(TInfo->Grid()->ScanningMode());

				myTargetInfo->Grid()->Swap(originalMode);
			}

			myTargetInfo->Data()->Set(opts.VVOut, opts.N);

			cudaFreeHost(opts.VVOut);

		}
		else
		{
			deviceType = "CPU";

			shared_ptr<NFmiGrid> targetGrid(myTargetInfo->Grid()->ToNewbaseGrid());
			shared_ptr<NFmiGrid> TGrid(TInfo->Grid()->ToNewbaseGrid());
			shared_ptr<NFmiGrid> VVGrid(VVInfo->Grid()->ToNewbaseGrid());

			assert(targetGrid->Size() == myTargetInfo->Data()->Size());

			myTargetInfo->ResetLocation();

			targetGrid->Reset();

			while (myTargetInfo->NextLocation() && targetGrid->Next())
			{
				count++;

				double T = kFloatMissing;
				double P = kFloatMissing;
				double VV = kFloatMissing;

				InterpolateToPoint(targetGrid, TGrid, equalGrids, T);
				InterpolateToPoint(targetGrid, VVGrid, equalGrids, VV);

				if (isPressureLevel)
				{
					P = 100 * myTargetInfo->Level().Value();
				}
				else
				{
				 	InterpolateToPoint(targetGrid, PGrid, equalGrids, P);
				}

				if (T == kFloatMissing || P == kFloatMissing || VV == kFloatMissing)
				{
					missingCount++;

					myTargetInfo->Value(kFloatMissing);
					continue;
				}

				double VVms = 287 * -VV * (T + TBase) / (9.81 * P * PScale);

				if (!myTargetInfo->Value(VVms))
				{
					throw runtime_error(ClassName() + ": Failed to set value to matrix");
				}
			}

			/*
			 * Newbase normalizes scanning mode to bottom left -- if that's not what
			 * the target scanning mode is, we have to swap the data back.
			 */

			if (myTargetInfo->Grid()->ScanningMode() != kBottomLeft)
			{
				HPScanningMode originalMode = myTargetInfo->Grid()->ScanningMode();

				myTargetInfo->Grid()->ScanningMode(kBottomLeft);

				myTargetInfo->Grid()->Swap(originalMode);
			}
		}

		if (conf->StatisticsEnabled())
		{
			processTimer->Stop();
			conf->Statistics()->AddToProcessingTime(processTimer->GetTime());

#ifdef DEBUG
			itsLogger->Debug("Calculation took " + boost::lexical_cast<string> (processTimer->GetTime()) + " microseconds on "  + deviceType);
#endif

			conf->Statistics()->AddToMissingCount(missingCount);
			conf->Statistics()->AddToValueCount(count);

		}

		/*
		 * Now we are done for this level
		 *
		 * Clone info-instance to writer since it might change our descriptor places
		 */

		myThreadedLogger->Info("Missing values: " + boost::lexical_cast<string> (missingCount) + "/" + boost::lexical_cast<string> (count));

		if (conf->FileWriteOption() == kNeons || conf->FileWriteOption() == kMultipleFiles)
		{
			shared_ptr<writer> theWriter = dynamic_pointer_cast <writer> (plugin_factory::Instance()->Plugin("writer"));

			theWriter->ToFile(shared_ptr<info> (new info(*myTargetInfo)), conf);
		}
	}
}
<|endoftext|>


<commit_before><commit_msg>fdo#54718 fix opcode detection in basic resulting in failed/unregcognized code<commit_after><|endoftext|>


<commit_before>// Copyright 2012 Cloudera Inc.
//
// 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 <gtest/gtest.h>
#include <sstream>
#include "runtime/raw-value.h"

#include "common/names.h"

using namespace impala;

namespace impala {

class RawValueTest : public testing::Test {
};

TEST_F(RawValueTest, Compare) {
  int64_t v1, v2;
  v1 = -2128609280;
  v2 = 9223372036854775807;
  EXPECT_LT(RawValue::Compare(&v1, &v2, TYPE_BIGINT), 0);
  EXPECT_GT(RawValue::Compare(&v2, &v1, TYPE_BIGINT), 0);

  int32_t i1, i2;
  i1 = 2147483647;
  i2 = -2147483640;
  EXPECT_GT(RawValue::Compare(&i1, &i2, TYPE_INT), 0);
  EXPECT_LT(RawValue::Compare(&i2, &i1, TYPE_INT), 0);

  int16_t s1, s2;
  s1 = 32767;
  s2 = -32767;
  EXPECT_GT(RawValue::Compare(&s1, &s2, TYPE_SMALLINT), 0);
  EXPECT_LT(RawValue::Compare(&s2, &s1, TYPE_SMALLINT), 0);
}

TEST_F(RawValueTest, TypeChar) {
  const int N = 5;
  const char* v1 = "aaaaa";
  const char* v2 = "aaaaab";
  const char* v3 = "aaaab";

  EXPECT_EQ(RawValue::Compare(v1, v1, ColumnType::CreateCharType(N)), 0);
  EXPECT_EQ(RawValue::Compare(v1, v2, ColumnType::CreateCharType(N)), 0);
  EXPECT_LT(RawValue::Compare(v1, v3, ColumnType::CreateCharType(N)), 0);

  EXPECT_EQ(RawValue::Compare(v2, v1, ColumnType::CreateCharType(N)), 0);
  EXPECT_EQ(RawValue::Compare(v2, v2, ColumnType::CreateCharType(N)), 0);
  EXPECT_LT(RawValue::Compare(v2, v3, ColumnType::CreateCharType(N)), 0);

  EXPECT_GT(RawValue::Compare(v3, v1, ColumnType::CreateCharType(N)), 0);
  EXPECT_GT(RawValue::Compare(v3, v2, ColumnType::CreateCharType(N)), 0);
  EXPECT_EQ(RawValue::Compare(v3, v3, ColumnType::CreateCharType(N)), 0);

  // Try putting non-string data (multiple nulls, non-ascii) and make
  // sure we can output it.
  stringstream ss;
  int val = 123;
  RawValue::PrintValue(&val, ColumnType::CreateCharType(sizeof(int)), -1, &ss);
  string s = ss.str();
  EXPECT_EQ(s.size(), sizeof(int));
  EXPECT_EQ(memcmp(&val, s.data(), sizeof(int)), 0);
}

// IMPALA-2270: "", false, and NULL should hash to distinct values.
TEST_F(RawValueTest, HashEmptyAndNull) {
  uint32_t seed = 12345;
  uint32_t null_hash = RawValue::GetHashValue(NULL, TYPE_STRING, seed);
  uint32_t null_hash_fnv = RawValue::GetHashValueFnv(NULL, TYPE_STRING, seed);
  StringValue empty(NULL, 0);
  uint32_t empty_hash = RawValue::GetHashValue(&empty, TYPE_STRING, seed);
  uint32_t empty_hash_fnv = RawValue::GetHashValueFnv(&empty, TYPE_STRING, seed);
  bool false_val = false;
  uint32_t false_hash = RawValue::GetHashValue(&false_val, TYPE_BOOLEAN, seed);
  uint32_t false_hash_fnv = RawValue::GetHashValue(&false_val, TYPE_BOOLEAN, seed);
  EXPECT_NE(seed, null_hash);
  EXPECT_NE(seed, empty_hash);
  EXPECT_NE(seed, false_hash);
  EXPECT_NE(seed, null_hash_fnv);
  EXPECT_NE(seed, empty_hash_fnv);
  EXPECT_NE(seed, false_hash_fnv);
  EXPECT_NE(null_hash, empty_hash);
  EXPECT_NE(null_hash_fnv, empty_hash_fnv);
  EXPECT_NE(null_hash, false_hash);
  EXPECT_NE(false_hash, null_hash_fnv);
}

/// IMPALA-2270: Test that FNV hash of (int, "") is not skewed.
TEST(HashUtil, IntNullSkew) {
  int num_values = 100000;
  int num_buckets = 16;
  vector<int> buckets(num_buckets, 0);
  for (int32_t i = 0; i < num_values; ++i) {
    uint32_t hash = RawValue::GetHashValueFnv(&i, TYPE_INT, 9999);
    StringValue empty(NULL, 0);
    hash = RawValue::GetHashValueFnv(&empty, TYPE_STRING, hash);
    ++buckets[hash % num_buckets];
  }

  for (int i = 0; i < num_buckets; ++i) {
    LOG(INFO) << "Bucket " << i << ": " << buckets[i];
    double exp_count = num_values / (double) num_buckets;
    EXPECT_GT(buckets[i], 0.9 * exp_count) << "Bucket " << i
                                           << " has <= 90%% of expected";
    EXPECT_LT(buckets[i], 1.1 * exp_count) << "Bucket " << i
                                           << " has >= 110%% of expected";
  }
}

TEST_F(RawValueTest, TemplatizedHash) {
  uint32_t seed = 12345;

  int8_t tinyint_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int8_t>(&tinyint_val, TYPE_TINYINT, seed),
    RawValue::GetHashValue(&tinyint_val, TYPE_TINYINT, seed));

  int16_t smallint_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int16_t>(&smallint_val, TYPE_SMALLINT, seed),
    RawValue::GetHashValue(&smallint_val, TYPE_SMALLINT, seed));

  int32_t int_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int32_t>(&int_val, TYPE_INT, seed),
    RawValue::GetHashValue(&int_val, TYPE_INT, seed));

  int64_t bigint_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int64_t>(&bigint_val, TYPE_BIGINT, seed),
    RawValue::GetHashValue(&bigint_val, TYPE_BIGINT, seed));

  float float_val = 8.0f;
  EXPECT_EQ(RawValue::GetHashValue<float>(&float_val, TYPE_FLOAT, seed),
    RawValue::GetHashValue(&float_val, TYPE_FLOAT, seed));

  double double_val = 8.0d;
  EXPECT_EQ(RawValue::GetHashValue<double>(&double_val, TYPE_DOUBLE, seed),
    RawValue::GetHashValue(&double_val, TYPE_DOUBLE, seed));

  bool false_val = false;
  EXPECT_EQ(RawValue::GetHashValue<bool>(&false_val, TYPE_BOOLEAN, seed),
    RawValue::GetHashValue(&false_val, TYPE_BOOLEAN, seed));

  bool true_val = true;
  EXPECT_EQ(RawValue::GetHashValue<bool>(&true_val, TYPE_BOOLEAN, seed),
    RawValue::GetHashValue(&true_val, TYPE_BOOLEAN, seed));

  StringValue string_value("aaaaa");
  EXPECT_EQ(RawValue::GetHashValue<impala::StringValue>(
    &string_value, ColumnType::CreateCharType(10), seed),
    RawValue::GetHashValue(&string_value, ColumnType::CreateCharType(10), seed));

  EXPECT_EQ(RawValue::GetHashValue<impala::StringValue>(
    &string_value, TYPE_STRING, seed),
    RawValue::GetHashValue(&string_value, TYPE_STRING, seed));

  EXPECT_EQ(RawValue::GetHashValue<impala::StringValue>(
    &string_value, ColumnType::CreateVarcharType(
    ColumnType::MAX_VARCHAR_LENGTH), seed),
    RawValue::GetHashValue(&string_value,ColumnType::CreateVarcharType(
    ColumnType::MAX_VARCHAR_LENGTH), seed));

  TimestampValue timestamp_value(253433923200);
  EXPECT_EQ(RawValue::GetHashValue<impala::TimestampValue>(
    &timestamp_value, TYPE_TIMESTAMP, seed),RawValue::GetHashValue(
    &timestamp_value, TYPE_TIMESTAMP, seed));

  ColumnType d4_type = ColumnType::CreateDecimalType(9, 1);
  Decimal4Value d4_value(123456789);
  EXPECT_EQ(RawValue::GetHashValue<impala::Decimal4Value>(&d4_value, d4_type, seed),
   RawValue::GetHashValue(&d4_value, d4_type, seed));

  ColumnType d8_type = ColumnType::CreateDecimalType(18, 6);
  Decimal8Value d8_value(123456789);
  EXPECT_EQ(RawValue::GetHashValue<impala::Decimal8Value>(&d8_value, d8_type, seed),
    RawValue::GetHashValue(&d8_value, d8_type, seed));

  ColumnType d16_type = ColumnType::CreateDecimalType(19, 4);
  Decimal16Value d16_value(123456789);
  EXPECT_EQ(RawValue::GetHashValue<impala::Decimal16Value>(&d16_value, d16_type, seed),
    RawValue::GetHashValue(&d16_value, d16_type, seed));
}

}

int main(int argc, char **argv) {
  google::InitGoogleLogging(argv[0]);
  ::testing::InitGoogleTest(&argc, argv);
  impala::CpuInfo::Init();
  return RUN_ALL_TESTS();
}
<commit_msg>IMPALA-2955 : ASAN compilation fix, remove suffix 'd' on floating constant<commit_after>// Copyright 2012 Cloudera Inc.
//
// 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 <gtest/gtest.h>
#include <sstream>
#include "runtime/raw-value.h"

#include "common/names.h"

using namespace impala;

namespace impala {

class RawValueTest : public testing::Test {
};

TEST_F(RawValueTest, Compare) {
  int64_t v1, v2;
  v1 = -2128609280;
  v2 = 9223372036854775807;
  EXPECT_LT(RawValue::Compare(&v1, &v2, TYPE_BIGINT), 0);
  EXPECT_GT(RawValue::Compare(&v2, &v1, TYPE_BIGINT), 0);

  int32_t i1, i2;
  i1 = 2147483647;
  i2 = -2147483640;
  EXPECT_GT(RawValue::Compare(&i1, &i2, TYPE_INT), 0);
  EXPECT_LT(RawValue::Compare(&i2, &i1, TYPE_INT), 0);

  int16_t s1, s2;
  s1 = 32767;
  s2 = -32767;
  EXPECT_GT(RawValue::Compare(&s1, &s2, TYPE_SMALLINT), 0);
  EXPECT_LT(RawValue::Compare(&s2, &s1, TYPE_SMALLINT), 0);
}

TEST_F(RawValueTest, TypeChar) {
  const int N = 5;
  const char* v1 = "aaaaa";
  const char* v2 = "aaaaab";
  const char* v3 = "aaaab";

  EXPECT_EQ(RawValue::Compare(v1, v1, ColumnType::CreateCharType(N)), 0);
  EXPECT_EQ(RawValue::Compare(v1, v2, ColumnType::CreateCharType(N)), 0);
  EXPECT_LT(RawValue::Compare(v1, v3, ColumnType::CreateCharType(N)), 0);

  EXPECT_EQ(RawValue::Compare(v2, v1, ColumnType::CreateCharType(N)), 0);
  EXPECT_EQ(RawValue::Compare(v2, v2, ColumnType::CreateCharType(N)), 0);
  EXPECT_LT(RawValue::Compare(v2, v3, ColumnType::CreateCharType(N)), 0);

  EXPECT_GT(RawValue::Compare(v3, v1, ColumnType::CreateCharType(N)), 0);
  EXPECT_GT(RawValue::Compare(v3, v2, ColumnType::CreateCharType(N)), 0);
  EXPECT_EQ(RawValue::Compare(v3, v3, ColumnType::CreateCharType(N)), 0);

  // Try putting non-string data (multiple nulls, non-ascii) and make
  // sure we can output it.
  stringstream ss;
  int val = 123;
  RawValue::PrintValue(&val, ColumnType::CreateCharType(sizeof(int)), -1, &ss);
  string s = ss.str();
  EXPECT_EQ(s.size(), sizeof(int));
  EXPECT_EQ(memcmp(&val, s.data(), sizeof(int)), 0);
}

// IMPALA-2270: "", false, and NULL should hash to distinct values.
TEST_F(RawValueTest, HashEmptyAndNull) {
  uint32_t seed = 12345;
  uint32_t null_hash = RawValue::GetHashValue(NULL, TYPE_STRING, seed);
  uint32_t null_hash_fnv = RawValue::GetHashValueFnv(NULL, TYPE_STRING, seed);
  StringValue empty(NULL, 0);
  uint32_t empty_hash = RawValue::GetHashValue(&empty, TYPE_STRING, seed);
  uint32_t empty_hash_fnv = RawValue::GetHashValueFnv(&empty, TYPE_STRING, seed);
  bool false_val = false;
  uint32_t false_hash = RawValue::GetHashValue(&false_val, TYPE_BOOLEAN, seed);
  uint32_t false_hash_fnv = RawValue::GetHashValue(&false_val, TYPE_BOOLEAN, seed);
  EXPECT_NE(seed, null_hash);
  EXPECT_NE(seed, empty_hash);
  EXPECT_NE(seed, false_hash);
  EXPECT_NE(seed, null_hash_fnv);
  EXPECT_NE(seed, empty_hash_fnv);
  EXPECT_NE(seed, false_hash_fnv);
  EXPECT_NE(null_hash, empty_hash);
  EXPECT_NE(null_hash_fnv, empty_hash_fnv);
  EXPECT_NE(null_hash, false_hash);
  EXPECT_NE(false_hash, null_hash_fnv);
}

/// IMPALA-2270: Test that FNV hash of (int, "") is not skewed.
TEST(HashUtil, IntNullSkew) {
  int num_values = 100000;
  int num_buckets = 16;
  vector<int> buckets(num_buckets, 0);
  for (int32_t i = 0; i < num_values; ++i) {
    uint32_t hash = RawValue::GetHashValueFnv(&i, TYPE_INT, 9999);
    StringValue empty(NULL, 0);
    hash = RawValue::GetHashValueFnv(&empty, TYPE_STRING, hash);
    ++buckets[hash % num_buckets];
  }

  for (int i = 0; i < num_buckets; ++i) {
    LOG(INFO) << "Bucket " << i << ": " << buckets[i];
    double exp_count = num_values / (double) num_buckets;
    EXPECT_GT(buckets[i], 0.9 * exp_count) << "Bucket " << i
                                           << " has <= 90%% of expected";
    EXPECT_LT(buckets[i], 1.1 * exp_count) << "Bucket " << i
                                           << " has >= 110%% of expected";
  }
}

TEST_F(RawValueTest, TemplatizedHash) {
  uint32_t seed = 12345;

  int8_t tinyint_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int8_t>(&tinyint_val, TYPE_TINYINT, seed),
    RawValue::GetHashValue(&tinyint_val, TYPE_TINYINT, seed));

  int16_t smallint_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int16_t>(&smallint_val, TYPE_SMALLINT, seed),
    RawValue::GetHashValue(&smallint_val, TYPE_SMALLINT, seed));

  int32_t int_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int32_t>(&int_val, TYPE_INT, seed),
    RawValue::GetHashValue(&int_val, TYPE_INT, seed));

  int64_t bigint_val = 8;
  EXPECT_EQ(RawValue::GetHashValue<int64_t>(&bigint_val, TYPE_BIGINT, seed),
    RawValue::GetHashValue(&bigint_val, TYPE_BIGINT, seed));

  float float_val = 8.0f;
  EXPECT_EQ(RawValue::GetHashValue<float>(&float_val, TYPE_FLOAT, seed),
    RawValue::GetHashValue(&float_val, TYPE_FLOAT, seed));

  double double_val = 8.0;
  EXPECT_EQ(RawValue::GetHashValue<double>(&double_val, TYPE_DOUBLE, seed),
    RawValue::GetHashValue(&double_val, TYPE_DOUBLE, seed));

  bool false_val = false;
  EXPECT_EQ(RawValue::GetHashValue<bool>(&false_val, TYPE_BOOLEAN, seed),
    RawValue::GetHashValue(&false_val, TYPE_BOOLEAN, seed));

  bool true_val = true;
  EXPECT_EQ(RawValue::GetHashValue<bool>(&true_val, TYPE_BOOLEAN, seed),
    RawValue::GetHashValue(&true_val, TYPE_BOOLEAN, seed));

  StringValue string_value("aaaaa");
  EXPECT_EQ(RawValue::GetHashValue<impala::StringValue>(
    &string_value, ColumnType::CreateCharType(10), seed),
    RawValue::GetHashValue(&string_value, ColumnType::CreateCharType(10), seed));

  EXPECT_EQ(RawValue::GetHashValue<impala::StringValue>(
    &string_value, TYPE_STRING, seed),
    RawValue::GetHashValue(&string_value, TYPE_STRING, seed));

  EXPECT_EQ(RawValue::GetHashValue<impala::StringValue>(
    &string_value, ColumnType::CreateVarcharType(
    ColumnType::MAX_VARCHAR_LENGTH), seed),
    RawValue::GetHashValue(&string_value,ColumnType::CreateVarcharType(
    ColumnType::MAX_VARCHAR_LENGTH), seed));

  TimestampValue timestamp_value(253433923200);
  EXPECT_EQ(RawValue::GetHashValue<impala::TimestampValue>(
    &timestamp_value, TYPE_TIMESTAMP, seed),RawValue::GetHashValue(
    &timestamp_value, TYPE_TIMESTAMP, seed));

  ColumnType d4_type = ColumnType::CreateDecimalType(9, 1);
  Decimal4Value d4_value(123456789);
  EXPECT_EQ(RawValue::GetHashValue<impala::Decimal4Value>(&d4_value, d4_type, seed),
   RawValue::GetHashValue(&d4_value, d4_type, seed));

  ColumnType d8_type = ColumnType::CreateDecimalType(18, 6);
  Decimal8Value d8_value(123456789);
  EXPECT_EQ(RawValue::GetHashValue<impala::Decimal8Value>(&d8_value, d8_type, seed),
    RawValue::GetHashValue(&d8_value, d8_type, seed));

  ColumnType d16_type = ColumnType::CreateDecimalType(19, 4);
  Decimal16Value d16_value(123456789);
  EXPECT_EQ(RawValue::GetHashValue<impala::Decimal16Value>(&d16_value, d16_type, seed),
    RawValue::GetHashValue(&d16_value, d16_type, seed));
}

}

int main(int argc, char **argv) {
  google::InitGoogleLogging(argv[0]);
  ::testing::InitGoogleTest(&argc, argv);
  impala::CpuInfo::Init();
  return RUN_ALL_TESTS();
}
<|endoftext|>