<commit_before>//===-- SymbolTable.cpp - Implement the SymbolTable class -------------------=//
//
// This file implements the SymbolTable class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/SymbolTable.h"
#include "llvm/InstrTypes.h"
#include "llvm/Support/StringExtras.h"
#include "llvm/DerivedTypes.h"

SymbolTable::~SymbolTable() {
  // Drop all abstract type references in the type plane...
  iterator TyPlane = find(Type::TypeTy);
  if (TyPlane != end()) {
    VarMap &TyP = TyPlane->second;
    for (VarMap::iterator I = TyP.begin(), E = TyP.end(); I != E; ++I) {
      const Type *Ty = cast<const Type>(I->second);
      if (Ty->isAbstract())   // If abstract, drop the reference...
	cast<DerivedType>(Ty)->removeAbstractTypeUser(this);
    }
  }
#ifndef NDEBUG   // Only do this in -g mode...
  bool LeftoverValues = true;
  for (iterator i = begin(); i != end(); ++i) {
    for (type_iterator I = i->second.begin(); I != i->second.end(); ++I)
      if (!isa<ConstPoolVal>(I->second) && !isa<Type>(I->second)) {
	cerr << "Value still in symbol table! Type = '"
	     << i->first->getDescription() << "' Name = '" << I->first << "'\n";
	LeftoverValues = false;
      }
  }

  assert(LeftoverValues && "Values remain in symbol table!");
#endif
}

SymbolTable::type_iterator SymbolTable::type_find(const Value *D) {
  assert(D->hasName() && "type_find(Value*) only works on named nodes!");
  return type_find(D->getType(), D->getName());
}

// find - returns end(Ty->getIDNumber()) on failure...
SymbolTable::type_iterator SymbolTable::type_find(const Type *Ty,
                                                  const string &Name) {
  iterator I = find(Ty);
  if (I == end()) {      // Not in collection yet... insert dummy entry
    (*this)[Ty] = VarMap();
    I = find(Ty);
    assert(I != end() && "How did insert fail?");
  }

  return I->second.find(Name);
}

// getUniqueName - Given a base name, return a string that is either equal to
// it (or derived from it) that does not already occur in the symbol table for
// the specified type.
//
string SymbolTable::getUniqueName(const Type *Ty, const string &BaseName) {
  iterator I = find(Ty);
  if (I == end()) return BaseName;

  string TryName = BaseName;
  unsigned Counter = 0;
  type_iterator End = I->second.end();

  while (I->second.find(TryName) != End)     // Loop until we find unoccupied
    TryName = BaseName + utostr(++Counter);  // Name in the symbol table
  return TryName;
}

// lookup - Returns null on failure...
Value *SymbolTable::lookup(const Type *Ty, const string &Name) {
  iterator I = find(Ty);
  if (I != end()) {                      // We have symbols in that plane...
    type_iterator J = I->second.find(Name);
    if (J != I->second.end())            // and the name is in our hash table...
      return J->second;
  }

  return ParentSymTab ? ParentSymTab->lookup(Ty, Name) : 0;
}

void SymbolTable::remove(Value *N) {
  assert(N->hasName() && "Value doesn't have name!");
  assert(type_find(N) != type_end(N->getType()) &&
         "Value not in symbol table!");
  type_remove(type_find(N));
}

#define DEBUG_SYMBOL_TABLE 0

Value *SymbolTable::type_remove(const type_iterator &It) {
  Value *Result = It->second;
  const Type *Ty = Result->getType();
#if DEBUG_SYMBOL_TABLE
  cerr << this << " Removing Value: " << Result->getName() << endl;
#endif

  // Remove the value from the plane...
  find(Ty)->second.erase(It);

  // If we are removing an abstract type, remove the symbol table from it's use
  // list...
  if (Ty == Type::TypeTy) {
    const Type *T = cast<const Type>(Result);
    if (T->isAbstract())
      cast<DerivedType>(T)->removeAbstractTypeUser(this);
  }

  return Result;
}

// insertEntry - Insert a value into the symbol table with the specified
// name...
//
void SymbolTable::insertEntry(const string &Name, const Type *VTy, Value *V) {
  // TODO: The typeverifier should catch this when its implemented
  assert(lookup(VTy, Name) == 0 &&
	 "SymbolTable::insertEntry - Name already in symbol table!");

#if DEBUG_SYMBOL_TABLE
  cerr << this << " Inserting definition: " << Name << ": "
       << VTy->getDescription() << endl;
#endif

  iterator I = find(VTy);
  if (I == end()) {      // Not in collection yet... insert dummy entry
    // Insert a new empty element.  I points to the new elements.
    I = super::insert(make_pair(VTy, VarMap())).first;
    assert(I != end() && "How did insert fail?");

    // Check to see if the type is abstract.  If so, it might be refined in the
    // future, which would cause the plane of the old type to get merged into
    // a new type plane.
    //
    if (VTy->isAbstract())
      cast<DerivedType>(VTy)->addAbstractTypeUser(this);
  }

  I->second.insert(make_pair(Name, V));

  // If we are adding an abstract type, add the symbol table to it's use list.
  if (VTy == Type::TypeTy) {
    const Type *T = cast<const Type>(V);
    if (T->isAbstract())
      cast<DerivedType>(T)->addAbstractTypeUser(this);
  }
}

// This function is called when one of the types in the type plane are refined
void SymbolTable::refineAbstractType(const DerivedType *OldType,
				     const Type *NewType) {
  if (OldType == NewType) return;  // Noop, don't waste time dinking around

  // Search to see if we have any values of the type oldtype.  If so, we need to
  // move them into the newtype plane...
  iterator TPI = find(OldType);
  if (TPI != end()) {
    VarMap &OldPlane = TPI->second;
    while (!OldPlane.empty()) {
      pair<const string, Value*> V = *OldPlane.begin();
      OldPlane.erase(OldPlane.begin());
      insertEntry(V.first, NewType, V.second);
    }

    // Ok, now we are not referencing the type anymore... take me off your user
    // list please!
    OldType->removeAbstractTypeUser(this);
  }

  TPI = find(Type::TypeTy);
  assert(TPI != end() &&"Type plane not in symbol table but we contain types!");

  // Loop over all of the types in the symbol table, replacing any references to
  // OldType with references to NewType.  Note that there may be multiple
  // occurances, and although we only need to remove one at a time, it's faster
  // to remove them all in one pass.
  //
  VarMap &TyPlane = TPI->second;
  for (VarMap::iterator I = TyPlane.begin(), E = TyPlane.end(); I != E; ++I)
    if (I->second == (Value*)OldType) {  // FIXME when Types aren't const.
      OldType->removeAbstractTypeUser(this);
      I->second = (Value*)NewType;  // TODO FIXME when types aren't const
      if (NewType->isAbstract())
	cast<const DerivedType>(NewType)->addAbstractTypeUser(this);
    }
}

#ifndef NDEBUG
#include "llvm/Assembly/Writer.h"
#include <algorithm>

static void DumpVal(const pair<const string, Value *> &V) {
  cout << "  '%" << V.first << "' = " << V.second << endl;
}

static void DumpPlane(const pair<const Type *, map<const string, Value *> >&P) {
  cout << "  Plane: " << P.first << endl;
  for_each(P.second.begin(), P.second.end(), DumpVal);
}

void SymbolTable::dump() const {
  cout << "Symbol table dump:\n";
  for_each(begin(), end(), DumpPlane);

  if (ParentSymTab) {
    cout << "Parent ";
    ParentSymTab->dump();
  }
}

#endif
<commit_msg>Fix a problem occuring with type unification of symbol table entries<commit_after>//===-- SymbolTable.cpp - Implement the SymbolTable class -------------------=//
//
// This file implements the SymbolTable class for the VMCore library.
//
//===----------------------------------------------------------------------===//

#include "llvm/SymbolTable.h"
#include "llvm/InstrTypes.h"
#include "llvm/Support/StringExtras.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Method.h"

SymbolTable::~SymbolTable() {
  // Drop all abstract type references in the type plane...
  iterator TyPlane = find(Type::TypeTy);
  if (TyPlane != end()) {
    VarMap &TyP = TyPlane->second;
    for (VarMap::iterator I = TyP.begin(), E = TyP.end(); I != E; ++I) {
      const Type *Ty = cast<const Type>(I->second);
      if (Ty->isAbstract())   // If abstract, drop the reference...
	cast<DerivedType>(Ty)->removeAbstractTypeUser(this);
    }
  }
#ifndef NDEBUG   // Only do this in -g mode...
  bool LeftoverValues = true;
  for (iterator i = begin(); i != end(); ++i) {
    for (type_iterator I = i->second.begin(); I != i->second.end(); ++I)
      if (!isa<ConstPoolVal>(I->second) && !isa<Type>(I->second)) {
	cerr << "Value still in symbol table! Type = '"
	     << i->first->getDescription() << "' Name = '" << I->first << "'\n";
	LeftoverValues = false;
      }
  }

  assert(LeftoverValues && "Values remain in symbol table!");
#endif
}

SymbolTable::type_iterator SymbolTable::type_find(const Value *D) {
  assert(D->hasName() && "type_find(Value*) only works on named nodes!");
  return type_find(D->getType(), D->getName());
}

// find - returns end(Ty->getIDNumber()) on failure...
SymbolTable::type_iterator SymbolTable::type_find(const Type *Ty,
                                                  const string &Name) {
  iterator I = find(Ty);
  if (I == end()) {      // Not in collection yet... insert dummy entry
    (*this)[Ty] = VarMap();
    I = find(Ty);
    assert(I != end() && "How did insert fail?");
  }

  return I->second.find(Name);
}

// getUniqueName - Given a base name, return a string that is either equal to
// it (or derived from it) that does not already occur in the symbol table for
// the specified type.
//
string SymbolTable::getUniqueName(const Type *Ty, const string &BaseName) {
  iterator I = find(Ty);
  if (I == end()) return BaseName;

  string TryName = BaseName;
  unsigned Counter = 0;
  type_iterator End = I->second.end();

  while (I->second.find(TryName) != End)     // Loop until we find unoccupied
    TryName = BaseName + utostr(++Counter);  // Name in the symbol table
  return TryName;
}

// lookup - Returns null on failure...
Value *SymbolTable::lookup(const Type *Ty, const string &Name) {
  iterator I = find(Ty);
  if (I != end()) {                      // We have symbols in that plane...
    type_iterator J = I->second.find(Name);
    if (J != I->second.end())            // and the name is in our hash table...
      return J->second;
  }

  return ParentSymTab ? ParentSymTab->lookup(Ty, Name) : 0;
}

void SymbolTable::remove(Value *N) {
  assert(N->hasName() && "Value doesn't have name!");
  assert(type_find(N) != type_end(N->getType()) &&
         "Value not in symbol table!");
  type_remove(type_find(N));
}

#define DEBUG_SYMBOL_TABLE 0

Value *SymbolTable::type_remove(const type_iterator &It) {
  Value *Result = It->second;
  const Type *Ty = Result->getType();
#if DEBUG_SYMBOL_TABLE
  cerr << this << " Removing Value: " << Result->getName() << endl;
#endif

  // Remove the value from the plane...
  find(Ty)->second.erase(It);

  // If we are removing an abstract type, remove the symbol table from it's use
  // list...
  if (Ty == Type::TypeTy) {
    const Type *T = cast<const Type>(Result);
    if (T->isAbstract())
      cast<DerivedType>(T)->removeAbstractTypeUser(this);
  }

  return Result;
}

// insertEntry - Insert a value into the symbol table with the specified
// name...
//
void SymbolTable::insertEntry(const string &Name, const Type *VTy, Value *V) {
  // TODO: The typeverifier should catch this when its implemented
  assert(lookup(VTy, Name) == 0 &&
	 "SymbolTable::insertEntry - Name already in symbol table!");

#if DEBUG_SYMBOL_TABLE
  cerr << this << " Inserting definition: " << Name << ": "
       << VTy->getDescription() << endl;
#endif

  iterator I = find(VTy);
  if (I == end()) {      // Not in collection yet... insert dummy entry
    // Insert a new empty element.  I points to the new elements.
    I = super::insert(make_pair(VTy, VarMap())).first;
    assert(I != end() && "How did insert fail?");

    // Check to see if the type is abstract.  If so, it might be refined in the
    // future, which would cause the plane of the old type to get merged into
    // a new type plane.
    //
    if (VTy->isAbstract())
      cast<DerivedType>(VTy)->addAbstractTypeUser(this);
  }

  I->second.insert(make_pair(Name, V));

  // If we are adding an abstract type, add the symbol table to it's use list.
  if (VTy == Type::TypeTy) {
    const Type *T = cast<const Type>(V);
    if (T->isAbstract())
      cast<DerivedType>(T)->addAbstractTypeUser(this);
  }
}

// This function is called when one of the types in the type plane are refined
void SymbolTable::refineAbstractType(const DerivedType *OldType,
				     const Type *NewType) {
  if (OldType == NewType) return;  // Noop, don't waste time dinking around

  // Get a handle to the new type plane...
  iterator NewTypeIt = find(NewType);
  if (NewTypeIt == super::end())       // If no plane exists, add one
    NewTypeIt = super::insert(make_pair(NewType, VarMap())).first;

  VarMap &NewPlane = NewTypeIt->second;

  // Search to see if we have any values of the type oldtype.  If so, we need to
  // move them into the newtype plane...
  iterator TPI = find(OldType);
  if (TPI != end()) {
    VarMap &OldPlane = TPI->second;
    while (!OldPlane.empty()) {
      pair<const string, Value*> V = *OldPlane.begin();

      // Check to see if there is already a value in the symbol table that this
      // would collide with.
      type_iterator TI = NewPlane.find(V.first);
      if (TI != NewPlane.end() && TI->second == V.second) {
        // No action

      } else if (TI != NewPlane.end()) {
        // The only thing we are allowing for now is two method prototypes being
        // folded into one.
        //
        if (Method *ExistM = dyn_cast<Method>(TI->second))
          if (Method *NewM = dyn_cast<Method>(V.second))
            if (ExistM->isExternal() && NewM->isExternal()) {
              // Ok we have two external methods.  Make all uses of the new one
              // use the old one...
              //
              NewM->replaceAllUsesWith(ExistM);

              // Now we just convert it to an unnamed method... which won't get
              // added to our symbol table.  The problem is that if we call
              // setName on the method that it will try to remove itself from
              // the symbol table and die... because it's not in the symtab
              // right now.  To fix this, we temporarily insert it (by setting
              // TI's entry to the old value.  Then after it is removed, we
              // restore ExistM into the symbol table.
              //
              if (NewM->getType() == NewType) {
                TI->second = NewM;     // Add newM to the symtab

                // Remove newM from the symtab
                NewM->setName("");

                // Readd ExistM to the symbol table....
                NewPlane.insert(make_pair(V.first, ExistM));
              } else {
                NewM->setName("");
              }
              continue;
            }
        assert(0 && "Two ploanes folded together with overlapping "
               "value names!");
      } else {
        insertEntry(V.first, NewType, V.second);

      }
      // Remove the item from the old type plane
      OldPlane.erase(OldPlane.begin());
    }

    // Ok, now we are not referencing the type anymore... take me off your user
    // list please!
    OldType->removeAbstractTypeUser(this);
  }

  TPI = find(Type::TypeTy);
  assert(TPI != end() &&"Type plane not in symbol table but we contain types!");

  // Loop over all of the types in the symbol table, replacing any references to
  // OldType with references to NewType.  Note that there may be multiple
  // occurances, and although we only need to remove one at a time, it's faster
  // to remove them all in one pass.
  //
  VarMap &TyPlane = TPI->second;
  for (VarMap::iterator I = TyPlane.begin(), E = TyPlane.end(); I != E; ++I)
    if (I->second == (Value*)OldType) {  // FIXME when Types aren't const.
      OldType->removeAbstractTypeUser(this);
      I->second = (Value*)NewType;  // TODO FIXME when types aren't const
      if (NewType->isAbstract())
	cast<const DerivedType>(NewType)->addAbstractTypeUser(this);
    }
}

#ifndef NDEBUG
#include "llvm/Assembly/Writer.h"
#include <algorithm>

static void DumpVal(const pair<const string, Value *> &V) {
  cout << "  '%" << V.first << "' = " << V.second << endl;
}

static void DumpPlane(const pair<const Type *, map<const string, Value *> >&P) {
  cout << "  Plane: " << P.first << endl;
  for_each(P.second.begin(), P.second.end(), DumpVal);
}

void SymbolTable::dump() const {
  cout << "Symbol table dump:\n";
  for_each(begin(), end(), DumpPlane);

  if (ParentSymTab) {
    cout << "Parent ";
    ParentSymTab->dump();
  }
}

#endif
<|endoftext|>


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

#include "config.h"
#include "PluginData.h"

#include "PluginInfoStore.h"

#undef LOG
#include "webkit/glue/glue_util.h"
#include "webkit/glue/webkit_glue.h"

namespace WebCore {

static bool refreshData = false;

void PluginData::initPlugins()
{
    std::vector<WebPluginInfo> plugins;
    if (!webkit_glue::GetPlugins(refreshData, &plugins))
        return;
    refreshData = false;

    PluginInfoStore c;
    for (size_t i = 0; i < plugins.size(); ++i) {
        PluginInfo* info = c.createPluginInfoForPluginAtIndex(i);
        m_plugins.append(info);
    }
}

void PluginData::refresh()
{
    // When next we initialize a PluginData, it'll be fresh.
    refreshData = true;
}

}
<commit_msg>Fix plugin data refreshing to work again.<commit_after>// Copyright (c) 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

#include "config.h"
#include "PluginData.h"

#include "PluginInfoStore.h"

namespace WebCore {

void PluginData::initPlugins()
{
    PluginInfoStore c;
    for (size_t i = 0; i < c.pluginCount(); ++i)
        m_plugins.append(c.createPluginInfoForPluginAtIndex(i));
}

void PluginData::refresh()
{
    refreshPlugins(true);
}

}
<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_TOPOLOGY_BEZIERTETRAHEDRONSETGEOMETRYALGORITHMS_INL
#define SOFA_COMPONENT_TOPOLOGY_BEZIERTETRAHEDRONSETGEOMETRYALGORITHMS_INL

#include <sofa/component/topology/BezierTetrahedronSetGeometryAlgorithms.h>
#include <sofa/core/visual/VisualParams.h>

namespace sofa
{

namespace component
{

namespace topology
{
using namespace sofa::defaulttype;

typedef std::pair<TetrahedronBezierIndex,double> bernsteinCoeffMapType;
typedef std::map<TetrahedronBezierIndex,double>::iterator bernsteinCoeffMapIterator;

/// this function is only valid for small value of n which should be sufficient for a regular use.
size_t factorial(size_t n)
 {
 	size_t retval = 1;
 	for (int i = n; i > 1; --i)
 		retval *= (size_t) i;
 	return retval;
 }
template< class DataTypes>
 BezierTetrahedronSetGeometryAlgorithms< DataTypes >::BezierTetrahedronSetGeometryAlgorithms() :
TetrahedronSetGeometryAlgorithms<DataTypes>()
		,degree(0)
        ,drawControlPointsEdges (core::objectmodel::Base::initData(&drawControlPointsEdges, (bool) false, "drawControlPointsEdges", "Debug : view Control point indices"))
        , _drawColor(initData(&_drawColor, sofa::defaulttype::Vec3f(0.2f,1.0f,1.0f), "drawColorEdges", "RGB code color used to draw edges"))
    {
    }
template< class DataTypes>
 void BezierTetrahedronSetGeometryAlgorithms< DataTypes >::init()
{
	TetrahedronSetGeometryAlgorithms<DataTypes>::init();
	// recovers the pointer to a BezierTetrahedronSetTopologyContainer
	BezierTetrahedronSetTopologyContainer *btstc = NULL;
	this->getContext()->get(btstc, sofa::core::objectmodel::BaseContext::Local);
	if (!btstc) {
		serr << " Could not find a BezierTetrahedronSetTopologyContainer object"<< sendl;
	} else {
		container=btstc;
		/// get the degree of the Bezier tetrahedron
		degree=container->getDegree();
		/// store the tetrahedron bezier index for each tetrahedron
		tbiArray=container->getTetrahedronBezierIndexArray();
		/// compute the Bernstein coefficient for each control point in a tetrahedron
		bernsteinCoefficientArray.clear();
		bernsteinCoeffMap.clear();
		bernsteinCoefficientArray.resize(tbiArray.size());
		size_t i;
		TetrahedronBezierIndex tbi;
		/// precompute the factorial of the degree.
		double degreeFactorial=(double)factorial(degree);
		for (i=0;i<tbiArray.size();++i) {
			tbi=tbiArray[i];
			bernsteinCoefficientArray[i]=degreeFactorial/(factorial(tbi[0])*factorial(tbi[1])*factorial(tbi[2])*factorial(tbi[3]));
			bernsteinCoeffMap.insert(bernsteinCoeffMapType(tbi,(double) bernsteinCoefficientArray[i]));
		}
		/// fills the array of edges
		bezierTetrahedronEdgeSet.clear();
		size_t j,k,l,m,n,index1,index2;
		TetrahedronBezierIndex tbiNext;
		/*
		const VecCoord& coords = *(this->object->getX());
		VecPointID indexArray;
		for ( i = 0; i<container->getNumberOfTetrahedra(); i++)
		{
			indexArray.clear();
			container->getGlobalIndexArrayOfBezierPointsInTetrahedron(i, indexArray);

			for (j=0;j<tbiArray.size();++j) {

				if (j>=4) {
					// test if the position is correct
					Coord pos=coords[indexArray[0]]*(double)tbiArray[j][0]/degree+coords[indexArray[1]]*(double)tbiArray[j][1]/degree+coords[indexArray[2]]*(double)tbiArray[j][2]/degree+coords[indexArray[3]]*(double)tbiArray[j][3]/degree;
					if ((pos-coords[indexArray[j]]).norm2()>1e-3) {
						std::cerr<<"error for vertex position : should be = "<< pos<<std::endl;
						std::cerr<<"Point no "<<j <<" of tetrahedron "<<i<<" = "<<(unsigned int)tbiArray[j][0] << ' '<<(unsigned int)tbiArray[j][1]<< ' '<<(unsigned int)tbiArray[j][2]<< ' '<<(unsigned int)tbiArray[j][3]<<std::endl;
						std::cerr<< coords[indexArray[j]]<<std::endl;
					}
				}

			}
		}*/
		for (i=0;i<=degree;++i) {
			for (j=0;j<=(degree-i);++j) {
				for (k=0;k<=(degree-j-i);++k) {
					l=degree-i-j-k;
					tbi=TetrahedronBezierIndex(i,j,k,l);
					index1=container->getLocalIndexFromTetrahedronBezierIndex(tbi);
					for(m=0;m<4;++m) {
						if (tbi[m]<degree) {
							for (n=1;n<4;++n) {
								if (tbi[(m+n)%4]!=0) {
									tbiNext=tbi;
									tbiNext[m]=tbi[m]+1;
									tbiNext[(m+n)%4]=tbi[(m+n)%4]-1;
									index2=container->getLocalIndexFromTetrahedronBezierIndex(tbiNext);
									Edge e(std::min(index1,index2),std::max(index1,index2));
									bezierTetrahedronEdgeSet.insert(e);
								}
							}
						}
					}
				}
			}
		}
	}

}

template< class DataTypes>
 void BezierTetrahedronSetGeometryAlgorithms< DataTypes >::reinit()
{
}
template< class DataTypes>
typename DataTypes::Coord BezierTetrahedronSetGeometryAlgorithms< DataTypes >::computeNodalValue(const size_t tetrahedronIndex,const Vec4 barycentricCoordinate)
{
    const typename DataTypes::VecCoord& p = *(this->object->getX());

	Coord nodalValue;
	nodalValue.clear();
	VecPointID indexArray;
	TetrahedronBezierIndex tbi;
	container->getGlobalIndexArrayOfBezierPointsInTetrahedron(tetrahedronIndex, indexArray);
	for(size_t i=0; i<tbiArray.size(); ++i)
	{
		tbi=tbiArray[i];
		nodalValue+=p[indexArray[i]]*bernsteinCoefficientArray[i]*pow(barycentricCoordinate[0],tbi[0])*pow(barycentricCoordinate[1],tbi[1])*pow(barycentricCoordinate[2],tbi[2])*pow(barycentricCoordinate[3],tbi[3]);
	}
	return(nodalValue);
}

template<class DataTypes>
typename DataTypes::Real BezierTetrahedronSetGeometryAlgorithms<DataTypes>::computeBernsteinPolynomial(const TetrahedronBezierIndex tbi, const Vec4 barycentricCoordinate)
{
	Real  val=pow(barycentricCoordinate[0],tbi[0])*pow(barycentricCoordinate[1],tbi[1])*pow(barycentricCoordinate[2],tbi[2])*pow(barycentricCoordinate[3],tbi[3]);
	bernsteinCoeffMapIterator it=bernsteinCoeffMap.find(tbi);
	if (it!=bernsteinCoeffMap.end()) {
		val*=(*it).second;
		return(val);
	} else {
		serr<< "Tetrahedron Bezier Index "<< tbi << " out of range"<< sendl;
		return ((Real)1);
	}
}

 template<class DataTypes>
 typename BezierTetrahedronSetGeometryAlgorithms<DataTypes>::Vec4 BezierTetrahedronSetGeometryAlgorithms<DataTypes>::computeBernsteinPolynomialGradient(const TetrahedronBezierIndex tbi, const Vec4 barycentricCoordinate)
 {
     Real  val=computeBernsteinPolynomial(tbi,barycentricCoordinate);
     Vec4 dval(0,0,0,0);
     for(unsigned i=0;i<4;++i)
         if(tbi[i] && barycentricCoordinate[i])
             dval[i]=(Real)tbi[i]*val/barycentricCoordinate[i];
     return dval;
 }

 template<class DataTypes>
 typename BezierTetrahedronSetGeometryAlgorithms<DataTypes>::Mat44 BezierTetrahedronSetGeometryAlgorithms<DataTypes>::computeBernsteinPolynomialHessian(const TetrahedronBezierIndex tbi, const Vec4 barycentricCoordinate)
 {
     Vec4 dval = computeBernsteinPolynomialGradient(tbi,barycentricCoordinate);
     Mat44 ddval;
     for(unsigned i=0;i<4;++i)
         if(barycentricCoordinate[i])
             for(unsigned j=0;j<4;++j)
             {
                 if(i==j) { if(tbi[i]>1) ddval[j][i]=((Real)tbi[i]-1.)*dval[j]/barycentricCoordinate[i]; }
                 else { if(tbi[i]) ddval[j][i]=(Real)tbi[i]*dval[j]/barycentricCoordinate[i]; }
             }
     return ddval;
 }

template<class DataTypes>
void BezierTetrahedronSetGeometryAlgorithms<DataTypes>::draw(const core::visual::VisualParams* vparams)
{
	if ((degree>0) && (container) ){
		TetrahedronSetGeometryAlgorithms<DataTypes>::draw(vparams);

#ifndef SOFA_NO_OPENGL
		// Draw Tetra
		if (drawControlPointsEdges.getValue())
		{
			const sofa::helper::vector<Tetrahedron> &tetraArray = this->m_topology->getTetrahedra();

			if (!tetraArray.empty())
			{
				glDisable(GL_LIGHTING);
				const sofa::defaulttype::Vec3f& color = _drawColor.getValue();
				glColor3f(color[0], color[1], color[2]);
				glBegin(GL_LINES);
				const VecCoord& coords = *(this->object->getX());
				VecPointID indexArray;
				Vec4 baryCoord;
				sofa::defaulttype::Vec3f p; //,p2;
				for (unsigned int i = 0; i<tetraArray.size(); i++)
				{
					indexArray.clear();
					container->getGlobalIndexArrayOfBezierPointsInTetrahedron(i, indexArray);
					sofa::helper::vector <sofa::defaulttype::Vec3f> tetraCoord;

					for (unsigned int j = 0; j<indexArray.size(); j++)
					{
/*
						baryCoord=Vec4((double)tbiArray[j][0]/degree,(double)tbiArray[j][1]/degree,(double)tbiArray[j][2]/degree,(double)tbiArray[j][3]/degree);

						p=DataTypes::getCPos(computeNodalValue(i,baryCoord));

						if ((p-p2).norm2()>1e-3) std::cerr<< "error in tetra"<< i << std::endl;*/
						p = DataTypes::getCPos(coords[indexArray[j]]);
						tetraCoord.push_back(p);
					}
					sofa::helper::set<Edge>::iterator ite=bezierTetrahedronEdgeSet.begin();
					for (; ite!=bezierTetrahedronEdgeSet.end(); ite++)
					{
						glVertex3f(tetraCoord[(*ite)[0]][0], tetraCoord[(*ite)[0]][1], tetraCoord[(*ite)[0]][2]);
						glVertex3f(tetraCoord[(*ite)[1]][0], tetraCoord[(*ite)[1]][1], tetraCoord[(*ite)[1]][2]);
					}
				}
				glEnd();
			}
		}
	}
#endif
}

} // namespace topology

} // namespace component

} // namespace sofa

#endif // SOFA_COMPONENTS_TETEAHEDRONSETGEOMETRYALGORITHMS_INL
<commit_msg>r10699/sofa : Fix compilation with NO_OPENGL flag.<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 RC 1        *
*                (c) 2006-2011 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This library is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU Lesser General Public License as published by    *
* the Free Software Foundation; either version 2.1 of the License, or (at     *
* your option) any later version.                                             *
*                                                                             *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details.                                                           *
*                                                                             *
* 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
*******************************************************************************
*                               SOFA :: Modules                               *
*                                                                             *
* Authors: The SOFA Team and external contributors (see Authors.txt)          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#ifndef SOFA_COMPONENT_TOPOLOGY_BEZIERTETRAHEDRONSETGEOMETRYALGORITHMS_INL
#define SOFA_COMPONENT_TOPOLOGY_BEZIERTETRAHEDRONSETGEOMETRYALGORITHMS_INL

#include <sofa/component/topology/BezierTetrahedronSetGeometryAlgorithms.h>
#include <sofa/core/visual/VisualParams.h>

namespace sofa
{

namespace component
{

namespace topology
{
using namespace sofa::defaulttype;

typedef std::pair<TetrahedronBezierIndex,double> bernsteinCoeffMapType;
typedef std::map<TetrahedronBezierIndex,double>::iterator bernsteinCoeffMapIterator;

/// this function is only valid for small value of n which should be sufficient for a regular use.
size_t factorial(size_t n)
 {
 	size_t retval = 1;
 	for (int i = n; i > 1; --i)
 		retval *= (size_t) i;
 	return retval;
 }
template< class DataTypes>
 BezierTetrahedronSetGeometryAlgorithms< DataTypes >::BezierTetrahedronSetGeometryAlgorithms() :
TetrahedronSetGeometryAlgorithms<DataTypes>()
		,degree(0)
        ,drawControlPointsEdges (core::objectmodel::Base::initData(&drawControlPointsEdges, (bool) false, "drawControlPointsEdges", "Debug : view Control point indices"))
        , _drawColor(initData(&_drawColor, sofa::defaulttype::Vec3f(0.2f,1.0f,1.0f), "drawColorEdges", "RGB code color used to draw edges"))
    {
    }
template< class DataTypes>
 void BezierTetrahedronSetGeometryAlgorithms< DataTypes >::init()
{
	TetrahedronSetGeometryAlgorithms<DataTypes>::init();
	// recovers the pointer to a BezierTetrahedronSetTopologyContainer
	BezierTetrahedronSetTopologyContainer *btstc = NULL;
	this->getContext()->get(btstc, sofa::core::objectmodel::BaseContext::Local);
	if (!btstc) {
		serr << " Could not find a BezierTetrahedronSetTopologyContainer object"<< sendl;
	} else {
		container=btstc;
		/// get the degree of the Bezier tetrahedron
		degree=container->getDegree();
		/// store the tetrahedron bezier index for each tetrahedron
		tbiArray=container->getTetrahedronBezierIndexArray();
		/// compute the Bernstein coefficient for each control point in a tetrahedron
		bernsteinCoefficientArray.clear();
		bernsteinCoeffMap.clear();
		bernsteinCoefficientArray.resize(tbiArray.size());
		size_t i;
		TetrahedronBezierIndex tbi;
		/// precompute the factorial of the degree.
		double degreeFactorial=(double)factorial(degree);
		for (i=0;i<tbiArray.size();++i) {
			tbi=tbiArray[i];
			bernsteinCoefficientArray[i]=degreeFactorial/(factorial(tbi[0])*factorial(tbi[1])*factorial(tbi[2])*factorial(tbi[3]));
			bernsteinCoeffMap.insert(bernsteinCoeffMapType(tbi,(double) bernsteinCoefficientArray[i]));
		}
		/// fills the array of edges
		bezierTetrahedronEdgeSet.clear();
		size_t j,k,l,m,n,index1,index2;
		TetrahedronBezierIndex tbiNext;
		/*
		const VecCoord& coords = *(this->object->getX());
		VecPointID indexArray;
		for ( i = 0; i<container->getNumberOfTetrahedra(); i++)
		{
			indexArray.clear();
			container->getGlobalIndexArrayOfBezierPointsInTetrahedron(i, indexArray);

			for (j=0;j<tbiArray.size();++j) {

				if (j>=4) {
					// test if the position is correct
					Coord pos=coords[indexArray[0]]*(double)tbiArray[j][0]/degree+coords[indexArray[1]]*(double)tbiArray[j][1]/degree+coords[indexArray[2]]*(double)tbiArray[j][2]/degree+coords[indexArray[3]]*(double)tbiArray[j][3]/degree;
					if ((pos-coords[indexArray[j]]).norm2()>1e-3) {
						std::cerr<<"error for vertex position : should be = "<< pos<<std::endl;
						std::cerr<<"Point no "<<j <<" of tetrahedron "<<i<<" = "<<(unsigned int)tbiArray[j][0] << ' '<<(unsigned int)tbiArray[j][1]<< ' '<<(unsigned int)tbiArray[j][2]<< ' '<<(unsigned int)tbiArray[j][3]<<std::endl;
						std::cerr<< coords[indexArray[j]]<<std::endl;
					}
				}

			}
		}*/
		for (i=0;i<=degree;++i) {
			for (j=0;j<=(degree-i);++j) {
				for (k=0;k<=(degree-j-i);++k) {
					l=degree-i-j-k;
					tbi=TetrahedronBezierIndex(i,j,k,l);
					index1=container->getLocalIndexFromTetrahedronBezierIndex(tbi);
					for(m=0;m<4;++m) {
						if (tbi[m]<degree) {
							for (n=1;n<4;++n) {
								if (tbi[(m+n)%4]!=0) {
									tbiNext=tbi;
									tbiNext[m]=tbi[m]+1;
									tbiNext[(m+n)%4]=tbi[(m+n)%4]-1;
									index2=container->getLocalIndexFromTetrahedronBezierIndex(tbiNext);
									Edge e(std::min(index1,index2),std::max(index1,index2));
									bezierTetrahedronEdgeSet.insert(e);
								}
							}
						}
					}
				}
			}
		}
	}

}

template< class DataTypes>
 void BezierTetrahedronSetGeometryAlgorithms< DataTypes >::reinit()
{
}
template< class DataTypes>
typename DataTypes::Coord BezierTetrahedronSetGeometryAlgorithms< DataTypes >::computeNodalValue(const size_t tetrahedronIndex,const Vec4 barycentricCoordinate)
{
    const typename DataTypes::VecCoord& p = *(this->object->getX());

	Coord nodalValue;
	nodalValue.clear();
	VecPointID indexArray;
	TetrahedronBezierIndex tbi;
	container->getGlobalIndexArrayOfBezierPointsInTetrahedron(tetrahedronIndex, indexArray);
	for(size_t i=0; i<tbiArray.size(); ++i)
	{
		tbi=tbiArray[i];
		nodalValue+=p[indexArray[i]]*bernsteinCoefficientArray[i]*pow(barycentricCoordinate[0],tbi[0])*pow(barycentricCoordinate[1],tbi[1])*pow(barycentricCoordinate[2],tbi[2])*pow(barycentricCoordinate[3],tbi[3]);
	}
	return(nodalValue);
}

template<class DataTypes>
typename DataTypes::Real BezierTetrahedronSetGeometryAlgorithms<DataTypes>::computeBernsteinPolynomial(const TetrahedronBezierIndex tbi, const Vec4 barycentricCoordinate)
{
	Real  val=pow(barycentricCoordinate[0],tbi[0])*pow(barycentricCoordinate[1],tbi[1])*pow(barycentricCoordinate[2],tbi[2])*pow(barycentricCoordinate[3],tbi[3]);
	bernsteinCoeffMapIterator it=bernsteinCoeffMap.find(tbi);
	if (it!=bernsteinCoeffMap.end()) {
		val*=(*it).second;
		return(val);
	} else {
		serr<< "Tetrahedron Bezier Index "<< tbi << " out of range"<< sendl;
		return ((Real)1);
	}
}

 template<class DataTypes>
 typename BezierTetrahedronSetGeometryAlgorithms<DataTypes>::Vec4 BezierTetrahedronSetGeometryAlgorithms<DataTypes>::computeBernsteinPolynomialGradient(const TetrahedronBezierIndex tbi, const Vec4 barycentricCoordinate)
 {
     Real  val=computeBernsteinPolynomial(tbi,barycentricCoordinate);
     Vec4 dval(0,0,0,0);
     for(unsigned i=0;i<4;++i)
         if(tbi[i] && barycentricCoordinate[i])
             dval[i]=(Real)tbi[i]*val/barycentricCoordinate[i];
     return dval;
 }

 template<class DataTypes>
 typename BezierTetrahedronSetGeometryAlgorithms<DataTypes>::Mat44 BezierTetrahedronSetGeometryAlgorithms<DataTypes>::computeBernsteinPolynomialHessian(const TetrahedronBezierIndex tbi, const Vec4 barycentricCoordinate)
 {
     Vec4 dval = computeBernsteinPolynomialGradient(tbi,barycentricCoordinate);
     Mat44 ddval;
     for(unsigned i=0;i<4;++i)
         if(barycentricCoordinate[i])
             for(unsigned j=0;j<4;++j)
             {
                 if(i==j) { if(tbi[i]>1) ddval[j][i]=((Real)tbi[i]-1.)*dval[j]/barycentricCoordinate[i]; }
                 else { if(tbi[i]) ddval[j][i]=(Real)tbi[i]*dval[j]/barycentricCoordinate[i]; }
             }
     return ddval;
 }

template<class DataTypes>
void BezierTetrahedronSetGeometryAlgorithms<DataTypes>::draw(const core::visual::VisualParams* vparams)
{
#ifndef SOFA_NO_OPENGL
	if ((degree>0) && (container) ){
		TetrahedronSetGeometryAlgorithms<DataTypes>::draw(vparams);
		// Draw Tetra
		if (drawControlPointsEdges.getValue())
		{
			const sofa::helper::vector<Tetrahedron> &tetraArray = this->m_topology->getTetrahedra();

			if (!tetraArray.empty())
			{
				glDisable(GL_LIGHTING);
				const sofa::defaulttype::Vec3f& color = _drawColor.getValue();
				glColor3f(color[0], color[1], color[2]);
				glBegin(GL_LINES);
				const VecCoord& coords = *(this->object->getX());
				VecPointID indexArray;
				Vec4 baryCoord;
				sofa::defaulttype::Vec3f p; //,p2;
				for (unsigned int i = 0; i<tetraArray.size(); i++)
				{
					indexArray.clear();
					container->getGlobalIndexArrayOfBezierPointsInTetrahedron(i, indexArray);
					sofa::helper::vector <sofa::defaulttype::Vec3f> tetraCoord;

					for (unsigned int j = 0; j<indexArray.size(); j++)
					{
/*
						baryCoord=Vec4((double)tbiArray[j][0]/degree,(double)tbiArray[j][1]/degree,(double)tbiArray[j][2]/degree,(double)tbiArray[j][3]/degree);

						p=DataTypes::getCPos(computeNodalValue(i,baryCoord));

						if ((p-p2).norm2()>1e-3) std::cerr<< "error in tetra"<< i << std::endl;*/
						p = DataTypes::getCPos(coords[indexArray[j]]);
						tetraCoord.push_back(p);
					}
					sofa::helper::set<Edge>::iterator ite=bezierTetrahedronEdgeSet.begin();
					for (; ite!=bezierTetrahedronEdgeSet.end(); ite++)
					{
						glVertex3f(tetraCoord[(*ite)[0]][0], tetraCoord[(*ite)[0]][1], tetraCoord[(*ite)[0]][2]);
						glVertex3f(tetraCoord[(*ite)[1]][0], tetraCoord[(*ite)[1]][1], tetraCoord[(*ite)[1]][2]);
					}
				}
				glEnd();
			}
		}
	}
#endif
}

} // namespace topology

} // namespace component

} // namespace sofa

#endif // SOFA_COMPONENTS_TETEAHEDRONSETGEOMETRYALGORITHMS_INL
<|endoftext|>


<commit_before>#ifndef __COMPHELPER_UNOINTERFACETOUNIQUEIDENTIFIERMAPPER__
#define __COMPHELPER_UNOINTERFACETOUNIQUEIDENTIFIERMAPPER__

#include <map>

#ifndef _RTL_USTRING_HXX_
#include <rtl/ustring.hxx>
#endif

#ifndef _COM_SUN_STAR_UNO_XINTERFACE_HPP_
#include <com/sun/star/uno/XInterface.hpp>
#endif

namespace comphelper
{

typedef ::std::map< rtl::OUString, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > IdMap_t;

class UnoInterfaceToUniqueIdentifierMapper
{
public:
    UnoInterfaceToUniqueIdentifierMapper();

    /** returns a unique identifier for the given uno object. IF a uno object is
        registered more than once, the returned identifier is always the same.
    */
    const rtl::OUString& registerReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface );

    /** registers the given uno object with the given identifier.

        @returns
            false, if the given identifier already exists and is not associated with the given interface
    */
    bool registerReference( const rtl::OUString& rIdentifier, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface );

    /** @returns
            the identifier for the given uno object. If this uno object is not already
            registered, an empty string is returned
    */
    const rtl::OUString& getIdentifier( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface ) const;

    /** @returns
        the uno object that is registered with the given identifier. If no uno object
        is registered with the given identifier, an empty reference is returned.
    */
    const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& getReference( const rtl::OUString& rIdentifier ) const;

private:
    bool findReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface, IdMap_t::const_iterator& rIter ) const;
    bool findIdentifier( const rtl::OUString& rIdentifier, IdMap_t::const_iterator& rIter ) const;

    IdMap_t maEntries;
    sal_Int32 mnNextId;
};

}

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.3.330); FILE MERGED 2008/04/01 16:09:12 thb 1.3.330.2: #i85898# Stripping all external header guards 2008/04/01 13:04:22 thb 1.3.330.1: #i85898# Stripping all external header guards<commit_after>#ifndef __COMPHELPER_UNOINTERFACETOUNIQUEIDENTIFIERMAPPER__
#define __COMPHELPER_UNOINTERFACETOUNIQUEIDENTIFIERMAPPER__

#include <map>
#include <rtl/ustring.hxx>
#include <com/sun/star/uno/XInterface.hpp>

namespace comphelper
{

typedef ::std::map< rtl::OUString, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > > IdMap_t;

class UnoInterfaceToUniqueIdentifierMapper
{
public:
    UnoInterfaceToUniqueIdentifierMapper();

    /** returns a unique identifier for the given uno object. IF a uno object is
        registered more than once, the returned identifier is always the same.
    */
    const rtl::OUString& registerReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface );

    /** registers the given uno object with the given identifier.

        @returns
            false, if the given identifier already exists and is not associated with the given interface
    */
    bool registerReference( const rtl::OUString& rIdentifier, const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface );

    /** @returns
            the identifier for the given uno object. If this uno object is not already
            registered, an empty string is returned
    */
    const rtl::OUString& getIdentifier( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface ) const;

    /** @returns
        the uno object that is registered with the given identifier. If no uno object
        is registered with the given identifier, an empty reference is returned.
    */
    const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& getReference( const rtl::OUString& rIdentifier ) const;

private:
    bool findReference( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rInterface, IdMap_t::const_iterator& rIter ) const;
    bool findIdentifier( const rtl::OUString& rIdentifier, IdMap_t::const_iterator& rIter ) const;

    IdMap_t maEntries;
    sal_Int32 mnNextId;
};

}

#endif
<|endoftext|>


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

#include "util/compress.h"
#include "exec/read-write-util.h"
#include "runtime/runtime-state.h"

// Codec libraries
#include <zlib.h>
#include <bzlib.h>
#include <snappy.h>

using namespace std;
using namespace boost;
using namespace impala;

GzipCompressor::GzipCompressor(Format format, MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer),
    format_(format) {
  bzero(&stream_, sizeof(stream_));
  Init();
}

GzipCompressor::~GzipCompressor() {
  (void)deflateEnd(&stream_);
}

Status GzipCompressor::Init() {
  int ret;
  // Initialize to run specified format
  int window_bits = WINDOW_BITS;
  if (format_ == DEFLATE) {
    window_bits = -window_bits;
  } else if (format_ == GZIP) {
    window_bits += GZIP_CODEC;
  }
  if ((ret = deflateInit2(&stream_, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
                          window_bits, 9, Z_DEFAULT_STRATEGY )) != Z_OK) {
    return Status("zlib deflateInit failed: " +  string(stream_.msg));
  }

  return Status::OK;
}

int GzipCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  return deflateBound(&stream_, input_len);
}

Status GzipCompressor::Compress(int input_length, uint8_t* input,
    int* output_length, uint8_t* output) {
  DCHECK_GE(*output_length, MaxOutputLen(input_length));
  stream_.next_in = reinterpret_cast<Bytef*>(input);
  stream_.avail_in = input_length;
  stream_.next_out = reinterpret_cast<Bytef*>(output);
  stream_.avail_out = *output_length;

  int ret = 0;
  if ((ret = deflate(&stream_, Z_FINISH)) != Z_STREAM_END) {
    stringstream ss;
    ss << "zlib deflate failed: " << stream_.msg;
    return Status(ss.str());
  }

  *output_length = *output_length - stream_.avail_out;

  if (deflateReset(&stream_) != Z_OK) {
    return Status("zlib deflateReset failed: " + string(stream_.msg));
  }
  return Status::OK;
}

Status GzipCompressor::ProcessBlock(bool output_preallocated,
                                    int input_length, uint8_t* input,
                                    int* output_length, uint8_t** output) {
  int max_compressed_len = MaxOutputLen(input_length);
  if (!output_preallocated) {
    if (!reuse_buffer_ || buffer_length_ < max_compressed_len || out_buffer_ == NULL) {
      DCHECK(memory_pool_ != NULL) << "Can't allocate without passing in a mem pool";
      buffer_length_ = max_compressed_len;
      out_buffer_ = memory_pool_->Allocate(buffer_length_);
      *output_length = buffer_length_;
    }
    *output = out_buffer_;
  } else if (*output_length < max_compressed_len) {
    return Status("GzipCompressor::ProcessBlock: output length too small");
  }

  RETURN_IF_ERROR(Compress(input_length, input, output_length, *output));
  return Status::OK;
}

BzipCompressor::BzipCompressor(MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer) {
}

int BzipCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  // TODO: is it possible to get a bound with bzip.
  return -1;
}

Status BzipCompressor::ProcessBlock(bool output_preallocated,
                                    int input_length, uint8_t* input,
                                    int *output_length, uint8_t** output) {
  // The bz2 library does not allow input to be NULL, even when input_length is 0. This
  // should be OK because we do not write any file formats that support bzip compression.
  DCHECK(input != NULL);

  // If length is set then the output has been allocated.
  if (output_preallocated) {
    buffer_length_ = *output_length;
    out_buffer_ = *output;
  } else if (!reuse_buffer_ || out_buffer_ == NULL) {
    // guess that we will need no more the input length.
    buffer_length_ = input_length;
    out_buffer_ = temp_memory_pool_.Allocate(buffer_length_);
  }

  unsigned int outlen;
  int ret = BZ_OUTBUFF_FULL;
  while (ret == BZ_OUTBUFF_FULL) {
    if (out_buffer_ == NULL) {
      DCHECK(!output_preallocated);
      temp_memory_pool_.Clear();
      buffer_length_ = buffer_length_ * 2;
      out_buffer_ = temp_memory_pool_.Allocate(buffer_length_);
    }
    outlen = static_cast<unsigned int>(buffer_length_);
    if ((ret = BZ2_bzBuffToBuffCompress(reinterpret_cast<char*>(out_buffer_), &outlen,
        reinterpret_cast<char*>(input),
        static_cast<unsigned int>(input_length), 5, 2, 0)) == BZ_OUTBUFF_FULL) {
      if (output_preallocated) {
        return Status("Too small buffer passed to BzipCompressor");
      }
      out_buffer_ = NULL;
    }
  }
  if (ret !=  BZ_OK) {
    stringstream ss;
    ss << "bzlib BZ2_bzBuffToBuffCompressor failed: " << ret;
    return Status(ss.str());

  }

  *output = out_buffer_;
  *output_length = outlen;
  memory_pool_->AcquireData(&temp_memory_pool_, false);
  return Status::OK;
}

// Currently this is only use for testing of the decompressor.
SnappyBlockCompressor::SnappyBlockCompressor(MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer) {
}

int SnappyBlockCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  // TODO: is it possible to get a bound on this?
  return -1;
}

Status SnappyBlockCompressor::ProcessBlock(bool output_preallocated,
                                           int input_length, uint8_t* input,
                                           int *output_length, uint8_t** output) {
  // Hadoop uses a block compression scheme on top of snappy.  First there is
  // an integer which is the size of the decompressed data followed by a
  // sequence of compressed blocks each preceded with an integer size.
  // For testing purposes we are going to generate two blocks.
  int block_size = input_length / 2;
  size_t length = snappy::MaxCompressedLength(block_size) * 2;
  length += 3 * sizeof (int32_t);
  DCHECK(!output_preallocated || length <= *output_length);

  if (output_preallocated) {
    buffer_length_ = *output_length;
    out_buffer_ = *output;
  } else if (!reuse_buffer_ || out_buffer_ == NULL || buffer_length_ < length) {
    buffer_length_ = length;
    out_buffer_ = memory_pool_->Allocate(buffer_length_);
  }

  uint8_t* outp = out_buffer_;
  uint8_t* sizep;
  ReadWriteUtil::PutInt(outp, static_cast<uint32_t>(input_length));
  outp += sizeof (int32_t);
  while (input_length > 0) {
    // TODO: should this be a while or a do-while loop? Check what Hadoop does.
    // Point at the spot to store the compressed size.
    sizep = outp;
    outp += sizeof (int32_t);
    size_t size;
    snappy::RawCompress(reinterpret_cast<const char*>(input),
        static_cast<size_t>(block_size), reinterpret_cast<char*>(outp), &size);

    ReadWriteUtil::PutInt(sizep, static_cast<uint32_t>(size));
    input += block_size;
    input_length -= block_size;
    outp += size;
  }

  *output = out_buffer_;
  *output_length = outp - out_buffer_;
  return Status::OK;
}

SnappyCompressor::SnappyCompressor(MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer) {
}

int SnappyCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  return snappy::MaxCompressedLength(input_len);
}

Status SnappyCompressor::ProcessBlock(bool output_preallocated,
                                      int input_length, uint8_t* input,
                                      int* output_length, uint8_t** output) {
  int max_compressed_len = MaxOutputLen(input_length);
  if (output_preallocated && *output_length < max_compressed_len) {
    return Status("SnappyCompressor::ProcessBlock: output length too small");
  }

  if (!output_preallocated) {
      if ((!reuse_buffer_ || buffer_length_ < max_compressed_len)) {
        DCHECK(memory_pool_ != NULL) << "Can't allocate without passing in a mem pool";
        buffer_length_ = max_compressed_len;
        out_buffer_ = memory_pool_->Allocate(buffer_length_);
      }
    *output = out_buffer_;
  }

  size_t out_len;
  snappy::RawCompress(reinterpret_cast<const char*>(input),
      static_cast<size_t>(input_length),
      reinterpret_cast<char*>(*output), &out_len);
  *output_length = out_len;
  return Status::OK;
}
<commit_msg>Workaround for zlib bug that was breaking code coverage build.<commit_after>// Copyright 2012 Cloudera Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "util/compress.h"
#include "exec/read-write-util.h"
#include "runtime/runtime-state.h"

// Codec libraries
#include <zlib.h>
#include <bzlib.h>
#include <snappy.h>

using namespace std;
using namespace boost;
using namespace impala;

GzipCompressor::GzipCompressor(Format format, MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer),
    format_(format) {
  bzero(&stream_, sizeof(stream_));
  Init();
}

GzipCompressor::~GzipCompressor() {
  (void)deflateEnd(&stream_);
}

Status GzipCompressor::Init() {
  int ret;
  // Initialize to run specified format
  int window_bits = WINDOW_BITS;
  if (format_ == DEFLATE) {
    window_bits = -window_bits;
  } else if (format_ == GZIP) {
    window_bits += GZIP_CODEC;
  }
  if ((ret = deflateInit2(&stream_, Z_DEFAULT_COMPRESSION, Z_DEFLATED,
                          window_bits, 9, Z_DEFAULT_STRATEGY )) != Z_OK) {
    return Status("zlib deflateInit failed: " +  string(stream_.msg));
  }

  return Status::OK;
}

int GzipCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
#if !defined ZLIB_VERNUM || ZLIB_VERNUM <= 0x1230
  if (UNLIKELY(input_len == 0 && format_ == GZIP)) {
    // zlib version 1.2.3 has a bug in deflateBound() that causes it to return too low a
    // bound for this case. Hardcode the value returned in zlib version 1.2.3.1+.
    return 23;
  }
#endif
  return deflateBound(&stream_, input_len);
}

Status GzipCompressor::Compress(int input_length, uint8_t* input,
    int* output_length, uint8_t* output) {
  DCHECK_GE(*output_length, MaxOutputLen(input_length));
  stream_.next_in = reinterpret_cast<Bytef*>(input);
  stream_.avail_in = input_length;
  stream_.next_out = reinterpret_cast<Bytef*>(output);
  stream_.avail_out = *output_length;

  int ret = 0;
  if ((ret = deflate(&stream_, Z_FINISH)) != Z_STREAM_END) {
    stringstream ss;
    ss << "zlib deflate failed: " << stream_.msg;
    return Status(ss.str());
  }

  *output_length = *output_length - stream_.avail_out;

  if (deflateReset(&stream_) != Z_OK) {
    return Status("zlib deflateReset failed: " + string(stream_.msg));
  }
  return Status::OK;
}

Status GzipCompressor::ProcessBlock(bool output_preallocated,
                                    int input_length, uint8_t* input,
                                    int* output_length, uint8_t** output) {
  int max_compressed_len = MaxOutputLen(input_length);
  if (!output_preallocated) {
    if (!reuse_buffer_ || buffer_length_ < max_compressed_len || out_buffer_ == NULL) {
      DCHECK(memory_pool_ != NULL) << "Can't allocate without passing in a mem pool";
      buffer_length_ = max_compressed_len;
      out_buffer_ = memory_pool_->Allocate(buffer_length_);
      *output_length = buffer_length_;
    }
    *output = out_buffer_;
  } else if (*output_length < max_compressed_len) {
    return Status("GzipCompressor::ProcessBlock: output length too small");
  }

  RETURN_IF_ERROR(Compress(input_length, input, output_length, *output));
  return Status::OK;
}

BzipCompressor::BzipCompressor(MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer) {
}

int BzipCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  // TODO: is it possible to get a bound with bzip.
  return -1;
}

Status BzipCompressor::ProcessBlock(bool output_preallocated,
                                    int input_length, uint8_t* input,
                                    int *output_length, uint8_t** output) {
  // The bz2 library does not allow input to be NULL, even when input_length is 0. This
  // should be OK because we do not write any file formats that support bzip compression.
  DCHECK(input != NULL);

  // If length is set then the output has been allocated.
  if (output_preallocated) {
    buffer_length_ = *output_length;
    out_buffer_ = *output;
  } else if (!reuse_buffer_ || out_buffer_ == NULL) {
    // guess that we will need no more the input length.
    buffer_length_ = input_length;
    out_buffer_ = temp_memory_pool_.Allocate(buffer_length_);
  }

  unsigned int outlen;
  int ret = BZ_OUTBUFF_FULL;
  while (ret == BZ_OUTBUFF_FULL) {
    if (out_buffer_ == NULL) {
      DCHECK(!output_preallocated);
      temp_memory_pool_.Clear();
      buffer_length_ = buffer_length_ * 2;
      out_buffer_ = temp_memory_pool_.Allocate(buffer_length_);
    }
    outlen = static_cast<unsigned int>(buffer_length_);
    if ((ret = BZ2_bzBuffToBuffCompress(reinterpret_cast<char*>(out_buffer_), &outlen,
        reinterpret_cast<char*>(input),
        static_cast<unsigned int>(input_length), 5, 2, 0)) == BZ_OUTBUFF_FULL) {
      if (output_preallocated) {
        return Status("Too small buffer passed to BzipCompressor");
      }
      out_buffer_ = NULL;
    }
  }
  if (ret !=  BZ_OK) {
    stringstream ss;
    ss << "bzlib BZ2_bzBuffToBuffCompressor failed: " << ret;
    return Status(ss.str());

  }

  *output = out_buffer_;
  *output_length = outlen;
  memory_pool_->AcquireData(&temp_memory_pool_, false);
  return Status::OK;
}

// Currently this is only use for testing of the decompressor.
SnappyBlockCompressor::SnappyBlockCompressor(MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer) {
}

int SnappyBlockCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  // TODO: is it possible to get a bound on this?
  return -1;
}

Status SnappyBlockCompressor::ProcessBlock(bool output_preallocated,
                                           int input_length, uint8_t* input,
                                           int *output_length, uint8_t** output) {
  // Hadoop uses a block compression scheme on top of snappy.  First there is
  // an integer which is the size of the decompressed data followed by a
  // sequence of compressed blocks each preceded with an integer size.
  // For testing purposes we are going to generate two blocks.
  int block_size = input_length / 2;
  size_t length = snappy::MaxCompressedLength(block_size) * 2;
  length += 3 * sizeof (int32_t);
  DCHECK(!output_preallocated || length <= *output_length);

  if (output_preallocated) {
    buffer_length_ = *output_length;
    out_buffer_ = *output;
  } else if (!reuse_buffer_ || out_buffer_ == NULL || buffer_length_ < length) {
    buffer_length_ = length;
    out_buffer_ = memory_pool_->Allocate(buffer_length_);
  }

  uint8_t* outp = out_buffer_;
  uint8_t* sizep;
  ReadWriteUtil::PutInt(outp, static_cast<uint32_t>(input_length));
  outp += sizeof (int32_t);
  while (input_length > 0) {
    // TODO: should this be a while or a do-while loop? Check what Hadoop does.
    // Point at the spot to store the compressed size.
    sizep = outp;
    outp += sizeof (int32_t);
    size_t size;
    snappy::RawCompress(reinterpret_cast<const char*>(input),
        static_cast<size_t>(block_size), reinterpret_cast<char*>(outp), &size);

    ReadWriteUtil::PutInt(sizep, static_cast<uint32_t>(size));
    input += block_size;
    input_length -= block_size;
    outp += size;
  }

  *output = out_buffer_;
  *output_length = outp - out_buffer_;
  return Status::OK;
}

SnappyCompressor::SnappyCompressor(MemPool* mem_pool, bool reuse_buffer)
  : Codec(mem_pool, reuse_buffer) {
}

int SnappyCompressor::MaxOutputLen(int input_len, const uint8_t* input) {
  return snappy::MaxCompressedLength(input_len);
}

Status SnappyCompressor::ProcessBlock(bool output_preallocated,
                                      int input_length, uint8_t* input,
                                      int* output_length, uint8_t** output) {
  int max_compressed_len = MaxOutputLen(input_length);
  if (output_preallocated && *output_length < max_compressed_len) {
    return Status("SnappyCompressor::ProcessBlock: output length too small");
  }

  if (!output_preallocated) {
      if ((!reuse_buffer_ || buffer_length_ < max_compressed_len)) {
        DCHECK(memory_pool_ != NULL) << "Can't allocate without passing in a mem pool";
        buffer_length_ = max_compressed_len;
        out_buffer_ = memory_pool_->Allocate(buffer_length_);
      }
    *output = out_buffer_;
  }

  size_t out_len;
  snappy::RawCompress(reinterpret_cast<const char*>(input),
      static_cast<size_t>(input_length),
      reinterpret_cast<char*>(*output), &out_len);
  *output_length = out_len;
  return Status::OK;
}
<|endoftext|>


<commit_before>#include "databasecontroller.h"
#include "dbsettings.h"

#include <QCoreApplication>
#include <QFileInfo>
#include <QGlobalStatic>
#include <QLockFile>

Q_GLOBAL_STATIC(DatabaseController, _instance)

static void setupDatabaseController();
Q_COREAPP_STARTUP_FUNCTION(setupDatabaseController)

DatabaseController::DatabaseController(QObject *parent) :
	QObject(parent),
	_settings(new QSettings()),
	_opQueue(new OperationQueue(this)),
	_dbPath(),
	_js(new QJsonSerializer(this)),
	_packageDatabase(),
	_watcher(new QFileSystemWatcher(this)),
	_loaded(false)
{
	_settings->beginGroup(QStringLiteral("lib/dbcontroller"));

	connect(this, &DatabaseController::operationsRequired,
			_opQueue, &OperationQueue::setOperations);

	try {
		if(_settings->contains(QStringLiteral("path"))) {
			loadDb(_settings->value(QStringLiteral("path")).toString());
			sync();
		}
	} catch(QException &e) {
		qCritical() << e.what();
		cleanUp();
	}

	connect(_watcher, &QFileSystemWatcher::fileChanged,
			this, &DatabaseController::fileChanged);
}

DatabaseController *DatabaseController::instance()
{
	return _instance;
}

OperationQueue *DatabaseController::operationQueue() const
{
	return _opQueue;
}

QStringList DatabaseController::listPackages() const
{
	return _packageDatabase.packages.keys();
}

QString DatabaseController::currentPath() const
{
	return _dbPath;
}

void DatabaseController::createDb(const QString &path, const QStringList &packages)
{
	PackageDatabase p;
	foreach (auto package, packages)
		p.packages[package] = {package, false};

	writeFile(p, path);

	loadDb(path);
}

void DatabaseController::loadDb(const QString &path)
{
	cleanUp();

	_settings->setValue(QStringLiteral("path"), path);
	_dbPath = path;

	readFile();

	_watcher->addPath(_dbPath);
	_loaded = true;
}

void DatabaseController::reloadDb()
{
	Q_UNIMPLEMENTED();
}

bool DatabaseController::isLoaded() const
{
	return _loaded;
}

QSettings::SettingsMap DatabaseController::readSettings() const
{
	return QJsonValue(_packageDatabase.settings).toVariant().toMap();
}

void DatabaseController::writeSettings(const QSettings::SettingsMap &map)
{
	_packageDatabase.settings = QJsonValue::fromVariant(map).toObject();

	writeFile(_packageDatabase, _dbPath);
}

void DatabaseController::updateDb(const QStringList &packages)
{
	auto set = QSet<QString>::fromList(packages);
	for(auto it = _packageDatabase.packages.begin(); it != _packageDatabase.packages.end(); ) {
		if(!set.contains(it.key()))
			it = _packageDatabase.packages.erase(it);
		else{
			set.remove(it.key());
			it++;
		}
	}

	foreach (auto package, set)
		_packageDatabase.packages[package] = {package};

	QLockFile lock(lockPath(_dbPath));
	QFile file(_dbPath);
	if(!lock.lock())
		throw DatabaseException("Lock failed");
	if(!file.open(QIODevice::WriteOnly))
		throw DatabaseException(file.errorString());

	_packageDatabase.parseHarderToJson(_js);
	_js->serializeTo<PackageDatabase>(&file, _packageDatabase);
	file.close();
	lock.unlock();
}

void DatabaseController::sync()
{
	QStringList pI, pUI;
	auto installedP = PluginLoader::plugin()->listAllPackages();
	auto targetP = _packageDatabase.packages;

	for(auto it = targetP.constBegin(); it != targetP.constEnd(); it++){
		auto contains = installedP.contains(it->name);
		if(!contains)
			pI.append(it->name);

		if(it->removed && contains)
			pUI.append(it->name);
	}

	emit operationsRequired(pI, pUI);
}

void DatabaseController::fileChanged()
{
	try {
		readFile();
		sync();
	} catch(QException &e){
		qWarning() << "Failed to reload changed file:" << e.what();
	}
}

void DatabaseController::cleanUp()
{
	_packageDatabase = PackageDatabase();
	_watcher->removePaths(_watcher->files());
}

void DatabaseController::readFile()
{
	QLockFile lock(lockPath(_dbPath));
	if(!lock.lock())
		throw DatabaseException("Lock failed");

	QFile file(_dbPath);
	file.open(QIODevice::ReadOnly);
	auto pdb = _js->deserializeFrom<PackageDatabase>(&file);
	file.close();
	lock.unlock();

	pdb.parseHarderFromJson(_js);
	_packageDatabase = pdb;
}

void DatabaseController::writeFile(PackageDatabase p, const QString &path)
{
	QLockFile lock(lockPath(path));
	if(!lock.lock())
		throw DatabaseException("Lock failed");
	QFile file(path);
	if(!file.open(QIODevice::WriteOnly))
		throw DatabaseException(file.errorString());

	p.parseHarderToJson(_js);
	_js->serializeTo<PackageDatabase>(&file, p);
	file.close();
	lock.unlock();
}

QString DatabaseController::lockPath(const QString &path)
{
	QFileInfo info(path);
	return info.absolutePath() + "." + info.fileName() + ".lock";
}

static void setupDatabaseController()
{
	QJsonSerializer::registerListConverters<PackageInfo>();
	DbSettings::registerSettings();
}
<commit_msg>fix lock path<commit_after>#include "databasecontroller.h"
#include "dbsettings.h"

#include <QCoreApplication>
#include <QFileInfo>
#include <QGlobalStatic>
#include <QLockFile>

Q_GLOBAL_STATIC(DatabaseController, _instance)

static void setupDatabaseController();
Q_COREAPP_STARTUP_FUNCTION(setupDatabaseController)

DatabaseController::DatabaseController(QObject *parent) :
	QObject(parent),
	_settings(new QSettings()),
	_opQueue(new OperationQueue(this)),
	_dbPath(),
	_js(new QJsonSerializer(this)),
	_packageDatabase(),
	_watcher(new QFileSystemWatcher(this)),
	_loaded(false)
{
	_settings->beginGroup(QStringLiteral("lib/dbcontroller"));

	connect(this, &DatabaseController::operationsRequired,
			_opQueue, &OperationQueue::setOperations);

	try {
		if(_settings->contains(QStringLiteral("path"))) {
			loadDb(_settings->value(QStringLiteral("path")).toString());
			sync();
		}
	} catch(QException &e) {
		qCritical() << e.what();
		cleanUp();
	}

	connect(_watcher, &QFileSystemWatcher::fileChanged,
			this, &DatabaseController::fileChanged);
}

DatabaseController *DatabaseController::instance()
{
	return _instance;
}

OperationQueue *DatabaseController::operationQueue() const
{
	return _opQueue;
}

QStringList DatabaseController::listPackages() const
{
	return _packageDatabase.packages.keys();
}

QString DatabaseController::currentPath() const
{
	return _dbPath;
}

void DatabaseController::createDb(const QString &path, const QStringList &packages)
{
	PackageDatabase p;
	foreach (auto package, packages)
		p.packages[package] = {package, false};

	writeFile(p, path);

	loadDb(path);
}

void DatabaseController::loadDb(const QString &path)
{
	cleanUp();

	_settings->setValue(QStringLiteral("path"), path);
	_dbPath = path;

	readFile();

	_watcher->addPath(_dbPath);
	_loaded = true;
}

void DatabaseController::reloadDb()
{
	Q_UNIMPLEMENTED();
}

bool DatabaseController::isLoaded() const
{
	return _loaded;
}

QSettings::SettingsMap DatabaseController::readSettings() const
{
	return QJsonValue(_packageDatabase.settings).toVariant().toMap();
}

void DatabaseController::writeSettings(const QSettings::SettingsMap &map)
{
	_packageDatabase.settings = QJsonValue::fromVariant(map).toObject();

	writeFile(_packageDatabase, _dbPath);
}

void DatabaseController::updateDb(const QStringList &packages)
{
	auto set = QSet<QString>::fromList(packages);
	for(auto it = _packageDatabase.packages.begin(); it != _packageDatabase.packages.end(); ) {
		if(!set.contains(it.key()))
			it = _packageDatabase.packages.erase(it);
		else{
			set.remove(it.key());
			it++;
		}
	}

	foreach (auto package, set)
		_packageDatabase.packages[package] = {package};

	QLockFile lock(lockPath(_dbPath));
	QFile file(_dbPath);
	if(!lock.lock())
		throw DatabaseException("Lock failed");
	if(!file.open(QIODevice::WriteOnly))
		throw DatabaseException(file.errorString());

	_packageDatabase.parseHarderToJson(_js);
	_js->serializeTo<PackageDatabase>(&file, _packageDatabase);
	file.close();
	lock.unlock();
}

void DatabaseController::sync()
{
	QStringList pI, pUI;
	auto installedP = PluginLoader::plugin()->listAllPackages();
	auto targetP = _packageDatabase.packages;

	for(auto it = targetP.constBegin(); it != targetP.constEnd(); it++){
		auto contains = installedP.contains(it->name);
		if(!contains)
			pI.append(it->name);

		if(it->removed && contains)
			pUI.append(it->name);
	}

	emit operationsRequired(pI, pUI);
}

void DatabaseController::fileChanged()
{
	try {
		readFile();
		sync();
	} catch(QException &e){
		qWarning() << "Failed to reload changed file:" << e.what();
	}
}

void DatabaseController::cleanUp()
{
	_packageDatabase = PackageDatabase();
	_watcher->removePaths(_watcher->files());
}

void DatabaseController::readFile()
{
	QLockFile lock(lockPath(_dbPath));
	if(!lock.lock())
		throw DatabaseException("Lock failed");

	QFile file(_dbPath);
	file.open(QIODevice::ReadOnly);
	auto pdb = _js->deserializeFrom<PackageDatabase>(&file);
	file.close();
	lock.unlock();

	pdb.parseHarderFromJson(_js);
	_packageDatabase = pdb;
}

void DatabaseController::writeFile(PackageDatabase p, const QString &path)
{
	QLockFile lock(lockPath(path));
	if(!lock.lock())
		throw DatabaseException("Lock failed");
	QFile file(path);
	if(!file.open(QIODevice::WriteOnly))
		throw DatabaseException(file.errorString());

	p.parseHarderToJson(_js);
	_js->serializeTo<PackageDatabase>(&file, p);
	file.close();
	lock.unlock();
}

QString DatabaseController::lockPath(const QString &path)
{
	QFileInfo info(path);
	return info.absolutePath() + "/." + info.fileName() + ".lock";
}

static void setupDatabaseController()
{
	QJsonSerializer::registerListConverters<PackageInfo>();
	DbSettings::registerSettings();
}
<|endoftext|>


<commit_before>
/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */
#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

#define SMALL   SkIntToScalar(2)
#define REAL    SkFloatToScalar(1.5f)
#define BIG     SkIntToScalar(10)
#define REALBIG SkFloatToScalar(30.5f)

class BlurRectBench: public SkBenchmark {
    SkScalar    fRadius;
    SkString    fName;

public:
    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
        fRadius = rad;
    }

protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    SkScalar radius() const {
        return fRadius;
    }

    void setName( SkString name ) {
        fName = name;
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        paint.setAntiAlias(true);

        int pad = fRadius * 1.5 + 1;
        SkRect r = SkRect::MakeWH(2 * pad + 1, 2 * pad + 1);

        int loop_count;

        if (fRadius > SkIntToScalar(50)) {
          loop_count = 10;
        } else if (fRadius > SkIntToScalar(5)) {
          loop_count = 1000;
        } else {
          loop_count = 10000;
        }

        preBenchSetup( r );

        for (int i = 0; i < SkBENCHLOOP(loop_count); i++) {
            makeBlurryRect( r );
        }
    }

    virtual void makeBlurryRect( SkRect &r ) = 0;
    virtual void preBenchSetup( SkRect &r ) {}
private:
    typedef SkBenchmark INHERITED;
};

class BlurRectDirectBench: public BlurRectBench {
 public:
    BlurRectDirectBench( void *param, SkScalar rad ) : BlurRectBench( param, rad ) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRound(rad));
        }

        setName( name );
    }
protected:
    virtual void makeBlurryRect( SkRect &r ) {
        SkMask mask;
        SkBlurMask::BlurRect( &mask, r, radius(), SkBlurMask::kNormal_Style, SkBlurMask::kHigh_Quality );
    }
};

class BlurRectSeparableBench: public BlurRectBench {
    SkMask fSrcMask;
public:
    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench( param, rad ) {
        SkString name;
        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_separable_%d", SkScalarRound(rad));
        }

        setName( name );
    }

protected:
    virtual void preBenchSetup( SkRect &r ) {
        fSrcMask.fFormat = SkMask::kA8_Format;
        fSrcMask.fRowBytes = r.width();
        fSrcMask.fBounds = SkIRect::MakeWH(r.width(), r.height());
        fSrcMask.fImage = SkMask::AllocImage( fSrcMask.computeTotalImageSize() );

        memset( fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize() );
    }

    virtual void makeBlurryRect( SkRect &r ) {
        SkMask mask;
        SkBlurMask::BlurSeparable( &mask, fSrcMask, radius(), SkBlurMask::kNormal_Style, SkBlurMask::kHigh_Quality );
    }
};

DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
<commit_msg>fix warnings (float to int), and convert to skia-style<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkBenchmark.h"
#include "SkCanvas.h"
#include "SkPaint.h"
#include "SkRandom.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkBlurMask.h"

#define SMALL   SkIntToScalar(2)
#define REAL    SkFloatToScalar(1.5f)
#define BIG     SkIntToScalar(10)
#define REALBIG SkFloatToScalar(30.5f)

class BlurRectBench: public SkBenchmark {
    SkScalar    fRadius;
    SkString    fName;

public:
    BlurRectBench(void *param, SkScalar rad) : INHERITED(param) {
        fRadius = rad;
    }

protected:
    virtual const char* onGetName() {
        return fName.c_str();
    }

    SkScalar radius() const {
        return fRadius;
    }

    void setName(const SkString& name) {
        fName = name;
    }

    virtual void onDraw(SkCanvas* canvas) {
        SkPaint paint;
        this->setupPaint(&paint);

        paint.setAntiAlias(true);

        SkScalar pad = fRadius*3/2 + SK_Scalar1;
        SkRect r = SkRect::MakeWH(2 * pad + SK_Scalar1, 2 * pad + SK_Scalar1);

        int loop_count;

        if (fRadius > SkIntToScalar(50)) {
          loop_count = 10;
        } else if (fRadius > SkIntToScalar(5)) {
          loop_count = 1000;
        } else {
          loop_count = 10000;
        }

        preBenchSetup(r);

        for (int i = 0; i < SkBENCHLOOP(loop_count); i++) {
            makeBlurryRect(r);
        }
    }

    virtual void makeBlurryRect(const SkRect&) = 0;
    virtual void preBenchSetup(const SkRect&) {}
private:
    typedef SkBenchmark INHERITED;
};

class BlurRectDirectBench: public BlurRectBench {
 public:
    BlurRectDirectBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;

        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_direct_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_direct_%d", SkScalarRound(rad));
        }

        setName(name);
    }
protected:
    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurRect(&mask, r, radius(), SkBlurMask::kNormal_Style,
                             SkBlurMask::kHigh_Quality);
    }
};

class BlurRectSeparableBench: public BlurRectBench {
    SkMask fSrcMask;
public:
    BlurRectSeparableBench(void *param, SkScalar rad) : BlurRectBench(param, rad) {
        SkString name;
        if (SkScalarFraction(rad) != 0) {
            name.printf("blurrect_separable_%.2f", SkScalarToFloat(rad));
        } else {
            name.printf("blurrect_separable_%d", SkScalarRound(rad));
        }

        setName(name);
    }

protected:
    virtual void preBenchSetup(const SkRect& r) SK_OVERRIDE {
        r.roundOut(&fSrcMask.fBounds);
        fSrcMask.fFormat = SkMask::kA8_Format;
        fSrcMask.fRowBytes = fSrcMask.fBounds.width();
        fSrcMask.fImage = SkMask::AllocImage(fSrcMask.computeTotalImageSize());

        memset(fSrcMask.fImage, 0xff, fSrcMask.computeTotalImageSize());
    }

    virtual void makeBlurryRect(const SkRect& r) SK_OVERRIDE {
        SkMask mask;
        SkBlurMask::BlurSeparable(&mask, fSrcMask, radius(),
                                  SkBlurMask::kNormal_Style,
                                  SkBlurMask::kHigh_Quality);
    }
};

DEF_BENCH(return new BlurRectSeparableBench(p, SMALL);)
DEF_BENCH(return new BlurRectSeparableBench(p, BIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REALBIG);)
DEF_BENCH(return new BlurRectSeparableBench(p, REAL);)
DEF_BENCH(return new BlurRectDirectBench(p, SMALL);)
DEF_BENCH(return new BlurRectDirectBench(p, BIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REALBIG);)
DEF_BENCH(return new BlurRectDirectBench(p, REAL);)
<|endoftext|>