<commit_before>/*
 * DistributionContainer.C
 *
 *  Created on: Jul 6, 2012
 *      Author: alfoa
 */
#include "DistributionContainer.h"
//#include "Factory.h"
//#include "distribution_1D.h"
#include "distribution_min.h"
#include <iostream>
#include <math.h>
#include <cmath>
#include <cstdlib>
#include <stdlib.h>
#include <vector>
#include <map>
using namespace std;

#ifndef mooseError
#define mooseError(msg) { std::cerr << "\n\n" << msg << "\n\n"; }
#endif

class DistributionContainer;

DistributionContainer::DistributionContainer()
{
}
DistributionContainer::~DistributionContainer()
{
}

/*void
DistributionContainer::addDistributionInContainer(const std::string & type, const std::string & name, InputParameters params){
   // create the distribution type
   distribution * dist = dynamic_cast<distribution *>(Factory::instance()->create(type, name, params));
   if (_dist_by_name.find(name) == _dist_by_name.end())
    _dist_by_name[name] = dist;
   else
     mooseError("Distribution with name " << name << " already exists");

   _dist_by_type[type].push_back(dist);

   }*/

void
DistributionContainer::addDistributionInContainer(const std::string & type, const std::string & name, distribution * dist){
   // create the distribution type
  //distribution * dist = dynamic_cast<distribution *>(Factory::instance()->create(type, name, params));
   if (_dist_by_name.find(name) == _dist_by_name.end())
    _dist_by_name[name] = dist;
   else
     mooseError("Distribution with name " << name << " already exists");

   _dist_by_type[type].push_back(dist);

}

//void
//DistributionContainer::constructDistributionContainer(std::string DistAlias, distribution_type type, double xmin, double xmax, double param1, double param2, unsigned int seed){
//	_distribution_cont.push_back(distribution(type, xmin, xmax, param1, param2, seed));
//	_vector_pos_map[DistAlias]=_distribution_cont.size()-1;
//}
//void
//DistributionContainer::constructDistributionContainerCustom(std::string DistAlias, distribution_type type, std::vector< double > dist_x, std::vector< double > dist_y, int numPoints, custom_dist_fit_type fit_type, unsigned int seed){
//
//	_distribution_cont.push_back(distribution(dist_x, dist_y, numPoints, fit_type, seed));
//	_vector_pos_map[DistAlias]=_distribution_cont.size()-1;
//}

std::string
DistributionContainer::getType(std::string DistAlias){

    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       std::string type = getDistributionType(*dist);
       if(type == "DistributionError"){
         mooseError("Type for distribution " << DistAlias << " not found");
       }
       return type;
    }
    else{
       mooseError("Distribution " << DistAlias << " not found in distribution container");
       return "DistributionError";
    }

}

void
DistributionContainer::seedRandom(unsigned int seed){
   srand( seed );
}
double
DistributionContainer::random(){
   return rand();
//   return -1.0;
}

// to be implemented
bool DistributionContainer::checkCdf(double probability, std::vector<double> values){
   return false;
}
// end to be implemented
// to be implemented
bool DistributionContainer::checkCdf(double probability, double value){
   return false;
}
// end to be implemented

double
DistributionContainer::getVariable(std::string paramName,std::string DistAlias){
    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       return getDistributionVariable(*dist,paramName);
    }
    mooseError("Distribution " << DistAlias << " not found in distribution container");
    return -1;
}

void
DistributionContainer::updateVariable(std::string paramName,double newValue,std::string DistAlias){
    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       DistributionUpdateVariable(*dist,paramName,newValue);
    }
    mooseError("Distribution " + DistAlias + " was not found in distribution container.");
}

//double
//DistributionContainer::getMin(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getMin();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//double
//DistributionContainer::getMax(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getMax();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//double
//DistributionContainer::getParamater1(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getParamater1();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//double
//DistributionContainer::getParameter2(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getParameter2();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//void
//DistributionContainer::changeParameter1(std::string DistAlias,double newParameter1){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	_distribution_cont[position].changeParameter1(newParameter1);
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    }
//
//}
//
//void
//DistributionContainer::changeParameter2(std::string DistAlias,double newParameter2){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	_distribution_cont[position].changeParameter2(newParameter2);
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    }
//
//}

double
DistributionContainer::Pdf(std::string DistAlias, double x){

    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       return DistributionPdf(*dist,x);
    }
    mooseError("Distribution " + DistAlias + " was not found in distribution container.");
    return -1.0;
}

double
DistributionContainer::Cdf(std::string DistAlias, double x){

   if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       return DistributionCdf(*dist,x);
    }
    mooseError("Distribution " + DistAlias + " was not found in distribution container.");
    return -1.0;

}

double
DistributionContainer::randGen(char * DistAlias, double RNG){
  return randGen(std::string(DistAlias), RNG);
}

double
DistributionContainer::randGen(std::string DistAlias, double RNG){

    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
        distribution * dist = _dist_by_name.find(DistAlias)->second;
        return dist->RandomNumberGenerator(RNG);
     }
     mooseError("Distribution " + DistAlias + " was not found in distribution container.");
     return -1.0;

}

//int DistributionContainer::getPosition(std::string DistAlias){
//	std::map <std::string, int>::iterator p;
//
//	p = _vector_pos_map.find(DistAlias);
//	if(p != _vector_pos_map.end()){
//       return (p->second);
//	}
//	else{
//		return -1;
//	}
//}

DistributionContainer & DistributionContainer::Instance() {
  if(_instance == NULL){
    _instance = new DistributionContainer();
  }
  return *_instance;
}

DistributionContainer * DistributionContainer::_instance;

/* the str_to_string_p and free_string_p are for python use */

std::string * str_to_string_p(char *s) {
  return new std::string(s);
}

void free_string_p(std::string * s) {
  delete s;
}

<commit_msg>random from 0 to 1<commit_after>/*
 * DistributionContainer.C
 *
 *  Created on: Jul 6, 2012
 *      Author: alfoa
 */
#include "DistributionContainer.h"
//#include "Factory.h"
//#include "distribution_1D.h"
#include "distribution_min.h"
#include <iostream>
#include <math.h>
#include <cmath>
#include <cstdlib>
#include <stdlib.h>
#include <vector>
#include <map>
using namespace std;

#ifndef mooseError
#define mooseError(msg) { std::cerr << "\n\n" << msg << "\n\n"; }
#endif

class DistributionContainer;

DistributionContainer::DistributionContainer()
{
}
DistributionContainer::~DistributionContainer()
{
}

/*void
DistributionContainer::addDistributionInContainer(const std::string & type, const std::string & name, InputParameters params){
   // create the distribution type
   distribution * dist = dynamic_cast<distribution *>(Factory::instance()->create(type, name, params));
   if (_dist_by_name.find(name) == _dist_by_name.end())
    _dist_by_name[name] = dist;
   else
     mooseError("Distribution with name " << name << " already exists");

   _dist_by_type[type].push_back(dist);

   }*/

void
DistributionContainer::addDistributionInContainer(const std::string & type, const std::string & name, distribution * dist){
   // create the distribution type
  //distribution * dist = dynamic_cast<distribution *>(Factory::instance()->create(type, name, params));
   if (_dist_by_name.find(name) == _dist_by_name.end())
    _dist_by_name[name] = dist;
   else
     mooseError("Distribution with name " << name << " already exists");

   _dist_by_type[type].push_back(dist);

}

//void
//DistributionContainer::constructDistributionContainer(std::string DistAlias, distribution_type type, double xmin, double xmax, double param1, double param2, unsigned int seed){
//	_distribution_cont.push_back(distribution(type, xmin, xmax, param1, param2, seed));
//	_vector_pos_map[DistAlias]=_distribution_cont.size()-1;
//}
//void
//DistributionContainer::constructDistributionContainerCustom(std::string DistAlias, distribution_type type, std::vector< double > dist_x, std::vector< double > dist_y, int numPoints, custom_dist_fit_type fit_type, unsigned int seed){
//
//	_distribution_cont.push_back(distribution(dist_x, dist_y, numPoints, fit_type, seed));
//	_vector_pos_map[DistAlias]=_distribution_cont.size()-1;
//}

std::string
DistributionContainer::getType(std::string DistAlias){

    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       std::string type = getDistributionType(*dist);
       if(type == "DistributionError"){
         mooseError("Type for distribution " << DistAlias << " not found");
       }
       return type;
    }
    else{
       mooseError("Distribution " << DistAlias << " not found in distribution container");
       return "DistributionError";
    }

}

void
DistributionContainer::seedRandom(unsigned int seed){
   srand( seed );
}
double
DistributionContainer::random(){
   return (rand()/RAND_MAX);
//   return -1.0;
}

// to be implemented
bool DistributionContainer::checkCdf(double probability, std::vector<double> values){
   return false;
}
// end to be implemented
// to be implemented
bool DistributionContainer::checkCdf(double probability, double value){
   return false;
}
// end to be implemented

double
DistributionContainer::getVariable(std::string paramName,std::string DistAlias){
    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       return getDistributionVariable(*dist,paramName);
    }
    mooseError("Distribution " << DistAlias << " not found in distribution container");
    return -1;
}

void
DistributionContainer::updateVariable(std::string paramName,double newValue,std::string DistAlias){
    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       DistributionUpdateVariable(*dist,paramName,newValue);
    }
    mooseError("Distribution " + DistAlias + " was not found in distribution container.");
}

//double
//DistributionContainer::getMin(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getMin();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//double
//DistributionContainer::getMax(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getMax();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//double
//DistributionContainer::getParamater1(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getParamater1();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//double
//DistributionContainer::getParameter2(std::string DistAlias){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	return _distribution_cont[position].getParameter2();
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    	return DISTRIBUTION_ERROR;
//    }
//
//}
//
//void
//DistributionContainer::changeParameter1(std::string DistAlias,double newParameter1){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	_distribution_cont[position].changeParameter1(newParameter1);
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    }
//
//}
//
//void
//DistributionContainer::changeParameter2(std::string DistAlias,double newParameter2){
//    int position;
//
//    position = getPosition(DistAlias);
//
//    if(position != -1){
//    	_distribution_cont[position].changeParameter2(newParameter2);
//    }
//    else{
//    	std::cerr << " ERROR: distribution " << DistAlias << "not present in the mapping";
//    }
//
//}

double
DistributionContainer::Pdf(std::string DistAlias, double x){

    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       return DistributionPdf(*dist,x);
    }
    mooseError("Distribution " + DistAlias + " was not found in distribution container.");
    return -1.0;
}

double
DistributionContainer::Cdf(std::string DistAlias, double x){

   if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
       distribution * dist = _dist_by_name.find(DistAlias)->second;
       return DistributionCdf(*dist,x);
    }
    mooseError("Distribution " + DistAlias + " was not found in distribution container.");
    return -1.0;

}

double
DistributionContainer::randGen(char * DistAlias, double RNG){
  return randGen(std::string(DistAlias), RNG);
}

double
DistributionContainer::randGen(std::string DistAlias, double RNG){

    if(_dist_by_name.find(DistAlias) != _dist_by_name.end()){
        distribution * dist = _dist_by_name.find(DistAlias)->second;
        return dist->RandomNumberGenerator(RNG);
     }
     mooseError("Distribution " + DistAlias + " was not found in distribution container.");
     return -1.0;

}

//int DistributionContainer::getPosition(std::string DistAlias){
//	std::map <std::string, int>::iterator p;
//
//	p = _vector_pos_map.find(DistAlias);
//	if(p != _vector_pos_map.end()){
//       return (p->second);
//	}
//	else{
//		return -1;
//	}
//}

DistributionContainer & DistributionContainer::Instance() {
  if(_instance == NULL){
    _instance = new DistributionContainer();
  }
  return *_instance;
}

DistributionContainer * DistributionContainer::_instance;

/* the str_to_string_p and free_string_p are for python use */

std::string * str_to_string_p(char *s) {
  return new std::string(s);
}

void free_string_p(std::string * s) {
  delete s;
}

<|endoftext|>


<commit_before>#define BUILDING_NODE_EXTENSION
#include <node.h>
#include <v8.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <telldus-core.h>

using namespace v8;
using namespace node;

#ifdef _WINDOWS
#define strcasecmp _stricmp
#define DEGREE " "
#else
#define DEGREE "°"
#endif

const int SUPPORTED_METHODS =
    TELLSTICK_TURNON |
    TELLSTICK_TURNOFF |
    TELLSTICK_BELL |
    TELLSTICK_DIM;

const int DATA_LENGTH = 20;

namespace telldus_v8 {

    Handle<Value> TdGetNumberOfDevices( const Arguments& args ) {
        HandleScope scope;
        //tdInit();
        Local<Number> num = Number::New(tdGetNumberOfDevices());
        return scope.Close(num);
    }

    Handle<Value> TdGetDevices( const Arguments& args ) {
        HandleScope scope;
        tdInit();

        int intNumberOfDevices = tdGetNumberOfDevices();
        Local<Array> devices = Array::New(intNumberOfDevices);

        for (int i = 0; i < intNumberOfDevices; i++) {
           int id = tdGetDeviceId( i );
           char *name = tdGetName( id );
           int length = strlen(name);
           Local<Object> obj = Object::New();
           obj->Set(String::NewSymbol("name"), String::New(name, length));
           obj->Set(String::NewSymbol("id"), Number::New(id));
           devices->Set(i, obj);
           tdReleaseString(name);
         }

        return scope.Close(devices);
    }

}

extern "C"
void init(Handle<Object> target) {

     HandleScope scope;
  //Local<FunctionTemplate> t = FunctionTemplate::New(telldus_v8::tdGetNumberOfDevices);

  //target->Set( String::NewSymbol( "tdGetNumberOfDevices" ), t->GetFunction() );
   target->Set(String::NewSymbol("TdGetNumberOfDevices"),
      FunctionTemplate::New(telldus_v8::TdGetNumberOfDevices)->GetFunction());
   target->Set(String::NewSymbol("TdGetDevices"),
      FunctionTemplate::New(telldus_v8::TdGetDevices)->GetFunction());
}

NODE_MODULE(telldus, init)<commit_msg>add suported metods to array<commit_after>#define BUILDING_NODE_EXTENSION
#include <node.h>
#include <v8.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <telldus-core.h>

using namespace v8;
using namespace node;

#ifdef _WINDOWS
#define strcasecmp _stricmp
#define DEGREE " "
#else
#define DEGREE "°"
#endif

namespace telldus_v8 {

    const int SUPPORTED_METHODS =
    TELLSTICK_TURNON
    | TELLSTICK_TURNOFF
    | TELLSTICK_BELL
    | TELLSTICK_TOGGLE
    | TELLSTICK_DIM
    | TELLSTICK_LEARN
    | TELLSTICK_EXECUTE
    | TELLSTICK_UP
    | TELLSTICK_DOWN
    | TELLSTICK_STOP;

    const int DATA_LENGTH = 20;

    Handle<Value> TdGetNumberOfDevices( const Arguments& args ) {
        HandleScope scope;
        //tdInit();
        Local<Number> num = Number::New(tdGetNumberOfDevices());
        return scope.Close(num);
    }

    Local<Object> GetSuportedMetods(int id){

        int methods = tdMethods( id, SUPPORTED_METHODS );
        Local<Array> methodsObj = Array::New();
        int i = 0;
        if (methods & TELLSTICK_TURNON)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_TURNON"));
        }
        if (methods & TELLSTICK_TURNOFF)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_TURNOFF"));
        }
        if (methods & TELLSTICK_BELL)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_BELL"));
        }
        if (methods & TELLSTICK_TOGGLE)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_TOGGLE"));
        }
        if (methods & TELLSTICK_DIM)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_DIM"));
        }
        if (methods & TELLSTICK_UP)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_UP"));
        }
        if (methods & TELLSTICK_DOWN)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_DOWN"));
        }
        if (methods & TELLSTICK_STOP)
        {
            methodsObj->Set(i++, String::New("TELLSTICK_STOP"));
        }

        return methodsObj;

    }

    Local<Object> GetDevice(int index){

        int id = tdGetDeviceId( index );
        char *name = tdGetName( id );
        char *model = tdGetModel(id);
        int methods = tdMethods( id, SUPPORTED_METHODS );

        Local<Object> obj = Object::New();
        obj->Set(String::NewSymbol("name"), String::New(name, strlen(name)));
        obj->Set(String::NewSymbol("id"), Number::New(id));
        obj->Set(String::NewSymbol("metods"), GetSuportedMetods(id));
        obj->Set(String::NewSymbol("model"), String::New(model, strlen(model)));

        tdReleaseString(name);
        tdReleaseString(model);

        return obj;
    }

    Handle<Value> TdGetDevices( const Arguments& args ) {
        HandleScope scope;
        tdInit();

        int intNumberOfDevices = tdGetNumberOfDevices();
        Local<Array> devices = Array::New(intNumberOfDevices);

        for (int i = 0; i < intNumberOfDevices; i++) {
           devices->Set(i, GetDevice(i));
         }

        return scope.Close(devices);
    }

}

extern "C"
void init(Handle<Object> target) {

     HandleScope scope;
  //Local<FunctionTemplate> t = FunctionTemplate::New(telldus_v8::tdGetNumberOfDevices);

  //target->Set( String::NewSymbol( "tdGetNumberOfDevices" ), t->GetFunction() );
   target->Set(String::NewSymbol("TdGetNumberOfDevices"),
      FunctionTemplate::New(telldus_v8::TdGetNumberOfDevices)->GetFunction());
   target->Set(String::NewSymbol("TdGetDevices"),
      FunctionTemplate::New(telldus_v8::TdGetDevices)->GetFunction());
}

NODE_MODULE(telldus, init)<|endoftext|>


<commit_before>/*
 * Software License Agreement (BSD License)
 *
 * Point Cloud Library (PCL) - www.pointclouds.org
 * Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
 * Copyright (c) 2010-2011, Willow Garage, 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.
 *
 *  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.
 *
 * $Id$
 *
 */

#include <pcl/io/lzf.h>
#include <cstring>
#include <climits>
#include <pcl/console/print.h>
#include <errno.h>

/*
 * Size of hashtable is (1 << HLOG) * sizeof (char *)
 * decompression is independent of the hash table size
 * the difference between 15 and 14 is very small
 * for small blocks (and 14 is usually a bit faster).
 * For a low-memory/faster configuration, use HLOG == 13;
 * For best compression, use 15 or 16 (or more, up to 22).
 */
#define HLOG 13

typedef unsigned int LZF_HSLOT;
typedef unsigned int LZF_STATE[1 << (HLOG)];

#define STRICT_ALIGN !(defined(__i386) || defined (__amd64))
#if !STRICT_ALIGN
/* for unaligned accesses we need a 16 bit datatype. */
# if USHRT_MAX == 65535
    typedef unsigned short u16;
# elif UINT_MAX == 65535
    typedef unsigned int u16;
# else
#  undef STRICT_ALIGN
#  define STRICT_ALIGN 1
# endif
#endif

// IDX works because it is very similar to a multiplicative hash, e.g.
// ((h * 57321 >> (3*8 - HLOG)) & ((1 << (HLOG)) - 1))
#define IDX(h) ((( h >> (3*8 - HLOG)) - h  ) & ((1 << (HLOG)) - 1))

///////////////////////////////////////////////////////////////////////////////////////////
//
// compressed format
//
// 000LLLLL <L+1>    ; literal, L+1=1..33 octets
// LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
// 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
//
//
unsigned int
pcl::lzfCompress (const void *const in_data, unsigned int in_len,
                  void *out_data, unsigned int out_len)
{
  LZF_STATE htab;
  const unsigned char *ip = static_cast<const unsigned char *> (in_data);
        unsigned char *op = static_cast<unsigned char *> (out_data);
  const unsigned char *in_end  = ip + in_len;
        unsigned char *out_end = op + out_len;
  const unsigned char *ref;

  // off requires a type wide enough to hold a general pointer difference.
  // ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
  // works for differences within a single object). We also assume that no
  // no bit pattern traps. Since the only platform that is both non-POSIX
  // and fails to support both assumptions is windows 64 bit, we make a
  // special workaround for it.
#if defined (WIN32) && defined (_M_X64)
  // workaround for missing POSIX compliance
  unsigned _int64 off;
#else
  unsigned long off;
#endif
  unsigned int hval;
  int lit;

  if (!in_len || !out_len)
  {
    PCL_WARN ("[pcl::lzf_compress] Input or output has 0 size!\n");
    return (0);
  }

  // Initialize the htab
  memset (htab, 0, sizeof (htab));

  // Start run
  lit = 0; op++;

  hval = (ip[0] << 8) | ip[1];
  while (ip < in_end - 2)
  {
    unsigned int *hslot;

    hval = (hval << 8) | ip[2];
    hslot = htab + IDX (hval);
    ref = *hslot + (static_cast<const unsigned char*> (in_data));
    *hslot = static_cast<unsigned int> (ip - (static_cast<const unsigned char*> (in_data)));

    if (
        // The next test will actually take care of this, but this is faster if htab is initialized
        ref < ip
        && (off = ip - ref - 1) < (1 << 13)
        && ref > static_cast<const unsigned char *> (in_data)
        && ref[2] == ip[2]
#if STRICT_ALIGN
        && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
#else
        && *reinterpret_cast<const u16 *> (ref) == *reinterpret_cast<const u16 *> (ip)
#endif
      )
    {
      // Match found at *ref++
      unsigned int len = 2;
      ptrdiff_t maxlen = in_end - ip - len;
      maxlen = maxlen > ((1 << 8) + (1 << 3)) ? ((1 << 8) + (1 << 3)) : maxlen;

      // First a faster conservative test
      if (op + 3 + 1 >= out_end)
      {
        // Second the exact but rare test
        if (op - !lit + 3 + 1 >= out_end)
        {
          PCL_WARN ("[pcl::lzf_compress] Attempting to write data outside the output buffer!\n");
          return (0);
        }
      }

      // Stop run
      op [- lit - 1] = static_cast<unsigned char>(lit - 1);
      // Undo run if length is zero
      op -= !lit;

      while (true)
      {
        if (maxlen > 16)
        {
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;

          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;

          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;

          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
        }

        do
          len++;
        while (len < static_cast<unsigned int> (maxlen) && ref[len] == ip[len]);

        break;
      }

      // Len is now #octets - 1
      len -= 2;
      ip++;

      if (len < 7)
      {
        *op++ = static_cast<unsigned char> ((off >> 8) + (len << 5));
      }
      else
      {
        *op++ = static_cast<unsigned char> ((off >> 8) + (  7 << 5));
        *op++ = static_cast<unsigned char> (len - 7);
      }

      *op++ = static_cast<unsigned char> (off);

      // Start run
      lit = 0; op++;

      ip += len + 1;

      if (ip >= in_end - 2)
        break;

      --ip;
      hval = (ip[0] << 8) | ip[1];

      hval = (hval << 8) | ip[2];
      htab[IDX (hval)] = static_cast<unsigned int> (ip - (static_cast<const unsigned char *> (in_data)));
      ip++;
    }
    else
    {
      // One more literal byte we must copy
      if (op >= out_end)
      {
        PCL_WARN ("[pcl::lzf_compress] Attempting to copy data outside the output buffer!\n");
        return (0);
      }

      lit++; *op++ = *ip++;

      if (lit == (1 <<  5))
      {
        // Stop run
        op [- lit - 1] = static_cast<unsigned char> (lit - 1);
        // Start run
        lit = 0; op++;
      }
    }
  }

  // At most 3 bytes can be missing here
  if (op + 3 > out_end)
    return (0);

  while (ip < in_end)
  {
    lit++; *op++ = *ip++;

    if (lit == (1 <<  5))
    {
      // Stop run
      op [- lit - 1] = static_cast<unsigned char> (lit - 1);
      // Start run
      lit = 0; op++;
    }
  }

  // End run
  op [- lit - 1] = static_cast<unsigned char> (lit - 1);
  // Undo run if length is zero
  op -= !lit;

  return (static_cast<unsigned int> (op - static_cast<unsigned char *> (out_data)));
}

///////////////////////////////////////////////////////////////////////////////////////////
unsigned int
pcl::lzfDecompress (const void *const in_data,  unsigned int in_len,
                    void             *out_data, unsigned int out_len)
{
  unsigned char const *ip = static_cast<const unsigned char *> (in_data);
  unsigned char       *op = static_cast<unsigned char *> (out_data);
  unsigned char const *const in_end  = ip + in_len;
  unsigned char       *const out_end = op + out_len;

  do
  {
    unsigned int ctrl = *ip++;

    // Literal run
    if (ctrl < (1 << 5))
    {
      ctrl++;

      if (op + ctrl > out_end)
      {
        errno = E2BIG;
        return (0);
      }

      // Check for overflow
      if (ip + ctrl > in_end)
      {
        errno = EINVAL;
        return (0);
      }
      switch (ctrl)
      {
        case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++;
        case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++;
        case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++;
        case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++;
        case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++;
        case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case  9: *op++ = *ip++;
        case  8: *op++ = *ip++; case  7: *op++ = *ip++; case  6: *op++ = *ip++; case  5: *op++ = *ip++;
        case  4: *op++ = *ip++; case  3: *op++ = *ip++; case  2: *op++ = *ip++; case  1: *op++ = *ip++;
      }
    }
    // Back reference
    else
    {
      unsigned int len = ctrl >> 5;

      unsigned char *ref = op - ((ctrl & 0x1f) << 8) - 1;

      // Check for overflow
      if (ip >= in_end)
      {
        errno = EINVAL;
        return (0);
      }
      if (len == 7)
      {
        len += *ip++;
        // Check for overflow
        if (ip >= in_end)
        {
          errno = EINVAL;
          return (0);
        }
      }
      ref -= *ip++;

      if (op + len + 2 > out_end)
      {
        errno = E2BIG;
        return (0);
      }

      if (ref < static_cast<unsigned char *> (out_data))
      {
        errno = EINVAL;
        return (0);
      }

      switch (len)
      {
        default:
        {
          len += 2;

          if (op >= ref + len)
          {
            // Disjunct areas
            memcpy (op, ref, len);
            op += len;
          }
          else
          {
            // Overlapping, use byte by byte copying
            do
              *op++ = *ref++;
            while (--len);
          }

          break;
        }
        case 9: *op++ = *ref++;
        case 8: *op++ = *ref++;
        case 7: *op++ = *ref++;
        case 6: *op++ = *ref++;
        case 5: *op++ = *ref++;
        case 4: *op++ = *ref++;
        case 3: *op++ = *ref++;
        case 2: *op++ = *ref++;
        case 1: *op++ = *ref++;
        case 0: *op++ = *ref++; // two octets more
                *op++ = *ref++;
      }
    }
  }
  while (ip < in_end);

  return (static_cast<unsigned int> (op - static_cast<unsigned char*> (out_data)));
}

<commit_msg>Update lzf.cpp<commit_after>/*
 * Software License Agreement (BSD License)
 *
 * Point Cloud Library (PCL) - www.pointclouds.org
 * Copyright (c) 2000-2010 Marc Alexander Lehmann <schmorp@schmorp.de>
 * Copyright (c) 2010-2011, Willow Garage, 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.
 *
 *  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.
 *
 * $Id$
 *
 */

#include <pcl/io/lzf.h>
#include <cstring>
#include <climits>
#include <pcl/console/print.h>
#include <errno.h>

/*
 * Size of hashtable is (1 << HLOG) * sizeof (char *)
 * decompression is independent of the hash table size
 * the difference between 15 and 14 is very small
 * for small blocks (and 14 is usually a bit faster).
 * For a low-memory/faster configuration, use HLOG == 13;
 * For best compression, use 15 or 16 (or more, up to 22).
 */
#define HLOG 13

typedef unsigned int LZF_HSLOT;
typedef unsigned int LZF_STATE[1 << (HLOG)];

#define STRICT_ALIGN !(defined(__i386) || defined (__amd64))
#if !STRICT_ALIGN
/* for unaligned accesses we need a 16 bit datatype. */
# if USHRT_MAX == 65535
    typedef unsigned short u16;
# elif UINT_MAX == 65535
    typedef unsigned int u16;
# else
#  undef STRICT_ALIGN
#  define STRICT_ALIGN 1
# endif
#endif

// IDX works because it is very similar to a multiplicative hash, e.g.
// ((h * 57321 >> (3*8 - HLOG)) & ((1 << (HLOG)) - 1))
#define IDX(h) ((( h >> (3*8 - HLOG)) - h  ) & ((1 << (HLOG)) - 1))

///////////////////////////////////////////////////////////////////////////////////////////
//
// compressed format
//
// 000LLLLL <L+1>    ; literal, L+1=1..33 octets
// LLLooooo oooooooo ; backref L+1=1..7 octets, o+1=1..4096 offset
// 111ooooo LLLLLLLL oooooooo ; backref L+8 octets, o+1=1..4096 offset
//
//
unsigned int
pcl::lzfCompress (const void *const in_data, unsigned int in_len,
                  void *out_data, unsigned int out_len)
{
  LZF_STATE htab;
  const unsigned char *ip = static_cast<const unsigned char *> (in_data);
        unsigned char *op = static_cast<unsigned char *> (out_data);
  const unsigned char *in_end  = ip + in_len;
        unsigned char *out_end = op + out_len;
  const unsigned char *ref;

  // off requires a type wide enough to hold a general pointer difference.
  // ISO C doesn't have that (size_t might not be enough and ptrdiff_t only
  // works for differences within a single object). We also assume that no
  // no bit pattern traps. Since the only platform that is both non-POSIX
  // and fails to support both assumptions is windows 64 bit, we make a
  // special workaround for it.
#if defined (WIN32) && defined (_M_X64) && defined (_MSC_VER)
  // workaround for missing POSIX compliance
  unsigned _int64 off;
#else
  unsigned long off;
#endif
  unsigned int hval;
  int lit;

  if (!in_len || !out_len)
  {
    PCL_WARN ("[pcl::lzf_compress] Input or output has 0 size!\n");
    return (0);
  }

  // Initialize the htab
  memset (htab, 0, sizeof (htab));

  // Start run
  lit = 0; op++;

  hval = (ip[0] << 8) | ip[1];
  while (ip < in_end - 2)
  {
    unsigned int *hslot;

    hval = (hval << 8) | ip[2];
    hslot = htab + IDX (hval);
    ref = *hslot + (static_cast<const unsigned char*> (in_data));
    *hslot = static_cast<unsigned int> (ip - (static_cast<const unsigned char*> (in_data)));

    if (
        // The next test will actually take care of this, but this is faster if htab is initialized
        ref < ip
        && (off = ip - ref - 1) < (1 << 13)
        && ref > static_cast<const unsigned char *> (in_data)
        && ref[2] == ip[2]
#if STRICT_ALIGN
        && ((ref[1] << 8) | ref[0]) == ((ip[1] << 8) | ip[0])
#else
        && *reinterpret_cast<const u16 *> (ref) == *reinterpret_cast<const u16 *> (ip)
#endif
      )
    {
      // Match found at *ref++
      unsigned int len = 2;
      ptrdiff_t maxlen = in_end - ip - len;
      maxlen = maxlen > ((1 << 8) + (1 << 3)) ? ((1 << 8) + (1 << 3)) : maxlen;

      // First a faster conservative test
      if (op + 3 + 1 >= out_end)
      {
        // Second the exact but rare test
        if (op - !lit + 3 + 1 >= out_end)
        {
          PCL_WARN ("[pcl::lzf_compress] Attempting to write data outside the output buffer!\n");
          return (0);
        }
      }

      // Stop run
      op [- lit - 1] = static_cast<unsigned char>(lit - 1);
      // Undo run if length is zero
      op -= !lit;

      while (true)
      {
        if (maxlen > 16)
        {
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;

          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;

          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;

          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
          len++; if (ref [len] != ip [len]) break;
        }

        do
          len++;
        while (len < static_cast<unsigned int> (maxlen) && ref[len] == ip[len]);

        break;
      }

      // Len is now #octets - 1
      len -= 2;
      ip++;

      if (len < 7)
      {
        *op++ = static_cast<unsigned char> ((off >> 8) + (len << 5));
      }
      else
      {
        *op++ = static_cast<unsigned char> ((off >> 8) + (  7 << 5));
        *op++ = static_cast<unsigned char> (len - 7);
      }

      *op++ = static_cast<unsigned char> (off);

      // Start run
      lit = 0; op++;

      ip += len + 1;

      if (ip >= in_end - 2)
        break;

      --ip;
      hval = (ip[0] << 8) | ip[1];

      hval = (hval << 8) | ip[2];
      htab[IDX (hval)] = static_cast<unsigned int> (ip - (static_cast<const unsigned char *> (in_data)));
      ip++;
    }
    else
    {
      // One more literal byte we must copy
      if (op >= out_end)
      {
        PCL_WARN ("[pcl::lzf_compress] Attempting to copy data outside the output buffer!\n");
        return (0);
      }

      lit++; *op++ = *ip++;

      if (lit == (1 <<  5))
      {
        // Stop run
        op [- lit - 1] = static_cast<unsigned char> (lit - 1);
        // Start run
        lit = 0; op++;
      }
    }
  }

  // At most 3 bytes can be missing here
  if (op + 3 > out_end)
    return (0);

  while (ip < in_end)
  {
    lit++; *op++ = *ip++;

    if (lit == (1 <<  5))
    {
      // Stop run
      op [- lit - 1] = static_cast<unsigned char> (lit - 1);
      // Start run
      lit = 0; op++;
    }
  }

  // End run
  op [- lit - 1] = static_cast<unsigned char> (lit - 1);
  // Undo run if length is zero
  op -= !lit;

  return (static_cast<unsigned int> (op - static_cast<unsigned char *> (out_data)));
}

///////////////////////////////////////////////////////////////////////////////////////////
unsigned int
pcl::lzfDecompress (const void *const in_data,  unsigned int in_len,
                    void             *out_data, unsigned int out_len)
{
  unsigned char const *ip = static_cast<const unsigned char *> (in_data);
  unsigned char       *op = static_cast<unsigned char *> (out_data);
  unsigned char const *const in_end  = ip + in_len;
  unsigned char       *const out_end = op + out_len;

  do
  {
    unsigned int ctrl = *ip++;

    // Literal run
    if (ctrl < (1 << 5))
    {
      ctrl++;

      if (op + ctrl > out_end)
      {
        errno = E2BIG;
        return (0);
      }

      // Check for overflow
      if (ip + ctrl > in_end)
      {
        errno = EINVAL;
        return (0);
      }
      switch (ctrl)
      {
        case 32: *op++ = *ip++; case 31: *op++ = *ip++; case 30: *op++ = *ip++; case 29: *op++ = *ip++;
        case 28: *op++ = *ip++; case 27: *op++ = *ip++; case 26: *op++ = *ip++; case 25: *op++ = *ip++;
        case 24: *op++ = *ip++; case 23: *op++ = *ip++; case 22: *op++ = *ip++; case 21: *op++ = *ip++;
        case 20: *op++ = *ip++; case 19: *op++ = *ip++; case 18: *op++ = *ip++; case 17: *op++ = *ip++;
        case 16: *op++ = *ip++; case 15: *op++ = *ip++; case 14: *op++ = *ip++; case 13: *op++ = *ip++;
        case 12: *op++ = *ip++; case 11: *op++ = *ip++; case 10: *op++ = *ip++; case  9: *op++ = *ip++;
        case  8: *op++ = *ip++; case  7: *op++ = *ip++; case  6: *op++ = *ip++; case  5: *op++ = *ip++;
        case  4: *op++ = *ip++; case  3: *op++ = *ip++; case  2: *op++ = *ip++; case  1: *op++ = *ip++;
      }
    }
    // Back reference
    else
    {
      unsigned int len = ctrl >> 5;

      unsigned char *ref = op - ((ctrl & 0x1f) << 8) - 1;

      // Check for overflow
      if (ip >= in_end)
      {
        errno = EINVAL;
        return (0);
      }
      if (len == 7)
      {
        len += *ip++;
        // Check for overflow
        if (ip >= in_end)
        {
          errno = EINVAL;
          return (0);
        }
      }
      ref -= *ip++;

      if (op + len + 2 > out_end)
      {
        errno = E2BIG;
        return (0);
      }

      if (ref < static_cast<unsigned char *> (out_data))
      {
        errno = EINVAL;
        return (0);
      }

      switch (len)
      {
        default:
        {
          len += 2;

          if (op >= ref + len)
          {
            // Disjunct areas
            memcpy (op, ref, len);
            op += len;
          }
          else
          {
            // Overlapping, use byte by byte copying
            do
              *op++ = *ref++;
            while (--len);
          }

          break;
        }
        case 9: *op++ = *ref++;
        case 8: *op++ = *ref++;
        case 7: *op++ = *ref++;
        case 6: *op++ = *ref++;
        case 5: *op++ = *ref++;
        case 4: *op++ = *ref++;
        case 3: *op++ = *ref++;
        case 2: *op++ = *ref++;
        case 1: *op++ = *ref++;
        case 0: *op++ = *ref++; // two octets more
                *op++ = *ref++;
      }
    }
  }
  while (ip < in_end);

  return (static_cast<unsigned int> (op - static_cast<unsigned char*> (out_data)));
}

<|endoftext|>


<commit_before>#include <QTimer>
#include <QHash>

#include "api/server-repo.h"
#include "utils/utils.h"
#include "seafile-applet.h"
#include "rpc/rpc-client.h"
#include "repo-item.h"
#include "repo-tree-view.h"
#include "repo-tree-model.h"

namespace {

const int kRefreshLocalReposInterval = 1000;

} // namespace

RepoTreeModel::RepoTreeModel(QObject *parent)
    : QStandardItemModel(parent),
      tree_view_(NULL)
{
    initialize();

    refresh_local_timer_ = new QTimer(this);
    connect(refresh_local_timer_, SIGNAL(timeout()),
            this, SLOT(refreshLocalRepos()));

    refresh_local_timer_->start(kRefreshLocalReposInterval);
}

void RepoTreeModel::initialize()
{
    my_repos_catetory_ = new RepoCategoryItem(tr("My Libraries"));
    shared_repos_catetory_ = new RepoCategoryItem(tr("Shared Libraries"));

    appendRow(my_repos_catetory_);
    appendRow(shared_repos_catetory_);

    if (tree_view_) {
        tree_view_->expand(indexFromItem(my_repos_catetory_));
    }
}

void RepoTreeModel::clear()
{
    QStandardItemModel::clear();
    initialize();
}

void RepoTreeModel::setRepos(const std::vector<ServerRepo>& repos)
{
    int i, n = repos.size();
    removeReposDeletedOnServer(repos);

    for (i = 0; i < n; i++) {
        const ServerRepo& repo = repos[i];
        if (repo.isPersonalRepo()) {
            checkPersonalRepo(repo);
        } else if (repo.isSharedRepo()) {
            checkSharedRepo(repo);
        } else {
            checkGroupRepo(repo);
        }
    }
}

struct DeleteRepoData {
    QHash<QString, const ServerRepo*> map;
    QList<RepoItem*> itemsToDelete;
};

void RepoTreeModel::collectDeletedRepos(RepoItem *item, void *vdata)
{
    DeleteRepoData *data = (DeleteRepoData *)vdata;
    const ServerRepo* repo = data->map.value(item->repo().id);
    if (!repo || repo->type != item->repo().type) {
        data->itemsToDelete << item;
    }
}

void RepoTreeModel::removeReposDeletedOnServer(const std::vector<ServerRepo>& repos)
{
    int i, n;
    DeleteRepoData data;
    n = repos.size();
    for (i = 0; i < n; i++) {
        const ServerRepo& repo = repos[i];
        data.map.insert(repo.id, &repo);
    }

    forEachRepoItem(&RepoTreeModel::collectDeletedRepos, (void *)&data);

    QListIterator<RepoItem*> iter(data.itemsToDelete);
    while(iter.hasNext()) {
        RepoItem *item = iter.next();

        const ServerRepo& repo = item->repo();

        qDebug("remove repo %s(%s) from \"%s\"\n",
               toCStr(repo.name), toCStr(repo.id),
               toCStr(((RepoCategoryItem*)item->parent())->name()));

        item->parent()->removeRow(item->row());
    }
}

void RepoTreeModel::checkPersonalRepo(const ServerRepo& repo)
{
    int row, n = my_repos_catetory_->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(my_repos_catetory_->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // The repo is new
    RepoItem *item = new RepoItem(repo);
    my_repos_catetory_->appendRow(item);
}

void RepoTreeModel::checkSharedRepo(const ServerRepo& repo)
{
    int row, n = shared_repos_catetory_->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(shared_repos_catetory_->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // The repo is new
    RepoItem *item = new RepoItem(repo);
    shared_repos_catetory_->appendRow(item);
}

void RepoTreeModel::checkGroupRepo(const ServerRepo& repo)
{
    QStandardItem *root = invisibleRootItem();
    RepoCategoryItem *group = NULL;

    int row, n = root->rowCount();

    // First find for create the group
    // Starts from row 2 because the first two rows are "My Libraries" and "Shared Libraries"
    for (row = 2; row < n; row ++) {
        RepoCategoryItem *item = (RepoCategoryItem *)(root->child(row));
        if (item->groupId() == repo.group_id) {
            group = item;
            break;
        }
    }
    if (!group) {
        group = new RepoCategoryItem(repo.group_name, repo.group_id);
        appendRow(group);
    }

    // Find the repo in this group
    n = group->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(group->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // Current repo not in this group yet
    RepoItem *item = new RepoItem(repo);
    group->appendRow(item);
}

void RepoTreeModel::updateRepoItem(RepoItem *item, const ServerRepo& repo)
{
    item->setRepo(repo);
}

void RepoTreeModel::forEachRepoItem(void (RepoTreeModel::*func)(RepoItem *, void *),
                                    void *data)
{
    int row;
    int n;
    QStandardItem *root = invisibleRootItem();
    n = root->rowCount();
    for (row = 0; row < n; row++) {
        RepoCategoryItem *category = (RepoCategoryItem *)root->child(row);
        int j, total;
        total = category->rowCount();
        for (j = 0; j < total; j++) {
            RepoItem *item = (RepoItem *)category->child(j);
            (this->*func)(item, data);
        }
    }
}

void RepoTreeModel::refreshLocalRepos()
{
    forEachRepoItem(&RepoTreeModel::refreshRepoItem, NULL);
}

void RepoTreeModel::refreshRepoItem(RepoItem *item, void *data)
{
    LocalRepo local_repo;
    seafApplet->rpcClient()->getLocalRepo(item->repo().id, &local_repo);
    if (local_repo != item->localRepo()) {
        item->setLocalRepo(local_repo);
        QModelIndex index = indexFromItem(item);
        emit dataChanged(index,index);
    }
}
<commit_msg>improve repos refresh<commit_after>#include <QTimer>
#include <QHash>

#include "api/server-repo.h"
#include "utils/utils.h"
#include "seafile-applet.h"
#include "rpc/rpc-client.h"
#include "repo-item.h"
#include "repo-tree-view.h"
#include "repo-tree-model.h"

namespace {

const int kRefreshLocalReposInterval = 1000;

} // namespace

RepoTreeModel::RepoTreeModel(QObject *parent)
    : QStandardItemModel(parent),
      tree_view_(NULL)
{
    initialize();

    refresh_local_timer_ = new QTimer(this);
    connect(refresh_local_timer_, SIGNAL(timeout()),
            this, SLOT(refreshLocalRepos()));

    refresh_local_timer_->start(kRefreshLocalReposInterval);
}

void RepoTreeModel::initialize()
{
    my_repos_catetory_ = new RepoCategoryItem(tr("My Libraries"));
    shared_repos_catetory_ = new RepoCategoryItem(tr("Shared Libraries"));

    appendRow(my_repos_catetory_);
    appendRow(shared_repos_catetory_);

    if (tree_view_) {
        tree_view_->expand(indexFromItem(my_repos_catetory_));
    }
}

void RepoTreeModel::clear()
{
    QStandardItemModel::clear();
    initialize();
}

void RepoTreeModel::setRepos(const std::vector<ServerRepo>& repos)
{
    int i, n = repos.size();
    // removeReposDeletedOnServer(repos);

    qDebug("refresh: %d repos\n", n);

    clear();

    for (i = 0; i < n; i++) {
        const ServerRepo& repo = repos[i];
        if (repo.isPersonalRepo()) {
            checkPersonalRepo(repo);
        } else if (repo.isSharedRepo()) {
            checkSharedRepo(repo);
        } else {
            checkGroupRepo(repo);
        }
    }
}

struct DeleteRepoData {
    QHash<QString, const ServerRepo*> map;
    QList<RepoItem*> itemsToDelete;
};

void RepoTreeModel::collectDeletedRepos(RepoItem *item, void *vdata)
{
    DeleteRepoData *data = (DeleteRepoData *)vdata;
    const ServerRepo* repo = data->map.value(item->repo().id);
    if (!repo || repo->type != item->repo().type) {
        data->itemsToDelete << item;
    }
}

void RepoTreeModel::removeReposDeletedOnServer(const std::vector<ServerRepo>& repos)
{
    int i, n;
    DeleteRepoData data;
    n = repos.size();
    for (i = 0; i < n; i++) {
        const ServerRepo& repo = repos[i];
        data.map.insert(repo.id, &repo);
    }

    forEachRepoItem(&RepoTreeModel::collectDeletedRepos, (void *)&data);

    QListIterator<RepoItem*> iter(data.itemsToDelete);
    while(iter.hasNext()) {
        RepoItem *item = iter.next();

        const ServerRepo& repo = item->repo();

        qDebug("remove repo %s(%s) from \"%s\"\n",
               toCStr(repo.name), toCStr(repo.id),
               toCStr(((RepoCategoryItem*)item->parent())->name()));

        item->parent()->removeRow(item->row());
    }
}

void RepoTreeModel::checkPersonalRepo(const ServerRepo& repo)
{
    int row, n = my_repos_catetory_->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(my_repos_catetory_->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // The repo is new
    RepoItem *item = new RepoItem(repo);
    my_repos_catetory_->appendRow(item);
}

void RepoTreeModel::checkSharedRepo(const ServerRepo& repo)
{
    int row, n = shared_repos_catetory_->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(shared_repos_catetory_->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // The repo is new
    RepoItem *item = new RepoItem(repo);
    shared_repos_catetory_->appendRow(item);
}

void RepoTreeModel::checkGroupRepo(const ServerRepo& repo)
{
    QStandardItem *root = invisibleRootItem();
    RepoCategoryItem *group = NULL;

    int row, n = root->rowCount();

    // First find for create the group
    // Starts from row 2 because the first two rows are "My Libraries" and "Shared Libraries"
    for (row = 2; row < n; row ++) {
        RepoCategoryItem *item = (RepoCategoryItem *)(root->child(row));
        if (item->groupId() == repo.group_id) {
            group = item;
            break;
        }
    }
    if (!group) {
        group = new RepoCategoryItem(repo.group_name, repo.group_id);
        appendRow(group);
    }

    // Find the repo in this group
    n = group->rowCount();
    for (row = 0; row < n; row++) {
        RepoItem *item = (RepoItem *)(group->child(row));
        if (item->repo().id == repo.id) {
            updateRepoItem(item, repo);
            return;
        }
    }

    // Current repo not in this group yet
    RepoItem *item = new RepoItem(repo);
    group->appendRow(item);
}

void RepoTreeModel::updateRepoItem(RepoItem *item, const ServerRepo& repo)
{
    item->setRepo(repo);
}

void RepoTreeModel::forEachRepoItem(void (RepoTreeModel::*func)(RepoItem *, void *),
                                    void *data)
{
    int row;
    int n;
    QStandardItem *root = invisibleRootItem();
    n = root->rowCount();
    for (row = 0; row < n; row++) {
        RepoCategoryItem *category = (RepoCategoryItem *)root->child(row);
        int j, total;
        total = category->rowCount();
        for (j = 0; j < total; j++) {
            RepoItem *item = (RepoItem *)category->child(j);
            (this->*func)(item, data);
        }
    }
}

void RepoTreeModel::refreshLocalRepos()
{
    forEachRepoItem(&RepoTreeModel::refreshRepoItem, NULL);
}

void RepoTreeModel::refreshRepoItem(RepoItem *item, void *data)
{
    LocalRepo local_repo;
    seafApplet->rpcClient()->getLocalRepo(item->repo().id, &local_repo);
    if (local_repo != item->localRepo()) {
        item->setLocalRepo(local_repo);
        QModelIndex index = indexFromItem(item);
        emit dataChanged(index,index);
    }
}
<|endoftext|>


<commit_before>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <iomanip>

#include "Log.h"
#include "GradientTester.h"

#include "NetGraphNode.h"

namespace Conv {

void GradientTester::TestGradient ( NetGraph& graph, unsigned int skip_weights, bool fatal_fail ) {
  const double epsilon = 0.005;
  LOGDEBUG << "Testing gradient. FeedForward...";
	graph.FeedForward();
  LOGDEBUG << "Testing gradient. BackPropagate...";
  graph.BackPropagate();

	const datum initial_loss = graph.AggregateLoss();
	unsigned int global_okay = 0;
	unsigned int global_tolerable = 0;
	unsigned int global_failed = 0;
	unsigned int global_weights = 0;

  LOGDEBUG << "Initial loss: " << initial_loss;
  LOGDEBUG << "Using epsilon: " << epsilon;
  for(unsigned int l = 0; l < graph.GetNodes().size(); l++) {
		NetGraphNode* node = graph.GetNodes()[l];
		Layer* layer = node->layer;
    if(layer->IsNotGradientSafe())
      continue;
    for(unsigned int p = 0; p < layer->parameters().size(); p++) {
			CombinedTensor* const param = layer->parameters()[p];
      LOGDEBUG << "Testing layer " << l << " (" << layer->GetLayerDescription() << "), parameter set " << p;
      LOGDEBUG << param->data;
      bool passed = true;
      unsigned int okay = 0;
      unsigned int tolerable = 0;
      unsigned int failed = 0;
      unsigned int total = 0;
      for(unsigned int e = 0; e < param->data.elements(); e+=(skip_weights + 1))
      {
        total++;
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
	param->delta.MoveToCPU();
#endif
	const datum old_param = param->data(e);

	param->data[e] = old_param + epsilon;
	graph.FeedForward();
	const double plus_loss = graph.AggregateLoss();

#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param - epsilon;
graph.FeedForward();
	const double minus_loss = graph.AggregateLoss();

	const double delta = param->delta[e];
	const double actual_delta = (plus_loss - minus_loss) / (2.0 * epsilon);

	const double ratio = actual_delta / delta;
	if(ratio > 1.02 || ratio < 0.98) {
	  if(ratio > 1.2 || ratio < 0.8) {
      if(passed) {
	      LOGWARN << "delta analytic: " << delta << ", numeric: " << actual_delta << ", ratio: " << ratio;
      }
	    passed = false;
	    // std::cout << "!" << std::flush;
			failed++;
	  } else {
	  // std::cout << "#" << std::flush;
		tolerable++;
	  }
	}
	else {
	  // std::cout << "." << std::flush;
	  okay++;
	}
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param;
      }
      // std::cout << "\n";
      if(passed) {
	LOGDEBUG << "Okay!";
      } else {
	LOGERROR << "Failed!";
      }
			LOGDEBUG << okay << " of " << total << " gradients okay (delta < 2%)";
			LOGDEBUG << tolerable << " of " << total << " gradients tolerable (delta < 20%)";
			LOGDEBUG << failed << " of " << total << " gradients failed (delta >= 20%)";
			global_okay += okay;
			global_tolerable += tolerable;
			global_failed += failed;
			global_weights += total;
    }
  }

	LOGRESULT << global_okay << " of " << global_weights << " tested gradients okay (delta < 2%)" << LOGRESULTEND;
	LOGRESULT << global_tolerable << " of " << global_weights << " tested gradients tolerable (delta < 20%)" << LOGRESULTEND;
	LOGRESULT << global_failed << " of " << global_weights << " tested gradients failed (delta >= 20%)" << LOGRESULTEND;

  if (global_failed > 0 && fatal_fail) {
    FATAL("Failed gradient check!");
  }

}

  bool GradientTester::DoGradientTest(Conv::Layer* layer, Conv::Tensor& data, Conv::Tensor& delta, std::vector<Conv::CombinedTensor*>& outputs, Conv::datum epsilon, void (*WriteLossDeltas)(const std::vector<CombinedTensor*>&), datum (*CalculateLoss)(Conv::Layer*, const std::vector<CombinedTensor*>&)) {
  layer->FeedForward();
  WriteLossDeltas(outputs);
  layer->BackPropagate();

  unsigned int elements = data.elements();
  unsigned int okay = 0;

  // Weight gradient test
  for (unsigned int w = 0; w < data.elements(); w++) {
#ifdef BUILD_OPENCL
    data.MoveToCPU();
    delta.MoveToCPU();
#endif
    const Conv::datum weight = data.data_ptr_const()[w];
    const Conv::datum gradient = delta.data_ptr_const()[w];

    // Using central diff
    data.data_ptr()[w] = weight + epsilon;
    layer->FeedForward();
    const Conv::datum forward_loss = CalculateLoss(layer,outputs);

#ifdef BUILD_OPENCL
    data.MoveToCPU();
#endif
    data.data_ptr()[w] = weight - epsilon;
    layer->FeedForward();
    const Conv::datum backward_loss = CalculateLoss(layer,outputs);

    const Conv::datum fd_gradient = (forward_loss - backward_loss) / (2.0 * epsilon);

#ifdef BUILD_OPENCL
    data.MoveToCPU();
#endif
    data.data_ptr()[w] = weight;

    const Conv::datum ratio = fd_gradient / gradient;
    if(ratio > 1.2 || ratio < 0.8) {
      LOGDEBUG << "BP Grad : " << gradient;
      LOGDEBUG << "FD Grad : " << fd_gradient;
      LOGDEBUG << "Ratio   : " << ratio;
      LOGDEBUG << "Diff    : " << gradient - fd_gradient;
    } else {
      okay++;
    }
  }
  if(okay != elements) {
    double success_rate = (double)okay/(double)elements;
    if(success_rate > 0.85)
      return true;
    else {
      LOGERROR << okay << " of " << elements << " gradients okay - " << std::setprecision(3) << 100.0 * (double)okay/(double)elements << "%";
      return false;
    }
  } else {
    return true;
  }
}

}
<commit_msg>GradientTester: Use IsNotGradientSafe to skip tests<commit_after>/*
 * This file is part of the CN24 semantic segmentation software,
 * copyright (C) 2015 Clemens-Alexander Brust (ikosa dot de at gmail dot com).
 *
 * For licensing information, see the LICENSE file included with this project.
 */

#include <iomanip>

#include "Log.h"
#include "GradientTester.h"

#include "NetGraphNode.h"

namespace Conv {

void GradientTester::TestGradient ( NetGraph& graph, unsigned int skip_weights, bool fatal_fail ) {
  const double epsilon = 0.005;
  LOGDEBUG << "Testing gradient. FeedForward...";
	graph.FeedForward();
  LOGDEBUG << "Testing gradient. BackPropagate...";
  graph.BackPropagate();

	const datum initial_loss = graph.AggregateLoss();
	unsigned int global_okay = 0;
	unsigned int global_tolerable = 0;
	unsigned int global_failed = 0;
	unsigned int global_weights = 0;

  LOGDEBUG << "Initial loss: " << initial_loss;
  LOGDEBUG << "Using epsilon: " << epsilon;
  for(unsigned int l = 0; l < graph.GetNodes().size(); l++) {
		NetGraphNode* node = graph.GetNodes()[l];
		Layer* layer = node->layer;
    if(layer->IsNotGradientSafe())
      continue;
    for(unsigned int p = 0; p < layer->parameters().size(); p++) {
			CombinedTensor* const param = layer->parameters()[p];
      LOGDEBUG << "Testing layer " << l << " (" << layer->GetLayerDescription() << "), parameter set " << p;
      LOGDEBUG << param->data;
      bool passed = true;
      unsigned int okay = 0;
      unsigned int tolerable = 0;
      unsigned int failed = 0;
      unsigned int total = 0;
      for(unsigned int e = 0; e < param->data.elements(); e+=(skip_weights + 1))
      {
        total++;
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
	param->delta.MoveToCPU();
#endif
	const datum old_param = param->data(e);

	param->data[e] = old_param + epsilon;
	graph.FeedForward();
	const double plus_loss = graph.AggregateLoss();

#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param - epsilon;
graph.FeedForward();
	const double minus_loss = graph.AggregateLoss();

	const double delta = param->delta[e];
	const double actual_delta = (plus_loss - minus_loss) / (2.0 * epsilon);

	const double ratio = actual_delta / delta;
	if(ratio > 1.02 || ratio < 0.98) {
	  if(ratio > 1.2 || ratio < 0.8) {
      if(passed) {
	      LOGWARN << "delta analytic: " << delta << ", numeric: " << actual_delta << ", ratio: " << ratio;
      }
	    passed = false;
	    // std::cout << "!" << std::flush;
			failed++;
	  } else {
	  // std::cout << "#" << std::flush;
		tolerable++;
	  }
	}
	else {
	  // std::cout << "." << std::flush;
	  okay++;
	}
#ifdef BUILD_OPENCL
	param->data.MoveToCPU();
#endif
	param->data[e] = old_param;
      }
      // std::cout << "\n";
      if(passed) {
	LOGDEBUG << "Okay!";
      } else {
	LOGERROR << "Failed!";
      }
			LOGDEBUG << okay << " of " << total << " gradients okay (delta < 2%)";
			LOGDEBUG << tolerable << " of " << total << " gradients tolerable (delta < 20%)";
			LOGDEBUG << failed << " of " << total << " gradients failed (delta >= 20%)";
			global_okay += okay;
			global_tolerable += tolerable;
			global_failed += failed;
			global_weights += total;
    }
  }

	LOGRESULT << global_okay << " of " << global_weights << " tested gradients okay (delta < 2%)" << LOGRESULTEND;
	LOGRESULT << global_tolerable << " of " << global_weights << " tested gradients tolerable (delta < 20%)" << LOGRESULTEND;
	LOGRESULT << global_failed << " of " << global_weights << " tested gradients failed (delta >= 20%)" << LOGRESULTEND;

  if (global_failed > 0 && fatal_fail) {
    FATAL("Failed gradient check!");
  }

}

  bool GradientTester::DoGradientTest(Conv::Layer* layer, Conv::Tensor& data, Conv::Tensor& delta, std::vector<Conv::CombinedTensor*>& outputs, Conv::datum epsilon, void (*WriteLossDeltas)(const std::vector<CombinedTensor*>&), datum (*CalculateLoss)(Conv::Layer*, const std::vector<CombinedTensor*>&)) {
  if(layer->IsNotGradientSafe()) {
    LOGINFO << "Skipping gradient test for " << layer->GetLayerDescription();
    return true;
  }
  layer->FeedForward();
  WriteLossDeltas(outputs);
  layer->BackPropagate();

  unsigned int elements = data.elements();
  unsigned int okay = 0;

  // Weight gradient test
  for (unsigned int w = 0; w < data.elements(); w++) {
#ifdef BUILD_OPENCL
    data.MoveToCPU();
    delta.MoveToCPU();
#endif
    const Conv::datum weight = data.data_ptr_const()[w];
    const Conv::datum gradient = delta.data_ptr_const()[w];

    // Using central diff
    data.data_ptr()[w] = weight + epsilon;
    layer->FeedForward();
    const Conv::datum forward_loss = CalculateLoss(layer,outputs);

#ifdef BUILD_OPENCL
    data.MoveToCPU();
#endif
    data.data_ptr()[w] = weight - epsilon;
    layer->FeedForward();
    const Conv::datum backward_loss = CalculateLoss(layer,outputs);

    const Conv::datum fd_gradient = (forward_loss - backward_loss) / (2.0 * epsilon);

#ifdef BUILD_OPENCL
    data.MoveToCPU();
#endif
    data.data_ptr()[w] = weight;

    const Conv::datum ratio = fd_gradient / gradient;
    if(ratio > 1.2 || ratio < 0.8) {
      LOGDEBUG << "BP Grad : " << gradient;
      LOGDEBUG << "FD Grad : " << fd_gradient;
      LOGDEBUG << "Ratio   : " << ratio;
      LOGDEBUG << "Diff    : " << gradient - fd_gradient;
    } else {
      okay++;
    }
  }
  if(okay != elements) {
    double success_rate = (double)okay/(double)elements;
    if(success_rate > 0.85)
      return true;
    else {
      LOGERROR << okay << " of " << elements << " gradients okay - " << std::setprecision(3) << 100.0 * (double)okay/(double)elements << "%";
      return false;
    }
  } else {
    return true;
  }
}

}
<|endoftext|>


<commit_before>#include "uistatecoordinator.h"

#include <QVariantMap>
#include <QDebug>

namespace Sonetta {

UIStateCoordinator::UIStateCoordinator(QObject *parent) :
    QObject(parent)
{
    m_fonts = new QQmlPropertyMap(this);
    m_colors = new QQmlPropertyMap(this);
    m_misc = new QQmlPropertyMap(this);
}

QVariant UIStateCoordinator::state() const
{
    return m_states.isEmpty() ? QVariantMap() : m_states.top();
}

void UIStateCoordinator::pushState(const QVariant &state)
{
    m_states.push(state);

    emit stateChanged();
    emit statePushed();
}

void UIStateCoordinator::resetState(const QVariant &state)
{
    m_states.clear();
    m_states.push(state);

    emit stateChanged();
    emit stateReset();
}

bool UIStateCoordinator::hasPreviousState() const
{
    return !m_states.empty();
}

void UIStateCoordinator::popState()
{
    if (hasPreviousState())
    {
        m_states.pop();
        emit stateChanged();
        emit statePopped();
    }
}

void UIStateCoordinator::setColorProperties(const QVariant &colors)
{
    if (colors.type() == QVariant::Map)
    {
        const QVariantMap colorMap = colors.toMap();

        m_colors->deleteLater();
        m_colors = new QQmlPropertyMap(this);

        // Insert key-value pairs to property map
        QVariantMap::ConstIterator i = colorMap.constBegin();
        while (i != colorMap.constEnd())
        {
            m_colors->insert(i.key(), i.value());
            ++i;
        }

        emit colorsChanged();
    }
}

void UIStateCoordinator::setFontProperties(const QVariant &fonts)
{
    if (fonts.type() == QVariant::Map)
    {
        const QVariantMap fontMap = fonts.toMap();

        m_fonts->deleteLater();
        m_fonts = new QQmlPropertyMap(this);

        // Insert key-value pairs to property map
        QVariantMap::ConstIterator i = fontMap.constBegin();
        while (i != fontMap.constEnd())
        {
            m_fonts->insert(i.key(), i.value());
            ++i;
        }

        emit fontsChanged();
    }
}

void UIStateCoordinator::setMiscProperties(const QVariant &misc)
{
    if (misc.type() == QVariant::Map)
    {
        const QVariantMap miscMap = misc.toMap();

        m_misc->deleteLater();
        m_misc = new QQmlPropertyMap(this);

        // Insert key-value pairs to property map
        QVariantMap::ConstIterator i = miscMap.constBegin();
        while (i != miscMap.constEnd())
        {
            m_misc->insert(i.key(), i.value());
            ++i;
        }

        emit miscChanged();
    }
}

QObject * UIStateCoordinator::colors() const
{
    return m_colors;
}

QObject * UIStateCoordinator::fonts() const
{
    return m_fonts;
}

QObject * UIStateCoordinator::misc() const
{
    return m_misc;
}

}
<commit_msg>Fixed: incorrect implementation of UIStateCoordinator::hasPreviousState<commit_after>#include "uistatecoordinator.h"

#include <QVariantMap>
#include <QDebug>

namespace Sonetta {

UIStateCoordinator::UIStateCoordinator(QObject *parent) :
    QObject(parent)
{
    m_fonts = new QQmlPropertyMap(this);
    m_colors = new QQmlPropertyMap(this);
    m_misc = new QQmlPropertyMap(this);
}

QVariant UIStateCoordinator::state() const
{
    return m_states.isEmpty() ? QVariantMap() : m_states.top();
}

void UIStateCoordinator::pushState(const QVariant &state)
{
    m_states.push(state);

    emit stateChanged();
    emit statePushed();
}

void UIStateCoordinator::resetState(const QVariant &state)
{
    m_states.clear();
    m_states.push(state);

    emit stateChanged();
    emit stateReset();
}

bool UIStateCoordinator::hasPreviousState() const
{
    return m_states.count() > 1;
}

void UIStateCoordinator::popState()
{
    if (hasPreviousState())
    {
        m_states.pop();
        emit stateChanged();
        emit statePopped();
    }
}

void UIStateCoordinator::setColorProperties(const QVariant &colors)
{
    if (colors.type() == QVariant::Map)
    {
        const QVariantMap colorMap = colors.toMap();

        m_colors->deleteLater();
        m_colors = new QQmlPropertyMap(this);

        // Insert key-value pairs to property map
        QVariantMap::ConstIterator i = colorMap.constBegin();
        while (i != colorMap.constEnd())
        {
            m_colors->insert(i.key(), i.value());
            ++i;
        }

        emit colorsChanged();
    }
}

void UIStateCoordinator::setFontProperties(const QVariant &fonts)
{
    if (fonts.type() == QVariant::Map)
    {
        const QVariantMap fontMap = fonts.toMap();

        m_fonts->deleteLater();
        m_fonts = new QQmlPropertyMap(this);

        // Insert key-value pairs to property map
        QVariantMap::ConstIterator i = fontMap.constBegin();
        while (i != fontMap.constEnd())
        {
            m_fonts->insert(i.key(), i.value());
            ++i;
        }

        emit fontsChanged();
    }
}

void UIStateCoordinator::setMiscProperties(const QVariant &misc)
{
    if (misc.type() == QVariant::Map)
    {
        const QVariantMap miscMap = misc.toMap();

        m_misc->deleteLater();
        m_misc = new QQmlPropertyMap(this);

        // Insert key-value pairs to property map
        QVariantMap::ConstIterator i = miscMap.constBegin();
        while (i != miscMap.constEnd())
        {
            m_misc->insert(i.key(), i.value());
            ++i;
        }

        emit miscChanged();
    }
}

QObject * UIStateCoordinator::colors() const
{
    return m_colors;
}

QObject * UIStateCoordinator::fonts() const
{
    return m_fonts;
}

QObject * UIStateCoordinator::misc() const
{
    return m_misc;
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "HTTPMimeHeaderMapper.h"

//--- standard modules used ----------------------------------------------------
#include "Dbg.h"
#include "MIMEHeader.h"
#include "RE.h"
#include "AnyIterators.h"
#include "AnythingUtils.h"

//---- HTTPMimeHeaderMapper ------------------------------------------------------------------
RegisterResultMapper(HTTPMimeHeaderMapper);

HTTPMimeHeaderMapper::HTTPMimeHeaderMapper(const char *name)
	: EagerResultMapper(name)
{
	StartTrace(HTTPMimeHeaderMapper.Ctor);
}

IFAObject *HTTPMimeHeaderMapper::Clone() const
{
	return new HTTPMimeHeaderMapper(fName);
}

bool HTTPMimeHeaderMapper::DoPutStream(const char *, istream &is, Context &ctx,  ROAnything config)
{
	// Ignore key, store under Mapper.HTTPHeader by default
	StartTrace(HTTPMimeHeaderMapper.DoPutStream);
	TraceAny(config, "My Config");
	MIMEHeader::ProcessMode eProcMode = MIMEHeader::eDoSplitHeaderFields;
	if (config.IsDefined("DoNotSplitHeaderFields") && config["DoNotSplitHeaderFields"].AsBool(0) == true) {
		eProcMode = MIMEHeader::eDoNotSplitHeaderFields;
	}
	MIMEHeader mh(URLUtils::eDownshift, eProcMode);
	bool result = mh.DoReadHeader(is);

	if (result && is.good()) {
		Anything header(mh.GetInfo());
		TraceAny(header, "header");
		if (eProcMode == MIMEHeader::eDoSplitHeaderFields) {
			CorrectDateFormats(header);
		}
		//!@FIXME: all of the following should go to separate mappers
		if (config["StoreCookies"].AsLong(0)) {
			StoreCookies(header, ctx);
		}
		if (config.IsDefined("Suppress")) {
			ROAnything suppresslist(config["Suppress"]);
			SuppressHeaders(header, suppresslist);
		}
		if (config.IsDefined("Add")) {
			ROAnything addlist(config["Add"]);
			AddHeaders(header, addlist);
		}
		if (config.IsDefined("Substitute")) {
			ROAnything addlist(config["Substitute"]);
			Substitute(header, addlist, ctx);
		}
		//!@FIXME: here we should use Put()/DoPutAny() to allow further processing of header data before storing
		result = DoFinalPutAny("HTTPHeader", header, ctx);
	}
	return result && is.good();
}

void HTTPMimeHeaderMapper::CorrectDateFormats(Anything &header)
{
	// we assume to-lower keys
	const char *keylist[] = {
		"if-modified-since",
		"if-range",
		"if-unmodified-since",
		"last-modified",
		"retry-after",
		"date",
		"expires"
	};
	for (int i = 0; i < (int)(sizeof(keylist) / sizeof(keylist[0])); ++i) {
		const char *key = keylist[i];
		if (header.IsDefined(key) && header[key].GetType() == AnyArrayType) {
			String newvalue;
			Anything oldvalue(header[key]);
			for (long j = 0L, sz = oldvalue.GetSize(); j < sz; ++j) {
				if (newvalue.Length() > 0) {
					newvalue.Append(", ");
				}
				newvalue.Append(oldvalue[j].AsString());
			}
			header[key] = newvalue;
		}
	}
}

void HTTPMimeHeaderMapper::SuppressHeaders(Anything &header, ROAnything &suppresslist)
{
	for (long i = 0, sz = suppresslist.GetSize(); i < sz; ++i) {
		String keytosuppress = suppresslist[i].AsCharPtr();
		keytosuppress.ToLower();
		if (header.IsDefined(keytosuppress)) {
			header.Remove(keytosuppress);
		}
	}
}

void HTTPMimeHeaderMapper::AddHeaders(Anything &header, ROAnything &addlist)
{
	for (long i = 0, sz = addlist.GetSize(); i < sz; ++i) {
		String key(addlist.SlotName(i));
		String hdr(addlist[i].AsString());
		// normalize key to lower-type (header info stays as is)
		key.ToLower();
		// overwrite, if existing
		header[key] = hdr;
	}
}

void HTTPMimeHeaderMapper::Substitute(Anything &header, ROAnything &addlist, Context &ctx)
{
	StartTrace(HTTPMimeHeaderMapper.Substitute);

	TraceAny(ctx.GetQuery(), "query:");

	String key;
	String pattern;
	String replacement;
	String slotName = addlist.SlotName(0);
	if (slotName.Length() > 0) {
		key = addlist["Key"].AsString();
		pattern = addlist["Pattern"].AsString();
		replacement = addlist["Replacement"].AsString();
		RE substRegex(pattern, RE::MATCH_ICASE);
		for (int i = 0; i < header.GetSize(); i++) {
			if (header.SlotName(i) == key) {
				header[i] = substRegex.Subst(header[i].AsString(), replacement);
			}
		}
	} else {
		for (int i = 0; i < addlist.GetSize(); i++) {
			key = addlist[i]["Key"].AsString();
			pattern = addlist[i]["Pattern"].AsString();
			replacement = addlist[i]["Replacement"].AsString();

			RE substRegex(pattern, RE::MATCH_ICASE);
			for (int j = 0; j < header.GetSize(); j++) {
				if (header.SlotName(j) == key) {
					header[j] = substRegex.Subst(header[j].AsString(), replacement);
				}
			}
		}
	}
}

void HTTPMimeHeaderMapper::StoreCookies(ROAnything const header, Context &ctx) {
	StartTrace(HTTPMimeHeaderMapper.StoreCookies);

	const String valueSlotName("_value_");
	const String attrSlotName("_attrs_");
	const String cookieID("set-cookie");
	const String backendName(ctx.Lookup("Backend.Name", ""));
	const char cookieEnd = ';';
	String strKeyValue(64L), strCookie(128L), strKey(32L), strValue(64L);
	Anything anyCookies;
	ROAnything roaCookie;
	AnyExtensions::Iterator<ROAnything> cookieIterator(header[cookieID]);
	while ( cookieIterator.Next(roaCookie) ) {
		TraceAny(roaCookie, "current cookie entry");
		strCookie = roaCookie.AsString();
		String cookieName(32L);
		StringTokenizer semiTokenizer(strCookie, cookieEnd);
		Anything anyNamedCookie;
		while ( semiTokenizer.NextToken(strKeyValue) ) {
			StringTokenizer valueTokenizer(strKeyValue, '=');
			if ( valueTokenizer.NextToken(strKey) ) {
				strKey.TrimWhitespace();
				strValue = valueTokenizer.GetRemainder();
				if ( !cookieName.Length() ) {
					cookieName = strKey;
					if ( strValue.Length() ) {
						anyNamedCookie[valueSlotName] = strValue;
					}
				} else {
					if ( strValue.Length() ) {
						anyNamedCookie[attrSlotName][strKey] = strValue;
					} else {
						anyNamedCookie[attrSlotName].Append(strKey);
					}
				}
			}
		}
		if ( anyNamedCookie.GetSize() > 0 && cookieName.Length() ) {
			anyCookies[cookieName].Append(anyNamedCookie);
		}
	}
	//!@FIXME: this part should be factored out into separate mapper
	String destSlotname("StoredCookies.");
	destSlotname.Append(backendName);
	if ( anyCookies.GetSize() > 0 ) {
		String plainCookieString(256L), cookieName(32L);
		AnyExtensions::Iterator<ROAnything> structureIter(anyCookies);
		ROAnything roaEntry;
		while ( structureIter.Next(roaEntry) ) {
			if (!plainCookieString.Length()) {
				plainCookieString.Append("Cookie:");
			}
			structureIter.SlotName(cookieName);
			//!@FIXME: in future we should decide on attributes to select correct value entry to use, currently we use the last one (roaEntry.GetSize()-1) if multiple entries exist
			plainCookieString.Append(' ').Append(cookieName).Append('=').Append(roaEntry[roaEntry.GetSize()-1][valueSlotName].AsString()).Append(cookieEnd);
		}
		Anything anyPlainString(plainCookieString);
		StorePutter::Operate(anyPlainString, ctx, "Session", String(destSlotname).Append(".Plain"));
	}
	TraceAny(anyCookies, "prepared cookie values");
	StorePutter::Operate(anyCookies, ctx, "Session", String(destSlotname).Append(".Structured"));
	TraceAny(ctx.Lookup("StoredCookies"), "cookies from context");
}
<commit_msg>not overwriting existing cookies anymore when no cookies were decoded<commit_after>/*
 * Copyright (c) 2005, Peter Sommerlad and IFS Institute for Software at HSR Rapperswil, Switzerland
 * All rights reserved.
 *
 * This library/application is free software; you can redistribute and/or modify it under the terms of
 * the license that is included with this library/application in the file license.txt.
 */

//--- interface include --------------------------------------------------------
#include "HTTPMimeHeaderMapper.h"

//--- standard modules used ----------------------------------------------------
#include "Dbg.h"
#include "MIMEHeader.h"
#include "RE.h"
#include "AnyIterators.h"
#include "AnythingUtils.h"

//---- HTTPMimeHeaderMapper ------------------------------------------------------------------
RegisterResultMapper(HTTPMimeHeaderMapper);

HTTPMimeHeaderMapper::HTTPMimeHeaderMapper(const char *name)
	: EagerResultMapper(name)
{
	StartTrace(HTTPMimeHeaderMapper.Ctor);
}

IFAObject *HTTPMimeHeaderMapper::Clone() const
{
	return new HTTPMimeHeaderMapper(fName);
}

bool HTTPMimeHeaderMapper::DoPutStream(const char *, istream &is, Context &ctx,  ROAnything config)
{
	// Ignore key, store under Mapper.HTTPHeader by default
	StartTrace(HTTPMimeHeaderMapper.DoPutStream);
	TraceAny(config, "My Config");
	MIMEHeader::ProcessMode eProcMode = MIMEHeader::eDoSplitHeaderFields;
	if (config.IsDefined("DoNotSplitHeaderFields") && config["DoNotSplitHeaderFields"].AsBool(0) == true) {
		eProcMode = MIMEHeader::eDoNotSplitHeaderFields;
	}
	MIMEHeader mh(URLUtils::eDownshift, eProcMode);
	bool result = mh.DoReadHeader(is);

	if (result && is.good()) {
		Anything header(mh.GetInfo());
		TraceAny(header, "header");
		if (eProcMode == MIMEHeader::eDoSplitHeaderFields) {
			CorrectDateFormats(header);
		}
		//!@FIXME: all of the following should go to separate mappers
		if (config["StoreCookies"].AsLong(0)) {
			StoreCookies(header, ctx);
		}
		if (config.IsDefined("Suppress")) {
			ROAnything suppresslist(config["Suppress"]);
			SuppressHeaders(header, suppresslist);
		}
		if (config.IsDefined("Add")) {
			ROAnything addlist(config["Add"]);
			AddHeaders(header, addlist);
		}
		if (config.IsDefined("Substitute")) {
			ROAnything addlist(config["Substitute"]);
			Substitute(header, addlist, ctx);
		}
		//!@FIXME: here we should use Put()/DoPutAny() to allow further processing of header data before storing
		result = DoFinalPutAny("HTTPHeader", header, ctx);
	}
	return result && is.good();
}

void HTTPMimeHeaderMapper::CorrectDateFormats(Anything &header)
{
	// we assume to-lower keys
	const char *keylist[] = {
		"if-modified-since",
		"if-range",
		"if-unmodified-since",
		"last-modified",
		"retry-after",
		"date",
		"expires"
	};
	for (int i = 0; i < (int)(sizeof(keylist) / sizeof(keylist[0])); ++i) {
		const char *key = keylist[i];
		if (header.IsDefined(key) && header[key].GetType() == AnyArrayType) {
			String newvalue;
			Anything oldvalue(header[key]);
			for (long j = 0L, sz = oldvalue.GetSize(); j < sz; ++j) {
				if (newvalue.Length() > 0) {
					newvalue.Append(", ");
				}
				newvalue.Append(oldvalue[j].AsString());
			}
			header[key] = newvalue;
		}
	}
}

void HTTPMimeHeaderMapper::SuppressHeaders(Anything &header, ROAnything &suppresslist)
{
	for (long i = 0, sz = suppresslist.GetSize(); i < sz; ++i) {
		String keytosuppress = suppresslist[i].AsCharPtr();
		keytosuppress.ToLower();
		if (header.IsDefined(keytosuppress)) {
			header.Remove(keytosuppress);
		}
	}
}

void HTTPMimeHeaderMapper::AddHeaders(Anything &header, ROAnything &addlist)
{
	for (long i = 0, sz = addlist.GetSize(); i < sz; ++i) {
		String key(addlist.SlotName(i));
		String hdr(addlist[i].AsString());
		// normalize key to lower-type (header info stays as is)
		key.ToLower();
		// overwrite, if existing
		header[key] = hdr;
	}
}

void HTTPMimeHeaderMapper::Substitute(Anything &header, ROAnything &addlist, Context &ctx)
{
	StartTrace(HTTPMimeHeaderMapper.Substitute);

	TraceAny(ctx.GetQuery(), "query:");

	String key;
	String pattern;
	String replacement;
	String slotName = addlist.SlotName(0);
	if (slotName.Length() > 0) {
		key = addlist["Key"].AsString();
		pattern = addlist["Pattern"].AsString();
		replacement = addlist["Replacement"].AsString();
		RE substRegex(pattern, RE::MATCH_ICASE);
		for (int i = 0; i < header.GetSize(); i++) {
			if (header.SlotName(i) == key) {
				header[i] = substRegex.Subst(header[i].AsString(), replacement);
			}
		}
	} else {
		for (int i = 0; i < addlist.GetSize(); i++) {
			key = addlist[i]["Key"].AsString();
			pattern = addlist[i]["Pattern"].AsString();
			replacement = addlist[i]["Replacement"].AsString();

			RE substRegex(pattern, RE::MATCH_ICASE);
			for (int j = 0; j < header.GetSize(); j++) {
				if (header.SlotName(j) == key) {
					header[j] = substRegex.Subst(header[j].AsString(), replacement);
				}
			}
		}
	}
}

void HTTPMimeHeaderMapper::StoreCookies(ROAnything const header, Context &ctx) {
	StartTrace(HTTPMimeHeaderMapper.StoreCookies);

	const String valueSlotName("_value_");
	const String attrSlotName("_attrs_");
	const String cookieID("set-cookie");
	const char cookieEnd = ';';
	String strKeyValue(64L), strCookie(128L), strKey(32L), strValue(64L);
	Anything anyCookies;
	ROAnything roaCookie;
	AnyExtensions::Iterator<ROAnything> cookieIterator(header[cookieID]);
	while ( cookieIterator.Next(roaCookie) ) {
		TraceAny(roaCookie, "current cookie entry");
		strCookie = roaCookie.AsString();
		String cookieName(32L);
		StringTokenizer semiTokenizer(strCookie, cookieEnd);
		Anything anyNamedCookie;
		while ( semiTokenizer.NextToken(strKeyValue) ) {
			StringTokenizer valueTokenizer(strKeyValue, '=');
			if ( valueTokenizer.NextToken(strKey) ) {
				strKey.TrimWhitespace();
				strValue = valueTokenizer.GetRemainder();
				if ( !cookieName.Length() ) {
					cookieName = strKey;
					if ( strValue.Length() ) {
						anyNamedCookie[valueSlotName] = strValue;
					}
				} else {
					if ( strValue.Length() ) {
						anyNamedCookie[attrSlotName][strKey] = strValue;
					} else {
						anyNamedCookie[attrSlotName].Append(strKey);
					}
				}
			}
		}
		if ( anyNamedCookie.GetSize() > 0 && cookieName.Length() ) {
			anyCookies[cookieName].Append(anyNamedCookie);
		}
	}
	//!@FIXME: this part should be factored out into separate mapper
	String destSlotname("StoredCookies.");
	const String backendName(ctx.Lookup("Backend.Name", ""));
	destSlotname.Append(backendName);
	if ( anyCookies.GetSize() > 0 ) {
		TraceAny(anyCookies, "prepared cookie values");
		String plainCookieString(256L), cookieName(32L);
		AnyExtensions::Iterator<ROAnything> structureIter(anyCookies);
		ROAnything roaEntry;
		while ( structureIter.Next(roaEntry) ) {
			if (!plainCookieString.Length()) {
				plainCookieString.Append("Cookie:");
			}
			structureIter.SlotName(cookieName);
			//!@FIXME: in future we should decide on attributes to select correct value entry to use, currently we use the last one (roaEntry.GetSize()-1) if multiple entries exist
			plainCookieString.Append(' ').Append(cookieName).Append('=').Append(roaEntry[roaEntry.GetSize()-1][valueSlotName].AsString()).Append(cookieEnd);
		}
		Anything anyPlainString(plainCookieString);
		StorePutter::Operate(anyPlainString, ctx, "Session", String(destSlotname).Append(".Plain"));
		StorePutter::Operate(anyCookies, ctx, "Session", String(destSlotname).Append(".Structured"));
	}
	TraceAny(ctx.Lookup("StoredCookies"), "cookies from context");
}
<|endoftext|>