<commit_before>/*
 * This program is under the GNU GPL.
 * Use at your own risk.
 *
 * written by David Bucciarelli (humanware@plus.it)
 *            Humanware s.r.l.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GL/glut.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif

#include "particles.h"
extern "C" {
#include "readtex.h"
}

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

#ifdef XMESA
#include "GL/xmesa.h"
static int fullscreen=1;
#endif

static int WIDTH=640;
static int HEIGHT=480;
static int NUMPART=7500;

#define FRAME 50

static float fogcolor[4]={1.0,1.0,1.0,1.0};

#define DIMP 40.0
#define DIMTP 32.0

static float q[4][3]={
  {-DIMP,0.0,-DIMP},
  {DIMP,0.0,-DIMP},
  {DIMP,0.0,DIMP},
  {-DIMP,0.0,DIMP}
};

static float qt[4][2]={
  {-DIMTP,-DIMTP},
  {DIMTP,-DIMTP},
  {DIMTP,DIMTP},
  {-DIMTP,DIMTP}
};

static int win=0;

static int fog=1;
static int help=1;

static GLuint groundid;

static float obs[3]={2.0,1.0,0.0};
static float dir[3];
static float v=0.0;
static float alpha=-90.0;
static float beta=90.0;

static particleSystem *ps;

static float gettime()
{
  static clock_t told=0;
  clock_t tnew,ris;

  tnew=clock();

  ris=tnew-told;

  told=tnew;

  return(ris/(float)CLOCKS_PER_SEC);
}

static float gettimerain()
{
  static clock_t told=0;
  clock_t tnew,ris;

  tnew=clock();

  ris=tnew-told;

  told=tnew;

  return(ris/(float)CLOCKS_PER_SEC);
}

static void calcposobs(void)
{
  dir[0]=sin(alpha*M_PI/180.0);
  dir[2]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  dir[1]=cos(beta*M_PI/180.0);

  obs[0]+=v*dir[0];
  obs[1]+=v*dir[1];
  obs[2]+=v*dir[2];

  rainParticle::setRainingArea(obs[0]-7.0f,-0.2f,obs[2]-7.0f,obs[0]+7.0f,8.0f,obs[2]+7.0f);
}

static void printstring(void *font, const char *string)
{
  int len,i;

  len=(int)strlen(string);
  for(i=0;i<len;i++)
    glutBitmapCharacter(font,string[i]);
}

static void reshape(int width, int height)
{
  WIDTH=width;
  HEIGHT=height;
  glViewport(0,0,(GLint)width,(GLint)height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(70.0,width/(float)height,0.1,30.0);

  glMatrixMode(GL_MODELVIEW);
}

static void printhelp(void)
{
  glEnable(GL_BLEND);
  glColor4f(0.0,0.0,0.0,0.5);
  glRecti(40,40,600,440);
  glDisable(GL_BLEND);

  glColor3f(1.0,0.0,0.0);
  glRasterPos2i(300,420);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help");

  glRasterPos2i(60,390);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Toggle Help");

  glRasterPos2i(60,360);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Toggle Fog");
  glRasterPos2i(60,330);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate");
  glRasterPos2i(60,300);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity");
  glRasterPos2i(60,270);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity");
  glRasterPos2i(60,240);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"l - Increase rain length");
  glRasterPos2i(60,210);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"k - Increase rain length");
}

static void drawrain(void)
{
  static int count=0;
  static char frbuf[80];
  float fr;

  glEnable(GL_DEPTH_TEST);

  if(fog)
    glEnable(GL_FOG);
  else
    glDisable(GL_FOG);

  glDepthMask(GL_TRUE);
  glClearColor(1.0,1.0,1.0,1.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  glPushMatrix();
  calcposobs();
  gluLookAt(obs[0],obs[1],obs[2],
	    obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
	    0.0,1.0,0.0);

  glColor4f(1.0,1.0,1.0,1.0);

  glEnable(GL_TEXTURE_2D);

  glBindTexture(GL_TEXTURE_2D,groundid);
  glBegin(GL_QUADS);
  glTexCoord2fv(qt[0]);
  glVertex3fv(q[0]);
  glTexCoord2fv(qt[1]);
  glVertex3fv(q[1]);
  glTexCoord2fv(qt[2]);
  glVertex3fv(q[2]);
  glTexCoord2fv(qt[3]);
  glVertex3fv(q[3]);
  glEnd();

  // Particle System

  glDisable(GL_TEXTURE_2D);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_BLEND);

  ps->draw();
  ps->addTime(gettimerain());

  glShadeModel(GL_FLAT);

  if((count % FRAME)==0) {
    fr=gettime();
    sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  }

  glDisable(GL_TEXTURE_2D);
  glDisable(GL_DEPTH_TEST);
  glDisable(GL_FOG);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glColor3f(1.0,0.0,0.0);
  glRasterPos2i(10,10);
  printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  glRasterPos2i(350,470);
  printstring(GLUT_BITMAP_HELVETICA_10,"Rain V1.0 Written by David Bucciarelli (humanware@plus.it)");

  if(help)
    printhelp();

  reshape(WIDTH,HEIGHT);
  glPopMatrix();

  glutSwapBuffers();

  count++;
}

static void special(int key, int x, int y)
{
  switch (key) {
  case GLUT_KEY_LEFT:
    alpha+=2.0;
    break;
  case GLUT_KEY_RIGHT:
    alpha-=2.0;
    break;
  case GLUT_KEY_DOWN:
    beta-=2.0;
    break;
  case GLUT_KEY_UP:
    beta+=2.0;
    break;
  }
}

static void key(unsigned char key, int x, int y)
{
  switch (key) {
  case 27:
    exit(0);
    break;

  case 'a':
    v+=0.01;
    break;
  case 'z':
    v-=0.01;
    break;

  case 'l':
    rainParticle::setLength(rainParticle::getLength()+0.025f);
    break;
  case 'k':
    rainParticle::setLength(rainParticle::getLength()-0.025f);
    break;

  case 'h':
    help=(!help);
    break;
  case 'f':
    fog=(!fog);
    break;
#ifdef XMESA
  case ' ':
    XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
    fullscreen=(!fullscreen);
    break;
#endif
  }
}

static void inittextures(void)
{
  GLubyte *img;
  GLint width,height;
  GLenum format;
  GLenum gluerr;

  glGenTextures(1,&groundid);
  glBindTexture(GL_TEXTURE_2D,groundid);

  if(!(img=LoadRGBImage("../images/s128.rgb",&width,&height,&format))){
  	fprintf(stderr,"Error reading a texture.\n");
  	exit(-1);
  }
  glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  if((gluerr=(GLenum)gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGB,
			       GL_UNSIGNED_BYTE, (GLvoid *)(img)))) {
    fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
    exit(-1);
  }

  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
}

static void initparticle(void)
{
  ps=new particleSystem;

  rainParticle::setRainingArea(-7.0f,-0.2f,-7.0f,7.0f,8.0f,7.0f);

  for(int i=0;i<NUMPART;i++) {
    rainParticle *p=new rainParticle;
    p->randomHeight();

    ps->addParticle((particle *)p);
  }
}

int main(int ac,char **av)
{
  fprintf(stderr,"Rain V1.0\nWritten by David Bucciarelli (humanware@plus.it)\n");

  /* Default settings */

  WIDTH=640;
  HEIGHT=480;

  glutInitWindowPosition(0,0);
  glutInitWindowSize(WIDTH,HEIGHT);
  glutInit(&ac,av);

  glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);

  if(!(win=glutCreateWindow("Rain"))) {
    fprintf(stderr,"Error opening a window.\n");
    exit(-1);
  }

  reshape(WIDTH,HEIGHT);

  inittextures();

  glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);

  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

  glEnable(GL_FOG);
  glFogi(GL_FOG_MODE,GL_EXP);
  glFogfv(GL_FOG_COLOR,fogcolor);
  glFogf(GL_FOG_DENSITY,0.1);
#ifdef FX
  glHint(GL_FOG_HINT,GL_NICEST);
#endif

  initparticle();

  glutKeyboardFunc(key);
  glutSpecialFunc(special);
  glutDisplayFunc(drawrain);
  glutIdleFunc(drawrain);
  glutReshapeFunc(reshape);
  glutMainLoop();

  return(0);
}
<commit_msg>progs/demos: Fix the progs/demos/rain help text<commit_after>/*
 * This program is under the GNU GPL.
 * Use at your own risk.
 *
 * written by David Bucciarelli (humanware@plus.it)
 *            Humanware s.r.l.
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>
#include <GL/glut.h>
#ifndef M_PI
#define M_PI 3.14159265
#endif

#include "particles.h"
extern "C" {
#include "readtex.h"
}

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

#ifdef XMESA
#include "GL/xmesa.h"
static int fullscreen=1;
#endif

static int WIDTH=640;
static int HEIGHT=480;
static int NUMPART=7500;

#define FRAME 50

static float fogcolor[4]={1.0,1.0,1.0,1.0};

#define DIMP 40.0
#define DIMTP 32.0

static float q[4][3]={
  {-DIMP,0.0,-DIMP},
  {DIMP,0.0,-DIMP},
  {DIMP,0.0,DIMP},
  {-DIMP,0.0,DIMP}
};

static float qt[4][2]={
  {-DIMTP,-DIMTP},
  {DIMTP,-DIMTP},
  {DIMTP,DIMTP},
  {-DIMTP,DIMTP}
};

static int win=0;

static int fog=1;
static int help=1;

static GLuint groundid;

static float obs[3]={2.0,1.0,0.0};
static float dir[3];
static float v=0.0;
static float alpha=-90.0;
static float beta=90.0;

static particleSystem *ps;

static float gettime()
{
  static clock_t told=0;
  clock_t tnew,ris;

  tnew=clock();

  ris=tnew-told;

  told=tnew;

  return(ris/(float)CLOCKS_PER_SEC);
}

static float gettimerain()
{
  static clock_t told=0;
  clock_t tnew,ris;

  tnew=clock();

  ris=tnew-told;

  told=tnew;

  return(ris/(float)CLOCKS_PER_SEC);
}

static void calcposobs(void)
{
  dir[0]=sin(alpha*M_PI/180.0);
  dir[2]=cos(alpha*M_PI/180.0)*sin(beta*M_PI/180.0);
  dir[1]=cos(beta*M_PI/180.0);

  obs[0]+=v*dir[0];
  obs[1]+=v*dir[1];
  obs[2]+=v*dir[2];

  rainParticle::setRainingArea(obs[0]-7.0f,-0.2f,obs[2]-7.0f,obs[0]+7.0f,8.0f,obs[2]+7.0f);
}

static void printstring(void *font, const char *string)
{
  int len,i;

  len=(int)strlen(string);
  for(i=0;i<len;i++)
    glutBitmapCharacter(font,string[i]);
}

static void reshape(int width, int height)
{
  WIDTH=width;
  HEIGHT=height;
  glViewport(0,0,(GLint)width,(GLint)height);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluPerspective(70.0,width/(float)height,0.1,30.0);

  glMatrixMode(GL_MODELVIEW);
}

static void printhelp(void)
{
  glEnable(GL_BLEND);
  glColor4f(0.0,0.0,0.0,0.5);
  glRecti(40,40,600,440);
  glDisable(GL_BLEND);

  glColor3f(1.0,0.0,0.0);
  glRasterPos2i(300,420);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Help");

  glRasterPos2i(60,390);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"h - Toggle Help");

  glRasterPos2i(60,360);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"f - Toggle Fog");
  glRasterPos2i(60,330);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"Arrow Keys - Rotate");
  glRasterPos2i(60,300);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"a - Increase velocity");
  glRasterPos2i(60,270);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"z - Decrease velocity");
  glRasterPos2i(60,240);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"l - Increase rain length");
  glRasterPos2i(60,210);
  printstring(GLUT_BITMAP_TIMES_ROMAN_24,"k - Decrease rain length");
}

static void drawrain(void)
{
  static int count=0;
  static char frbuf[80];
  float fr;

  glEnable(GL_DEPTH_TEST);

  if(fog)
    glEnable(GL_FOG);
  else
    glDisable(GL_FOG);

  glDepthMask(GL_TRUE);
  glClearColor(1.0,1.0,1.0,1.0);
  glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

  glPushMatrix();
  calcposobs();
  gluLookAt(obs[0],obs[1],obs[2],
	    obs[0]+dir[0],obs[1]+dir[1],obs[2]+dir[2],
	    0.0,1.0,0.0);

  glColor4f(1.0,1.0,1.0,1.0);

  glEnable(GL_TEXTURE_2D);

  glBindTexture(GL_TEXTURE_2D,groundid);
  glBegin(GL_QUADS);
  glTexCoord2fv(qt[0]);
  glVertex3fv(q[0]);
  glTexCoord2fv(qt[1]);
  glVertex3fv(q[1]);
  glTexCoord2fv(qt[2]);
  glVertex3fv(q[2]);
  glTexCoord2fv(qt[3]);
  glVertex3fv(q[3]);
  glEnd();

  // Particle System

  glDisable(GL_TEXTURE_2D);
  glShadeModel(GL_SMOOTH);
  glEnable(GL_BLEND);

  ps->draw();
  ps->addTime(gettimerain());

  glShadeModel(GL_FLAT);

  if((count % FRAME)==0) {
    fr=gettime();
    sprintf(frbuf,"Frame rate: %f",FRAME/fr);
  }

  glDisable(GL_TEXTURE_2D);
  glDisable(GL_DEPTH_TEST);
  glDisable(GL_FOG);

  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  glOrtho(-0.5,639.5,-0.5,479.5,-1.0,1.0);
  glMatrixMode(GL_MODELVIEW);
  glLoadIdentity();

  glColor3f(1.0,0.0,0.0);
  glRasterPos2i(10,10);
  printstring(GLUT_BITMAP_HELVETICA_18,frbuf);
  glRasterPos2i(350,470);
  printstring(GLUT_BITMAP_HELVETICA_10,"Rain V1.0 Written by David Bucciarelli (humanware@plus.it)");

  if(help)
    printhelp();

  reshape(WIDTH,HEIGHT);
  glPopMatrix();

  glutSwapBuffers();

  count++;
}

static void special(int key, int x, int y)
{
  switch (key) {
  case GLUT_KEY_LEFT:
    alpha+=2.0;
    break;
  case GLUT_KEY_RIGHT:
    alpha-=2.0;
    break;
  case GLUT_KEY_DOWN:
    beta-=2.0;
    break;
  case GLUT_KEY_UP:
    beta+=2.0;
    break;
  }
}

static void key(unsigned char key, int x, int y)
{
  switch (key) {
  case 27:
    exit(0);
    break;

  case 'a':
    v+=0.01;
    break;
  case 'z':
    v-=0.01;
    break;

  case 'l':
    rainParticle::setLength(rainParticle::getLength()+0.025f);
    break;
  case 'k':
    rainParticle::setLength(rainParticle::getLength()-0.025f);
    break;

  case 'h':
    help=(!help);
    break;
  case 'f':
    fog=(!fog);
    break;
#ifdef XMESA
  case ' ':
    XMesaSetFXmode(fullscreen ? XMESA_FX_FULLSCREEN : XMESA_FX_WINDOW);
    fullscreen=(!fullscreen);
    break;
#endif
  }
}

static void inittextures(void)
{
  GLubyte *img;
  GLint width,height;
  GLenum format;
  GLenum gluerr;

  glGenTextures(1,&groundid);
  glBindTexture(GL_TEXTURE_2D,groundid);

  if(!(img=LoadRGBImage("../images/s128.rgb",&width,&height,&format))){
  	fprintf(stderr,"Error reading a texture.\n");
  	exit(-1);
  }
  glPixelStorei(GL_UNPACK_ALIGNMENT,4);
  if((gluerr=(GLenum)gluBuild2DMipmaps(GL_TEXTURE_2D, 3, width, height,GL_RGB,
			       GL_UNSIGNED_BYTE, (GLvoid *)(img)))) {
    fprintf(stderr,"GLULib%s\n",gluErrorString(gluerr));
    exit(-1);
  }

  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_REPEAT);
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_REPEAT);

  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_LINEAR);
  glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);

  glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);
}

static void initparticle(void)
{
  ps=new particleSystem;

  rainParticle::setRainingArea(-7.0f,-0.2f,-7.0f,7.0f,8.0f,7.0f);

  for(int i=0;i<NUMPART;i++) {
    rainParticle *p=new rainParticle;
    p->randomHeight();

    ps->addParticle((particle *)p);
  }
}

int main(int ac,char **av)
{
  fprintf(stderr,"Rain V1.0\nWritten by David Bucciarelli (humanware@plus.it)\n");

  /* Default settings */

  WIDTH=640;
  HEIGHT=480;

  glutInitWindowPosition(0,0);
  glutInitWindowSize(WIDTH,HEIGHT);
  glutInit(&ac,av);

  glutInitDisplayMode(GLUT_RGB|GLUT_DEPTH|GLUT_DOUBLE);

  if(!(win=glutCreateWindow("Rain"))) {
    fprintf(stderr,"Error opening a window.\n");
    exit(-1);
  }

  reshape(WIDTH,HEIGHT);

  inittextures();

  glShadeModel(GL_FLAT);
  glEnable(GL_DEPTH_TEST);

  glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

  glEnable(GL_FOG);
  glFogi(GL_FOG_MODE,GL_EXP);
  glFogfv(GL_FOG_COLOR,fogcolor);
  glFogf(GL_FOG_DENSITY,0.1);
#ifdef FX
  glHint(GL_FOG_HINT,GL_NICEST);
#endif

  initparticle();

  glutKeyboardFunc(key);
  glutSpecialFunc(special);
  glutDisplayFunc(drawrain);
  glutIdleFunc(drawrain);
  glutReshapeFunc(reshape);
  glutMainLoop();

  return(0);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: cupsmgr.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: hr $ $Date: 2004-09-08 15:51:21 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _PSPRINT_CUPSMGR_HXX_
#define _PSPRINT_CUPSMGR_HXX_

#include <psprint/printerinfomanager.hxx>
#include <osl/module.h>
#include <osl/thread.h>
#include <osl/mutex.hxx>

namespace psp
{

class CUPSWrapper;
class PPDParser;

struct FPtrHash
{
    size_t operator()(const FILE* pPtr) const
    { return (size_t)pPtr; }
};

class CUPSManager : public PrinterInfoManager
{
    CUPSWrapper*                                                m_pCUPSWrapper;
    std::hash_map< FILE*, rtl::OString, FPtrHash >              m_aSpoolFiles;
    int                                                         m_nDests;
    void*                                                       m_pDests;
    bool                                                        m_bNewDests;
    std::hash_map< rtl::OUString, int, rtl::OUStringHash >      m_aCUPSDestMap;

    std::hash_map< rtl::OUString, PPDContext, rtl::OUStringHash > m_aDefaultContexts;

    rtl::OString                                                m_aUser;
    // this is a security risk, but the CUPS API demands
    // to deliver a pointer to a static buffer containing
    // the password, so this cannot be helped
    rtl::OString                                                m_aPassword;

    osl::Mutex                                                  m_aCUPSMutex;
    oslThread                                                   m_aDestThread;

    CUPSManager( CUPSWrapper* );
    virtual ~CUPSManager();

    virtual void initialize();

    void runDests();
    static void runDestThread(void* pMgr);
public:

    static CUPSManager* tryLoadCUPS();

    const PPDParser* createCUPSParser( const rtl::OUString& rPrinter );
    // wraps cupsGetPPD, so unlink after use !

    const char* authenticateUser( const char* );

    virtual FILE* startSpool( const rtl::OUString& rPrinterName );
    virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile );
    virtual void setupJobContextData( JobData& rData );

    // changes the info about a named printer
    virtual void changePrinterInfo( const ::rtl::OUString& rPrinter, const PrinterInfo& rNewInfo );

    // check if the printer configuration has changed
    virtual bool checkPrintersChanged();

    // members for administration (->padmin)
    // disable for CUPS
    virtual bool addPrinter( const rtl::OUString& rPrinterName, const ::rtl::OUString& rDriverName );
    virtual bool removePrinter( const rtl::OUString& rPrinterName, bool bCheckOnly = false );
    virtual bool writePrinterConfig();
    virtual bool setDefaultPrinter( const rtl::OUString& rPrinterName );
};

} // namespace psp

#endif
<commit_msg>INTEGRATION: CWS vcl28 (1.4.4); FILE MERGED 2004/10/07 16:31:25 pl 1.4.4.1: #i34799# make CUPSManager fall back to PrinterInfoManager as long as no dests are delivered<commit_after>/*************************************************************************
 *
 *  $RCSfile: cupsmgr.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: hr $ $Date: 2004-11-09 16:35:33 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _PSPRINT_CUPSMGR_HXX_
#define _PSPRINT_CUPSMGR_HXX_

#include <psprint/printerinfomanager.hxx>
#include <osl/module.h>
#include <osl/thread.h>
#include <osl/mutex.hxx>

namespace psp
{

class CUPSWrapper;
class PPDParser;

struct FPtrHash
{
    size_t operator()(const FILE* pPtr) const
    { return (size_t)pPtr; }
};

class CUPSManager : public PrinterInfoManager
{
    CUPSWrapper*                                                m_pCUPSWrapper;
    std::hash_map< FILE*, rtl::OString, FPtrHash >              m_aSpoolFiles;
    int                                                         m_nDests;
    void*                                                       m_pDests;
    bool                                                        m_bNewDests;
    std::hash_map< rtl::OUString, int, rtl::OUStringHash >      m_aCUPSDestMap;

    std::hash_map< rtl::OUString, PPDContext, rtl::OUStringHash > m_aDefaultContexts;

    rtl::OString                                                m_aUser;
    // this is a security risk, but the CUPS API demands
    // to deliver a pointer to a static buffer containing
    // the password, so this cannot be helped
    rtl::OString                                                m_aPassword;

    osl::Mutex                                                  m_aCUPSMutex;
    oslThread                                                   m_aDestThread;

    CUPSManager( CUPSWrapper* );
    virtual ~CUPSManager();

    virtual void initialize();

    void runDests();
    static void runDestThread(void* pMgr);
public:

    static CUPSManager* tryLoadCUPS();

    const PPDParser* createCUPSParser( const rtl::OUString& rPrinter );
    // wraps cupsGetPPD, so unlink after use !

    const char* authenticateUser( const char* );

    virtual FILE* startSpool( const rtl::OUString& rPrinterName );
    virtual int endSpool( const rtl::OUString& rPrinterName, const rtl::OUString& rJobTitle, FILE* pFile );
    virtual void setupJobContextData( JobData& rData );

    // changes the info about a named printer
    virtual void changePrinterInfo( const ::rtl::OUString& rPrinter, const PrinterInfo& rNewInfo );

    // check if the printer configuration has changed
    virtual bool checkPrintersChanged();

    // members for administration (->padmin)
    // disable for CUPS
    virtual bool addPrinter( const rtl::OUString& rPrinterName, const ::rtl::OUString& rDriverName );
    virtual bool removePrinter( const rtl::OUString& rPrinterName, bool bCheckOnly = false );
    virtual bool writePrinterConfig();
    virtual bool setDefaultPrinter( const rtl::OUString& rPrinterName );

    virtual bool addOrRemovePossible() const;
};

} // namespace psp

#endif
<|endoftext|>


<commit_before>#include <Internal/FluidManagerImpl.hpp>
#include <Internal/PhysicsModuleImplementation.hpp>
namespace DoremiEngine
{
    namespace Physics
    {
        FluidManagerImpl::FluidManagerImpl(InternalPhysicsUtils& p_utils) : m_utils(p_utils) {}
        FluidManagerImpl::~FluidManagerImpl() {}

        void FluidManagerImpl::CreateFluid(int p_id)
        {
            float maxParticles = 100;
            bool perParticleRestOffset = false;

            // Create the particle systen
            PxParticleSystem* particleSystem = m_utils.m_physics->createParticleSystem(maxParticles, perParticleRestOffset);

            // Add particle system to the world
            if(particleSystem)
            {
                m_utils.m_worldScene->addActor(*particleSystem);
            }
        }
        void FluidManagerImpl::CreateFluidParticles(int p_id, vector<XMFLOAT3>& p_positions, vector<XMFLOAT3>& p_velocities, vector<int32_t>& p_indices)
        {
            // Cast XMFLOAT3s into something that PhysX likes. Possible since the data of the types are identical. Thanks, Bolt!
            PxVec3* positions = reinterpret_cast<PxVec3*>(&p_positions[0]);
            PxVec3* velocities = reinterpret_cast<PxVec3*>(&p_velocities[0]);
            PxU32* indices = reinterpret_cast<PxU32*>(&p_indices[0]);
            // Create the data for the particles
            PxParticleCreationData particleData;
            particleData.positionBuffer = PxStrideIterator<const PxVec3>(positions);
            particleData.velocityBuffer = PxStrideIterator<const PxVec3>(velocities);
            particleData.indexBuffer = PxStrideIterator<const PxU32>(indices);
            // Check that the data is valid
            if(particleData.isValid())
            {
                // Create the particles
                m_fluids[p_id]->createParticles(particleData);
            }
            else
            {
                // Shit went wrong! Handle somehow?
            }
        }

        vector<XMFLOAT3> FluidManagerImpl::GetParticlePositions(int p_id)
        {
            PxParticleFluidReadData* readData = m_fluids[p_id]->lockParticleFluidReadData();
            return vector<XMFLOAT3>();
        }
    }
}<commit_msg>FluidManager: implementet method to get positions<commit_after>#include <Internal/FluidManagerImpl.hpp>
#include <Internal/PhysicsModuleImplementation.hpp>
namespace DoremiEngine
{
    namespace Physics
    {
        FluidManagerImpl::FluidManagerImpl(InternalPhysicsUtils& p_utils) : m_utils(p_utils) {}
        FluidManagerImpl::~FluidManagerImpl() {}

        void FluidManagerImpl::CreateFluid(int p_id)
        {
            float maxParticles = 100;
            bool perParticleRestOffset = false;

            // Create the particle systen
            PxParticleSystem* particleSystem = m_utils.m_physics->createParticleSystem(maxParticles, perParticleRestOffset);

            // Add particle system to the world
            if(particleSystem)
            {
                m_utils.m_worldScene->addActor(*particleSystem);
            }
        }
        void FluidManagerImpl::CreateFluidParticles(int p_id, vector<XMFLOAT3>& p_positions, vector<XMFLOAT3>& p_velocities, vector<int32_t>& p_indices)
        {
            // Cast XMFLOAT3s into something that PhysX likes. Possible since the data of the types are identical. Thanks, Bolt!
            PxVec3* positions = reinterpret_cast<PxVec3*>(&p_positions[0]);
            PxVec3* velocities = reinterpret_cast<PxVec3*>(&p_velocities[0]);
            PxU32* indices = reinterpret_cast<PxU32*>(&p_indices[0]);
            // Create the data for the particles
            PxParticleCreationData particleData;
            particleData.positionBuffer = PxStrideIterator<const PxVec3>(positions);
            particleData.velocityBuffer = PxStrideIterator<const PxVec3>(velocities);
            particleData.indexBuffer = PxStrideIterator<const PxU32>(indices);
            // Check that the data is valid
            if(particleData.isValid())
            {
                // Create the particles
                m_fluids[p_id]->createParticles(particleData);
            }
            else
            {
                // Shit went wrong! Handle somehow?
            }
        }

        vector<XMFLOAT3> FluidManagerImpl::GetParticlePositions(int p_id)
        {
            PxParticleFluidReadData* readData = m_fluids[p_id]->lockParticleFluidReadData();
            PxStrideIterator<const PxVec3> positions = readData->positionBuffer;
            const XMFLOAT3* positionsXM = reinterpret_cast<const XMFLOAT3*>(positions.ptr());
            int numParticles = readData->nbValidParticles;
            vector<const XMFLOAT3> positionsXMVector;
            positionsXMVector.reserve(numParticles);
            positionsXMVector.data = positionsXMVector;
        }
    }
}<|endoftext|>


<commit_before>/*  \brief Utility Functions for Transforming Data in accordance with BSZ Requirements
 *  \copyright 2018,2019 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <set>
#include "StlHelpers.h"
#include "BSZTransform.h"
#include "Downloader.h"
#include "FileUtil.h"
#include "MapUtil.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "UrlUtil.h"
#include "util.h"

namespace BSZTransform {

void LoadISSNToPPNMap(std::unordered_map<std::string, PPNandTitle> * const ISSN_to_superior_ppn_map) {
     enum ISSN_TO_PPN_OFFSET {ISSN_OFFSET = 0, PPN_OFFSET = 1, TITLE_OFFSET = 4};
     std::vector<std::vector<std::string>> parsed_issn_to_superior_content;
     TextUtil::ParseCSVFileOrDie(ISSN_TO_MISC_BITS_MAP_PATH_LOCAL, &parsed_issn_to_superior_content, ',', (char) 0x00);
     for (const auto parsed_line : parsed_issn_to_superior_content) {
         const std::string ISSN(parsed_line[ISSN_OFFSET]);
         const std::string PPN(parsed_line[PPN_OFFSET]);
         const std::string title(StringUtil::RightTrim(" \t", parsed_line[TITLE_OFFSET]));
         ISSN_to_superior_ppn_map->emplace(ISSN, PPNandTitle(PPN, title));
     }
}

AugmentMaps::AugmentMaps(const std::string &map_directory_path) {
    MapUtil::DeserialiseMap(map_directory_path + "language_to_language_code.map", &language_to_language_code_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_language_code.map", &ISSN_to_language_code_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_licence.map", &ISSN_to_licence_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_keyword_field.map", &ISSN_to_keyword_field_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_volume.map", &ISSN_to_volume_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_SSG.map", &ISSN_to_SSG_map_);
    LoadISSNToPPNMap(&ISSN_to_superior_ppn_and_title_map_);
}

// "author" must be in the lastname,firstname format. Returns the empty string if no PPN was found.
std::string DownloadAuthorPPN(const std::string &author, const std::string &author_lookup_base_url) {
    const std::string LOOKUP_URL(author_lookup_base_url + UrlUtil::UrlEncode(author));
    static std::unordered_map<std::string, std::string> url_to_lookup_result_cache;
    const auto url_and_lookup_result(url_to_lookup_result_cache.find(LOOKUP_URL));
    if (url_and_lookup_result == url_to_lookup_result_cache.end()) {
        static RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("PPN.*
([0-9X]+)"));
        Downloader downloader(LOOKUP_URL);
        if (downloader.anErrorOccurred())
            LOG_WARNING("couldn't download author PPN! downloader error: " + downloader.getLastErrorMessage());
        else if (matcher->matched(downloader.getMessageBody())) {
            url_to_lookup_result_cache.emplace(LOOKUP_URL, (*matcher)[1]);
            return (*matcher)[1];
        } else
            url_to_lookup_result_cache.emplace(LOOKUP_URL, "");
    } else
        return url_and_lookup_result->second;
    return "";
}

BSZTransform::BSZTransform(const std::string &map_directory_path): augment_maps_(AugmentMaps(map_directory_path)) {}
BSZTransform::BSZTransform(const AugmentMaps &augment_maps): augment_maps_(augment_maps) {}

void BSZTransform::DetermineKeywordOutputFieldFromISSN(const std::string &issn, std::string * const tag, char * const subfield) {
    if (not issn.empty()) {
        const auto issn_and_field_tag_and_subfield_code(augment_maps_.ISSN_to_keyword_field_map_.find(issn));
        if (issn_and_field_tag_and_subfield_code != augment_maps_.ISSN_to_keyword_field_map_.end()) {
            if (unlikely(issn_and_field_tag_and_subfield_code->second.length() != 3 + 1))
                LOG_ERROR("\"" + issn_and_field_tag_and_subfield_code->second
                          + "\" is not a valid MARC tag + subfield code! (Error in \"ISSN_to_keyword_field.map\"!)");
            *tag = issn_and_field_tag_and_subfield_code->second.substr(0, 3);
            *subfield = issn_and_field_tag_and_subfield_code->second[3];
            return;
        }
    }
    *tag = "650";
    *subfield = 'a';
}

void ParseAuthor(const std::string &author, std::string * const first_name, std::string * const last_name) {
    const auto normalised_author(TextUtil::CollapseAndTrimWhitespace(author));
    const auto name_separator(normalised_author.rfind(' '));
    if (name_separator != std::string::npos) {
        *first_name = normalised_author.substr(0, name_separator);
        *last_name = normalised_author.substr(name_separator + 1);
    } else {
        *first_name = normalised_author;
        last_name->clear();
    }
}

bool FilterEmptyAndCommentLines(std::string str) {
    StringUtil::TrimWhite(&str);
    return not str.empty() and str.front() != '#';
}

void StripBlacklistedTokensFromAuthorName(std::string * const first_name, std::string * const last_name) {
    static std::unique_ptr<RegexMatcher> matcher;
    if (matcher == nullptr) {
        std::unordered_set<std::string> blacklisted_tokens, filtered_blacklisted_tokens;
        auto string_data(FileUtil::ReadStringOrDie(AUTHOR_NAME_BLACKLIST));
        StringUtil::Split(string_data, '\n', &blacklisted_tokens, /* suppress_empty_components = */true);

        StlHelpers::Functional::Filter(blacklisted_tokens.begin(), blacklisted_tokens.end(), filtered_blacklisted_tokens,
                                       FilterEmptyAndCommentLines);

        std::string match_regex("\\b(");
        for (auto blacklisted_token : filtered_blacklisted_tokens) {
            // escape backslashes first to keep from overwriting other escape sequences
            blacklisted_token = StringUtil::ReplaceString("\\", "\\\\", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString("(", "\\(", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString(")", "\\)", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString(".", "\\.", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString("/", "\\/", blacklisted_token);

            match_regex += blacklisted_token + "|";
        }
        match_regex += ")\\b";

        matcher.reset(RegexMatcher::RegexMatcherFactoryOrDie(match_regex, RegexMatcher::ENABLE_UTF8));
    }

    std::string first_name_buffer(matcher->replaceAll(*first_name, "")), last_name_buffer(matcher->replaceAll(*last_name, ""));
    StringUtil::TrimWhite(&first_name_buffer);
    StringUtil::TrimWhite(&last_name_buffer);

    *first_name = first_name_buffer;
    *last_name = last_name_buffer;
}

bool IsAuthorNameTokenTitle(std::string token) {
    static const std::unordered_set<std::string> VALID_TITLES {
        "jr", "sr", "sj", "s.j", "fr", "hr", "dr", "prof", "em"
    };

    bool final_period(token.back() == '.');
    if (final_period)
        token.erase(token.size() - 1);

    TextUtil::UTF8ToLower(&token);
    return VALID_TITLES.find(token) != VALID_TITLES.end();
}

bool IsAuthorNameTokenAffix(std::string token) {
    static const std::unordered_set<std::string> VALID_AFFIXES {
        "i", "ii", "iii", "iv", "v"
    };

    TextUtil::UTF8ToLower(&token);
    return VALID_AFFIXES.find(token) != VALID_AFFIXES.end();
}

void PostProcessAuthorName(std::string * const first_name, std::string * const last_name, std::string * const title,
                           std::string * const affix)
{
    std::string first_name_buffer, last_name_buffer, title_buffer, affix_buffer;
    std::vector<std::string> tokens;

    StringUtil::Split(*first_name, ' ', &tokens);
    for (const auto &token : tokens) {
        if (IsAuthorNameTokenTitle(token))
            title_buffer += token + " ";
        else
            first_name_buffer += token + " ";
    }

    StringUtil::Split(*last_name, ' ', &tokens);
    for (const auto &token : tokens) {
        if (IsAuthorNameTokenTitle(token))
            title_buffer += token + " ";
        else if (IsAuthorNameTokenAffix(token))
            affix_buffer += token + " ";
        else
            last_name_buffer += token + " ";
    }

    TextUtil::CollapseAndTrimWhitespace(&first_name_buffer);
    TextUtil::CollapseAndTrimWhitespace(&last_name_buffer);
    TextUtil::CollapseAndTrimWhitespace(&title_buffer);
    TextUtil::CollapseAndTrimWhitespace(&affix_buffer);

    StripBlacklistedTokensFromAuthorName(&first_name_buffer, &last_name_buffer);

    *title = title_buffer;
    *affix = affix_buffer;
    // try to reparse the name if either part of the name is empty
    if (first_name_buffer.empty())
        ParseAuthor(last_name_buffer, first_name, last_name);
    else if (last_name_buffer.empty())
        ParseAuthor(first_name_buffer, first_name, last_name);
    else if (not first_name_buffer.empty() and not last_name_buffer.empty()) {
        *first_name = first_name_buffer;
        *last_name = last_name_buffer;
    }

    LOG_DEBUG("post-processed author first name = '" + *first_name + "', last name = '" + *last_name +
              "', title = '" + *title + "', affix = '" + *affix + "'");
}

} // end namespace BSZTransform
<commit_msg>Minor changes<commit_after>/*  \brief Utility Functions for Transforming Data in accordance with BSZ Requirements
 *  \copyright 2018,2019 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include <set>
#include "StlHelpers.h"
#include "BSZTransform.h"
#include "Downloader.h"
#include "FileUtil.h"
#include "MapUtil.h"
#include "RegexMatcher.h"
#include "StringUtil.h"
#include "UrlUtil.h"
#include "util.h"

namespace BSZTransform {

void LoadISSNToPPNMap(std::unordered_map<std::string, PPNandTitle> * const ISSN_to_superior_ppn_map) {
     enum ISSN_TO_PPN_OFFSET {ISSN_OFFSET = 0, PPN_OFFSET = 1, TITLE_OFFSET = 4};
     std::vector<std::vector<std::string>> parsed_issn_to_superior_content;
     TextUtil::ParseCSVFileOrDie(ISSN_TO_MISC_BITS_MAP_PATH_LOCAL, &parsed_issn_to_superior_content, ',', (char) 0x00);
     for (const auto parsed_line : parsed_issn_to_superior_content) {
         const std::string ISSN(parsed_line[ISSN_OFFSET]);
         const std::string PPN(parsed_line[PPN_OFFSET]);
         const std::string title(StringUtil::RightTrim(" \t", parsed_line[TITLE_OFFSET]));
         ISSN_to_superior_ppn_map->emplace(ISSN, PPNandTitle(PPN, title));
     }
}

AugmentMaps::AugmentMaps(const std::string &map_directory_path) {
    MapUtil::DeserialiseMap(map_directory_path + "language_to_language_code.map", &language_to_language_code_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_language_code.map", &ISSN_to_language_code_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_licence.map", &ISSN_to_licence_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_keyword_field.map", &ISSN_to_keyword_field_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_volume.map", &ISSN_to_volume_map_);
    MapUtil::DeserialiseMap(map_directory_path + "ISSN_to_SSG.map", &ISSN_to_SSG_map_);
    LoadISSNToPPNMap(&ISSN_to_superior_ppn_and_title_map_);
}

// "author" must be in the lastname,firstname format. Returns the empty string if no PPN was found.
std::string DownloadAuthorPPN(const std::string &author, const std::string &author_lookup_base_url) {
    const std::string LOOKUP_URL(author_lookup_base_url + UrlUtil::UrlEncode(author));
    static std::unordered_map<std::string, std::string> url_to_lookup_result_cache;
    const auto url_and_lookup_result(url_to_lookup_result_cache.find(LOOKUP_URL));
    if (url_and_lookup_result == url_to_lookup_result_cache.end()) {
        static RegexMatcher * const matcher(RegexMatcher::RegexMatcherFactory("PPN.*
([0-9X]+)"));
        Downloader downloader(LOOKUP_URL);
        if (downloader.anErrorOccurred())
            LOG_WARNING("couldn't download author PPN! downloader error: " + downloader.getLastErrorMessage());
        else if (matcher->matched(downloader.getMessageBody())) {
            url_to_lookup_result_cache.emplace(LOOKUP_URL, (*matcher)[1]);
            return (*matcher)[1];
        } else
            url_to_lookup_result_cache.emplace(LOOKUP_URL, "");
    } else
        return url_and_lookup_result->second;
    return "";
}

BSZTransform::BSZTransform(const std::string &map_directory_path): augment_maps_(AugmentMaps(map_directory_path)) {}
BSZTransform::BSZTransform(const AugmentMaps &augment_maps): augment_maps_(augment_maps) {}

void BSZTransform::DetermineKeywordOutputFieldFromISSN(const std::string &issn, std::string * const tag, char * const subfield) {
    if (not issn.empty()) {
        const auto issn_and_field_tag_and_subfield_code(augment_maps_.ISSN_to_keyword_field_map_.find(issn));
        if (issn_and_field_tag_and_subfield_code != augment_maps_.ISSN_to_keyword_field_map_.end()) {
            if (unlikely(issn_and_field_tag_and_subfield_code->second.length() != 3 + 1))
                LOG_ERROR("\"" + issn_and_field_tag_and_subfield_code->second
                          + "\" is not a valid MARC tag + subfield code! (Error in \"ISSN_to_keyword_field.map\"!)");
            *tag = issn_and_field_tag_and_subfield_code->second.substr(0, 3);
            *subfield = issn_and_field_tag_and_subfield_code->second[3];
            return;
        }
    }
    *tag = "650";
    *subfield = 'a';
}

void ParseAuthor(const std::string &author, std::string * const first_name, std::string * const last_name) {
    const auto normalised_author(TextUtil::CollapseAndTrimWhitespace(author));
    const auto name_separator(normalised_author.rfind(' '));
    if (name_separator != std::string::npos) {
        *first_name = normalised_author.substr(0, name_separator);
        *last_name = normalised_author.substr(name_separator + 1);
    } else {
        *first_name = normalised_author;
        last_name->clear();
    }
}

bool FilterEmptyAndCommentLines(std::string str) {
    StringUtil::TrimWhite(&str);
    return not str.empty() and str.front() != '#';
}

void StripBlacklistedTokensFromAuthorName(std::string * const first_name, std::string * const last_name) {
    static std::unique_ptr<RegexMatcher> matcher;
    if (matcher == nullptr) {
        std::unordered_set<std::string> blacklisted_tokens, filtered_blacklisted_tokens;
        auto string_data(FileUtil::ReadStringOrDie(AUTHOR_NAME_BLACKLIST));
        StringUtil::Split(string_data, '\n', &blacklisted_tokens, /* suppress_empty_components = */true);

        StlHelpers::Functional::Filter(blacklisted_tokens.begin(), blacklisted_tokens.end(), filtered_blacklisted_tokens,
                                       FilterEmptyAndCommentLines);

        std::string match_regex("\\b(");
        for (auto blacklisted_token : filtered_blacklisted_tokens) {
            // escape backslashes first to keep from overwriting other escape sequences
            blacklisted_token = StringUtil::ReplaceString("\\", "\\\\", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString("(", "\\(", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString(")", "\\)", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString(".", "\\.", blacklisted_token);
            blacklisted_token = StringUtil::ReplaceString("/", "\\/", blacklisted_token);

            match_regex += blacklisted_token + "|";
        }
        match_regex += ")\\b";

        matcher.reset(RegexMatcher::RegexMatcherFactoryOrDie(match_regex, RegexMatcher::ENABLE_UTF8));
    }

    std::string first_name_buffer(matcher->replaceAll(*first_name, "")), last_name_buffer(matcher->replaceAll(*last_name, ""));
    StringUtil::TrimWhite(&first_name_buffer);
    StringUtil::TrimWhite(&last_name_buffer);

    *first_name = first_name_buffer;
    *last_name = last_name_buffer;
}

bool IsAuthorNameTokenTitle(std::string token) {
    static const std::set<std::string> VALID_TITLES {
        "jr", "sr", "sj", "s.j", "fr", "hr", "dr", "prof", "em"
    };

    bool final_period(token.back() == '.');
    if (final_period)
        token.erase(token.size() - 1);

    TextUtil::UTF8ToLower(&token);
    return VALID_TITLES.find(token) != VALID_TITLES.end();
}

bool IsAuthorNameTokenAffix(std::string token) {
    static const std::set<std::string> VALID_AFFIXES {
        "i", "ii", "iii", "iv", "v"
    };

    TextUtil::UTF8ToLower(&token);
    return VALID_AFFIXES.find(token) != VALID_AFFIXES.end();
}

void PostProcessAuthorName(std::string * const first_name, std::string * const last_name, std::string * const title,
                           std::string * const affix)
{
    std::string first_name_buffer, last_name_buffer, title_buffer, affix_buffer;
    std::vector<std::string> tokens;

    StringUtil::Split(*first_name, ' ', &tokens);
    for (const auto &token : tokens) {
        if (IsAuthorNameTokenTitle(token))
            title_buffer += token + " ";
        else
            first_name_buffer += token + " ";
    }

    StringUtil::Split(*last_name, ' ', &tokens);
    for (const auto &token : tokens) {
        if (IsAuthorNameTokenTitle(token))
            title_buffer += token + " ";
        else if (IsAuthorNameTokenAffix(token))
            affix_buffer += token + " ";
        else
            last_name_buffer += token + " ";
    }

    TextUtil::CollapseAndTrimWhitespace(&first_name_buffer);
    TextUtil::CollapseAndTrimWhitespace(&last_name_buffer);
    TextUtil::CollapseAndTrimWhitespace(&title_buffer);
    TextUtil::CollapseAndTrimWhitespace(&affix_buffer);

    StripBlacklistedTokensFromAuthorName(&first_name_buffer, &last_name_buffer);

    *title = title_buffer;
    *affix = affix_buffer;
    // try to reparse the name if either part of the name is empty
    if (first_name_buffer.empty())
        ParseAuthor(last_name_buffer, first_name, last_name);
    else if (last_name_buffer.empty())
        ParseAuthor(first_name_buffer, first_name, last_name);
    else if (not first_name_buffer.empty() and not last_name_buffer.empty()) {
        *first_name = first_name_buffer;
        *last_name = last_name_buffer;
    }

    LOG_DEBUG("post-processed author first name = '" + *first_name + "', last name = '" + *last_name +
              "', title = '" + *title + "', affix = '" + *affix + "'");
}

} // end namespace BSZTransform
<|endoftext|>


<commit_before>/** \file   RegexMatcher.cc
 *  \brief  Implementation of the RegexMatcher class.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2015,2017 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "RegexMatcher.h"
#include "Compiler.h"
#include "util.h"

bool RegexMatcher::utf8_configured_;

bool CompileRegex(const std::string &pattern, const unsigned options, ::pcre **pcre_arg,
                  ::pcre_extra **pcre_extra_arg, std::string * const err_msg)
{
    if (err_msg != nullptr)
        err_msg->clear();

    const char *errptr;
    int erroffset;

    int pcre_options(0);
    if (options & RegexMatcher::ENABLE_UTF8)
        pcre_options |= PCRE_UTF8;
    if (options & RegexMatcher::CASE_INSENSITIVE)
        pcre_options |= PCRE_CASELESS;

    *pcre_arg = ::pcre_compile(pattern.c_str(), pcre_options, &errptr, &erroffset, nullptr);
    if (*pcre_arg == nullptr) {
        *pcre_extra_arg = nullptr;
        if (err_msg != nullptr)
            *err_msg = "failed to compile invalid regular expression: \"" + pattern + "\"! ("
                + std::string(errptr) + ")";
        return false;
    }

    // Can't use PCRE_STUDY_JIT_COMPILE because it's not thread safe.
    *pcre_extra_arg = ::pcre_study(*pcre_arg, 0, &errptr);
    if (*pcre_extra_arg == nullptr and errptr != nullptr) {
        ::pcre_free(*pcre_arg);
        *pcre_arg = nullptr;
        if (err_msg != nullptr)
            *err_msg = "failed to \"study\" the compiled pattern \"" + pattern + "\"! (" + std::string(errptr) + ")";
        return false;
    }

    return true;
}

RegexMatcher *RegexMatcher::RegexMatcherFactory(const std::string &pattern, std::string * const err_msg,
                                                const unsigned options)
{
    // Make sure the PCRE library supports UTF8:
    if ((options & RegexMatcher::ENABLE_UTF8) and not RegexMatcher::utf8_configured_) {
        int utf8_available;
        if (::pcre_config(PCRE_CONFIG_UTF8, reinterpret_cast<void *>(&utf8_available)) == PCRE_ERROR_BADOPTION) {
            if (err_msg != nullptr)
                *err_msg = "PCRE library does not know PCRE_CONFIG_UTF8!";
            return nullptr;
        }

        if (utf8_available != 1) {
            if (err_msg != nullptr)
                *err_msg = "This version of the PCRE library does not support UTF8!";
            return nullptr;
        }

        RegexMatcher::utf8_configured_ = true;
    }

    ::pcre *pcre_ptr;
    ::pcre_extra *pcre_extra_ptr;
    if (not CompileRegex(pattern, options, &pcre_ptr, &pcre_extra_ptr, err_msg))
        return nullptr;

    return new RegexMatcher(pattern, options, pcre_ptr, pcre_extra_ptr);
}

RegexMatcher *RegexMatcher::FactoryOrDie(const std::string &regex, const unsigned options) {
    std::string error_message;
    RegexMatcher *regex_matcher(RegexMatcher::RegexMatcherFactory(regex, &error_message, options));
    if (not error_message.empty())
        ERROR("failed to compile regex \"" + regex + "\": " + error_message);

    return regex_matcher;
}

RegexMatcher::RegexMatcher(const RegexMatcher &that): pattern_(that.pattern_) {
    if (this == &that)
        return;

    if (that.pcre_ == nullptr) {
        pcre_ = nullptr;
        pcre_extra_ = nullptr;
    } else {
        std::string err_msg;
        if (not CompileRegex(pattern_, that.options_, &pcre_, &pcre_extra_, &err_msg))
            logger->error("In RegexMatcher copy constructor: unexpected error: " + err_msg);
        substr_vector_    = that.substr_vector_;
        last_match_count_ = that.last_match_count_;
    }
}

RegexMatcher::RegexMatcher(RegexMatcher &&that)
    : pattern_(std::move(that.pattern_)), options_(that.options_), pcre_(that.pcre_),
      pcre_extra_(that.pcre_extra_), last_subject_(std::move(that.last_subject_)),
      substr_vector_(std::move(that.substr_vector_)), last_match_count_(that.last_match_count_)
{
    that.pcre_       = nullptr;
    that.pcre_extra_ = nullptr;
}

bool RegexMatcher::matched(const std::string &subject, std::string * const err_msg,
                           size_t * const start_pos, size_t * const end_pos)
{
    if (err_msg != nullptr)
        err_msg->clear();

    const int retcode = ::pcre_exec(pcre_, pcre_extra_, subject.data(), subject.length(), 0, 0,
                                    &substr_vector_[0], substr_vector_.size());

    if (retcode == 0) {
        if (err_msg != nullptr)
            *err_msg = "Too many captured substrings! (We only support "
                       + std::to_string(substr_vector_.size() / 3 - 1) + " substrings.)";
        return false;
    }

    if (retcode > 0) {
        last_match_count_ = retcode;
        last_subject_     = subject;
        if (start_pos != nullptr)
            *start_pos = substr_vector_[0];
        if (end_pos != nullptr)
            *end_pos = substr_vector_[1];
        return true;
    }

    if (retcode != PCRE_ERROR_NOMATCH) {
        if (retcode == PCRE_ERROR_BADUTF8) {
            if (err_msg != nullptr)
                *err_msg = "A \"subject\" with invalid UTF-8 was passed into RegexMatcher::matched()!";
        } else if (err_msg != nullptr)
            *err_msg = "Unknown error!";
    }

    return false;
}

std::string RegexMatcher::operator[](const unsigned group) const {
    if (unlikely(group >= last_match_count_))
        throw std::out_of_range("in RegexMatcher::operator[]: group(" + std::to_string(group) + ") >= "
                                + std::to_string(last_match_count_) + "!");

    const unsigned first_index(group * 2);
    const unsigned substring_length(substr_vector_[first_index + 1] - substr_vector_[first_index]);
    return (substring_length == 0) ? "" : last_subject_.substr(substr_vector_[first_index], substring_length);
}
<commit_msg>Update RegexMatcher.cc<commit_after>/** \file   RegexMatcher.cc
 *  \brief  Implementation of the RegexMatcher class.
 *  \author Dr. Johannes Ruscheinski (johannes.ruscheinski@uni-tuebingen.de)
 *
 *  \copyright 2015,2017,2018 Universitätsbibliothek Tübingen.  All rights reserved.
 *
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License, or (at your option) any later version.
 *
 *  This program 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 Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
#include "RegexMatcher.h"
#include "Compiler.h"
#include "util.h"

bool RegexMatcher::utf8_configured_;

bool CompileRegex(const std::string &pattern, const unsigned options, ::pcre **pcre_arg,
                  ::pcre_extra **pcre_extra_arg, std::string * const err_msg)
{
    if (err_msg != nullptr)
        err_msg->clear();

    const char *errptr;
    int erroffset;

    int pcre_options(0);
    if (options & RegexMatcher::ENABLE_UTF8)
        pcre_options |= PCRE_UTF8;
    if (options & RegexMatcher::CASE_INSENSITIVE)
        pcre_options |= PCRE_CASELESS;

    *pcre_arg = ::pcre_compile(pattern.c_str(), pcre_options, &errptr, &erroffset, nullptr);
    if (*pcre_arg == nullptr) {
        *pcre_extra_arg = nullptr;
        if (err_msg != nullptr)
            *err_msg = "failed to compile invalid regular expression: \"" + pattern + "\"! ("
                + std::string(errptr) + ")";
        return false;
    }

    // Can't use PCRE_STUDY_JIT_COMPILE because it's not thread safe.
    *pcre_extra_arg = ::pcre_study(*pcre_arg, 0, &errptr);
    if (*pcre_extra_arg == nullptr and errptr != nullptr) {
        ::pcre_free(*pcre_arg);
        *pcre_arg = nullptr;
        if (err_msg != nullptr)
            *err_msg = "failed to \"study\" the compiled pattern \"" + pattern + "\"! (" + std::string(errptr) + ")";
        return false;
    }

    return true;
}

RegexMatcher *RegexMatcher::RegexMatcherFactory(const std::string &pattern, std::string * const err_msg,
                                                const unsigned options)
{
    // Make sure the PCRE library supports UTF8:
    if ((options & RegexMatcher::ENABLE_UTF8) and not RegexMatcher::utf8_configured_) {
        int utf8_available;
        if (::pcre_config(PCRE_CONFIG_UTF8, reinterpret_cast<void *>(&utf8_available)) == PCRE_ERROR_BADOPTION) {
            if (err_msg != nullptr)
                *err_msg = "PCRE library does not know PCRE_CONFIG_UTF8!";
            return nullptr;
        }

        if (utf8_available != 1) {
            if (err_msg != nullptr)
                *err_msg = "This version of the PCRE library does not support UTF8!";
            return nullptr;
        }

        RegexMatcher::utf8_configured_ = true;
    }

    ::pcre *pcre_ptr;
    ::pcre_extra *pcre_extra_ptr;
    if (not CompileRegex(pattern, options, &pcre_ptr, &pcre_extra_ptr, err_msg))
        return nullptr;

    return new RegexMatcher(pattern, options, pcre_ptr, pcre_extra_ptr);
}

RegexMatcher *RegexMatcher::FactoryOrDie(const std::string &regex, const unsigned options) {
    std::string error_message;
    RegexMatcher *regex_matcher(RegexMatcher::RegexMatcherFactory(regex, &error_message, options));
    if (not error_message.empty())
        ERROR("failed to compile regex \"" + regex + "\": " + error_message);

    return regex_matcher;
}

RegexMatcher::RegexMatcher(const RegexMatcher &that): pattern_(that.pattern_) {
    if (this == &that)
        return;

    if (that.pcre_ == nullptr) {
        pcre_ = nullptr;
        pcre_extra_ = nullptr;
    } else {
        std::string err_msg;
        if (not CompileRegex(pattern_, that.options_, &pcre_, &pcre_extra_, &err_msg))
            logger->error("In RegexMatcher copy constructor: unexpected error: " + err_msg);
        substr_vector_    = that.substr_vector_;
        last_match_count_ = that.last_match_count_;
    }
}

RegexMatcher::RegexMatcher(RegexMatcher &&that)
    : pattern_(std::move(that.pattern_)), options_(that.options_), pcre_(that.pcre_),
      pcre_extra_(that.pcre_extra_), last_subject_(std::move(that.last_subject_)),
      substr_vector_(std::move(that.substr_vector_)), last_match_count_(that.last_match_count_)
{
    that.pcre_       = nullptr;
    that.pcre_extra_ = nullptr;
}

bool RegexMatcher::matched(const std::string &subject, std::string * const err_msg,
                           size_t * const start_pos, size_t * const end_pos)
{
    if (err_msg != nullptr)
        err_msg->clear();

    const int retcode = ::pcre_exec(pcre_, pcre_extra_, subject.data(), subject.length(), 0, 0,
                                    &substr_vector_[0], substr_vector_.size());

    if (retcode == 0) {
        if (err_msg != nullptr)
            *err_msg = "Too many captured substrings! (We only support "
                       + std::to_string(substr_vector_.size() / 3 - 1) + " substrings.)";
        return false;
    }

    if (retcode > 0) {
        last_match_count_ = retcode;
        last_subject_     = subject;
        if (start_pos != nullptr)
            *start_pos = substr_vector_[0];
        if (end_pos != nullptr)
            *end_pos = substr_vector_[1];
        return true;
    }

    if (retcode != PCRE_ERROR_NOMATCH) {
        if (retcode == PCRE_ERROR_BADUTF8) {
            if (err_msg != nullptr)
                *err_msg = "A \"subject\" with invalid UTF-8 was passed into RegexMatcher::matched()!";
        } else if (err_msg != nullptr)
            *err_msg = "Unknown error!";
    }

    return false;
}

std::string RegexMatcher::operator[](const unsigned group) const {
    if (unlikely(group >= last_match_count_))
        throw std::out_of_range("in RegexMatcher::operator[]: group(" + std::to_string(group) + ") >= "
                                + std::to_string(last_match_count_) + "!");

    const unsigned first_index(group * 2);
    const unsigned substring_length(substr_vector_[first_index + 1] - substr_vector_[first_index]);
    return (substring_length == 0) ? "" : last_subject_.substr(substr_vector_[first_index], substring_length);
}
<|endoftext|>


<commit_before>/*
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Modified by Cloudius Systems
 *
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include "function.hh"
#include "aggregate_fcts.hh"
#include "time_uuid_fcts.hh"
#include "uuid_fcts.hh"
#include "bytes_conversion_fcts.hh"
#include "aggregate_fcts.hh"
#include "bytes_conversion_fcts.hh"
#include "cql3/assignment_testable.hh"
#include "cql3/cql3_type.hh"
#include "cql3/column_identifier.hh"
#include "to_string.hh"
#include <unordered_map>
#include <boost/lexical_cast.hpp>

namespace cql3 {

namespace functions {

#if 0
    // We special case the token function because that's the only function whose argument types actually
    // depend on the table on which the function is called. Because it's the sole exception, it's easier
    // to handle it as a special case.
    private static final FunctionName TOKEN_FUNCTION_NAME = FunctionName.nativeFunction("token");
#endif

class functions {
    static thread_local std::unordered_multimap<function_name, shared_ptr<function>> _declared;
private:
    static std::unordered_multimap<function_name, shared_ptr<function>> init() {
        std::unordered_multimap<function_name, shared_ptr<function>> ret;
        auto declare = [&ret] (shared_ptr<function> f) { ret.emplace(f->name(), std::move(f)); };
        declare(aggregate_fcts::make_count_rows_function());
        declare(time_uuid_fcts::make_now_fct());
        declare(time_uuid_fcts::make_min_timeuuid_fct());
        declare(time_uuid_fcts::make_max_timeuuid_fct());
        declare(time_uuid_fcts::make_date_of_fct());
        declare(time_uuid_fcts::make_unix_timestamp_of_fcf());
        declare(make_uuid_fct());

        for (auto&& type : cql3_type::values()) {
            // Note: because text and varchar ends up being synonimous, our automatic makeToBlobFunction doesn't work
            // for varchar, so we special case it below. We also skip blob for obvious reasons.
            if (type == cql3_type::varchar || type == cql3_type::blob) {
                continue;
            }

            declare(make_to_blob_function(type->get_type()));
            declare(make_from_blob_function(type->get_type()));
        }
        declare(aggregate_fcts::make_count_function<int32_t>());
        declare(aggregate_fcts::make_max_function<int32_t>());
        declare(aggregate_fcts::make_min_function<int32_t>());

        declare(aggregate_fcts::make_count_function<int64_t>());
        declare(aggregate_fcts::make_max_function<int64_t>());
        declare(aggregate_fcts::make_min_function<int64_t>());

        //FIXME:
        //declare(aggregate_fcts::make_count_function<bytes>());
        //declare(aggregate_fcts::make_max_function<bytes>());
        //declare(aggregate_fcts::make_min_function<bytes>());

        // FIXME: more count/min/max

        declare(make_varchar_as_blob_fct());
        declare(make_blob_as_varchar_fct());
        declare(aggregate_fcts::make_sum_function<int32_t>());
        declare(aggregate_fcts::make_sum_function<int64_t>());
        declare(aggregate_fcts::make_avg_function<int32_t>());
        declare(aggregate_fcts::make_avg_function<int64_t>());
#if 0
        declare(AggregateFcts.sumFunctionForFloat);
        declare(AggregateFcts.sumFunctionForDouble);
        declare(AggregateFcts.sumFunctionForDecimal);
        declare(AggregateFcts.sumFunctionForVarint);
        declare(AggregateFcts.avgFunctionForFloat);
        declare(AggregateFcts.avgFunctionForDouble);
        declare(AggregateFcts.avgFunctionForVarint);
        declare(AggregateFcts.avgFunctionForDecimal);
#endif

        // also needed for smp:
#if 0
        MigrationManager.instance.register(new FunctionsMigrationListener());
#endif
        return ret;
    }

public:
    static shared_ptr<column_specification> make_arg_spec(const sstring& receiver_ks, const sstring& receiver_cf,
            const function& fun, size_t i) {
        auto&& name = boost::lexical_cast<std::string>(fun.name());
        std::transform(name.begin(), name.end(), name.begin(), ::tolower);
        return ::make_shared<column_specification>(receiver_ks,
                                       receiver_cf,
                                       ::make_shared<column_identifier>(sprint("arg%d(%s)", i, name), true),
                                       fun.arg_types()[i]);
    }

    static int get_overload_count(const function_name& name) {
        return _declared.count(name);
    }

public:
    static shared_ptr<function> get(const sstring& keyspace,
                                    const function_name& name,
                                    const std::vector<shared_ptr<assignment_testable>>& provided_args,
                                    const sstring& receiver_ks,
                                    const sstring& receiver_cf) {
        // FIXME:
#if 0
        // later
        if (name.has_keyspace()
            ? name.equals(TOKEN_FUNCTION_NAME)
            : name.name.equals(TOKEN_FUNCTION_NAME.name))
            return new TokenFct(Schema.instance.getCFMetaData(receiverKs, receiverCf));
#endif
        std::vector<shared_ptr<function>> candidates;
        auto&& add_declared = [&] (function_name fn) {
            auto&& fns = _declared.equal_range(fn);
            for (auto i = fns.first; i != fns.second; ++i) {
                candidates.push_back(i->second);
            }
        };
        if (!name.has_keyspace()) {
            // add 'SYSTEM' (native) candidates
            add_declared(name.as_native_function());
            add_declared(function_name(keyspace, name.name));
        } else {
            // function name is fully qualified (keyspace + name)
            add_declared(name);
        }

        if (candidates.empty()) {
            return {};
        }

        // Fast path if there is only one choice
        if (candidates.size() == 1) {
            auto fun = std::move(candidates[0]);
            validate_types(keyspace, fun, provided_args, receiver_ks, receiver_cf);
            return fun;
        }

        std::vector<shared_ptr<function>> compatibles;
        for (auto&& to_test : candidates) {
            auto r = match_arguments(keyspace, to_test, provided_args, receiver_ks, receiver_cf);
            switch (r) {
                case assignment_testable::test_result::EXACT_MATCH:
                    // We always favor exact matches
                    return to_test;
                case assignment_testable::test_result::WEAKLY_ASSIGNABLE:
                    compatibles.push_back(std::move(to_test));
                    break;
                default:
                    ;
            };
        }

        if (compatibles.empty()) {
            throw exceptions::invalid_request_exception(
                    sprint("Invalid call to function %s, none of its type signatures match (known type signatures: %s)",
                                                            name, join(", ", candidates)));
        }

        if (compatibles.size() > 1) {
            throw exceptions::invalid_request_exception(
                    sprint("Ambiguous call to function %s (can be matched by following signatures: %s): use type casts to disambiguate",
                        name, join(", ", compatibles)));
        }

        return std::move(compatibles[0]);
    }

    template <typename AssignmentTestablePtrRange>
    static shared_ptr<function> get(const sstring& keyspace,
                                    const function_name& name,
                                    AssignmentTestablePtrRange&& provided_args,
                                    const sstring& receiver_ks,
                                    const sstring& receiver_cf) {
        const std::vector<shared_ptr<assignment_testable>> args(std::begin(provided_args), std::end(provided_args));
        return get(keyspace, name, args, receiver_ks, receiver_cf);
    }

    static std::vector<shared_ptr<function>> find(const function_name& name) {
        auto range = _declared.equal_range(name);
        std::vector<shared_ptr<function>> ret;
        for (auto i = range.first; i != range.second; ++i) {
            ret.push_back(i->second);
        }
        return ret;
    }

    static shared_ptr<function> find(const function_name& name, const std::vector<data_type>& arg_types) {
        assert(name.has_keyspace()); // : "function name not fully qualified";
        for (auto&& f : find(name)) {
            if (type_equals(f->arg_types(), arg_types)) {
                return f;
            }
        }
        return {};
    }

private:
    // This method and matchArguments are somewhat duplicate, but this method allows us to provide more precise errors in the common
    // case where there is no override for a given function. This is thus probably worth the minor code duplication.
    static void validate_types(const sstring& keyspace,
                              shared_ptr<function> fun,
                              const std::vector<shared_ptr<assignment_testable>>& provided_args,
                              const sstring& receiver_ks,
                              const sstring& receiver_cf) {
        if (provided_args.size() != fun->arg_types().size()) {
            throw exceptions::invalid_request_exception(
                    sprint("Invalid number of arguments in call to function %s: %d required but %d provided",
                            fun->name(), fun->arg_types().size(), provided_args.size()));
        }

        for (size_t i = 0; i < provided_args.size(); ++i) {
            auto&& provided = provided_args[i];

            // If the concrete argument is a bind variables, it can have any type.
            // We'll validate the actually provided value at execution time.
            if (!provided) {
                continue;
            }

            auto&& expected = make_arg_spec(receiver_ks, receiver_cf, *fun, i);
            if (!is_assignable(provided->test_assignment(keyspace, expected))) {
                throw exceptions::invalid_request_exception(
                        sprint("Type error: %s cannot be passed as argument %d of function %s of type %s",
                                provided, i, fun->name(), expected->type->as_cql3_type()));
            }
        }
    }

    static assignment_testable::test_result match_arguments(const sstring& keyspace,
            shared_ptr<function> fun,
            const std::vector<shared_ptr<assignment_testable>>& provided_args,
            const sstring& receiver_ks,
            const sstring& receiver_cf) {
        if (provided_args.size() != fun->arg_types().size()) {
            return assignment_testable::test_result::NOT_ASSIGNABLE;
        }

        // It's an exact match if all are exact match, but is not assignable as soon as any is non assignable.
        auto res = assignment_testable::test_result::EXACT_MATCH;
        for (size_t i = 0; i < provided_args.size(); ++i) {
            auto&& provided = provided_args[i];
            if (!provided) {
                res = assignment_testable::test_result::WEAKLY_ASSIGNABLE;
                continue;
            }
            auto&& expected = make_arg_spec(receiver_ks, receiver_cf, *fun, i);
            auto arg_res = provided->test_assignment(keyspace, expected);
            if (arg_res == assignment_testable::test_result::NOT_ASSIGNABLE) {
                return assignment_testable::test_result::NOT_ASSIGNABLE;
            }
            if (arg_res == assignment_testable::test_result::WEAKLY_ASSIGNABLE) {
                res = assignment_testable::test_result::WEAKLY_ASSIGNABLE;
            }
        }
        return res;
    }

#if 0
    // This is *not* thread safe but is only called in SchemaTables that is synchronized.
    public static void addFunction(AbstractFunction fun)
    {
        // We shouldn't get there unless that function don't exist
        assert find(fun.name(), fun.argTypes()) == null;
        declare(fun);
    }

    // Same remarks than for addFunction
    public static void removeFunction(FunctionName name, List<AbstractType<?>> argsTypes)
    {
        Function old = find(name, argsTypes);
        assert old != null && !old.isNative();
        declared.remove(old.name(), old);
    }

    // Same remarks than for addFunction
    public static void replaceFunction(AbstractFunction fun)
    {
        removeFunction(fun.name(), fun.argTypes());
        addFunction(fun);
    }

    public static List<Function> getReferencesTo(Function old)
    {
        List<Function> references = new ArrayList<>();
        for (Function function : declared.values())
            if (function.hasReferenceTo(old))
                references.add(function);
        return references;
    }

    public static Collection<Function> all()
    {
        return declared.values();
    }

    public static boolean typeEquals(AbstractType<?> t1, AbstractType<?> t2)
    {
        return t1.asCQL3Type().toString().equals(t2.asCQL3Type().toString());
    }

#endif

    static bool type_equals(const std::vector<data_type>& t1, const std::vector<data_type>& t2) {
#if 0
        if (t1.size() != t2.size())
            return false;
        for (int i = 0; i < t1.size(); i ++)
            if (!typeEquals(t1.get(i), t2.get(i)))
                return false;
        return true;
#endif
        abort();
    }

#if 0
    private static class FunctionsMigrationListener implements IMigrationListener
    {
        public void onCreateKeyspace(String ksName) { }
        public void onCreateColumnFamily(String ksName, String cfName) { }
        public void onCreateUserType(String ksName, String typeName) { }
        public void onCreateFunction(String ksName, String functionName) { }
        public void onCreateAggregate(String ksName, String aggregateName) { }

        public void onUpdateKeyspace(String ksName) { }
        public void onUpdateColumnFamily(String ksName, String cfName) { }
        public void onUpdateUserType(String ksName, String typeName) {
            for (Function function : all())
                if (function instanceof UDFunction)
                    ((UDFunction)function).userTypeUpdated(ksName, typeName);
        }
        public void onUpdateFunction(String ksName, String functionName) { }
        public void onUpdateAggregate(String ksName, String aggregateName) { }

        public void onDropKeyspace(String ksName) { }
        public void onDropColumnFamily(String ksName, String cfName) { }
        public void onDropUserType(String ksName, String typeName) { }
        public void onDropFunction(String ksName, String functionName) { }
        public void onDropAggregate(String ksName, String aggregateName) { }
    }
#endif
};

}
}
<commit_msg>cql3: fix too eager move in functions.hh<commit_after>/*
 * 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
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/*
 * Modified by Cloudius Systems
 *
 * Copyright 2015 Cloudius Systems
 */

#pragma once

#include "function.hh"
#include "aggregate_fcts.hh"
#include "time_uuid_fcts.hh"
#include "uuid_fcts.hh"
#include "bytes_conversion_fcts.hh"
#include "aggregate_fcts.hh"
#include "bytes_conversion_fcts.hh"
#include "cql3/assignment_testable.hh"
#include "cql3/cql3_type.hh"
#include "cql3/column_identifier.hh"
#include "to_string.hh"
#include <unordered_map>
#include <boost/lexical_cast.hpp>

namespace cql3 {

namespace functions {

#if 0
    // We special case the token function because that's the only function whose argument types actually
    // depend on the table on which the function is called. Because it's the sole exception, it's easier
    // to handle it as a special case.
    private static final FunctionName TOKEN_FUNCTION_NAME = FunctionName.nativeFunction("token");
#endif

class functions {
    static thread_local std::unordered_multimap<function_name, shared_ptr<function>> _declared;
private:
    static std::unordered_multimap<function_name, shared_ptr<function>> init() {
        std::unordered_multimap<function_name, shared_ptr<function>> ret;
        auto declare = [&ret] (shared_ptr<function> f) { ret.emplace(f->name(), f); };
        declare(aggregate_fcts::make_count_rows_function());
        declare(time_uuid_fcts::make_now_fct());
        declare(time_uuid_fcts::make_min_timeuuid_fct());
        declare(time_uuid_fcts::make_max_timeuuid_fct());
        declare(time_uuid_fcts::make_date_of_fct());
        declare(time_uuid_fcts::make_unix_timestamp_of_fcf());
        declare(make_uuid_fct());

        for (auto&& type : cql3_type::values()) {
            // Note: because text and varchar ends up being synonimous, our automatic makeToBlobFunction doesn't work
            // for varchar, so we special case it below. We also skip blob for obvious reasons.
            if (type == cql3_type::varchar || type == cql3_type::blob) {
                continue;
            }

            declare(make_to_blob_function(type->get_type()));
            declare(make_from_blob_function(type->get_type()));
        }
        declare(aggregate_fcts::make_count_function<int32_t>());
        declare(aggregate_fcts::make_max_function<int32_t>());
        declare(aggregate_fcts::make_min_function<int32_t>());

        declare(aggregate_fcts::make_count_function<int64_t>());
        declare(aggregate_fcts::make_max_function<int64_t>());
        declare(aggregate_fcts::make_min_function<int64_t>());

        //FIXME:
        //declare(aggregate_fcts::make_count_function<bytes>());
        //declare(aggregate_fcts::make_max_function<bytes>());
        //declare(aggregate_fcts::make_min_function<bytes>());

        // FIXME: more count/min/max

        declare(make_varchar_as_blob_fct());
        declare(make_blob_as_varchar_fct());
        declare(aggregate_fcts::make_sum_function<int32_t>());
        declare(aggregate_fcts::make_sum_function<int64_t>());
        declare(aggregate_fcts::make_avg_function<int32_t>());
        declare(aggregate_fcts::make_avg_function<int64_t>());
#if 0
        declare(AggregateFcts.sumFunctionForFloat);
        declare(AggregateFcts.sumFunctionForDouble);
        declare(AggregateFcts.sumFunctionForDecimal);
        declare(AggregateFcts.sumFunctionForVarint);
        declare(AggregateFcts.avgFunctionForFloat);
        declare(AggregateFcts.avgFunctionForDouble);
        declare(AggregateFcts.avgFunctionForVarint);
        declare(AggregateFcts.avgFunctionForDecimal);
#endif

        // also needed for smp:
#if 0
        MigrationManager.instance.register(new FunctionsMigrationListener());
#endif
        return ret;
    }

public:
    static shared_ptr<column_specification> make_arg_spec(const sstring& receiver_ks, const sstring& receiver_cf,
            const function& fun, size_t i) {
        auto&& name = boost::lexical_cast<std::string>(fun.name());
        std::transform(name.begin(), name.end(), name.begin(), ::tolower);
        return ::make_shared<column_specification>(receiver_ks,
                                       receiver_cf,
                                       ::make_shared<column_identifier>(sprint("arg%d(%s)", i, name), true),
                                       fun.arg_types()[i]);
    }

    static int get_overload_count(const function_name& name) {
        return _declared.count(name);
    }

public:
    static shared_ptr<function> get(const sstring& keyspace,
                                    const function_name& name,
                                    const std::vector<shared_ptr<assignment_testable>>& provided_args,
                                    const sstring& receiver_ks,
                                    const sstring& receiver_cf) {
        // FIXME:
#if 0
        // later
        if (name.has_keyspace()
            ? name.equals(TOKEN_FUNCTION_NAME)
            : name.name.equals(TOKEN_FUNCTION_NAME.name))
            return new TokenFct(Schema.instance.getCFMetaData(receiverKs, receiverCf));
#endif
        std::vector<shared_ptr<function>> candidates;
        auto&& add_declared = [&] (function_name fn) {
            auto&& fns = _declared.equal_range(fn);
            for (auto i = fns.first; i != fns.second; ++i) {
                candidates.push_back(i->second);
            }
        };
        if (!name.has_keyspace()) {
            // add 'SYSTEM' (native) candidates
            add_declared(name.as_native_function());
            add_declared(function_name(keyspace, name.name));
        } else {
            // function name is fully qualified (keyspace + name)
            add_declared(name);
        }

        if (candidates.empty()) {
            return {};
        }

        // Fast path if there is only one choice
        if (candidates.size() == 1) {
            auto fun = std::move(candidates[0]);
            validate_types(keyspace, fun, provided_args, receiver_ks, receiver_cf);
            return fun;
        }

        std::vector<shared_ptr<function>> compatibles;
        for (auto&& to_test : candidates) {
            auto r = match_arguments(keyspace, to_test, provided_args, receiver_ks, receiver_cf);
            switch (r) {
                case assignment_testable::test_result::EXACT_MATCH:
                    // We always favor exact matches
                    return to_test;
                case assignment_testable::test_result::WEAKLY_ASSIGNABLE:
                    compatibles.push_back(std::move(to_test));
                    break;
                default:
                    ;
            };
        }

        if (compatibles.empty()) {
            throw exceptions::invalid_request_exception(
                    sprint("Invalid call to function %s, none of its type signatures match (known type signatures: %s)",
                                                            name, join(", ", candidates)));
        }

        if (compatibles.size() > 1) {
            throw exceptions::invalid_request_exception(
                    sprint("Ambiguous call to function %s (can be matched by following signatures: %s): use type casts to disambiguate",
                        name, join(", ", compatibles)));
        }

        return std::move(compatibles[0]);
    }

    template <typename AssignmentTestablePtrRange>
    static shared_ptr<function> get(const sstring& keyspace,
                                    const function_name& name,
                                    AssignmentTestablePtrRange&& provided_args,
                                    const sstring& receiver_ks,
                                    const sstring& receiver_cf) {
        const std::vector<shared_ptr<assignment_testable>> args(std::begin(provided_args), std::end(provided_args));
        return get(keyspace, name, args, receiver_ks, receiver_cf);
    }

    static std::vector<shared_ptr<function>> find(const function_name& name) {
        auto range = _declared.equal_range(name);
        std::vector<shared_ptr<function>> ret;
        for (auto i = range.first; i != range.second; ++i) {
            ret.push_back(i->second);
        }
        return ret;
    }

    static shared_ptr<function> find(const function_name& name, const std::vector<data_type>& arg_types) {
        assert(name.has_keyspace()); // : "function name not fully qualified";
        for (auto&& f : find(name)) {
            if (type_equals(f->arg_types(), arg_types)) {
                return f;
            }
        }
        return {};
    }

private:
    // This method and matchArguments are somewhat duplicate, but this method allows us to provide more precise errors in the common
    // case where there is no override for a given function. This is thus probably worth the minor code duplication.
    static void validate_types(const sstring& keyspace,
                              shared_ptr<function> fun,
                              const std::vector<shared_ptr<assignment_testable>>& provided_args,
                              const sstring& receiver_ks,
                              const sstring& receiver_cf) {
        if (provided_args.size() != fun->arg_types().size()) {
            throw exceptions::invalid_request_exception(
                    sprint("Invalid number of arguments in call to function %s: %d required but %d provided",
                            fun->name(), fun->arg_types().size(), provided_args.size()));
        }

        for (size_t i = 0; i < provided_args.size(); ++i) {
            auto&& provided = provided_args[i];

            // If the concrete argument is a bind variables, it can have any type.
            // We'll validate the actually provided value at execution time.
            if (!provided) {
                continue;
            }

            auto&& expected = make_arg_spec(receiver_ks, receiver_cf, *fun, i);
            if (!is_assignable(provided->test_assignment(keyspace, expected))) {
                throw exceptions::invalid_request_exception(
                        sprint("Type error: %s cannot be passed as argument %d of function %s of type %s",
                                provided, i, fun->name(), expected->type->as_cql3_type()));
            }
        }
    }

    static assignment_testable::test_result match_arguments(const sstring& keyspace,
            shared_ptr<function> fun,
            const std::vector<shared_ptr<assignment_testable>>& provided_args,
            const sstring& receiver_ks,
            const sstring& receiver_cf) {
        if (provided_args.size() != fun->arg_types().size()) {
            return assignment_testable::test_result::NOT_ASSIGNABLE;
        }

        // It's an exact match if all are exact match, but is not assignable as soon as any is non assignable.
        auto res = assignment_testable::test_result::EXACT_MATCH;
        for (size_t i = 0; i < provided_args.size(); ++i) {
            auto&& provided = provided_args[i];
            if (!provided) {
                res = assignment_testable::test_result::WEAKLY_ASSIGNABLE;
                continue;
            }
            auto&& expected = make_arg_spec(receiver_ks, receiver_cf, *fun, i);
            auto arg_res = provided->test_assignment(keyspace, expected);
            if (arg_res == assignment_testable::test_result::NOT_ASSIGNABLE) {
                return assignment_testable::test_result::NOT_ASSIGNABLE;
            }
            if (arg_res == assignment_testable::test_result::WEAKLY_ASSIGNABLE) {
                res = assignment_testable::test_result::WEAKLY_ASSIGNABLE;
            }
        }
        return res;
    }

#if 0
    // This is *not* thread safe but is only called in SchemaTables that is synchronized.
    public static void addFunction(AbstractFunction fun)
    {
        // We shouldn't get there unless that function don't exist
        assert find(fun.name(), fun.argTypes()) == null;
        declare(fun);
    }

    // Same remarks than for addFunction
    public static void removeFunction(FunctionName name, List<AbstractType<?>> argsTypes)
    {
        Function old = find(name, argsTypes);
        assert old != null && !old.isNative();
        declared.remove(old.name(), old);
    }

    // Same remarks than for addFunction
    public static void replaceFunction(AbstractFunction fun)
    {
        removeFunction(fun.name(), fun.argTypes());
        addFunction(fun);
    }

    public static List<Function> getReferencesTo(Function old)
    {
        List<Function> references = new ArrayList<>();
        for (Function function : declared.values())
            if (function.hasReferenceTo(old))
                references.add(function);
        return references;
    }

    public static Collection<Function> all()
    {
        return declared.values();
    }

    public static boolean typeEquals(AbstractType<?> t1, AbstractType<?> t2)
    {
        return t1.asCQL3Type().toString().equals(t2.asCQL3Type().toString());
    }

#endif

    static bool type_equals(const std::vector<data_type>& t1, const std::vector<data_type>& t2) {
#if 0
        if (t1.size() != t2.size())
            return false;
        for (int i = 0; i < t1.size(); i ++)
            if (!typeEquals(t1.get(i), t2.get(i)))
                return false;
        return true;
#endif
        abort();
    }

#if 0
    private static class FunctionsMigrationListener implements IMigrationListener
    {
        public void onCreateKeyspace(String ksName) { }
        public void onCreateColumnFamily(String ksName, String cfName) { }
        public void onCreateUserType(String ksName, String typeName) { }
        public void onCreateFunction(String ksName, String functionName) { }
        public void onCreateAggregate(String ksName, String aggregateName) { }

        public void onUpdateKeyspace(String ksName) { }
        public void onUpdateColumnFamily(String ksName, String cfName) { }
        public void onUpdateUserType(String ksName, String typeName) {
            for (Function function : all())
                if (function instanceof UDFunction)
                    ((UDFunction)function).userTypeUpdated(ksName, typeName);
        }
        public void onUpdateFunction(String ksName, String functionName) { }
        public void onUpdateAggregate(String ksName, String aggregateName) { }

        public void onDropKeyspace(String ksName) { }
        public void onDropColumnFamily(String ksName, String cfName) { }
        public void onDropUserType(String ksName, String typeName) { }
        public void onDropFunction(String ksName, String functionName) { }
        public void onDropAggregate(String ksName, String aggregateName) { }
    }
#endif
};

}
}
<|endoftext|>


<commit_before>/**************************************************************************
 * This file is property of and copyright by the Experimental Nuclear     *
 * Physics Group, Dep. of Physics                                         *
 * University of Oslo, Norway, 2007                                       *
 *                                                                        *
 * Author: Per Thomas Hille <perthi@fys.uio.no> for the ALICE HLT Project.*
 * Contributors are mentioned in the code where appropriate.              *
 * Please report bugs to perthi@fys.uio.no                                *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTEMCALRawAnalyzerLMSComponent.h"
#include "AliCaloRawAnalyzerLMS.h"

//Evaluation of Amplitude and Peak position using Least Mean Square (LMS) fit
//-----------
//-----------
//-----------
//-----------

AliHLTEMCALRawAnalyzerLMSComponent  gAliHLTEMCALRawAnalyzerLMSComponent;

AliHLTEMCALRawAnalyzerLMSComponent::AliHLTEMCALRawAnalyzerLMSComponent() : AliHLTEMCALRawAnalyzerComponent(kLMS)
{
  // fAnalyzerPtr
  //  fAnalyzerPtr = new AliCaloRawAnalyzerLMS();
}

AliHLTEMCALRawAnalyzerLMSComponent::~AliHLTEMCALRawAnalyzerLMSComponent()
{
  // delete fAnalyzerPtr;
}

const char*
AliHLTEMCALRawAnalyzerLMSComponent::GetComponentID()
{
  return "EmcalRawLms";
}

AliHLTComponent*
AliHLTEMCALRawAnalyzerLMSComponent::Spawn()
{
  return new AliHLTEMCALRawAnalyzerLMSComponent();
}

int
AliHLTEMCALRawAnalyzerLMSComponent::Deinit()
{
  return 0;
}
<commit_msg>Removing obsolete class AliCaloRawAnalyzerLMS<commit_after>/**************************************************************************
 * This file is property of and copyright by the Experimental Nuclear     *
 * Physics Group, Dep. of Physics                                         *
 * University of Oslo, Norway, 2007                                       *
 *                                                                        *
 * Author: Per Thomas Hille <perthi@fys.uio.no> for the ALICE HLT Project.*
 * Contributors are mentioned in the code where appropriate.              *
 * Please report bugs to perthi@fys.uio.no                                *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

#include "AliHLTEMCALRawAnalyzerLMSComponent.h"
#include "AliCaloRawAnalyzerKStandard.h"
//#include "AliCaloRawAnalyzerLMS.h"

//Evaluation of Amplitude and Peak position using Least Mean Square (LMS) fit
//-----------
//-----------
//-----------
//-----------

AliHLTEMCALRawAnalyzerLMSComponent  gAliHLTEMCALRawAnalyzerLMSComponent;

//AliHLTEMCALRawAnalyzerLMSComponent::AliHLTEMCALRawAnalyzerLMSComponent() : AliHLTEMCALRawAnalyzerComponent(kLMS)
AliHLTEMCALRawAnalyzerLMSComponent::AliHLTEMCALRawAnalyzerLMSComponent() : AliHLTEMCALRawAnalyzerComponent(kStandard)
{
  // fAnalyzerPtr
  //  fAnalyzerPtr = new AliCaloRawAnalyzerLMS();
}

AliHLTEMCALRawAnalyzerLMSComponent::~AliHLTEMCALRawAnalyzerLMSComponent()
{
  // delete fAnalyzerPtr;
}

const char*
AliHLTEMCALRawAnalyzerLMSComponent::GetComponentID()
{
  return "EmcalRawLms";
}

AliHLTComponent*
AliHLTEMCALRawAnalyzerLMSComponent::Spawn()
{
  return new AliHLTEMCALRawAnalyzerLMSComponent();
}

int
AliHLTEMCALRawAnalyzerLMSComponent::Deinit()
{
  return 0;
}
<|endoftext|>