<commit_before>/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2015-2018 OSRE ( Open Source Render Engine ) by Kim Kulling

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 "osre_testcommon.h"
#include <osre/Platform/AbstractThread.h>

namespace OSRE {
namespace UnitTest {

using namespace ::OSRE::Platform;

class TestThread : public AbstractThread {
public:
    TestThread() : AbstractThread() {
    }

    virtual bool start(void *pData) {
        return true;
    }

    virtual bool stop() {
        return true;
    }

    virtual bool suspend() {
        return true;
    }

    virtual bool resume() {
        return true;
    }

    virtual void setName(const String &name) {
        // empty
    }

    virtual const String &getName() const {
        static const String Name = "test";
        return Name;
    }

    virtual void waitForTimeout( ui32 ms ) {
        // empty
    }

    virtual void wait() {
        // empty
    }

    virtual AbstractThreadEvent *getThreadEvent() const {
        return nullptr;
    }

    virtual void setPriority( Priority prio ) {
        // empty
    }

    virtual Priority getPriority() const {
        return AbstractThread::Priority::Normal;
    }

    virtual const String &getThreadName() const {
        static const String ThreadName = "testthread";
        return ThreadName;
    }

    virtual AbstractThreadLocalStorage *getThreadLocalStorage() {
        return nullptr;
    }

    virtual void setThreadLocalStorage( AbstractThreadLocalStorage *tls ) {
        // empty
    }

    virtual void setThreadId( const ThreadId &id ) {
        // empty
    }

    virtual ThreadId getThreadId() {
        static const ThreadId id;
        return id;
    }

protected:
    virtual i32 run() {
        return 0;
    }
};

class AbstractThreadTest : public ::testing::Test {
    // empty
};

TEST_F( AbstractThreadTest, ThreadIdTest ) {
    ThreadId tid1, tid2, tid3;
    tid1.Id = 1;
    tid2.Id = 2;
    tid3.Id = 1;
    EXPECT_NE( tid1, tid2 );
    EXPECT_EQ( tid1, tid3 );
}

TEST_F( AbstractThreadTest, createTest ) {
    bool ok( true );
    try {
        TestThread test_thread;
    } catch ( ... ) {
        ok = false;
    }
    EXPECT_TRUE( ok );
}

TEST_F( AbstractThreadTest, accessStateTest ) {
    TestThread test_thread;

    EXPECT_EQ( AbstractThread::ThreadState::New, test_thread.getCurrentState() );
}

} // Namespace UnitTest
} // Namespace OSRE
<commit_msg>Unittest: fix compiler warnings - unused parameters.<commit_after>/*-----------------------------------------------------------------------------------------------
The MIT License (MIT)

Copyright (c) 2015-2018 OSRE ( Open Source Render Engine ) by Kim Kulling

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 "osre_testcommon.h"
#include <osre/Platform/AbstractThread.h>

namespace OSRE {
namespace UnitTest {

using namespace ::OSRE::Platform;

class TestThread : public AbstractThread {
public:
    TestThread()
    : AbstractThread() {
        // empty
    }

    virtual bool start( void* ) {
        return true;
    }

    virtual bool stop() {
        return true;
    }

    virtual bool suspend() {
        return true;
    }

    virtual bool resume() {
        return true;
    }

    virtual void setName( const String & ) {
        // empty
    }

    virtual const String &getName() const {
        static const String Name = "test";
        return Name;
    }

    virtual void waitForTimeout( ui32 ) {
        // empty
    }

    virtual void wait() {
        // empty
    }

    virtual AbstractThreadEvent *getThreadEvent() const {
        return nullptr;
    }

    virtual void setPriority( Priority ) {
        // empty
    }

    virtual Priority getPriority() const {
        return AbstractThread::Priority::Normal;
    }

    virtual const String &getThreadName() const {
        static const String ThreadName = "testthread";
        return ThreadName;
    }

    virtual AbstractThreadLocalStorage *getThreadLocalStorage() {
        return nullptr;
    }

    virtual void setThreadLocalStorage( AbstractThreadLocalStorage* ) {
        // empty
    }

    virtual void setThreadId( const ThreadId& ) {
        // empty
    }

    virtual ThreadId getThreadId() {
        static const ThreadId id;
        return id;
    }

protected:
    virtual i32 run() {
        return 0;
    }
};

class AbstractThreadTest : public ::testing::Test {
    // empty
};

TEST_F( AbstractThreadTest, ThreadIdTest ) {
    ThreadId tid1, tid2, tid3;
    tid1.Id = 1;
    tid2.Id = 2;
    tid3.Id = 1;
    EXPECT_NE( tid1, tid2 );
    EXPECT_EQ( tid1, tid3 );
}

TEST_F( AbstractThreadTest, createTest ) {
    bool ok( true );
    try {
        TestThread test_thread;
    } catch ( ... ) {
        ok = false;
    }
    EXPECT_TRUE( ok );
}

TEST_F( AbstractThreadTest, accessStateTest ) {
    TestThread test_thread;

    EXPECT_EQ( AbstractThread::ThreadState::New, test_thread.getCurrentState() );
}

} // Namespace UnitTest
} // Namespace OSRE
<|endoftext|>


<commit_before>// Stress test recovery mode with many threads.
//
// RUN: %clangxx_asan -fsanitize-recover=address -pthread %s -o %t
//
// RUN: env ASAN_OPTIONS=halt_on_error=false %run %t 1 10 >1.txt 2>&1
// RUN: FileCheck %s < 1.txt
// RUN: [ $(wc -l < 1.txt) -eq 10 ]
// RUN: FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
//
// Collisions are unlikely but still possible so we need the ||.
// RUN: env ASAN_OPTIONS=halt_on_error=false %run %t 10 20 >10.txt 2>&1 || true
// This one is racy although _very_ unlikely to fail:
// RUN: FileCheck %s < 10.txt
// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
//
// REQUIRES: stable-runtime

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

#include <sanitizer/asan_interface.h>

size_t nthreads = 10;
size_t niter = 10;

void random_delay(unsigned *seed) {
  *seed = 1664525 * *seed + 1013904223;
  struct timespec delay = { 0, (*seed % 1000) * 1000 };
  nanosleep(&delay, 0);
}

void *run(void *arg) {
  unsigned seed = (unsigned)(size_t)arg;

  volatile char tmp[2];
  __asan_poison_memory_region(&tmp, sizeof(tmp));

  for (size_t i = 0; i < niter; ++i) {
    random_delay(&seed);
    // Expect error collisions here
    // CHECK: ERROR: AddressSanitizer: use-after-poison
    volatile int idx = 0;
    tmp[idx] = 0;
  }

  return 0;
}

int main(int argc, char **argv) {
  if (argc != 3) {
    fprintf(stderr, "Syntax: %s nthreads niter\n", argv[0]);
    exit(1);
  }

  nthreads = (size_t)strtoul(argv[1], 0, 0);
  niter = (size_t)strtoul(argv[2], 0, 0);

  pthread_t *tids = new pthread_t[nthreads];

  for (size_t i = 0; i < nthreads; ++i) {
    if (0 != pthread_create(&tids[i], 0, run, (void *)i)) {
      fprintf(stderr, "Failed to create thread\n");
      exit(1);
    }
  }

  for (size_t i = 0; i < nthreads; ++i) {
    if (0 != pthread_join(tids[i], 0)) {
      fprintf(stderr, "Failed to join thread\n");
      exit(1);
    }
  }

  // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting
  // CHECK-NO-COLLISION: All threads terminated
  printf("All threads terminated\n");

  delete [] tids;

  return 0;
}
<commit_msg>[asan] Dump test output in case of error in single-threaded mode.<commit_after>// Stress test recovery mode with many threads.
//
// RUN: %clangxx_asan -fsanitize-recover=address -pthread %s -o %t
//
// RUN: env ASAN_OPTIONS=halt_on_error=false %run %t 1 10 >1.txt 2>&1 || cat 1.txt
// RUN: FileCheck %s < 1.txt
// RUN: [ $(wc -l < 1.txt) -eq 10 ]
// RUN: FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
//
// Collisions are unlikely but still possible so we need the ||.
// RUN: env ASAN_OPTIONS=halt_on_error=false %run %t 10 20 >10.txt 2>&1 || true
// This one is racy although _very_ unlikely to fail:
// RUN: FileCheck %s < 10.txt
// RUN: FileCheck --check-prefix=CHECK-COLLISION %s < 1.txt || FileCheck --check-prefix=CHECK-NO-COLLISION %s < 1.txt
//
// REQUIRES: stable-runtime

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <time.h>

#include <sanitizer/asan_interface.h>

size_t nthreads = 10;
size_t niter = 10;

void random_delay(unsigned *seed) {
  *seed = 1664525 * *seed + 1013904223;
  struct timespec delay = { 0, (*seed % 1000) * 1000 };
  nanosleep(&delay, 0);
}

void *run(void *arg) {
  unsigned seed = (unsigned)(size_t)arg;

  volatile char tmp[2];
  __asan_poison_memory_region(&tmp, sizeof(tmp));

  for (size_t i = 0; i < niter; ++i) {
    random_delay(&seed);
    // Expect error collisions here
    // CHECK: ERROR: AddressSanitizer: use-after-poison
    volatile int idx = 0;
    tmp[idx] = 0;
  }

  return 0;
}

int main(int argc, char **argv) {
  if (argc != 3) {
    fprintf(stderr, "Syntax: %s nthreads niter\n", argv[0]);
    exit(1);
  }

  nthreads = (size_t)strtoul(argv[1], 0, 0);
  niter = (size_t)strtoul(argv[2], 0, 0);

  pthread_t *tids = new pthread_t[nthreads];

  for (size_t i = 0; i < nthreads; ++i) {
    if (0 != pthread_create(&tids[i], 0, run, (void *)i)) {
      fprintf(stderr, "Failed to create thread\n");
      exit(1);
    }
  }

  for (size_t i = 0; i < nthreads; ++i) {
    if (0 != pthread_join(tids[i], 0)) {
      fprintf(stderr, "Failed to join thread\n");
      exit(1);
    }
  }

  // CHECK-COLLISION: AddressSanitizer: nested bug in the same thread, aborting
  // CHECK-NO-COLLISION: All threads terminated
  printf("All threads terminated\n");

  delete [] tids;

  return 0;
}
<|endoftext|>


<commit_before>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Stefan Seefeld <seefelds@magellan.umontreal.ca>
 * Copyright (C) 1999 Graydon Hoare <graydon@pobox.com>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include "Warsaw/config.hh"
#include "Warsaw/Transform.hh"
#include "Drawing/openGL/GLDrawingKit.hh"
#include "Warsaw/Text.hh"
#include "Berlin/Logger.hh"

extern "C" {
#include "ggi/ggi.h"
}

#include <GL/glu.h>
#include <strstream>
#include <iostream>

GLDrawingKit::GLDrawingKit()
  : rasters(500)
{
  ggiInit();
  drawable = new GLDrawable();
  drawable->_obj_is_ready(CORBA::BOA::getBOA());
  gnufont = new GLUnifont();
  gnufont->_obj_is_ready(CORBA::BOA::getBOA());
  Color c = {0.0,0.0,0.0,1.0};
  gnufont->setColor(c);
}

GLDrawingKit::~GLDrawingKit()
{
  drawable->_dispose();
  gnufont->_dispose();
  ggiExit();
}

void GLDrawingKit::setFont(const Text::FontDescriptor &fd, const Style::Spec &sty)
  throw (Text::NoSuchFontException)
{
  MutexGuard guard(mutex);

  // make sure the gnufont tracks color changes
  for (unsigned long i = 0; i < sty.length(); i++) {
      Color *tmp;
      if (sty[i].a == Style::fillcolor) {
	  sty[i].val >>= tmp;
	  //	  cerr << "set color " << tmp->red << ", " << tmp->green << ", " << tmp->blue << ", " << tmp->alpha << endl;
	  gnufont->setColor(*tmp);
      }
  }

  try
      {
	  //
	  // at this time, there is _no_ way to add new fonts to the runtime.
	  // it uses GNU Unifont, and nothing else.
	  //
	  // it will eventually look like this, once we get the GLFont truetype &
	  // T1 registry alive.
	  //

	  /*      GLFont *newfont = new GLFont(fd,sty);
		  newfont->_obj_is_ready(_boa());
		  if (font) font->_dispose();
		  font = newfont;*/
      }
  catch (Text::NoSuchFontException &ex)
      {
	  throw ex;
      }
}

Text::Font_ptr GLDrawingKit::currentFont()
{
  MutexGuard guard(mutex);
  if (font) return font->_this();
  else return gnufont->_this();
}

Drawable_ptr GLDrawingKit::getDrawable()
{
  MutexGuard guard(mutex);
  return drawable->_this();
}

Pencil_ptr GLDrawingKit::getPencil(const Style::Spec &sty)
{
  MutexGuard guard(mutex);
  GLPencil *pencil = new GLPencil(sty, drawable);
  pencil->_obj_is_ready(_boa());
  pencils.push_back(pencil);
  return pencil->_this();
}

// lower.x, lower.y, upper.x, upper.y
void GLDrawingKit::clear(Coord l, Coord t, Coord r, Coord b)
{
  glColor4d(1., 0., 0., 1.);
  glRectf(l, t, r, b);
  glFlush();
  char c;
  cout << "GLDrawingKit::clear: enter key to continue :"; cin >> c;
  glColor4d(0., 0., 0., 1.);
  glRectf(l, t, r, b);
}

void GLDrawingKit::image(Raster_ptr raster, Transform_ptr transform)
{
  GLRaster *glraster = rasters.lookup(Raster::_duplicate(raster));
  transformedImage(glraster, transform);
}

/*
 * openGL requires glTexImage2D to take width and height in the form 2^k
 * se we extract the exponent here and the residue
 */
inline void logbase2(unsigned int n, unsigned int &v, float &r)
{
  unsigned int k;
  for (k = 0; n >>= 1; k++);
  v = 1 << (k + 1), r = v - n;
}

void GLDrawingKit::transformedImage(const GLRaster *raster, Transform_ptr transform)
{
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, raster->texture);
  glColor4f(1., 1., 1., 1.);
  glBegin(GL_POLYGON);
  Path path;
  path.p.length(4);
  path.p[0].x = path.p[0].y = path.p[0].z = 0.;
  path.p[1].x = raster->width, path.p[1].y = path.p[1].z = 0.;
  path.p[2].x = raster->width, path.p[2].y = raster->height, path.p[2].z = 0.;
  path.p[3].x = 0, path.p[3].y = raster->height, path.p[3].z = 0.;
  for (unsigned int i = 0; i != 4; i++) transform->transformVertex(path.p[i]);
  glTexCoord2f(0., 0.);              glVertex3f(path.p[3].x, path.p[3].y, path.p[3].z);
  glTexCoord2f(1., 0.);              glVertex3f(path.p[2].x, path.p[2].y, path.p[2].z);
  glTexCoord2f(1., 1.);              glVertex3f(path.p[1].x, path.p[1].y, path.p[1].z);
  glTexCoord2f(0., 1.);              glVertex3f(path.p[0].x, path.p[0].y, path.p[0].z);
  glEnd();
  glDisable(GL_TEXTURE_2D);
}

void GLDrawingKit::scaledImage(const GLRaster *raster, Transform_ptr transform)
{
}

void GLDrawingKit::translatedImage(const GLRaster *raster, Transform_ptr transform)
{
  Vertex origin;
  origin.x = origin.y = origin.z = 0.;
  transform->transformVertex(origin);
  glRasterPos2d(origin.x, origin.y + raster->height);
  glPixelStorei(GL_UNPACK_ROW_LENGTH, raster->width);
  glDrawPixels(raster->width, raster->height, GL_RGBA, GL_UNSIGNED_BYTE, raster->data.begin());
}
<commit_msg><commit_after>/*$Id$
 *
 * This source file is a part of the Berlin Project.
 * Copyright (C) 1999 Stefan Seefeld <seefelds@magellan.umontreal.ca>
 * Copyright (C) 1999 Graydon Hoare <graydon@pobox.com>
 * http://www.berlin-consortium.org
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the
 * Free Software Foundation, Inc., 675 Mass Ave, Cambridge,
 * MA 02139, USA.
 */

#include "Warsaw/config.hh"
#include "Warsaw/Transform.hh"
#include "Drawing/openGL/GLDrawingKit.hh"
#include "Warsaw/Text.hh"
#include "Berlin/Logger.hh"

extern "C" {
#include "ggi/ggi.h"
}

#include <GL/glu.h>
#include <strstream>
#include <iostream>

GLDrawingKit::GLDrawingKit()
  : rasters(500)
{
  ggiInit();
  drawable = new GLDrawable();
  drawable->_obj_is_ready(CORBA::BOA::getBOA());
  gnufont = new GLUnifont();
  gnufont->_obj_is_ready(CORBA::BOA::getBOA());
  Color c = {0.0,0.0,0.0,1.0};
  gnufont->setColor(c);
}

GLDrawingKit::~GLDrawingKit()
{
  drawable->_dispose();
  gnufont->_dispose();
  ggiExit();
}

void GLDrawingKit::setFont(const Text::FontDescriptor &fd, const Style::Spec &sty)
  throw (Text::NoSuchFontException)
{
  MutexGuard guard(mutex);

  // make sure the gnufont tracks color changes
  for (unsigned long i = 0; i < sty.length(); i++) {
      Color *tmp;
      if (sty[i].a == Style::fillcolor) {
	  sty[i].val >>= tmp;
	  //	  cerr << "set color " << tmp->red << ", " << tmp->green << ", " << tmp->blue << ", " << tmp->alpha << endl;
	  gnufont->setColor(*tmp);
      }
  }

  try
      {
	  //
	  // at this time, there is _no_ way to add new fonts to the runtime.
	  // it uses GNU Unifont, and nothing else.
	  //
	  // it will eventually look like this, once we get the GLFont truetype &
	  // T1 registry alive.
	  //

	  /*      GLFont *newfont = new GLFont(fd,sty);
		  newfont->_obj_is_ready(_boa());
		  if (font) font->_dispose();
		  font = newfont;*/
      }
  catch (Text::NoSuchFontException &ex)
      {
	  throw ex;
      }
}

Text::Font_ptr GLDrawingKit::currentFont()
{
  MutexGuard guard(mutex);
  if (font) return font->_this();
  else return gnufont->_this();
}

Drawable_ptr GLDrawingKit::getDrawable()
{
  MutexGuard guard(mutex);
  return drawable->_this();
}

Pencil_ptr GLDrawingKit::getPencil(const Style::Spec &sty)
{
  MutexGuard guard(mutex);
  GLPencil *pencil = new GLPencil(sty, drawable);
  pencil->_obj_is_ready(_boa());
  pencils.push_back(pencil);
  return pencil->_this();
}

// lower.x, lower.y, upper.x, upper.y
void GLDrawingKit::clear(Coord l, Coord t, Coord r, Coord b)
{
  glColor4d(1., 0., 0., 1.);
  glRectf(l, t, r, b);
  glFlush();
  char c;
  cout << "GLDrawingKit::clear: enter key to continue :";
  cin.get(c);
  glColor4d(0., 0., 0., 1.);
  glRectf(l, t, r, b);
}

void GLDrawingKit::image(Raster_ptr raster, Transform_ptr transform)
{
  GLRaster *glraster = rasters.lookup(Raster::_duplicate(raster));
  transformedImage(glraster, transform);
}

/*
 * openGL requires glTexImage2D to take width and height in the form 2^k
 * se we extract the exponent here and the residue
 */
inline void logbase2(unsigned int n, unsigned int &v, float &r)
{
  unsigned int k;
  for (k = 0; n >>= 1; k++);
  v = 1 << (k + 1), r = v - n;
}

void GLDrawingKit::transformedImage(const GLRaster *raster, Transform_ptr transform)
{
  glEnable(GL_TEXTURE_2D);
  glBindTexture(GL_TEXTURE_2D, raster->texture);
  glColor4f(1., 1., 1., 1.);
  glBegin(GL_POLYGON);
  Path path;
  path.p.length(4);
  path.p[0].x = path.p[0].y = path.p[0].z = 0.;
  path.p[1].x = raster->width, path.p[1].y = path.p[1].z = 0.;
  path.p[2].x = raster->width, path.p[2].y = raster->height, path.p[2].z = 0.;
  path.p[3].x = 0, path.p[3].y = raster->height, path.p[3].z = 0.;
  for (unsigned int i = 0; i != 4; i++) transform->transformVertex(path.p[i]);
  glTexCoord2f(0., 0.);              glVertex3f(path.p[3].x, path.p[3].y, path.p[3].z);
  glTexCoord2f(1., 0.);              glVertex3f(path.p[2].x, path.p[2].y, path.p[2].z);
  glTexCoord2f(1., 1.);              glVertex3f(path.p[1].x, path.p[1].y, path.p[1].z);
  glTexCoord2f(0., 1.);              glVertex3f(path.p[0].x, path.p[0].y, path.p[0].z);
  glEnd();
  glDisable(GL_TEXTURE_2D);
}

void GLDrawingKit::scaledImage(const GLRaster *raster, Transform_ptr transform)
{
}

void GLDrawingKit::translatedImage(const GLRaster *raster, Transform_ptr transform)
{
  Vertex origin;
  origin.x = origin.y = origin.z = 0.;
  transform->transformVertex(origin);
  glRasterPos2d(origin.x, origin.y + raster->height);
  glPixelStorei(GL_UNPACK_ROW_LENGTH, raster->width);
  glDrawPixels(raster->width, raster->height, GL_RGBA, GL_UNSIGNED_BYTE, raster->data.begin());
}
<|endoftext|>


<commit_before>// smallpt, a Path Tracer by Kevin Beason, 2008
//
// Modified by Peter uek
// For the original code, see github.com/munificient/smallpt
// For the original license, see smallpt.LICENSE.txt

#include <cmath>
#include <cstdlib>
#include <cstdio>

#include <sycl.hpp>

#include "classes.h"
#include "msvc.h"

namespace ns_sycl_gtx {

static const int numSpheres = 9;
Sphere spheres[numSpheres] = {//Scene: radius, position, emission, color, material
	Sphere(1e5, Vec(1e5 + 1, 40.8, 81.6), Vec(), Vec(.75, .25, .25), DIFF),//Left
	Sphere(1e5, Vec(-1e5 + 99, 40.8, 81.6), Vec(), Vec(.25, .25, .75), DIFF),//Rght
	Sphere(1e5, Vec(50, 40.8, 1e5), Vec(), Vec(.75, .75, .75), DIFF),//Back
	Sphere(1e5, Vec(50, 40.8, -1e5 + 170), Vec(), Vec(), DIFF),//Frnt
	Sphere(1e5, Vec(50, 1e5, 81.6), Vec(), Vec(.75, .75, .75), DIFF),//Botm
	Sphere(1e5, Vec(50, -1e5 + 81.6, 81.6), Vec(), Vec(.75, .75, .75), DIFF),//Top
	Sphere(16.5, Vec(27, 16.5, 47), Vec(), Vec(1, 1, 1)*.999, SPEC),//Mirr
	Sphere(16.5, Vec(73, 16.5, 78), Vec(), Vec(1, 1, 1)*.999, REFR),//Glas
	Sphere(600, Vec(50, 681.6 - .27, 81.6), Vec(12, 12, 12), Vec(), DIFF) //Lite
};

inline bool intersect(const Ray& r, double& t, int& id) {
	double d;
	double inf = t = 1e20;
	for(int i = numSpheres; i > 0;) {
		--i;
		if((d = spheres[i].intersect(r)) && d < t) {
			t = d;
			id = i;
		}
	}
	return t < inf;
}

enum class DoNext {
	Return, ContinueLoop, Proceed
};

DoNext radianceInner(
	Ray& r, int& depth, unsigned short* Xi,	// Original parameters
	double& t, int& id, Vec& cl, Vec& cf,	// Passed references
	// Output references
	double& Re, double& Tr, double& P, double& RP, double& TP, Ray& reflRay, Vec& x, Vec& tdir
) {
	if(!intersect(r, t, id)) {
		// if miss, don't add anything
		return DoNext::Return;
	}
	const Sphere& obj = spheres[id]; // the hit object
	x = r.o + r.d*t;
	Vec n = (x - obj.p).norm();
	Vec nl = n;
	if(n.dot(r.d) > 0) {
		nl = nl * -1;
	}
	Vec f = obj.c;
	double p;	// max refl
	if(f.x > f.y && f.x > f.z) {
		p = f.x;
	}
	else if(f.y > f.z) {
		p = f.y;
	}
	else {
		p = f.z;
	}

	cl = cl + cf.mult(obj.e);

	depth += 1;
	if(depth > 5) {
		if(erand48(Xi) < p) {
			f = f*(1 / p);
		}
		else {
			return DoNext::Return;
		}
	}

	cf = cf.mult(f);

	if(obj.refl == DIFF) {	// Ideal DIFFUSE reflection
		double r1 = 2 * M_PI*erand48(Xi), r2 = erand48(Xi), r2s = sqrt(r2);
		Vec w = nl;
		Vec u;
		if(fabs(w.x) > .1) {
			u.y = 1;
		}
		else {
			u.x = 1;
		}
		u = (u % w).norm();
		Vec v = w%u;
		Vec d = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1 - r2)).norm();

		// Recursion
		r = Ray(x, d);
		return DoNext::ContinueLoop;
	}
	else if(obj.refl == SPEC) {	// Ideal SPECULAR reflection
		// Recursion
		r = Ray(x, r.d - n * 2 * n.dot(r.d));
		return DoNext::ContinueLoop;
	}
	reflRay = Ray(x, r.d - n * 2 * n.dot(r.d));	// Ideal dielectric REFRACTION
	bool into = n.dot(nl) > 0;	// Ray from outside going in?
	double nc = 1;
	double nt = 1.5;
	double nnt;
	if(into) {
		nnt = nc / nt;
	}
	else {
		nnt = nt / nc;
	}
	double ddn = r.d.dot(nl);
	double cos2t;
	if((cos2t = 1 - nnt*nnt*(1 - ddn*ddn)) < 0) {	// Total internal reflection
		// Recursion
		r = reflRay;
		return DoNext::ContinueLoop;
	}
	double tmp = 1;
	if(!into) {
		tmp = -1;
	}
	tdir = (r.d*nnt - n*(tmp*(ddn*nnt + sqrt(cos2t)))).norm();
	double a = nt - nc;
	double b = nt + nc;
	double R0 = a*a / (b*b);
	double c = 1;
	if(into) {
		c += ddn;
	}
	else {
		c -= tdir.dot(n);
	}
	Re = R0 + (1 - R0)*c*c*c*c*c;
	Tr = 1 - Re;
	P = .25 + .5*Re;
	RP = Re / P;
	TP = Tr / (1 - P);

	return DoNext::Proceed;
}

void radiance(Ray r, int depth, unsigned short* Xi, Vec& cl, Vec& cf) {
	double t;	// distance to intersection
	int id = 0;	// id of intersected object

	double Re, Tr, P, RP, TP;
	Ray reflRay(0, 0);
	Vec x, tdir;

	while(true) {
		auto doNext = radianceInner(
			r, depth, Xi,
			t, id, cl, cf,
			Re, Tr, P, RP, TP, reflRay, x, tdir
		);

		if(doNext == DoNext::ContinueLoop) {
			continue;
		}
		if(doNext == DoNext::Return) {
			return;
		}

		if(erand48(Xi) < P) {
			cf = cf * RP;
			r = reflRay;
		}
		else {
			cf = cf * TP;
			r = Ray(x, tdir);
		}
	}
}

template <int depth_ = 0>
Vec radiance(Ray r, unsigned short* Xi, Vec cl = { 0, 0, 0 }, Vec cf = {1, 1, 1}) {
	double t;	// distance to intersection
	int id = 0;	// id of intersected object
	int depth = depth_;

	// cl is accumulated color
	// cf is accumulated reflectance

	double Re, Tr, P, RP, TP;
	Ray reflRay(0, 0);
	Vec x, tdir;

	while(true) {
		auto doNext = radianceInner(
			r, depth, Xi,
			t, id, cl, cf,
			Re, Tr, P, RP, TP, reflRay, x, tdir
		);

		if(doNext == DoNext::ContinueLoop) {
			continue;
		}
		if(doNext == DoNext::Return) {
			return cl;
		}

		if(depth == 1) {
			return radiance<1>(reflRay, Xi, cl, cf * Re) + radiance<1>(Ray(x, tdir), Xi, cl, cf * Tr);
		}
		else if(depth == 2) {
			return radiance<2>(reflRay, Xi, cl, cf * Re) + radiance<2>(Ray(x, tdir), Xi, cl, cf * Tr);
		}
		else {
			radiance(r, depth, Xi, cl, cf);
			return cl;
		}
	}
}

} // namespace ns_sycl_gtx

inline double clamp(double x) {
	if(x < 0) {
		return 0;
	}
	if(x > 1) {
		return 1;
	}
	return x;
}

void compute_sycl_gtx_cpu(int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c) {
	#pragma omp parallel for schedule(dynamic, 1) private(r)
	for(int y = 0; y < h; y++) {						// Loop over image rows
		fprintf(stderr, "\rRendering (%d spp) %5.2f%%", samps * 4, 100.*y / (h - 1));
		for(unsigned short x = 0, Xi[3] = { 0, 0, y*y*y }; x < w; x++) {	// Loop cols
			for(int sy = 0, i = (h - y - 1)*w + x; sy < 2; sy++) {	 // 2x2 subpixel rows
				for(int sx = 0; sx < 2; sx++, r = Vec()) {		// 2x2 subpixel cols
					for(int s = 0; s < samps; s++) {
						double r1 = 2 * erand48(Xi);
						double r2 = 2 * erand48(Xi);

						double dx, dy;
						if(r1 < 1) {
							dx = sqrt(r1) - 1;
						}
						else {
							dx = 1 - sqrt(2 - r1);
						}
						if(r2 < 1) {
							dy = sqrt(r2) - 1;
						}
						else {
							dy = 1 - sqrt(2 - r2);
						}

						Vec d = cx*(((sx + .5 + dx) / 2 + x) / w - .5) + cy*(((sy + .5 + dy) / 2 + y) / h - .5) + cam.d;
						r = r + ns_sycl_gtx::radiance(Ray(cam.o + d * 140, d.norm()), Xi)*(1. / samps);
					} // Camera rays are pushed ^^^^^ forward to start in interior

					c[i] = c[i] + Vec(clamp(r.x), clamp(r.y), clamp(r.z))*.25;
				}
			}
		}
	}
}

void compute_sycl_gtx_gpu(int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c) {
	using namespace cl::sycl;

	gpu_selector gpu;
}
<commit_msg>Basic queue submit.<commit_after>// smallpt, a Path Tracer by Kevin Beason, 2008
//
// Modified by Peter uek
// For the original code, see github.com/munificient/smallpt
// For the original license, see smallpt.LICENSE.txt

#include <cmath>
#include <cstdlib>
#include <cstdio>

#include <sycl.hpp>

#include "classes.h"
#include "msvc.h"

namespace ns_sycl_gtx {

static const int numSpheres = 9;
Sphere spheres[numSpheres] = {//Scene: radius, position, emission, color, material
	Sphere(1e5, Vec(1e5 + 1, 40.8, 81.6), Vec(), Vec(.75, .25, .25), DIFF),//Left
	Sphere(1e5, Vec(-1e5 + 99, 40.8, 81.6), Vec(), Vec(.25, .25, .75), DIFF),//Rght
	Sphere(1e5, Vec(50, 40.8, 1e5), Vec(), Vec(.75, .75, .75), DIFF),//Back
	Sphere(1e5, Vec(50, 40.8, -1e5 + 170), Vec(), Vec(), DIFF),//Frnt
	Sphere(1e5, Vec(50, 1e5, 81.6), Vec(), Vec(.75, .75, .75), DIFF),//Botm
	Sphere(1e5, Vec(50, -1e5 + 81.6, 81.6), Vec(), Vec(.75, .75, .75), DIFF),//Top
	Sphere(16.5, Vec(27, 16.5, 47), Vec(), Vec(1, 1, 1)*.999, SPEC),//Mirr
	Sphere(16.5, Vec(73, 16.5, 78), Vec(), Vec(1, 1, 1)*.999, REFR),//Glas
	Sphere(600, Vec(50, 681.6 - .27, 81.6), Vec(12, 12, 12), Vec(), DIFF) //Lite
};

inline bool intersect(const Ray& r, double& t, int& id) {
	double d;
	double inf = t = 1e20;
	for(int i = numSpheres; i > 0;) {
		--i;
		if((d = spheres[i].intersect(r)) && d < t) {
			t = d;
			id = i;
		}
	}
	return t < inf;
}

enum class DoNext {
	Return, ContinueLoop, Proceed
};

DoNext radianceInner(
	Ray& r, int& depth, unsigned short* Xi,	// Original parameters
	double& t, int& id, Vec& cl, Vec& cf,	// Passed references
	// Output references
	double& Re, double& Tr, double& P, double& RP, double& TP, Ray& reflRay, Vec& x, Vec& tdir
) {
	if(!intersect(r, t, id)) {
		// if miss, don't add anything
		return DoNext::Return;
	}
	const Sphere& obj = spheres[id]; // the hit object
	x = r.o + r.d*t;
	Vec n = (x - obj.p).norm();
	Vec nl = n;
	if(n.dot(r.d) > 0) {
		nl = nl * -1;
	}
	Vec f = obj.c;
	double p;	// max refl
	if(f.x > f.y && f.x > f.z) {
		p = f.x;
	}
	else if(f.y > f.z) {
		p = f.y;
	}
	else {
		p = f.z;
	}

	cl = cl + cf.mult(obj.e);

	depth += 1;
	if(depth > 5) {
		if(erand48(Xi) < p) {
			f = f*(1 / p);
		}
		else {
			return DoNext::Return;
		}
	}

	cf = cf.mult(f);

	if(obj.refl == DIFF) {	// Ideal DIFFUSE reflection
		double r1 = 2 * M_PI*erand48(Xi), r2 = erand48(Xi), r2s = sqrt(r2);
		Vec w = nl;
		Vec u;
		if(fabs(w.x) > .1) {
			u.y = 1;
		}
		else {
			u.x = 1;
		}
		u = (u % w).norm();
		Vec v = w%u;
		Vec d = (u*cos(r1)*r2s + v*sin(r1)*r2s + w*sqrt(1 - r2)).norm();

		// Recursion
		r = Ray(x, d);
		return DoNext::ContinueLoop;
	}
	else if(obj.refl == SPEC) {	// Ideal SPECULAR reflection
		// Recursion
		r = Ray(x, r.d - n * 2 * n.dot(r.d));
		return DoNext::ContinueLoop;
	}
	reflRay = Ray(x, r.d - n * 2 * n.dot(r.d));	// Ideal dielectric REFRACTION
	bool into = n.dot(nl) > 0;	// Ray from outside going in?
	double nc = 1;
	double nt = 1.5;
	double nnt;
	if(into) {
		nnt = nc / nt;
	}
	else {
		nnt = nt / nc;
	}
	double ddn = r.d.dot(nl);
	double cos2t;
	if((cos2t = 1 - nnt*nnt*(1 - ddn*ddn)) < 0) {	// Total internal reflection
		// Recursion
		r = reflRay;
		return DoNext::ContinueLoop;
	}
	double tmp = 1;
	if(!into) {
		tmp = -1;
	}
	tdir = (r.d*nnt - n*(tmp*(ddn*nnt + sqrt(cos2t)))).norm();
	double a = nt - nc;
	double b = nt + nc;
	double R0 = a*a / (b*b);
	double c = 1;
	if(into) {
		c += ddn;
	}
	else {
		c -= tdir.dot(n);
	}
	Re = R0 + (1 - R0)*c*c*c*c*c;
	Tr = 1 - Re;
	P = .25 + .5*Re;
	RP = Re / P;
	TP = Tr / (1 - P);

	return DoNext::Proceed;
}

void radiance(Ray r, int depth, unsigned short* Xi, Vec& cl, Vec& cf) {
	double t;	// distance to intersection
	int id = 0;	// id of intersected object

	double Re, Tr, P, RP, TP;
	Ray reflRay(0, 0);
	Vec x, tdir;

	while(true) {
		auto doNext = radianceInner(
			r, depth, Xi,
			t, id, cl, cf,
			Re, Tr, P, RP, TP, reflRay, x, tdir
		);

		if(doNext == DoNext::ContinueLoop) {
			continue;
		}
		if(doNext == DoNext::Return) {
			return;
		}

		if(erand48(Xi) < P) {
			cf = cf * RP;
			r = reflRay;
		}
		else {
			cf = cf * TP;
			r = Ray(x, tdir);
		}
	}
}

template <int depth_ = 0>
Vec radiance(Ray r, unsigned short* Xi, Vec cl = { 0, 0, 0 }, Vec cf = {1, 1, 1}) {
	double t;	// distance to intersection
	int id = 0;	// id of intersected object
	int depth = depth_;

	// cl is accumulated color
	// cf is accumulated reflectance

	double Re, Tr, P, RP, TP;
	Ray reflRay(0, 0);
	Vec x, tdir;

	while(true) {
		auto doNext = radianceInner(
			r, depth, Xi,
			t, id, cl, cf,
			Re, Tr, P, RP, TP, reflRay, x, tdir
		);

		if(doNext == DoNext::ContinueLoop) {
			continue;
		}
		if(doNext == DoNext::Return) {
			return cl;
		}

		if(depth == 1) {
			return radiance<1>(reflRay, Xi, cl, cf * Re) + radiance<1>(Ray(x, tdir), Xi, cl, cf * Tr);
		}
		else if(depth == 2) {
			return radiance<2>(reflRay, Xi, cl, cf * Re) + radiance<2>(Ray(x, tdir), Xi, cl, cf * Tr);
		}
		else {
			radiance(r, depth, Xi, cl, cf);
			return cl;
		}
	}
}

} // namespace ns_sycl_gtx

inline double clamp(double x) {
	if(x < 0) {
		return 0;
	}
	if(x > 1) {
		return 1;
	}
	return x;
}

void compute_sycl_gtx_openmp(int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c) {
	#pragma omp parallel for schedule(dynamic, 1) private(r)
	for(int y = 0; y < h; y++) {						// Loop over image rows
		fprintf(stderr, "\rRendering (%d spp) %5.2f%%", samps * 4, 100.*y / (h - 1));
		for(unsigned short x = 0, Xi[3] = { 0, 0, y*y*y }; x < w; x++) {	// Loop cols
			for(int sy = 0, i = (h - y - 1)*w + x; sy < 2; sy++) {	 // 2x2 subpixel rows
				for(int sx = 0; sx < 2; sx++, r = Vec()) {		// 2x2 subpixel cols
					for(int s = 0; s < samps; s++) {
						double r1 = 2 * erand48(Xi);
						double r2 = 2 * erand48(Xi);

						double dx, dy;
						if(r1 < 1) {
							dx = sqrt(r1) - 1;
						}
						else {
							dx = 1 - sqrt(2 - r1);
						}
						if(r2 < 1) {
							dy = sqrt(r2) - 1;
						}
						else {
							dy = 1 - sqrt(2 - r2);
						}

						Vec d = cx*(((sx + .5 + dx) / 2 + x) / w - .5) + cy*(((sy + .5 + dy) / 2 + y) / h - .5) + cam.d;
						r = r + ns_sycl_gtx::radiance(Ray(cam.o + d * 140, d.norm()), Xi)*(1. / samps);
					} // Camera rays are pushed ^^^^^ forward to start in interior

					c[i] = c[i] + Vec(clamp(r.x), clamp(r.y), clamp(r.z))*.25;
				}
			}
		}
	}
}
void compute_sycl_gtx(int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c, cl::sycl::device_selector& selector) {
	using namespace cl::sycl;

	queue q(selector);

	buffer<Vec> colors(c, range<1>(w*h));

	q.submit([&](handler& cgh) {
		// TODO
	});
}

void compute_sycl_gtx_cpu(int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c) {
	cl::sycl::cpu_selector cpu;
	compute_sycl_gtx(w, h, samps, cam, cx, cy, r, c, cpu);
}

void compute_sycl_gtx_gpu(int w, int h, int samps, Ray& cam, Vec& cx, Vec& cy, Vec r, Vec* c) {
	cl::sycl::gpu_selector gpu;
	compute_sycl_gtx(w, h, samps, cam, cx, cy, r, c, gpu);
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <rtl/ustring.hxx>

#include <tools/solar.h>

#include <vcl/salgtype.hxx>
#include <vcl/region.hxx>
#include <vcl/salnativewidgets.hxx>

#include <com/sun/star/drawing/LineCap.hpp>

class SalGraphics;
class SalBitmap;

class SalGraphicsImpl
{
public:

    virtual ~SalGraphicsImpl();

    virtual void freeResources() = 0;

    virtual bool setClipRegion( const vcl::Region& ) = 0;
    //
    // get the depth of the device
    virtual sal_uInt16 GetBitCount() const = 0;

    // get the width of the device
    virtual long GetGraphicsWidth() const = 0;

    // set the clip region to empty
    virtual void ResetClipRegion() = 0;

    // set the line color to transparent (= don't draw lines)

    virtual void SetLineColor() = 0;

    // set the line color to a specific color
    virtual void SetLineColor( SalColor nSalColor ) = 0;

    // set the fill color to transparent (= don't fill)
    virtual void SetFillColor() = 0;

    // set the fill color to a specific color, shapes will be
    // filled accordingly
    virtual void SetFillColor( SalColor nSalColor ) = 0;

    // enable/disable XOR drawing
    virtual void SetXORMode( bool bSet, bool bInvertOnly ) = 0;

    // set line color for raster operations
    virtual void SetROPLineColor( SalROPColor nROPColor ) = 0;

    // set fill color for raster operations
    virtual void SetROPFillColor( SalROPColor nROPColor ) = 0;

    // draw --> LineColor and FillColor and RasterOp and ClipRegion
    virtual void drawPixel( long nX, long nY ) = 0;
    virtual void drawPixel( long nX, long nY, SalColor nSalColor ) = 0;

    virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) = 0;

    virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) = 0;

    virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) = 0;

    virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) = 0;

    virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) = 0;
    virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) = 0;

    virtual bool drawPolyLine(
                const ::basegfx::B2DPolygon&,
                double fTransparency,
                const ::basegfx::B2DVector& rLineWidths,
                basegfx::B2DLineJoin,
                com::sun::star::drawing::LineCap) = 0;

    virtual bool drawPolyLineBezier(
                sal_uInt32 nPoints,
                const SalPoint* pPtAry,
                const sal_uInt8* pFlgAry ) = 0;

    virtual bool drawPolygonBezier(
                sal_uInt32 nPoints,
                const SalPoint* pPtAry,
                const sal_uInt8* pFlgAry ) = 0;

    virtual bool drawPolyPolygonBezier(
                sal_uInt32 nPoly,
                const sal_uInt32* pPoints,
                const SalPoint* const* pPtAry,
                const sal_uInt8* const* pFlgAry ) = 0;

    // CopyArea --> No RasterOp, but ClipRegion
    virtual void copyArea(
                long nDestX, long nDestY,
                long nSrcX, long nSrcY,
                long nSrcWidth, long nSrcHeight,
                sal_uInt16 nFlags ) = 0;

    // CopyBits and DrawBitmap --> RasterOp and ClipRegion
    // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
    virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) = 0;

    virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) = 0;

    virtual void drawBitmap(
                const SalTwoRect& rPosAry,
                const SalBitmap& rSalBitmap,
                SalColor nTransparentColor ) = 0;

    virtual void drawBitmap(
                const SalTwoRect& rPosAry,
                const SalBitmap& rSalBitmap,
                const SalBitmap& rMaskBitmap ) = 0;

    virtual void drawMask(
                const SalTwoRect& rPosAry,
                const SalBitmap& rSalBitmap,
                SalColor nMaskColor ) = 0;

    virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) = 0;

    virtual SalColor getPixel( long nX, long nY ) = 0;

    // invert --> ClipRegion (only Windows or VirDevs)
    virtual void invert(
                long nX, long nY,
                long nWidth, long nHeight,
                SalInvert nFlags) = 0;

    virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) = 0;

    virtual bool drawEPS(
                long nX, long nY,
                long nWidth, long nHeight,
                void* pPtr,
                sal_uLong nSize ) = 0;

    /** Render bitmap with alpha channel

        @param rSourceBitmap
        Source bitmap to blit

        @param rAlphaBitmap
        Alpha channel to use for blitting

        @return true, if the operation succeeded, and false
        otherwise. In this case, clients should try to emulate alpha
        compositing themselves
     */
    virtual bool drawAlphaBitmap(
                const SalTwoRect&,
                const SalBitmap& rSourceBitmap,
                const SalBitmap& rAlphaBitmap ) = 0;

    /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
    virtual bool drawTransformedBitmap(
                const basegfx::B2DPoint& rNull,
                const basegfx::B2DPoint& rX,
                const basegfx::B2DPoint& rY,
                const SalBitmap& rSourceBitmap,
                const SalBitmap* pAlphaBitmap) = 0;

    /** Render solid rectangle with given transparency

        @param nTransparency
        Transparency value (0-255) to use. 0 blits and opaque, 255 a
        fully transparent rectangle
     */
    virtual bool drawAlphaRect(
                    long nX, long nY,
                    long nWidth, long nHeight,
                    sal_uInt8 nTransparency ) = 0;

};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>we need to export the SalGraphicsImpl class<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you 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 .
 */

#include <vcl/dllapi.h>

#include <rtl/ustring.hxx>

#include <tools/solar.h>

#include <vcl/salgtype.hxx>
#include <vcl/region.hxx>
#include <vcl/salnativewidgets.hxx>

#include <com/sun/star/drawing/LineCap.hpp>

class SalGraphics;
class SalBitmap;

class VCL_PLUGIN_PUBLIC SalGraphicsImpl
{
public:

    virtual ~SalGraphicsImpl();

    virtual void freeResources() = 0;

    virtual bool setClipRegion( const vcl::Region& ) = 0;
    //
    // get the depth of the device
    virtual sal_uInt16 GetBitCount() const = 0;

    // get the width of the device
    virtual long GetGraphicsWidth() const = 0;

    // set the clip region to empty
    virtual void ResetClipRegion() = 0;

    // set the line color to transparent (= don't draw lines)

    virtual void SetLineColor() = 0;

    // set the line color to a specific color
    virtual void SetLineColor( SalColor nSalColor ) = 0;

    // set the fill color to transparent (= don't fill)
    virtual void SetFillColor() = 0;

    // set the fill color to a specific color, shapes will be
    // filled accordingly
    virtual void SetFillColor( SalColor nSalColor ) = 0;

    // enable/disable XOR drawing
    virtual void SetXORMode( bool bSet, bool bInvertOnly ) = 0;

    // set line color for raster operations
    virtual void SetROPLineColor( SalROPColor nROPColor ) = 0;

    // set fill color for raster operations
    virtual void SetROPFillColor( SalROPColor nROPColor ) = 0;

    // draw --> LineColor and FillColor and RasterOp and ClipRegion
    virtual void drawPixel( long nX, long nY ) = 0;
    virtual void drawPixel( long nX, long nY, SalColor nSalColor ) = 0;

    virtual void drawLine( long nX1, long nY1, long nX2, long nY2 ) = 0;

    virtual void drawRect( long nX, long nY, long nWidth, long nHeight ) = 0;

    virtual void drawPolyLine( sal_uInt32 nPoints, const SalPoint* pPtAry ) = 0;

    virtual void drawPolygon( sal_uInt32 nPoints, const SalPoint* pPtAry ) = 0;

    virtual void drawPolyPolygon( sal_uInt32 nPoly, const sal_uInt32* pPoints, PCONSTSALPOINT* pPtAry ) = 0;
    virtual bool drawPolyPolygon( const ::basegfx::B2DPolyPolygon&, double fTransparency ) = 0;

    virtual bool drawPolyLine(
                const ::basegfx::B2DPolygon&,
                double fTransparency,
                const ::basegfx::B2DVector& rLineWidths,
                basegfx::B2DLineJoin,
                com::sun::star::drawing::LineCap) = 0;

    virtual bool drawPolyLineBezier(
                sal_uInt32 nPoints,
                const SalPoint* pPtAry,
                const sal_uInt8* pFlgAry ) = 0;

    virtual bool drawPolygonBezier(
                sal_uInt32 nPoints,
                const SalPoint* pPtAry,
                const sal_uInt8* pFlgAry ) = 0;

    virtual bool drawPolyPolygonBezier(
                sal_uInt32 nPoly,
                const sal_uInt32* pPoints,
                const SalPoint* const* pPtAry,
                const sal_uInt8* const* pFlgAry ) = 0;

    // CopyArea --> No RasterOp, but ClipRegion
    virtual void copyArea(
                long nDestX, long nDestY,
                long nSrcX, long nSrcY,
                long nSrcWidth, long nSrcHeight,
                sal_uInt16 nFlags ) = 0;

    // CopyBits and DrawBitmap --> RasterOp and ClipRegion
    // CopyBits() --> pSrcGraphics == NULL, then CopyBits on same Graphics
    virtual void copyBits( const SalTwoRect& rPosAry, SalGraphics* pSrcGraphics ) = 0;

    virtual void drawBitmap( const SalTwoRect& rPosAry, const SalBitmap& rSalBitmap ) = 0;

    virtual void drawBitmap(
                const SalTwoRect& rPosAry,
                const SalBitmap& rSalBitmap,
                SalColor nTransparentColor ) = 0;

    virtual void drawBitmap(
                const SalTwoRect& rPosAry,
                const SalBitmap& rSalBitmap,
                const SalBitmap& rMaskBitmap ) = 0;

    virtual void drawMask(
                const SalTwoRect& rPosAry,
                const SalBitmap& rSalBitmap,
                SalColor nMaskColor ) = 0;

    virtual SalBitmap* getBitmap( long nX, long nY, long nWidth, long nHeight ) = 0;

    virtual SalColor getPixel( long nX, long nY ) = 0;

    // invert --> ClipRegion (only Windows or VirDevs)
    virtual void invert(
                long nX, long nY,
                long nWidth, long nHeight,
                SalInvert nFlags) = 0;

    virtual void invert( sal_uInt32 nPoints, const SalPoint* pPtAry, SalInvert nFlags ) = 0;

    virtual bool drawEPS(
                long nX, long nY,
                long nWidth, long nHeight,
                void* pPtr,
                sal_uLong nSize ) = 0;

    /** Render bitmap with alpha channel

        @param rSourceBitmap
        Source bitmap to blit

        @param rAlphaBitmap
        Alpha channel to use for blitting

        @return true, if the operation succeeded, and false
        otherwise. In this case, clients should try to emulate alpha
        compositing themselves
     */
    virtual bool drawAlphaBitmap(
                const SalTwoRect&,
                const SalBitmap& rSourceBitmap,
                const SalBitmap& rAlphaBitmap ) = 0;

    /** draw transformed bitmap (maybe with alpha) where Null, X, Y define the coordinate system */
    virtual bool drawTransformedBitmap(
                const basegfx::B2DPoint& rNull,
                const basegfx::B2DPoint& rX,
                const basegfx::B2DPoint& rY,
                const SalBitmap& rSourceBitmap,
                const SalBitmap* pAlphaBitmap) = 0;

    /** Render solid rectangle with given transparency

        @param nTransparency
        Transparency value (0-255) to use. 0 blits and opaque, 255 a
        fully transparent rectangle
     */
    virtual bool drawAlphaRect(
                    long nX, long nY,
                    long nWidth, long nHeight,
                    sal_uInt8 nTransparency ) = 0;

};

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>// $Id$

/**
   Important macro to get certain Aliroot parameters. They are stored
   in a file "Init.cxx". New init of AliL3Transform uses output to read certain
   TPC parameters.
*/

void Make_Init(char *file, char *tofile="Init.cxx"){

  TFile * rootf = new TFile(file,"READ");

  if(!rootf->IsOpen()){
    cerr<<"no file: "<<file<<endl;
    return;
  }

  AliRun *gAlice = (AliRun*)rootf->Get("gAlice");
  if(!gAlice){
    cerr<<"no gAlice in file: "<<file<<endl;
    return;
  }

  AliTPCParam* par = (AliTPCParam*)rootf->Get("75x40_100x60");
  if(!par){
    cerr<<"no AliTPCParam 75x40_100x60 in file: "<<file<<endl;
    return;
  }

  AliTPCParamSR *param=(AliTPCParamSR*)par;
  AliTPCPRF2D    * prfinner   = new AliTPCPRF2D;
  AliTPCPRF2D    * prfouter   = new AliTPCPRF2D;
  AliTPCRF1D     * rf    = new AliTPCRF1D(kTRUE);
  rf->SetGauss(param->GetZSigma(),param->GetZWidth(),1.);
  rf->SetOffset(3*param->GetZSigma());
  rf->Update();

  TDirectory *savedir=gDirectory;
  TFile *if=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root");
  if (!if->IsOpen()) {
    cerr<<"Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !\n" ;
    exit(3);
  }
  prfinner->Read("prf_07504_Gati_056068_d02");
  prfouter->Read("prf_10006_Gati_047051_d03");
  if->Close();
  savedir->cd();

  param->SetInnerPRF(prfinner);
  param->SetOuterPRF(prfouter);
  param->SetTimeRF(rf);

  int fNTimeBins = par->GetMaxTBin()+1;
  int fNRowLow = par->GetNRowLow();
  int fNRowUp  = par->GetNRowUp();
  int fNRow= fNRowLow + fNRowUp;
  int fNSectorLow = par->GetNInnerSector();
  int fNSectorUp = par->GetNOuterSector();
  int fNSector = fNSectorLow + fNSectorUp;
  int fNSlice = fNSectorLow;

  FILE *f = fopen(tofile,"w");
  fprintf(f,"void AliL3Transform::Init(){\n");

  fprintf(f,"  fBFieldFactor = %d ;\n",gAlice->Field()->Factor());
  fprintf(f,"  //sector:\n");
  fprintf(f,"  fNTimeBins = %d ;\n",fNTimeBins);
  fprintf(f,"  fNRowLow = %d ;\n",fNRowLow);
  fprintf(f,"  fNRowUp = %d ;\n",fNRowUp);
  fprintf(f,"  fNSectorLow = %d ;\n",fNSectorLow);
  fprintf(f,"  fNSectorUp = %d ;\n",fNSectorUp);
  fprintf(f,"  fNSector = %d ;\n",fNSector);
  fprintf(f,"  fPadPitchWidthLow = %f ;\n",par->GetPadPitchWidth(0));
  fprintf(f,"  fPadPitchWidthUp = %f ;\n",par->GetPadPitchWidth(fNSectorLow));
  fprintf(f,"  fZWidth = %.20f ;\n",par->GetZWidth());
  fprintf(f,"  fZSigma = %.20f ;\n",par->GetZSigma());
  fprintf(f,"  fZLength = %.20f ;\n",par->GetZLength());
  fprintf(f,"  fZOffset = %.20f ;\n",par->GetZOffset());
  fprintf(f,"  fDiffT = %.20f ;\n",par->GetDiffT());
  fprintf(f,"  fDiffL = %.20f ;\n",par->GetDiffL());
  fprintf(f,"  fInnerPadLength = %f ;\n",par->GetInnerPadLength());
  fprintf(f,"  fOuterPadLength = %f ;\n",par->GetOuterPadLength());
  fprintf(f,"  fInnerPRFSigma = %.20f ;\n",param->GetInnerPRF()->GetSigmaX());
  fprintf(f,"  fOuterPRFSigma = %.20f ;\n",param->GetOuterPRF()->GetSigmaX());
  fprintf(f,"  fTimeSigma = %.20f ;\n",param->GetTimeRF()->GetSigma());

  fprintf(f,"\n  //slices:\n");
  fprintf(f,"  fNSlice = %d ;\n",fNSectorLow);
  fprintf(f,"  fNRow = %d ;\n",fNRow);

  //rotation shift put in by hand -> Constantin
  fprintf(f,"  fNRotShift = 0.5 ;\n");

  fprintf(f,"  fPi = %.15f ;\n",TMath::Pi());
  fprintf(f,"  for(Int_t i=0;i<36;i++){\n");
  fprintf(f,"    fCos[i] = cos(2*fPi/9*(i+0.5));\n");
  fprintf(f,"    fSin[i] = sin(2*fPi/9*(i+0.5));\n");
  fprintf(f,"  }\n\n");

  for(Int_t i=0;i<fNRow;i++){
    int sec,row;
    if( i < fNRowLow){sec =0;row =i;}
    else{sec = fNSectorLow;row =i-fNRowLow;}
    fprintf(f,"  fX[%d] = %3.15f ;\n",i,par->GetPadRowRadii(sec,row));
  }
  for(Int_t i=0;i<fNRow;i++){
    int sec,row;
    if( i < fNRowLow){sec =0;row =i;}
    else{sec = fNSectorLow;row =i-fNRowLow;}
    fprintf(f,"  fNPads[%d] = %d ;\n",i,par->GetNPads(sec,row));
  }

  fprintf(f,"}\n");
  fclose(f);
}

void Make_Default(char *file,char *tofile)
{
  /*
    Macro to write out default values, which should be used to initialize
    the static data members of the AliL3Transform class. Macro does more
    or less the same as the above, only the output syntax is changed in order
    to use it for static data member initialization.
  */

  TFile * rootf = new TFile(file,"READ");

  if(!rootf->IsOpen()){
    cerr<<"no file: "<<file<<endl;
    return;
  }

  AliTPCParam* par = (AliTPCParam*)rootf->Get("75x40_100x60");

  if(!par){
    cerr<<"no AliTPCParam 75x40_100x60 in file: "<<file<<endl;
    return;
  }

  int fNTimeBins = par->GetMaxTBin()+1;
  int fNRowLow = par->GetNRowLow();
  int fNRowUp  = par->GetNRowUp();
  int fNRow= fNRowLow + fNRowUp;
  int fNSectorLow = par->GetNInnerSector();
  int fNSectorUp = par->GetNOuterSector();
  int fNSector = fNSectorLow + fNSectorUp;
  int fNSlice = fNSectorLow;

  FILE *f = fopen(tofile,"w");
  fprintf(f,"Int_t AliL3Transform::fNTimeBins = %d ;\n",fNTimeBins);
  fprintf(f,"Int_t AliL3Transform::fNRowLow = %d ;\n",fNRowLow);
  fprintf(f,"Int_t AliL3Transform::fNRowUp = %d ;\n",fNRowUp);
  fprintf(f,"Int_t AliL3Transform::fNSectorLow = %d ;\n",fNSectorLow);
  fprintf(f,"Int_t AliL3Transform::fNSectorUp = %d ;\n",fNSectorUp);
  fprintf(f,"Int_t AliL3Transform::fNSector = %d ;\n",fNSector);
  fprintf(f,"Double_t AliL3Transform::fPadPitchWidthLow = %f ;\n",par->GetPadPitchWidth(0));
  fprintf(f,"Double_t AliL3Transform::fPadPitchWidthUp = %f ;\n",par->GetPadPitchWidth(fNSectorLow));
  fprintf(f,"Double_t AliL3Transform::fZWidth = %.20f ;\n",par->GetZWidth());
  fprintf(f,"Double_t AliL3Transform::fZSigma = %.20f ;\n",par->GetZSigma());
  fprintf(f,"Int_t AliL3Transform::fNSlice = %d ;\n",fNSectorLow);
  fprintf(f,"Int_t AliL3Transform::fNRow = %d ;\n",fNRow);
  fprintf(f,"Double_t AliL3Transform::fNRotShift = 0.5 ;\n");
  fprintf(f,"Double_t AliL3Transform::fPi = %.15f ;\n",TMath::Pi());
  fprintf(f,"Double_t AliL3Transform::fX[176] = {\n");
  for(Int_t i=0;i<fNRow;i++){
    int sec,row;
    if( i < fNRowLow){sec =0;row =i;}
    else{sec = fNSectorLow;row =i-fNRowLow;}

  fprintf(f,"                                    %3.15f,\n",par->GetPadRowRadii(sec,row));
  }
  fprintf(f,"};\n\n");

  fprintf(f,"Int_t AliL3Transform::fNPads[176] = {\n");
  for(Int_t i=0;i<fNRow;i++){
    int sec,row;
    if( i < fNRowLow){sec =0;row =i;}
    else{sec = fNSectorLow;row =i-fNRowLow;}
  fprintf(f,"                                     %d,\n",par->GetNPads(sec,row));
  }
  fprintf(f,"};\n");
  fclose(f);
}
<commit_msg>Moved this functionaly to a functio in AliL3Transform::MakeInitFile. This macro can now be used to create default values for AliL3Transform.cxx.<commit_after>// $Id$

/**
   Macro to get the default parameters from AliTPCParam.
   Output is written to a file, which can be inserted directly into
   AliL3Transform.cxx as the default parameters to be set at top
*/

void Make_Init(char *tofile="Init.cxx")
{
  AliTPCParamSR *param = new AliTPCParamSR();
  param->SetDefault();
  if(!param)
    {
      cerr<<"AliL3Transform::MakeInitFile : No TPC parameters found"<<endl;
      return;
    }

  AliTPCPRF2D    * prfinner   = new AliTPCPRF2D;
  AliTPCPRF2D    * prfouter1   = new AliTPCPRF2D;
  AliTPCPRF2D    * prfouter2   = new AliTPCPRF2D;
  AliTPCRF1D     * rf    = new AliTPCRF1D(kTRUE);
  rf->SetGauss(param->GetZSigma(),param->GetZWidth(),1.);
  rf->SetOffset(3*param->GetZSigma());
  rf->Update();

  TDirectory *savedir=gDirectory;
  TFile *f1=TFile::Open("$ALICE_ROOT/TPC/AliTPCprf2d.root");
  if (!f1->IsOpen())
    {
      cerr<<"Can't open $ALICE_ROOT/TPC/AliTPCprf2d.root !\n" ;
      exit(3);
    }
  prfinner->Read("prf_07504_Gati_056068_d02");
  prfouter1->Read("prf_10006_Gati_047051_d03");
  prfouter2->Read("prf_15006_Gati_047051_d03");
  f1->Close();
  savedir->cd();

  param->SetInnerPRF(prfinner);
  param->SetOuter1PRF(prfouter1);
  param->SetOuter2PRF(prfouter2);
  param->SetTimeRF(rf);

  Int_t fNTimeBins = param->GetMaxTBin()+1;
  Int_t fNRowLow = param->GetNRowLow();
  Int_t fNRowUp  = param->GetNRowUp();
  Int_t fNRowUp1 = param->GetNRowUp1();
  Int_t fNRowUp2 = param->GetNRowUp2();
  Int_t fNRow= fNRowLow + fNRowUp;
  Int_t fNSectorLow = param->GetNInnerSector();
  Int_t fNSectorUp = param->GetNOuterSector();
  Int_t fNSector = fNSectorLow + fNSectorUp;
  Int_t fNSlice = fNSectorLow;

  FILE *f = fopen(tofile,"w");
  if(!f)
    {
      cerr<<"Error opening file "<<tofile<<endl;
      return;
    }
  fprintf(f,"const Double_t AliL3Transform::fBFACT = 0.0029980;\n");
  fprintf(f,"Double_t AliL3Transform::fBField = 0.2;\n");
  fprintf(f,"Int_t AliL3Transform::fVersion = 0;\n");
  fprintf(f,"Int_t AliL3Transform::fBFieldFactor = %d ;\n",gAlice->Field()->Factor());
  fprintf(f,"Int_t AliL3Transform::fNTimeBins = %d ;\n",fNTimeBins);
  fprintf(f,"Int_t AliL3Transform::fNRowLow = %d ;\n",fNRowLow);
  fprintf(f,"Int_t AliL3Transform::fNRowUp = %d ;\n",fNRowUp);
  fprintf(f,"Int_t AliL3Transform::fNRowUp1 = %d ;\n",fNRowUp1);
  fprintf(f,"Int_t AliL3Transform::fNRowUp2 = %d ;\n",fNRowUp2);
  fprintf(f,"Int_t AliL3Transform::fNSectorLow = %d ;\n",fNSectorLow);
  fprintf(f,"Int_t AliL3Transform::fNSectorUp = %d ;\n",fNSectorUp);
  fprintf(f,"Int_t AliL3Transform::fNSector = %d ;\n",fNSector);
  fprintf(f,"Double_t AliL3Transform::fPadPitchWidthLow = %f ;\n",param->GetInnerPadPitchWidth());
  fprintf(f,"Double_t AliL3Transform::fPadPitchWidthUp = %f ;\n",param->GetOuterPadPitchWidth());
  fprintf(f,"Double_t AliL3Transform::fZWidth = %.20f ;\n",param->GetZWidth());
  fprintf(f,"Double_t AliL3Transform::fZSigma = %.20f ;\n",param->GetZSigma());
  fprintf(f,"Double_t AliL3Transform::fZLength = %.20f ;\n",param->GetZLength());
  fprintf(f,"Double_t AliL3Transform::fZOffset = %.20f ;\n",param->GetZOffset());
  fprintf(f,"Double_t AliL3Transform::fDiffT = %.20f ;\n",param->GetDiffT());
  fprintf(f,"Double_t AliL3Transform::fDiffL = %.20f ;\n",param->GetDiffL());
  fprintf(f,"Double_t AliL3Transform::fInnerPadLength = %f ;\n",param->GetInnerPadLength());
  fprintf(f,"Double_t AliL3Transform::fOuter1PadLength = %f ;\n",param->GetOuter1PadLength());
  fprintf(f,"Double_t AliL3Transform::fOuter2PadLength = %f ;\n",param->GetOuter2PadLength());
  fprintf(f,"Double_t AliL3Transform::fInnerPRFSigma = %.20f ;\n",param->GetInnerPRF()->GetSigmaX());
  fprintf(f,"Double_t AliL3Transform::fOuter1PRFSigma = %.20f ;\n",param->GetOuter1PRF()->GetSigmaX());
  fprintf(f,"Double_t AliL3Transform::fOuter2PRFSigma = %.20f ;\n",param->GetOuter2PRF()->GetSigmaX());
  fprintf(f,"Double_t AliL3Transform::fTimeSigma = %.20f ;\n",param->GetTimeRF()->GetSigma());
  fprintf(f,"Int_t AliL3Transform::fNSlice = %d ;\n",fNSectorLow);
  fprintf(f,"Int_t AliL3Transform::fNRow = %d ;\n",fNRow);
  fprintf(f,"Int_t AliL3Transform::fNRotShift = 0.5 ;\n");
  fprintf(f,"Double_t AliL3Transform::fPi = %.15f ;\n",TMath::Pi());

  fprintf(f,"Double_t AliL3Transform::fX[159] = {");
  for(Int_t i=0;i<fNRow;i++){
    int sec,row;
    if( i < fNRowLow){sec =0;row =i;}
    else{sec = fNSectorLow;row =i-fNRowLow;}

    fprintf(f,"                                    %3.15f,\n",param->GetPadRowRadii(sec,row));
  }
  fprintf(f,"};\n\n");

  fprintf(f,"Int_t AliL3Transform::fNPads[159] = {");
  for(Int_t i=0;i<fNRow;i++){
    int sec,row;
    if( i < fNRowLow){sec =0;row =i;}
    else{sec = fNSectorLow;row =i-fNRowLow;}
  fprintf(f,"                                     %d,\n",param->GetNPads(sec,row));
  }

  fprintf(f,"};\n");
  fclose(f);
}
<|endoftext|>


<commit_before>#include "test.h"
#include "runtime/Exception.h"
#include "base/Basic.h"
using namespace snow;

TEST_SUITE(Exception);

TEST_CASE(throw_catch) {
	HandleScope _scope;
	ExceptionHandler _handler;
	volatile int a = 0;
	volatile int b = 0;
	if (TRY_CATCH(_handler)) {
		a = 1;
		throw_exception(value(123));
		b = 1;
		// SHOULD NOT BE REACHED
		TEST_EQ(true, false);
	} else {
		// Exception caught
		TEST_EQ(_handler.exception(), value(123));
	}
	TEST_EQ(a, 1);
	TEST_EQ(b, 0);
}

struct DestructorsTestMock {
	volatile int* n;
	DestructorsTestMock(volatile int* m) : n(m) { (*n)++; }
	~DestructorsTestMock() { (*n)++; }
};

static void destructors_test_helper(volatile int* n) {
	HandleScope _s;
	Local<DestructorsTestMock> mock(n);
	throw_exception(nil());
}

TEST_CASE(destructors) {
	HandleScope _s;
	ExceptionHandler tc;
	volatile int a = 0;
	if (TRY_CATCH(tc)) {
		TEST_EQ(a, 0);
		destructors_test_helper(&a);
	} else {
		// if a == 1, the destructor wasn't called :(
		TEST_EQ(a, 2);
	}
}

<commit_msg>Added test of throwing a string.<commit_after>#include "test.h"
#include "runtime/Exception.h"
#include "runtime/SnowString.h"
#include "base/Basic.h"
using namespace snow;

TEST_SUITE(Exception);

TEST_CASE(throw_catch) {
	HandleScope _scope;
	ExceptionHandler _handler;
	volatile int a = 0;
	volatile int b = 0;
	if (TRY_CATCH(_handler)) {
		a = 1;
		throw_exception(value(123));
		b = 1;
		// SHOULD NOT BE REACHED
		TEST_EQ(true, false);
	} else {
		// Exception caught
		TEST_EQ(_handler.exception(), value(123));
	}
	TEST_EQ(a, 1);
	TEST_EQ(b, 0);
}

TEST_CASE(throw_string) {
	HandleScope _scope;
	ExceptionHandler _handler;
	Handle<String> exception_string = gc_new<String>("I'm raised.");

	if (TRY_CATCH(_handler)) {
		throw_exception(exception_string);
		TEST_EQ(true, false);
	} else {
		TEST_EQ(_handler.exception(), exception_string.value());
	}
}

struct DestructorsTestMock {
	volatile int* n;
	DestructorsTestMock(volatile int* m) : n(m) { (*n)++; }
	~DestructorsTestMock() { (*n)++; }
};

static void destructors_test_helper(volatile int* n) {
	HandleScope _s;
	Local<DestructorsTestMock> mock(n);
	throw_exception(nil());
}

TEST_CASE(destructors) {
	HandleScope _s;
	ExceptionHandler tc;
	volatile int a = 0;
	if (TRY_CATCH(tc)) {
		TEST_EQ(a, 0);
		destructors_test_helper(&a);
	} else {
		// if a == 1, the destructor wasn't called :(
		TEST_EQ(a, 2);
	}
}

<|endoftext|>


<commit_before>#include "gfakluge.hpp"

using namespace std;
namespace gfak{
GFAKluge::GFAKluge(){
  map<std::string, std::string> header;
  map<std::string, vector<contained_elem> > seq_to_contained;
  map<std::string, vector<link_elem> > seq_to_link;
  //Since we can't compare sequence elements for hashing,
  // we cheat and use their names (which are sort of guaranteed to be
  // unique.
  map<string, sequence_elem> name_to_seq;
}

GFAKluge::~GFAKluge(){

}

// Borrow from
//http://stackoverflow.com/questions/236129/split-a-string-in-c
// Thanks StackOverflow!
vector<string> GFAKluge::split(string s, char delim){
    vector<string> ret;
    stringstream sstream(s);
    string temp;
    while(getline(sstream, temp, delim)){
        ret.push_back(temp);
    }
    return ret;

}

bool GFAKluge::parse_gfa_file(string filename){
    ifstream gfi;
    gfi.open(filename.c_str(), std::ifstream::in);
    if (!gfi.good()){
        cerr << "Invalid input stream. Exiting." << endl;
        return false;
    }
    cerr << "Reading " << filename << "..." << endl;

    string line;
    vector<string> line_tokens;
    while (getline(gfi, line)){
        vector<string> tokens = split(line, '\t');
        if (tokens[0] == "H"){
            header_elem h;
            line_tokens = split(tokens[1], ':');
            //TODO this is not well implemented
            // GFA places no guarantees on header format
            h.key = line_tokens[0];
            h.val = line_tokens[1];
            header[h.key] = h.val;
        }
        else if (tokens[0] ==  "S"){
            //TODO: we've got some tokens at the end of the line
            //that have not been handled yet.
            sequence_elem s;
            s.name = tokens[1];
            s.seq = tokens[2];
            //s.id = atol(s.name.c_str());
            name_to_seq[s.name] = s;
        }
        else if (tokens[0] ==  "L"){
            // TODO: we need to deal with links where the link is given before
            // its corresponding sequence in the file. TODO this is probably
            // now fixed by using the string: sequence map.
            link_elem l;
            l.source_name = tokens[1];
            l.sink_name = tokens[3];
            //TODO: search the input strings for "-" and "+" and set using ternary operator
            l.source_orientation_forward = tokens[2] == "+" ? true : false;
            l.sink_orientation_forward = tokens[4] == "+" ? true : false;
            //l.pos = tokens[0];
            l.cigar = tokens[5];
            add_link(l.source_name, l);
        }
        else if (tokens[0] == "C"){
            contained_elem c;
            //TODO fix token indices here
            c.source_name = tokens[1];
            c.sink_name = tokens[3];
            c.source_orientation_forward = tokens[2] == "+" ? true : false;
            c.sink_orientation_forward = tokens[4] == "+" ? true : false;
            c.pos = atoi(tokens[5].c_str());
            c.cigar = tokens[6];
            add_contained(c.sink_name, c);
        }
        else if (tokens[0] == "x"){
            annotation_elem x;
            x.key = tokens[1];
            x.info = tokens[2];
        }
        else if (tokens[0] == "a"){
            annotation_elem a;
            a.key = tokens[1];
            a.info = tokens[2];
        }
        else{
            cerr << "Unknown line identifier  encountered: " << tokens[0] <<  " . Exiting." << endl;
        }

    }

    return true;

    }

    bool GFAKluge::parse_gfa_file(fstream fs){
        cerr << "Not implemented: parse_gfa_file(fstream)" << endl; exit(1);
        return true;
    }

    void GFAKluge::add_link(sequence_elem seq, link_elem link){
        seq_to_link[seq.name].push_back(link);
    }

    void GFAKluge::add_contained(sequence_elem seq, contained_elem con){
        seq_to_contained[seq.name].push_back(con);
    }

    void GFAKluge::add_link(string seq_name, link_elem link){
        seq_to_link[seq_name].push_back(link);
    }

    void GFAKluge::add_contained(string seq_name, contained_elem con){
        seq_to_contained[seq_name].push_back(con);
    }

    vector<link_elem> GFAKluge::get_links(string seq_name){
        return seq_to_link[seq_name];
    }

    vector<link_elem> GFAKluge::get_links(sequence_elem seq){
        string seq_name = seq.name;
        return seq_to_link[seq_name];
    }

    vector<contained_elem> GFAKluge::get_contained(string seq_name){
        return seq_to_contained[seq_name];
    }

    vector<contained_elem> GFAKluge::get_contained(sequence_elem seq){
        string seq_name = seq.name;
        return seq_to_contained[seq_name];
    }

    std::string GFAKluge::to_string(){
        string ret = "";
        //First print header lines.
        if (header.size() > 0){
          map<std::string, std::string>::iterator it;
          for (it = header.begin(); it != header.end(); it++){
              ret += "H\t" + it->first + "\t" + it->second + "\n";
            }
        }
        if (name_to_seq.size() > 0){
          map<std::string, sequence_elem>::iterator st;
          for (st = name_to_seq.begin(); st != name_to_seq.end(); st++){
              ret += "S\t" + (st->second).name + "\t" + (st->second).seq + "\n";
              //TODO iterate over links

              //TODO iterate over contains
          }
        }
        //TODO iterate over annotation lines.

        //Print sequences and links in order, then annotation lines.

        return ret;
    }

    // std::ostream& operator<<(std::ostream& os, const gfak::GFAKluge& g){
    //     os << g.to_string();
    //     return os;
    // }
}
<commit_msg>More additions to to_string method<commit_after>#include "gfakluge.hpp"

using namespace std;
namespace gfak{
GFAKluge::GFAKluge(){
  map<std::string, std::string> header;
  map<std::string, vector<contained_elem> > seq_to_contained;
  map<std::string, vector<link_elem> > seq_to_link;
  //Since we can't compare sequence elements for hashing,
  // we cheat and use their names (which are sort of guaranteed to be
  // unique.
  map<string, sequence_elem> name_to_seq;
}

GFAKluge::~GFAKluge(){

}

// Borrow from
//http://stackoverflow.com/questions/236129/split-a-string-in-c
// Thanks StackOverflow!
vector<string> GFAKluge::split(string s, char delim){
    vector<string> ret;
    stringstream sstream(s);
    string temp;
    while(getline(sstream, temp, delim)){
        ret.push_back(temp);
    }
    return ret;

}

bool GFAKluge::parse_gfa_file(string filename){
    ifstream gfi;
    gfi.open(filename.c_str(), std::ifstream::in);
    if (!gfi.good()){
        cerr << "Invalid input stream. Exiting." << endl;
        return false;
    }
    cerr << "Reading " << filename << "..." << endl;

    string line;
    vector<string> line_tokens;
    while (getline(gfi, line)){
        vector<string> tokens = split(line, '\t');
        if (tokens[0] == "H"){
            header_elem h;
            line_tokens = split(tokens[1], ':');
            //TODO this is not well implemented
            // GFA places no guarantees on header format
            h.key = line_tokens[0];
            h.val = line_tokens[1];
            header[h.key] = h.val;
        }
        else if (tokens[0] ==  "S"){
            //TODO: we've got some tokens at the end of the line
            //that have not been handled yet.
            sequence_elem s;
            s.name = tokens[1];
            s.seq = tokens[2];
            //s.id = atol(s.name.c_str());
            name_to_seq[s.name] = s;
        }
        else if (tokens[0] ==  "L"){
            // TODO: we need to deal with links where the link is given before
            // its corresponding sequence in the file. TODO this is probably
            // now fixed by using the string: sequence map.
            link_elem l;
            l.source_name = tokens[1];
            l.sink_name = tokens[3];
            //TODO: search the input strings for "-" and "+" and set using ternary operator
            l.source_orientation_forward = tokens[2] == "+" ? true : false;
            l.sink_orientation_forward = tokens[4] == "+" ? true : false;
            //l.pos = tokens[0];
            l.cigar = tokens[5];
            add_link(l.source_name, l);
        }
        else if (tokens[0] == "C"){
            contained_elem c;
            //TODO fix token indices here
            c.source_name = tokens[1];
            c.sink_name = tokens[3];
            c.source_orientation_forward = tokens[2] == "+" ? true : false;
            c.sink_orientation_forward = tokens[4] == "+" ? true : false;
            c.pos = atoi(tokens[5].c_str());
            c.cigar = tokens[6];
            add_contained(c.sink_name, c);
        }
        else if (tokens[0] == "x"){
            annotation_elem x;
            x.key = tokens[1];
            x.info = tokens[2];
        }
        else if (tokens[0] == "a"){
            annotation_elem a;
            a.key = tokens[1];
            a.info = tokens[2];
        }
        else{
            cerr << "Unknown line identifier  encountered: " << tokens[0] <<  " . Exiting." << endl;
        }

    }

    return true;

    }

    bool GFAKluge::parse_gfa_file(fstream fs){
        cerr << "Not implemented: parse_gfa_file(fstream)" << endl; exit(1);
        return true;
    }

    void GFAKluge::add_link(sequence_elem seq, link_elem link){
        seq_to_link[seq.name].push_back(link);
    }

    void GFAKluge::add_contained(sequence_elem seq, contained_elem con){
        seq_to_contained[seq.name].push_back(con);
    }

    void GFAKluge::add_link(string seq_name, link_elem link){
        seq_to_link[seq_name].push_back(link);
    }

    void GFAKluge::add_contained(string seq_name, contained_elem con){
        seq_to_contained[seq_name].push_back(con);
    }

    vector<link_elem> GFAKluge::get_links(string seq_name){
        return seq_to_link[seq_name];
    }

    vector<link_elem> GFAKluge::get_links(sequence_elem seq){
        string seq_name = seq.name;
        return seq_to_link[seq_name];
    }

    vector<contained_elem> GFAKluge::get_contained(string seq_name){
        return seq_to_contained[seq_name];
    }

    vector<contained_elem> GFAKluge::get_contained(sequence_elem seq){
        string seq_name = seq.name;
        return seq_to_contained[seq_name];
    }

    std::string GFAKluge::to_string(){
        string ret = "";
        int i;
        //First print header lines.
        if (header.size() > 0){
          map<std::string, std::string>::iterator it;
          for (it = header.begin(); it != header.end(); it++){
              ret += "H\t" + it->first + "\t" + it->second + "\n";
            }
        }
        if (name_to_seq.size() > 0){
          map<std::string, sequence_elem>::iterator st;
          for (st = name_to_seq.begin(); st != name_to_seq.end(); st++){
              ret += "S\t" + (st->second).name + "\t" + (st->second).seq + "\n";
              //TODO iterate over links
              //L    segName1,segOri1,segName2,segOri2,CIGAR      Link
              if (seq_to_links[st->first].size() > 0){
                for (i = 0; i < seq_to_links[st->first]; i++){
                    ret += "L\t" + seq_to_links[st->first].source_name + "\t" + \
                            seq_to_links[st->first].source_orientation_forward + "\t" + \
                            seq_to_links[st->first].sink_name + "\t" + \
                            seq_to_links[st->first].sink_orientation_forward + "\t" + \
                            seq_to_links[st->first].cigar + \
                            "\n";
                }

              }

              //TODO iterate over contains
              if (seq_to_contained[st->first].size() > 0){
                for (i = 0; i < seq_to_contained[st->first]; i++){
                    ret += "C\t" + seq_to_contained[st->first] + "\t" + "\n";
                }
              }
          }
        }
        //TODO iterate over annotation lines.

        //Print sequences and links in order, then annotation lines.

        return ret;
    }

    // std::ostream& operator<<(std::ostream& os, const gfak::GFAKluge& g){
    //     os << g.to_string();
    //     return os;
    // }
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2010-2012 Jeremy Lainé
 * Contact: http://code.google.com/p/qdjango/
 *
 * This file is part of the QDjango Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#include "QDjango.h"
#include "QDjango_p.h"
#include "QDjangoModel.h"
#include "QDjangoQuerySet.h"
#include "QDjangoWhere.h"

#include "tst_qdjangometamodel.h"
#include "util.h"

#define Q QDjangoWhere

template<class T>
void init(const QStringList &sql)
{
    const QDjangoMetaModel metaModel = QDjango::registerModel<T>();
    QCOMPARE(metaModel.createTableSql(), sql);
    QCOMPARE(metaModel.createTable(), true);
}

template<class T, class K>
void setAndGet(const K &value)
{
    // save object
    T v1;
    v1.setValue(value);
    QCOMPARE(v1.save(), true);
    QVERIFY(!v1.pk().isNull());

    // save again
    QCOMPARE(v1.save(), true);

    // get object
    T v2;
    QVERIFY(QDjangoQuerySet<T>().get(Q(QLatin1String("pk"), Q::Equals, v1.pk()), &v2) != 0);
    QCOMPARE(v2.value(), value);
}

template<class T>
void cleanup()
{
    const QDjangoMetaModel metaModel = QDjango::registerModel<T>();
    QCOMPARE(metaModel.dropTable(), true);
}

tst_FkConstraint::tst_FkConstraint(QObject *parent)
    : QDjangoModel(parent)
{
    setForeignKey("noConstraint", new User(this));
    setForeignKey("cascadeConstraint", new User(this));
    setForeignKey("restrictConstraint", new User(this));
    setForeignKey("nullConstraint", new User(this));
}

User *tst_FkConstraint::noConstraint() const
{
    return qobject_cast<User*>(foreignKey("noConstraint"));
}

void tst_FkConstraint::setNoConstraint(User *user)
{
    setForeignKey("noConstraint", user);
}

User *tst_FkConstraint::cascadeConstraint() const
{
    return qobject_cast<User*>(foreignKey("cascadeConstraint"));
}

void tst_FkConstraint::setCascadeConstraint(User *user)
{
    setForeignKey("cascadeConstraint", user);
}

User *tst_FkConstraint::restrictConstraint() const
{
    return qobject_cast<User*>(foreignKey("restrictConstraint"));
}

void tst_FkConstraint::setRestrictConstraint(User *user)
{
    setForeignKey("restrictConstraint", user);
}

User *tst_FkConstraint::nullConstraint() const
{
    return qobject_cast<User*>(foreignKey("nullConstraint"));
}

void tst_FkConstraint::setNullConstraint(User *user)
{
    setForeignKey("nullConstraint", user);
}

void tst_QDjangoMetaModel::initTestCase()
{
    QVERIFY(initialiseDatabase());
}

void tst_QDjangoMetaModel::testBool()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_bool\" (\"id\" serial PRIMARY KEY, \"value\" boolean NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_bool\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" bool NOT NULL)");

    init<tst_Bool>(sql);
    setAndGet<tst_Bool>(true);
    setAndGet<tst_Bool>(false);
    cleanup<tst_Bool>();
}

void tst_QDjangoMetaModel::testByteArray()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_bytearray\" (\"id\" serial PRIMARY KEY, \"value\" bytea NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_bytearray\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" blob NOT NULL)");

    init<tst_ByteArray>(sql);
    setAndGet<tst_ByteArray>(QByteArray("01234567", 8));
    setAndGet<tst_ByteArray>(QByteArray("\x00\x01\x02\x03\x04\x05\x06\x07", 8));
    cleanup<tst_ByteArray>();
}

void tst_QDjangoMetaModel::testDate()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_date\" (\"id\" serial PRIMARY KEY, \"value\" date NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_date\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" date NOT NULL)");

    init<tst_Date>(sql);
    setAndGet<tst_Date>(QDate(2012, 1, 8));
    cleanup<tst_Date>();
}

void tst_QDjangoMetaModel::testDateTime()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_datetime\" (\"id\" serial PRIMARY KEY, \"value\" timestamp NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_datetime\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" datetime NOT NULL)");

    init<tst_DateTime>(sql);
    setAndGet<tst_DateTime>(QDateTime(QDate(2012, 1, 8), QTime(3, 4, 5)));
    cleanup<tst_DateTime>();
}

void tst_QDjangoMetaModel::testDouble()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_double\" (\"id\" serial PRIMARY KEY, \"value\" real NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_double\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" real NOT NULL)");

    init<tst_Double>(sql);
    setAndGet<tst_Double>(double(3.14159));;
    cleanup<tst_Double>();
}

void tst_QDjangoMetaModel::testInteger()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_integer\" (\"id\" serial PRIMARY KEY, \"value\" integer NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_integer\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" integer NOT NULL)");

    init<tst_Integer>(sql);
    setAndGet<tst_Integer>(0);
    setAndGet<tst_Integer>(-2147483647);
    setAndGet<tst_Integer>(2147483647);
    cleanup<tst_Integer>();
}

void tst_QDjangoMetaModel::testLongLong()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_longlong\" (\"id\" serial PRIMARY KEY, \"value\" bigint NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_longlong\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" bigint NOT NULL)");

    init<tst_LongLong>(sql);
    setAndGet<tst_LongLong>(qlonglong(0));
    setAndGet<tst_LongLong>(qlonglong(-9223372036854775807ll));
    setAndGet<tst_LongLong>(qlonglong(9223372036854775807ll));
    cleanup<tst_LongLong>();
}

void tst_QDjangoMetaModel::testString()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_string\" (\"id\" serial PRIMARY KEY, \"value\" varchar(255) NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_string\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" varchar(255) NOT NULL)");

    init<tst_String>(sql);
    setAndGet<tst_String>(QLatin1String("foo bar"));
    cleanup<tst_String>();
}

void tst_QDjangoMetaModel::testTime()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_time\" (\"id\" serial PRIMARY KEY, \"value\" time NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_time\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" time NOT NULL)");

    init<tst_Time>(sql);
    setAndGet<tst_Time>(QTime(3, 4, 5));
    cleanup<tst_Time>();
}

void tst_QDjangoMetaModel::testOptions()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String(
            "CREATE TABLE \"some_table\" ("
                "\"id\" serial PRIMARY KEY, "
                "\"aField\" integer NOT NULL, "
                "\"b_field\" integer NOT NULL, "
                "\"indexField\" integer NOT NULL, "
                "\"nullField\" integer, "
                "\"uniqueField\" integer NOT NULL UNIQUE, "
                "UNIQUE (\"aField\", \"b_field\")"
            ")");
    else
        sql << QLatin1String(
            "CREATE TABLE \"some_table\" ("
                "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
                "\"aField\" integer NOT NULL, "
                "\"b_field\" integer NOT NULL, "
                "\"indexField\" integer NOT NULL, "
                "\"nullField\" integer, "
                "\"uniqueField\" integer NOT NULL UNIQUE, "
                "UNIQUE (\"aField\", \"b_field\")"
            ")");

    sql << QLatin1String("CREATE INDEX \"some_table_ac243651\" ON \"some_table\" (\"indexField\")");
    init<tst_Options>(sql);
    cleanup<tst_Options>();
}

/** Test foreign key constraint sql generation
 */
void tst_QDjangoMetaModel::testConstraints()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_fkconstraint\" ("
            "\"id\" serial PRIMARY KEY, "
            "\"noConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED, "
            "\"cascadeConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED ON DELETE CASCADE, "
            "\"restrictConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED ON DELETE RESTRICT, "
            "\"nullConstraint_id\" integer REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED ON DELETE SET NULL"
            ")");
    else
       sql << QLatin1String("CREATE TABLE \"tst_fkconstraint\" ("
            "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
            "\"noConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\"), "
            "\"cascadeConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE CASCADE, "
            "\"restrictConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE RESTRICT, "
            "\"nullConstraint_id\" integer REFERENCES \"user\" (\"id\") ON DELETE SET NULL"
            ")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_f388fc3c\" ON \"tst_fkconstraint\" (\"noConstraint_id\")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_4634d592\" ON \"tst_fkconstraint\" (\"cascadeConstraint_id\")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_728cefe1\" ON \"tst_fkconstraint\" (\"restrictConstraint_id\")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_44c71620\" ON \"tst_fkconstraint\" (\"nullConstraint_id\")");

    QDjangoMetaModel tst_ = QDjango::registerModel<tst_FkConstraint>();
    QCOMPARE(tst_.createTableSql(), sql);
}

QTEST_MAIN(tst_QDjangoMetaModel)
<commit_msg>fix unit test<commit_after>/*
 * Copyright (C) 2010-2012 Jeremy Lainé
 * Contact: http://code.google.com/p/qdjango/
 *
 * This file is part of the QDjango Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 */

#include "QDjango.h"
#include "QDjango_p.h"
#include "QDjangoModel.h"
#include "QDjangoQuerySet.h"
#include "QDjangoWhere.h"

#include "tst_qdjangometamodel.h"
#include "util.h"

#define Q QDjangoWhere

template<class T>
void init(const QStringList &sql)
{
    const QDjangoMetaModel metaModel = QDjango::registerModel<T>();
    QCOMPARE(metaModel.createTableSql(), sql);
    QCOMPARE(metaModel.createTable(), true);
}

template<class T, class K>
void setAndGet(const K &value)
{
    // save object
    T v1;
    v1.setValue(value);
    QCOMPARE(v1.save(), true);
    QVERIFY(!v1.pk().isNull());

    // save again
    QCOMPARE(v1.save(), true);

    // get object
    T v2;
    QVERIFY(QDjangoQuerySet<T>().get(Q(QLatin1String("pk"), Q::Equals, v1.pk()), &v2) != 0);
    QCOMPARE(v2.value(), value);
}

template<class T>
void cleanup()
{
    const QDjangoMetaModel metaModel = QDjango::registerModel<T>();
    QCOMPARE(metaModel.dropTable(), true);
}

tst_FkConstraint::tst_FkConstraint(QObject *parent)
    : QDjangoModel(parent)
{
    setForeignKey("noConstraint", new User(this));
    setForeignKey("cascadeConstraint", new User(this));
    setForeignKey("restrictConstraint", new User(this));
    setForeignKey("nullConstraint", new User(this));
}

User *tst_FkConstraint::noConstraint() const
{
    return qobject_cast<User*>(foreignKey("noConstraint"));
}

void tst_FkConstraint::setNoConstraint(User *user)
{
    setForeignKey("noConstraint", user);
}

User *tst_FkConstraint::cascadeConstraint() const
{
    return qobject_cast<User*>(foreignKey("cascadeConstraint"));
}

void tst_FkConstraint::setCascadeConstraint(User *user)
{
    setForeignKey("cascadeConstraint", user);
}

User *tst_FkConstraint::restrictConstraint() const
{
    return qobject_cast<User*>(foreignKey("restrictConstraint"));
}

void tst_FkConstraint::setRestrictConstraint(User *user)
{
    setForeignKey("restrictConstraint", user);
}

User *tst_FkConstraint::nullConstraint() const
{
    return qobject_cast<User*>(foreignKey("nullConstraint"));
}

void tst_FkConstraint::setNullConstraint(User *user)
{
    setForeignKey("nullConstraint", user);
}

void tst_QDjangoMetaModel::initTestCase()
{
    QVERIFY(initialiseDatabase());
}

void tst_QDjangoMetaModel::testBool()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_bool\" (\"id\" serial PRIMARY KEY, \"value\" boolean NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_bool\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" bool NOT NULL)");

    init<tst_Bool>(sql);
    setAndGet<tst_Bool>(true);
    setAndGet<tst_Bool>(false);
    cleanup<tst_Bool>();
}

void tst_QDjangoMetaModel::testByteArray()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_bytearray\" (\"id\" serial PRIMARY KEY, \"value\" bytea NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_bytearray\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" blob NOT NULL)");

    init<tst_ByteArray>(sql);
    setAndGet<tst_ByteArray>(QByteArray("01234567", 8));
    setAndGet<tst_ByteArray>(QByteArray("\x00\x01\x02\x03\x04\x05\x06\x07", 8));
    cleanup<tst_ByteArray>();
}

void tst_QDjangoMetaModel::testDate()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_date\" (\"id\" serial PRIMARY KEY, \"value\" date NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_date\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" date NOT NULL)");

    init<tst_Date>(sql);
    setAndGet<tst_Date>(QDate(2012, 1, 8));
    cleanup<tst_Date>();
}

void tst_QDjangoMetaModel::testDateTime()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_datetime\" (\"id\" serial PRIMARY KEY, \"value\" timestamp NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_datetime\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" datetime NOT NULL)");

    init<tst_DateTime>(sql);
    setAndGet<tst_DateTime>(QDateTime(QDate(2012, 1, 8), QTime(3, 4, 5)));
    cleanup<tst_DateTime>();
}

void tst_QDjangoMetaModel::testDouble()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_double\" (\"id\" serial PRIMARY KEY, \"value\" real NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_double\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" real NOT NULL)");

    init<tst_Double>(sql);
    setAndGet<tst_Double>(double(3.14159));;
    cleanup<tst_Double>();
}

void tst_QDjangoMetaModel::testInteger()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_integer\" (\"id\" serial PRIMARY KEY, \"value\" integer NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_integer\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" integer NOT NULL)");

    init<tst_Integer>(sql);
    setAndGet<tst_Integer>(0);
    setAndGet<tst_Integer>(-2147483647);
    setAndGet<tst_Integer>(2147483647);
    cleanup<tst_Integer>();
}

void tst_QDjangoMetaModel::testLongLong()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_longlong\" (\"id\" serial PRIMARY KEY, \"value\" bigint NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_longlong\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" bigint NOT NULL)");

    init<tst_LongLong>(sql);
    setAndGet<tst_LongLong>(qlonglong(0));
    setAndGet<tst_LongLong>(qlonglong(-9223372036854775807ll));
    setAndGet<tst_LongLong>(qlonglong(9223372036854775807ll));
    cleanup<tst_LongLong>();
}

void tst_QDjangoMetaModel::testString()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_string\" (\"id\" serial PRIMARY KEY, \"value\" varchar(255) NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_string\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" varchar(255) NOT NULL)");

    init<tst_String>(sql);
    setAndGet<tst_String>(QLatin1String("foo bar"));
    cleanup<tst_String>();
}

void tst_QDjangoMetaModel::testTime()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_time\" (\"id\" serial PRIMARY KEY, \"value\" time NOT NULL)");
    else
        sql << QLatin1String("CREATE TABLE \"tst_time\" (\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, \"value\" time NOT NULL)");

    init<tst_Time>(sql);
    setAndGet<tst_Time>(QTime(3, 4, 5));
    cleanup<tst_Time>();
}

void tst_QDjangoMetaModel::testOptions()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String(
            "CREATE TABLE \"some_table\" ("
                "\"id\" serial PRIMARY KEY, "
                "\"aField\" integer NOT NULL, "
                "\"b_field\" integer NOT NULL, "
                "\"indexField\" integer NOT NULL, "
                "\"nullField\" integer, "
                "\"uniqueField\" integer NOT NULL UNIQUE, "
                "UNIQUE (\"aField\", \"b_field\")"
            ")");
    else
        sql << QLatin1String(
            "CREATE TABLE \"some_table\" ("
                "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
                "\"aField\" integer NOT NULL, "
                "\"b_field\" integer NOT NULL, "
                "\"indexField\" integer NOT NULL, "
                "\"nullField\" integer, "
                "\"uniqueField\" integer NOT NULL UNIQUE, "
                "UNIQUE (\"aField\", \"b_field\")"
            ")");

    sql << QLatin1String("CREATE INDEX \"some_table_ac243651\" ON \"some_table\" (\"indexField\")");
    init<tst_Options>(sql);
    cleanup<tst_Options>();
}

/** Test foreign key constraint sql generation
 */
void tst_QDjangoMetaModel::testConstraints()
{
    QStringList sql;
    if (QDjango::database().driverName() == QLatin1String("QPSQL"))
        sql << QLatin1String("CREATE TABLE \"tst_fkconstraint\" ("
            "\"id\" serial PRIMARY KEY, "
            "\"noConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED, "
            "\"cascadeConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED ON DELETE CASCADE, "
            "\"restrictConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED ON DELETE RESTRICT, "
            "\"nullConstraint_id\" integer REFERENCES \"user\" (\"id\") DEFERRABLE INITIALLY DEFERRED ON DELETE SET NULL"
            ")");
    else
       sql << QLatin1String("CREATE TABLE \"tst_fkconstraint\" ("
            "\"id\" integer NOT NULL PRIMARY KEY AUTOINCREMENT, "
            "\"noConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\"), "
            "\"cascadeConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE CASCADE, "
            "\"restrictConstraint_id\" integer NOT NULL REFERENCES \"user\" (\"id\") ON DELETE RESTRICT, "
            "\"nullConstraint_id\" integer REFERENCES \"user\" (\"id\") ON DELETE SET NULL"
            ")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_f388fc3c\" ON \"tst_fkconstraint\" (\"noConstraint_id\")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_4634d592\" ON \"tst_fkconstraint\" (\"cascadeConstraint_id\")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_728cefe1\" ON \"tst_fkconstraint\" (\"restrictConstraint_id\")");
    sql << QLatin1String("CREATE INDEX \"tst_fkconstraint_44c71620\" ON \"tst_fkconstraint\" (\"nullConstraint_id\")");

    QDjango::registerModel<User>();
    QDjangoMetaModel metaModel = QDjango::registerModel<tst_FkConstraint>();
    QCOMPARE(metaModel.createTableSql(), sql);
}

QTEST_MAIN(tst_QDjangoMetaModel)
<|endoftext|>