text:
#pragma once
#include <typeinfo>
#ifndef _MSC_VER
#include <cxxabi.h>
#endif
#include "traits.hpp"
#include "Common.hpp"
#include "JsonUtil.hpp"
#include <boost/lexical_cast.hpp>
#include <fmt/format.h>

namespace kapok {
class Serializer : NonCopyable
{
public:

	Serializer()
	{
	}

	~Serializer()
	{
	}

	const char* GetString()
	{
		return m_jsutil.GetJsonText();
	}

	//template<typename T>
	//void Serialize(T const& t, const char* key = nullptr)
	//{
	//	m_jsutil.Reset();
	//	if (key == nullptr)
	//	{
	//		WriteObject(t, std::true_type{});
	//	}
	//	else
	//	{
	//		SerializeImpl(t, key);
	//	}
	//}

	template<typename T>
	void Serialize(const T& t, const char* key = nullptr)
	{
		m_jsutil.Reset();
		if (key == nullptr)
		{
			WriteObject(t, std::true_type{});
		}
		else
		{
			SerializeImpl(t, key);
		}
	}

private:
	template<typename T>
	void SerializeImpl(T const& t, const char* key)
	{
		m_jsutil.StartObject();
		m_jsutil.WriteValue(key);
		WriteObject(t, std::true_type{});
		m_jsutil.EndObject();
	}

	template<typename T>
	const char* type_name()
	{
#ifndef _MSC_VER
		return abi::__cxa_demangle(typeid(T).name(), nullptr, nullptr, nullptr);
#else
		return typeid(T).name();
#endif
	}

	template<typename T>
	const char* get_type_name()
	{
		const char* name = type_name<T>();
		return has_space(name) ? "temp" : type_name<T>();
	}

	bool has_space(const char* str)
	{
		const size_t len = strlen(str);
		for (size_t i = 0; i < len; i++)
		{
			if (str[i] == ' ')
				return true;
		}

		return false;
	}

	template <typename T, typename BeginObjec>
	std::enable_if_t<is_optional<T>::value> WriteObject(T const& t, BeginObjec bj)
	{
		if (static_cast<bool>(t))
		{
			WriteObject(*t, bj);
		}
		else
		{
			WriteNull();
		}
	}

	//template<typename T>
	//typename std::enable_if<is_user_class<T>::value>::type WriteObject(T&& t)
	//{
	//	m_jsutil.StartObject();
	//	WriteTuple(t.Meta());
	//	m_jsutil.EndObject();
	//}

	// variant visitor
	template <typename BeginObj>
	struct serialize_visitor : boost::static_visitor<>
	{
		explicit serialize_visitor(Serializer& s, int which)
			: s_(s)
			, which_(which - 1)
		{
		}

		template <typename T>
		void operator() (T const& to_write) const
		{
			s_.BeginWriteKV(std::to_string(which_).c_str(), to_write);
		}

		void operator() (boost::blank) const
		{
			throw std::invalid_argument( "Cannot serialize an uninitialized Variant!" );
		}

		Serializer& s_;
		int which_;
	};

	template <typename BeginObj, typename ... Args>
	void WriteObject(variant<Args...> const& v, BeginObj bj)
	{
		if (static_cast<bool>(v))
		{
			//WriteObject(*t, bj);
			boost::apply_visitor(serialize_visitor<BeginObj>{ *this, v.which() }, v);
		}
		else
		{
			WriteNull();
		}
	}

	template<typename T, typename BeginObjec>
	typename std::enable_if<is_user_class<T>::value>::type WriteObject(const T& t, BeginObjec)
	{
		m_jsutil.StartObject();
		WriteTuple(((T&)t).Meta());
		m_jsutil.EndObject();
	}

	template<typename T, typename BeginObjec>
	typename std::enable_if<is_tuple<T>::value>::type WriteObject(T const& t, BeginObjec)
	{
		m_jsutil.StartArray();
		WriteTuple(t);
		m_jsutil.EndArray();
	}

	template<std::size_t I = 0, typename Tuple>
	typename std::enable_if<I == std::tuple_size<Tuple>::value>::type WriteTuple(const Tuple& t)
	{
	}

	template<std::size_t I = 0, typename Tuple>
	typename std::enable_if<I < std::tuple_size<Tuple>::value>::type WriteTuple(const Tuple& t)
	{
		WriteObject(std::get<I>(t), std::false_type{});
		WriteTuple<I + 1>(t);
	}

	template<typename T, typename BeginObjec>
	typename std::enable_if<is_singlevalue_container<T>::value>::type WriteObject(T const& t, BeginObjec)
	{
		WriteArray(t);
	}

	template <typename Adaptor, typename F>
	auto WriteAdaptor(Adaptor&& adaptor, F get)
	{
		using adaptor_t = std::remove_cv_t<std::remove_reference_t<Adaptor>>;
		adaptor_t temp = std::forward<Adaptor>(adaptor);
		m_jsutil.StartArray();
		while (!temp.empty())
		{
			WriteObject(get(temp), std::false_type{});
			temp.pop();
		}
		m_jsutil.EndArray();
	}

	template <typename T, typename BeginObject>
	auto WriteObject(T&& t, BeginObject) -> std::enable_if_t<is_queue<T>::value>
	{
		WriteAdaptor(std::forward<T>(t), [](auto const& adaptor) { return adaptor.front(); });
	}

	template<typename T, typename BeginObject>
	auto WriteObject(T&& t, BeginObject) -> std::enable_if_t<is_stack<T>::value || is_priority_queue<T>::value>
	{
		WriteAdaptor(std::forward<T>(t), [](auto const& adaptor) { return adaptor.top(); });
	}

	template<typename T, typename BeginObject>
	typename std::enable_if<is_map_container<T>::value>::type WriteObject(T const& t, BeginObject)
	{
		m_jsutil.StartObject();
		m_wr.clear();
		for (auto const& pair : t)
		{
			m_wr << pair.first;
			WriteKV(m_wr.c_str(), pair.second);
			m_wr.clear();
		}
		m_jsutil.EndObject();
	}

	template<typename T>
	typename std::enable_if<is_pair<T>::value>::type WriteObject(T const& t, std::true_type)
	{
		m_jsutil.StartObject();
		m_wr << t.first;
		WriteKV(m_wr.c_str(), t.second);
		m_wr.clear();
		m_jsutil.EndObject();
	}

	template<typename T>
	typename std::enable_if<is_pair<T>::value>::type WriteObject(T const& t, std::false_type)
	{
		m_wr.clear();
		m_wr << t.first;
		WriteKV(m_wr.c_str(), t.second);
		m_wr.clear();
	}

	template<typename T, size_t N, typename BeginObject>
	void WriteObject(std::array<T, N> const& t, BeginObject)
	{
		WriteArray(t);
	}

	template <typename T, size_t N, typename BeginObject>
	void WriteObject(T const(&p)[N], BeginObject)
	{
		WriteArray(p);
	}

	template <size_t N, typename BeginObject>
	void WriteObject(char const(&p)[N], BeginObject bj)
	{
		WriteObject((const char*)p, bj);
	}

	//template <size_t N>
	//void WriteObject(char const(&p)[N], std::false_type)
	//{
	//	WriteObject((const char*)p, bj);
	//}

	template<typename Array>
	inline void WriteArray(Array const& v)
	{
		m_jsutil.StartArray();
		for (auto const& i : v)
		{
			WriteObject(i, std::false_type{});
		}
		m_jsutil.EndArray();
	}

	template<typename T, typename BeginObject>
	typename std::enable_if<is_basic_type<T>::value>::type WriteObject(T const& t, BeginObject)
	{
		m_jsutil.WriteValue(t);
	}

	template <typename T, typename BeginObject>
	auto WriteObject(T const& val, BeginObject) ->std::enable_if_t<std::is_enum<
		std::remove_reference_t<std::remove_cv_t<T>>>::value>
	{
		using under_type = std::underlying_type_t<
			std::remove_reference_t<std::remove_cv_t<T>>>;
		m_jsutil.WriteValue(static_cast<under_type>(val));
	}

	void WriteObject(const char* t, std::true_type)
	{
		m_jsutil.WriteValue(t);
	}

	void WriteObject(const char* t, std::false_type)
	{
		m_jsutil.WriteValue(t);
	}

	//template<typename T>
	//typename std::enable_if<is_normal_class<T>::value>::type WriteValue(T&& t)
	//{
	//	WriteKV(boost::lexical_cast<std::string>(t.first).c_str(), t.second);
	//}

	template<typename V>
	void WriteKV(const char* k, V& v)
	{
		m_jsutil.WriteValue(k);
		WriteObject(v, std::true_type{});
	}

	template<typename V>
	void BeginWriteKV(const char* k, V& v)
	{
		m_jsutil.StartObject();
		WriteKV(k, v);
		m_jsutil.EndObject();
	}

	template<typename T, typename BeginObject>
	typename std::enable_if<is_basic_type<T>::value>::type WriteValue(T const& t, BeginObject)
	{
		m_jsutil.WriteValue(std::forward<T>(t));
	}

	void WriteNull()
	{
		m_jsutil.WriteNull();
	}

private:
	JsonUtil m_jsutil;
	fmt::MemoryWriter m_wr;
};
} // namespace kapok

max_stars_repo_name: mind-owner/Kapok

max_issues_repo_name: mind-owner/Kapok

max_forks_repo_name: mind-owner/Kapok


text:
#pragma once

#include <boost/asio.hpp>
#include <boost/asio/ssl.hpp>

namespace cpool {

namespace asio = boost::asio;

/**
 * Defines the available states fo the connection_state object.
 */
enum class client_connection_state : uint8_t {
    /**
     * @brief The TcpConnection is not connected to a remote endpoint
     *
     */
    disconnected = 0,

    /**
     * @brief The TcpConnection is resolving a URL to determine the IP address
     * of the remote endpoint
     *
     */
    resolving,

    /**
     * @brief The TcpConnection is connecting to a remote endpoint
     *
     */
    connecting,

    /**
     * @brief The TcpConnection is connected to a remote endpoint and able to
     * send requests and receive responses
     *
     */
    connected,

    /**
     * @brief The TcpConnection is disconnecting from a remote endpoint and is
     * no longer able to interact with it
     *
     */
    disconnecting
};

inline bool
error_means_client_disconnected(const boost::system::error_code& ec) {
    if (ec == asio::error::broken_pipe ||
        ec == asio::error::connection_aborted ||
        ec == asio::error::connection_refused ||
        ec == asio::error::connection_reset ||
        ec == asio::error::network_down || ec == asio::error::network_reset ||
        ec == asio::error::network_unreachable ||
        ec == asio::error::not_connected || ec == asio::error::eof ||
        ec == asio::ssl::error::stream_truncated) {
        return true;
    }

    return false;
}

} // namespace cpool

ext: hpp

max_stars_repo_name: cblauvelt/connection-pool

max_issues_repo_name: cblauvelt/connection-pool

max_forks_repo_name: cblauvelt/connection-pool


text:
#include <iostream>
#include <vector>
#include <memory>
#include <string>
#include <numeric>
#include <iomanip>
#include <thread>
using namespace std;

#include <boost/log/core.hpp>
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#define DUMP_VAR(x) {BOOST_LOG_TRIVIAL(debug) << typeid(*this).name() \
<< "::" << __func__ << ":" << __LINE__ << " " #x "=<" << x << ">" << endl;}

#include "audio_layer.hpp"
#include "base_layer.hpp"
#include "wave.hpp"

using namespace WatorVapor;
AudioWaveLayer::AudioWaveLayer() {
}

int AudioWaveLayer::width(void) {
    return 0;
}

void AudioWaveLayer::snapshot(void) {
}

void AudioWaveLayer::execBody(void) {
    DUMP_VAR(name_);
    DUMP_VAR(t_.get_id());
    for(int i = 0;i < 1;i++) {
        this->forwardOneWave("./waveform/myRecording06.wav");
    }
    isRunning = false;
    DUMP_VAR(t_.get_id());
}

void AudioWaveLayer::forwardOneWave(const string &path){
    auto waves = readWave(path);
    DUMP_VAR(waves.size());
    if(waves.empty()) {
        return ;
    }
    int32_t minWave = waves.begin()->size();
    for(int channel = 0; channel <waves.size();channel++ ) {
        auto &wave = waves.at(channel);
        if(blobs_.size() <= channel) {
            auto blob = std::make_shared<Blob<int16_t>>(cond_var_,mtx_,memoryWidth_);
            blobs_.push_back(blob);
        }
        if(minWave > wave.size()) {
            minWave = wave.size();
        }
    }
    DUMP_VAR(minWave);
    for(int frame = 0 ; frame < minWave; frame++ ) {
        int channel = 0;
        for( auto &wave :waves) {
            blobs_.at(channel++)->push(wave.at(frame));
        }
    }
}

void AudioWaveLayer::fetch(int16_t &value,int16_t &channel) {
    for(auto blob:blobs_) {
        value = blob->wait();
    }
}

Peak2PeakLayer::Peak2PeakLayer() {
}

void Peak2PeakLayer::onThink(void) {
    DUMP_VAR(name_);
    for(auto buttom :buttom_) {
        auto wave = std::dynamic_pointer_cast<AudioWaveLayer>(buttom);
        if(wave) {
            DUMP_VAR("AudioWaveLayer");
            int16_t value;
            int16_t channel;
            wave->fetch(value,channel);
        }
        auto peak = std::dynamic_pointer_cast<Peak2PeakLayer>(buttom);
        if(peak) {
            DUMP_VAR("Peak2PeakLayer");
        }
    }
}

ext: cpp


text:
#ifndef NEIGHBORHOODS_HPP
#define NEIGHBORHOODS_HPP

#include <stdio.h>
#include <vector>
#include <boost/unordered_map.hpp>

class Neighborhoods {
public:

	typedef std::vector<std::pair<float, float> > Geometry;
	typedef boost::unordered_map<std::string, Geometry> GeometryMap;

	Neighborhoods() {
	}

	Neighborhoods(const char *filename) {
		this->loadFromFile(filename);
	}

	void loadFromFile(const char *filename) {
		char name[128];
		int N, nPoly, nPoint;
		double lat, lon;
		Geometry poly;

		FILE *fi = fopen(filename, "r");
		fscanf(fi, "%d", &N);
		fgets(name, sizeof(name), fi);

		this->geometries.clear();
		for (int i = 0; i < N; i++) {
			fgets(name, sizeof(name), fi);
			name[strlen(name) - 1] = 0;
			poly.clear();
			fscanf(fi, "%d\n", &nPoly);
			for (int j = 0; j < nPoly; j++) {
				fscanf(fi, "%d\n", &nPoint);
				for (int k = 0; k < nPoint; k++) {
					fscanf(fi, "%lf %lf\n", &lon, &lat);
					poly.push_back(std::make_pair(lon, lat));
				}
			}
			this->geometries[std::string(name)] = poly;
		}
		fclose(fi);
	}

	void get(std::string neighbor, Geometry &geom) {
		GeometryMap::iterator it = this->geometries.find(neighbor);
		if (it != this->geometries.end())
			geom = (*it).second;
	}

	void append(std::string neighbor, Geometry &geom) {
		GeometryMap::iterator it = this->geometries.find(neighbor);
		if (it != this->geometries.end())
			geom.insert(geom.end(), (*it).second.begin(), (*it).second.end());
	}

	static void getBounds(const Geometry &geom, double bounds[4]) {
		if (geom.size() == 0) {
			bounds[0] = bounds[1] = -1e30;
			bounds[2] = bounds[3] = 1e30;
		} else {
			bounds[0] = bounds[1] = 1e30;
			bounds[2] = bounds[3] = -1e30;
			for (size_t i = 0; i < geom.size(); i++) {
				if (geom[i].first < bounds[0])
					bounds[0] = geom[i].first;
				if (geom[i].first > bounds[2])
					bounds[2] = geom[i].first;
				if (geom[i].second < bounds[1])
					bounds[1] = geom[i].second;
				if (geom[i].second > bounds[3])
					bounds[3] = geom[i].second;
			}
		}
	}

#ifdef __CUDACC__
	__host__ __device__
#endif
	static bool isInside(int nvert, float *vert, float testx, float testy) {
		if (nvert <= 0)
			return true;
		float firstX = vert[0];
		float firstY = vert[1];
		int i, j, c = 0;
		for (i = 1, j = 0; i < nvert; j = i++) {
			if (((vert[i * 2 + 1] > testy) != (vert[j * 2 + 1] > testy))
					&& (testx
							< (vert[j * 2] - vert[i * 2])
									* (testy - vert[i * 2 + 1])
									/ (vert[j * 2 + 1] - vert[i * 2 + 1])
									+ vert[i * 2]))
				c = !c;
			if (vert[i * 2] == firstX && vert[i * 2 + 1] == firstY) {
				if (++i < nvert) {
					firstX = vert[i * 2];
					firstY = vert[i * 2 + 1];
				}
			}
		}
		return c;
	}

private:
	GeometryMap geometries;
};

#endif


text:
/**
 * Copyright (c) 2017 Melown Technologies SE
 *
 * 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 HOLDER 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.
 */
/**
 * @file mesh-voxelizer.hpp
 * @author Tomas Drinovsky <tomas.drinovsky@citationtech.net>
 *
 * Mesh voxelization class.
 *
 * This module provides a class voxelization of the generic meshes.
 * The implementation is based on the paper "Simplification and Repair of
 * Polygonal Models Using Volumetric Techniques" by F.S. Nooruddin and Greg Turk
 */

#ifndef GEOMETRY_MESH_VOXELIZER_HPP
#define GEOMETRY_MESH_VOXELIZER_HPP

#include "geometry/mesh.hpp"
#include "geometry/volume.hpp"

#include <memory>

#include <boost/filesystem.hpp>

namespace geometry{

namespace fs = boost::filesystem;

/**
 * @brief MeshVoxelizer
 * @details Class Mesh Voxelizer is able to voxelize arbitrary mesh
 * (even non-water-tight), refilter the voxel grid to different resolution
 * and extract iso surface of this voxel grid.
 * Right now the voxel sizes must be all same - voxel must be a cube.
 */
class MeshVoxelizer{

public:
    typedef ScalarField_t<unsigned short, VolumeArray<unsigned short>> Volume;
    typedef VolumeUnit<unsigned short> VoxelizerUnit;

    enum class Method{ PARITY_COUNT, RAY_STABING };

    struct Parameters {
        float voxelSize;
        bool addSeal;
        float isoThreshold;
        float sealFactor;
        Method method;
        bool shaveVolume; // turn hack on or off
        // if provided, expected to be compatible with voxel size
        math::Extents3 overrideExtents;

        Parameters():
            voxelSize(0.25)
          , addSeal(true)
          , isoThreshold(0.5)
          , sealFactor(5)
          , method(Method::PARITY_COUNT)
          , shaveVolume(true)
          , overrideExtents(math::InvalidExtents{})
         {};
    };

    /**
     * @brief Constructs MeshVoxelizer class
     * @param mesh The geometry to voxelize
     * @param params parameters of MeshVoxelizer
     */

    MeshVoxelizer(const Parameters & params);

    void add( geometry::Mesh & mesh );
    void voxelize();
    std::shared_ptr<Volume> volume();
    void reset();
private:
    /**
     * LayeredZbuffer is container for storing 2D image
     * with multiple values per pixel.
     * It models the following concepts:
     *
     * class LayeredBuffer {
     * public:
     *      LayeredBuffer( math::Size2i & size );
     *      Iterator begin(uint x, uint y);
     *      Iterator end(uint x, uint y);
     * };
     */

    struct LayeredZBuffer{
        typedef std::vector<std::vector<std::vector<float>>> LZBData;
        typedef std::vector<float>::iterator Iterator;
        math::Size2i size;
        LZBData data;

        LayeredZBuffer(math::Size2i & size){
            this->size = size;
            data = LZBData(size.width);
            for(int i=0;i<size.width; ++i){
                data[i]= std::vector<std::vector<float>>(size.height);
                for(int j=0;j<size.height; ++j){
                    data[i][j].reserve(0);
                };
            };
        }

        void sortCells(){
            for( auto &col : data){
                for( auto &cell : col){
                    std::sort(cell.begin(),cell.end());
                }
            }
        }

        long long mem(){
            long long dataMem=0;
            for( auto &col : data){
                for( auto &cell : col){
                    dataMem+= cell.size()*sizeof(float);
                }
            }

            return sizeof(std::vector<float>)*(size.width*size.height+size.width)
                     + dataMem;
        }

        Iterator begin(uint x, uint y){
            return data[x][y].begin();
        }

        Iterator end(uint x, uint y){
            return data[x][y].end();
        }
    };

    struct CompressedLayeredZBuffer{
        typedef std::vector<float>::iterator Iterator;
        typedef std::vector<float>::const_iterator CIterator;
        math::Size2i size;
        std::vector<float> data;
        std::vector<uint> rowpos;
        std::vector<size_t> colStart;
        std::vector<unsigned short> count;

        CompressedLayeredZBuffer():size(math::Size2(0,0)){}

        CompressedLayeredZBuffer(LayeredZBuffer &lzBuffer){
            this->size = lzBuffer.size;
            colStart.reserve(size.width);
            rowpos.reserve(size.width*size.height);
            count.reserve(size.width*size.height);

            std::size_t size = 0;
            for( auto &col : lzBuffer.data){
                colStart.push_back(size);
                for( auto &cell : col){
                    count.push_back(cell.size());
                    rowpos.push_back(size-colStart.back());
                    size+=cell.size();
                }
            }
            data.reserve(size);
            for( auto &col : lzBuffer.data){
                for( auto &cell : col){
                    for( auto &zval : cell){
                        data.push_back(zval);
                    }
                }
            }
        }

        long long mem(){
            return data.size()*sizeof(float) + rowpos.size()*sizeof(uint)
                + colStart.size()*sizeof(size_t)
                + count.size()*sizeof(unsigned short);
        }

        Iterator begin(uint x, uint y){
            return data.begin()+colStart[x]
                    +rowpos[(std::size_t)x*size.height+y];
        }

        CIterator begin(uint x, uint y) const {
            return data.begin()+colStart[x]
                    +rowpos[(std::size_t)x*size.height+y];
        }

        Iterator end(uint x, uint y) {
            return begin(x,y)+count[(std::size_t)x*size.height+y];
        }

        CIterator end(uint x, uint y) const {
            return begin(x,y)+count[(std::size_t)x*size.height+y];
        }

    };

    struct Projection{
        math::Matrix4 transformation;
        math::Size2 viewportSize;

        Projection( math::Matrix4 transformation, math::Size2 viewportSize):
                  transformation(transformation),viewportSize(viewportSize){}
    };

    struct ProjectionResult{
        math::Matrix4 transformation;
        CompressedLayeredZBuffer buffer;

        ProjectionResult( math::Matrix4 transformation
                        , CompressedLayeredZBuffer buffer):
            transformation(transformation), buffer(buffer){};
    };

    typedef std::vector<ProjectionResult> ProjectionResults;
    typedef std::vector<Projection> Projections;
    typedef std::vector<CompressedLayeredZBuffer> CompLZBuffers;

    Parameters params_;
    std::shared_ptr<Volume> volume_;
    std::vector<geometry::Mesh*> meshes;

    Projection orthoProj( const math::Point3 &direction
                               , const math::Extents3 &extents
                               , const float &voxelSize);

    geometry::Mesh sealOfMesh(geometry::Mesh & mesh);
    void fillVolumeFromSeal();

    /**
     * @brief rasterizeMesh renders the mesh into layered z-buffer using
     * given projection matrix.
     * @param mesh
     * @param projection
     */
    void rasterizeMesh( const geometry::Mesh & mesh
                       , const math::Matrix4 & projMat
                       , LayeredZBuffer & lZBuffer);

    /**
     * @brief Determines if point on given position is inside.
     * From each projection it determines if the voxel is inside or outside
     * by parity-counting or by ray-stabing method.
     * @return True if the voxel is inside
     */
    bool isInside(  const math::Point3 & position
                  , ProjectionResults & projectionResults);

    void visualizeDepthMap(const ProjectionResult &proj
                           , const math::Extents3 &extents, const fs::path &path);

};

} //namespace geometry

#endif// GEOMETRY_MESH_VOXELIZER_HPP

max_issues_repo_name: HanochZhu/vts-browser-unity-plugin

max_forks_repo_name: HanochZhu/vts-browser-unity-plugin


text:
/* GNU C Compiler Detection */
#ifdef __clang_version__
  #if __clang_major__ == 4
    #define LLVM_4
  #endif
  #if __clang_major__ == 11 || __clang_major__ == 12
    #define LLVM_11
  #endif
#endif

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include <set>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <chrono>
#include <algorithm>
#include <cassert>
#include <dlfcn.h>
#include <cxxabi.h>
#include "llvm/Pass.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/SmallVector.h"
#include <llvm/IR/User.h>
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/PassManager.h"
#include "llvm/IR/LegacyPassManager.h"
#include <llvm/IR/Module.h>			// for Module
#include <llvm/IR/Function.h>		// for Function
#include <llvm/IR/BasicBlock.h>		// for BasicBlock
#include <llvm/IR/GlobalVariable.h>	// for GlobalVariable
#include <llvm/IR/InstrTypes.h>		// for TerminatorInst
#include <llvm/IR/IntrinsicInst.h>	// for intrinsic instruction
#include <llvm/IR/InstIterator.h>	// for inst iteration
#include <llvm/IR/CFG.h>			// for CFG
#include "llvm/IR/Constant.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/Analysis/CallGraph.h"
#include <llvm/Analysis/CFG.h>		// for CFG
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
#include "llvm/Transforms/Utils/Local.h"	// for FindDbgAddrUses
#include <llvm/Support/CommandLine.h>
#include "llvm/Support/Debug.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/raw_ostream.h"
#include <llvm/IRReader/IRReader.h>			// for isIRFiler isBitcode
#include <sys/resource.h>					// increase stack size
#include <boost/algorithm/string.hpp>

#ifdef LLVM_11
  #include <llvm/Pass.h>
#else
  #include "llvm/IR/CallSite.h"
  #include <llvm/PassAnalysisSupport.h>
#endif

using namespace llvm;
using namespace llvm;
using namespace std::chrono;
using namespace std;
using std::vector;

//Lock analysis
#define LockFunctionNum 6
char LockFunctionString[][25] = {
  "Lock",
  "mutex_lock",
  "task_lock",
  "PR_RWLock_Rlock",
  "PR_RWLock_Wlock",
  "PR_Lock",
};
char UnlockFunctionString[][25] = {
  "Unlock",
  "mutex_unlock",
  "task_unlock",
  "PR_RWLock_Unlock",
  "PR_Unlock",
  "UK"
};

//Manually Marked Interesting Functions
#define MarkedInterestingNum 1
char MarkedInterestingString[][30] = {
  "js_ClearContextThread",
  "UK"
};

#define DEBUG_TYPE "SensitiveOperations"

//#define WC_DEBUG
//#define WC_DEBUG_2

namespace {
	struct SensitiveOperations :public ModulePass {

		static char ID; // Pass ID, replacement for typeid

		SensitiveOperations():ModulePass(ID){}

		bool runOnModule(Module &M) override;

        virtual void getAnalysisUsage(AnalysisUsage &AU) const override {
          AU.addRequiredTransitive<CallGraphWrapperPass>();
          AU.setPreservesAll();
        }

		StringRef getPassName() const override {
			return "SensitiveOperations Instrumentation";
      	}
	};
}

inline const char *get_funcname(const char *src) {
	int status = 99;
	const char *f = abi::__cxa_demangle(src, nullptr, nullptr, &status);
	return f == nullptr ? src : f;
}

int CountLines(char *filename)
{
    ifstream ReadFile;
    int n=0;
    string line;
    ReadFile.open(filename,ios::in);//ios::in 表示以只读的方式读取文件
    if(ReadFile.fail())//文件打开失败:返回0
    {
        return 0;
    }
    else//文件存在
    {
        while(getline(ReadFile,line,'\n'))
        {
            if (line.size() == 0 || line.empty())
              continue;
            else
              n++;
        }
        ReadFile.close();
        return n;
    }
}

std::string getSourceLoc(const Value* val) {
  if(val==NULL)  return "empty val";

  std::string str;
  raw_string_ostream rawstr(str);
  if (const Instruction *inst = dyn_cast<Instruction>(val)) {
    if (isa<AllocaInst>(inst)) {
#ifdef LLVM_4 /* LLVM 4.0 */
	  DbgDeclareInst* DDI = llvm::FindAllocaDbgDeclare(const_cast<Instruction*>(inst));
      if (DDI) {
        DIVariable *DIVar = cast<DIVariable>(DDI->getVariable());
        rawstr << DIVar->getLine();
      }
#else /* LLVM 6.0+ */
      for (DbgInfoIntrinsic *DII : FindDbgAddrUses(const_cast<Instruction*>(inst))) {
        if (DbgDeclareInst *DDI = dyn_cast<DbgDeclareInst>(DII)) {
          DIVariable *DIVar = cast<DIVariable>(DDI->getVariable());
          rawstr << DIVar->getLine();
          break;
        }
      }
#endif

    }
    else if (MDNode *N = inst->getMetadata("dbg")) { // Here I is an LLVM instruction
      DILocation* Loc = cast<DILocation>(N); // DILocation is in DebugInfo.h
      unsigned Line = Loc->getLine();
      StringRef File = Loc->getFilename();
      rawstr << File << ":" << Line;
      //StringRef Dir = Loc->getDirectory();
      //rawstr << Dir << "/" << File << ":" << Line;
    }
  }
  else {
    //Can only get source location for instruction, argument, global var or function.
    rawstr << "N.A.";
  }
  return rawstr.str();
}

uint16_t string_hash_encoding(const char* str){
	uint16_t encodingNum = 26;
	for(int k=0; k<strlen(str); k++){
		encodingNum *= int(str[k]);
		encodingNum = encodingNum + int(str[k]);
	}
	return encodingNum;
}

uint16_t string_hash_encoding(std::string str){
	uint16_t encodingNum = 26;
	for(int k = 0; k < str.length(); k++){
		encodingNum *= int(str[k]);
		encodingNum = encodingNum + int(str[k]);
	}
	return encodingNum;
}

bool SensitiveOperations::runOnModule(Module &M) {

  int linesNum = 0;
  int lockNum = 0;
  int SoNum = 0;

  //Function指针到bool的映射表
  std::map<llvm::Function*, bool> pthreadFunctionMap;
  std::set<llvm::Function*> pthreadAllCalleeSet;
  std::set<llvm::Function*> pthreadCallFunction;

  //包装了一层Lock的函数的集合
  std::set<llvm::Function*> LockFunctionSet;
  //包装了一层Unlock的函数的集合
  std::set<llvm::Function*> UnlockFunctionSet;

  //pthread_mutex_Lock的集合
  std::set<string> mutexLockSet;
  //SoFunc的集合
  std::set<string> SoFuncSet;

  //初始化functionMap和controlDependenceMap
  for (Module::iterator function = M.begin(), FEnd = M.end(); function != FEnd; function++) {
    Function* curF = &*function;
    if (pthreadFunctionMap.find(curF) == pthreadFunctionMap.end())
    {
      pthreadFunctionMap[curF] = false;
    }
  }

  //找pthread_create的参数，找pthread_mutex_lock, atomic_fetch_add, atomic_fetch_sub, atomic_exchange
  //refers to: https://www.nuomiphp.com/eplan/85333.html
  for (Module::iterator function = M.begin(), FEnd = M.end(); function != FEnd; function++) {
      if (function->isDeclaration() || function->size() == 0){
          continue;
      }
      //判断是否是MarkedInterestingNum
      for(int i = 0; i < MarkedInterestingNum; i++){
          if (MarkedInterestingString[i] == function->getName()){
              pthreadFunctionMap[&*function]=true;
              break;
          }
      }
      for (Function::iterator basicblock = function->begin(), BBEnd = function->end(); basicblock != BBEnd; basicblock++) { //遍历每一个Basic Block

          for(BasicBlock::iterator instruction = basicblock->begin(), IEnd = basicblock->end(); instruction!=IEnd; instruction++) {    //遍历每一条instruction

              if(Instruction *inst = dyn_cast<Instruction>(instruction)) {

                  if(inst->getOpcode() == Instruction::Call) {

                      std::string instr_create = "pthread_create";
                      std::string instr_create2 = "PR_CreateThread";
                      if(inst->getNumOperands() >= 5 ){ //操作数大于5

                          int find_thread_flag = 0;
                          int arg_id = 0;

                          if (inst->getNumOperands() == 5 && instr_create == std::string(inst->getOperand(4)->getName())){//找pthread_create
                              find_thread_flag = 1;
                              arg_id = 2;
                          }
                          else if (inst->getNumOperands() == 8 && instr_create2 == std::string(inst->getOperand(7)->getName())){
                              find_thread_flag = 1;
                              arg_id = 1;
                          }

                          if (find_thread_flag==1){
                              Function *pthread_task = dyn_cast<Function>(inst->getOperand(arg_id)->stripPointerCasts());
                              pthreadCallFunction.insert(pthread_task);
                              pthreadAllCalleeSet.insert(pthread_task);
                              pthreadFunctionMap[pthread_task]=true;
                          }
                      }

                      std::string str_free = "free";
                      if(inst->getNumOperands() >= 2 ){ //操作数大于2
                          if (str_free == std::string(inst->getOperand(1)->getName())){ //free
                              std::string SourceLoc = getSourceLoc(inst);
                              if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                continue;
                              if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                continue;
                              std::string tmpstring("./");
                              if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                SourceLoc.erase(0,2);
                              }

                              //freeFuncSet
                              SoFuncSet.insert(SourceLoc);
                              SoNum ++;
                          }
                      }

                      std::string str_mutex_lock = "pthread_mutex_lock";
                      std::string str_mutex_unlock = "pthread_mutex_unlock";
                      if(inst->getNumOperands() >= 2 ){ //操作数大于2
                          if (str_mutex_lock == std::string(inst->getOperand(1)->getName())){ //pthread_mutex_lock
                              std::string SourceLoc = getSourceLoc(inst);
                              if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                continue;
                              if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                continue;
                              std::string tmpstring("./");
                              if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                SourceLoc.erase(0,2);
                              }

                              // C++函数名解码
#ifdef LLVM_11
                              string strfname = function->getName().str();
#else
                              string strfname = function->getName();
#endif
                              string strfnameDemangled = get_funcname(strfname.c_str());
                              size_t iIndex = strfnameDemangled.rfind("(");
                              if(iIndex != std::string::npos)
                                strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                              //outs() << strfnameDemangled << "\n";

                              //判断是否是包装的Lock函数
                              int isLockFunction = 0;
                              for(int i = 0; i < LockFunctionNum; i++){
                                if (LockFunctionString[i] == function->getName() || LockFunctionString[i] == strfnameDemangled){
                                  LockFunctionSet.insert(&*function);
                                  isLockFunction = 1;
                                  break;
                                }
                              }

                              if (isLockFunction == 0) {
                                  if (function->size() == 1 && function->arg_size() == 1 && function->getInstructionCount() <= 10 && function->isVarArg() == false && function->hasAddressTaken() == false) { //Heuristic judgment
                                      LockFunctionSet.insert(&*function);
                                      isLockFunction = 1;
                                  }
                              }

                              // 就是pthread_mutex_lock
                              if (isLockFunction == 0) {
                                mutexLockSet.insert(SourceLoc);
                                lockNum ++;

                              }

                          } else if (str_mutex_unlock == std::string(inst->getOperand(1)->getName())){ //pthread_mutex_unlock
                              std::string SourceLoc = getSourceLoc(inst);
                              if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                continue;
                              if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                continue;
                              std::string tmpstring("./");
                              if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                SourceLoc.erase(0,2);
                              }

                              // C++函数名解码
#ifdef LLVM_11
                              string strfname = function->getName().str();
#else
                              string strfname = function->getName();
#endif
                              string strfnameDemangled = get_funcname(strfname.c_str());
                              size_t iIndex = strfnameDemangled.rfind("(");
                              if(iIndex != std::string::npos)
                                strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                              //outs() << strfnameDemangled << "\n";

                              //判断是否是包装的unLock函数
                              int isUnLockFunction = 0;
                              for(int i = 0; i < LockFunctionNum; i++){
                                if (UnlockFunctionString[i] == function->getName() || UnlockFunctionString[i] == strfnameDemangled){
                                  UnlockFunctionSet.insert(&*function);
                                  isUnLockFunction = 1;
                                  break;
                                }
                              }

                              if (isUnLockFunction == 0) {
                                  if (function->size() == 1 && function->arg_size() == 1 && function->getInstructionCount() <= 10 && function->isVarArg() == false && function->hasAddressTaken() == false) { //Heuristic judgment
                                      UnlockFunctionSet.insert(&*function);
                                      isUnLockFunction = 1;
                                  }
                              }
                              // 就是pthread_mutex_unlock则可以忽略

                          } else {

                              // C++函数名解码
#ifdef LLVM_11
                              string strfname = inst->getOperand(1)->getName().str();
#else
                              string strfname = inst->getOperand(1)->getName();
#endif
                              string strfnameDemangled = get_funcname(strfname.c_str());
                              size_t iIndex = strfnameDemangled.rfind("(");
                              if(iIndex != std::string::npos)
                                strfnameDemangled = strfnameDemangled.substr(0,iIndex);

                              //判断是否是interesting的Lock函数
                              for(int i = 0; i < LockFunctionNum; i++){
                                if (LockFunctionString[i] == std::string(inst->getOperand(1)->getName()) || LockFunctionString[i] == strfnameDemangled){
                                  Function *function_of_lock = dyn_cast<Function>(inst->getOperand(1)->stripPointerCasts());
                                  LockFunctionSet.insert(&*function_of_lock);
                                  pthreadFunctionMap[&*function]=true; //Open a back door for interested lock functions, regardless of thread creation and function calls
                                  break;
                                }
                              }
                              //判断是否是interesting的unLock函数
                              for(int i = 0; i < LockFunctionNum; i++){
                                if (UnlockFunctionString[i] == std::string(inst->getOperand(1)->getName()) || UnlockFunctionString[i] == strfnameDemangled){
                                  Function *function_of_lock = dyn_cast<Function>(inst->getOperand(1)->stripPointerCasts());
                                  UnlockFunctionSet.insert(&*function_of_lock);
                                  break;
                                }
                              }
                          }

                      }

                      std::string str_atomic_fetch_add = "long std::atomic_fetch_add<long>";
                      std::string str_atomic_fetch_sub = "long std::atomic_fetch_sub<long>";
                      std::string str_atomic_exchange1 = "std::atomic<void*>::exchange";
                      std::string str_atomic_exchange2 = "webrtc::SSRCDatabase* std::atomic_exchange<webrtc::SSRCDatabase*>";
                      if(inst->getNumOperands() == 3 || inst->getNumOperands() == 4){ //操作数大于3, 有类对象是操作数为4，因为还有this
                          if(CallInst *callfunInst = dyn_cast<CallInst>(instruction)) {
                            string strfname;
                            Function *callfun = callfunInst->getCalledFunction();
                            if (callfun){
#ifdef LLVM_11
                              strfname = callfun->getName().str();
#else
                              strfname = callfun->getName();
#endif

                            } else {
                              if (inst->getNumOperands() == 3) {
#ifdef LLVM_11
                                strfname = inst->getOperand(2)->getName().str();
#else
                                strfname = inst->getOperand(2)->getName();
#endif
                              }
                              else if (inst->getNumOperands() == 4){
#ifdef LLVM_11
                                strfname = inst->getOperand(3)->getName().str();
#else
                                strfname = inst->getOperand(3)->getName();
#endif
                              }
                            }
                            // C++函数名解码
                            string strfnameDemangled = get_funcname(strfname.c_str());
                            size_t iIndex = strfnameDemangled.rfind("(");
                            if(iIndex != std::string::npos)
                                strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                            //outs() << "[DEBUG] " << getSourceLoc(inst) << ", " << strfnameDemangled << "\n";

                            if (str_atomic_fetch_add == strfnameDemangled ||
                              str_atomic_fetch_sub == strfnameDemangled ||
                              str_atomic_exchange1 == strfnameDemangled ||
                              str_atomic_exchange2 == strfnameDemangled){

                                std::string SourceLoc = getSourceLoc(inst);
                                if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                  continue;
                                if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                  continue;
                                std::string tmpstring("./");
                                if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                  SourceLoc.erase(0,2);
                                }

                                SoFuncSet.insert(SourceLoc);
                                SoNum ++;
                            }
                          }
                      }

                      std::string str_std_Map_size = "std::map<unsigned int, unsigned int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::size";
                      if(inst->getNumOperands() == 2 ){ //操作数等于2
                          if(CallInst *callfunInst = dyn_cast<CallInst>(instruction)) {
                            string strfname;
                            Function *callfun = callfunInst->getCalledFunction();
                            if (callfun){
#ifdef LLVM_11
                              strfname = callfun->getName().str();
#else
                              strfname = callfun->getName();
#endif
                            } else {
#ifdef LLVM_11
                              strfname = inst->getOperand(1)->getName().str();
#else
                              strfname = inst->getOperand(1)->getName();
#endif
                            }
                            // C++函数名解码
                            string strfnameDemangled = get_funcname(strfname.c_str());
                            size_t iIndex = strfnameDemangled.rfind("(");
                            if(iIndex != std::string::npos)
                              strfnameDemangled = strfnameDemangled.substr(0,iIndex);

                            if (str_std_Map_size == strfnameDemangled){
                              std::string SourceLoc = getSourceLoc(inst);
                              if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                continue;
                              if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                continue;
                              std::string tmpstring("./");
                              if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                SourceLoc.erase(0,2);
                              }

                              SoFuncSet.insert(SourceLoc);
                              SoNum ++;
                            }
                          }
                      }

                      //memset函数
                      std::string memsetstring = "llvm.memset.";
                      if(inst->getNumOperands() == 5){ //操作数等于5
                          if (boost::algorithm::starts_with(std::string(inst->getOperand(4)->getName()), memsetstring)){
                              std::string SourceLoc = getSourceLoc(inst);
                              if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                continue;
                              if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                continue;
                              std::string tmpstring("./");
                              if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                SourceLoc.erase(0,2);
                              }

                              SoFuncSet.insert(SourceLoc);
                              SoNum ++;
                          }
                      }

                  }
                  /*else if (inst->getOpcode() == Instruction::ICmp) {
                      // cmp null statement. i.e., if (xxx==NULL)
                      if(inst->getNumOperands() == 2){ //操作数等于5
                          if (ConstantPointerNull *CI = dyn_cast<ConstantPointerNull>(inst->getOperand(1))){
                              std::string SourceLoc = getSourceLoc(inst);
                              if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                continue;
                              if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                continue;
                              std::string tmpstring("./");
                              if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                SourceLoc.erase(0,2);
                              }

                              SoFuncSet.insert(SourceLoc);
                              SoNum ++;
                          }
                      }
                  }*/
                  else if(inst->getOpcode() == Instruction::Invoke){
                      std::string VecResizeStart = "std::vector<";
                      std::string VecResizeEnd = ">::resize";
                      if(inst->getNumOperands() == 5){ //找std::vector<...>::resize
#ifdef LLVM_11
                        string strfname = inst->getOperand(inst->getNumOperands()-1)->getName().str();
#else
                        string strfname = inst->getOperand(inst->getNumOperands()-1)->getName();
#endif
                        string strfnameDemangled = get_funcname(strfname.c_str());// C++函数名解码
                        size_t iIndex = strfnameDemangled.rfind("(");
                        if(iIndex != std::string::npos)
                          strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                        if (boost::algorithm::istarts_with(strfnameDemangled, VecResizeStart)
                          && boost::algorithm::ends_with(strfnameDemangled, VecResizeEnd) ) {
                            std::string SourceLoc = getSourceLoc(inst);
                            if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                              continue;
                            if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                              continue;
                            std::string tmpstring("./");
                            if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                              SourceLoc.erase(0,2);
                            }

                            SoFuncSet.insert(SourceLoc);
                            SoNum ++;
                        }
                      }
                  }

              }
          }
      }
  }

  //找包装过的Lock函数
  for (Module::iterator function = M.begin(), FEnd = M.end(); function != FEnd; function++) {
      if (function->isDeclaration() || function->size() == 0){
          continue;
      }
      for (Function::iterator basicblock = function->begin(), BBEnd = function->end(); basicblock != BBEnd; basicblock++) { //遍历每一个Basic Block

          for(BasicBlock::iterator instruction = basicblock->begin(), IEnd = basicblock->end(); instruction!=IEnd; instruction++) {    //遍历每一条instruction

              if(Instruction *inst = dyn_cast<Instruction>(instruction)) {

                  if(inst->getOpcode() == Instruction::Call){

                      //lock function
                      if(inst->getNumOperands() >= 2) { //操作数大于二
                          std::set<llvm::Function*>::iterator LockFunctionSetiter; //定义前向集合迭代器
                          for(LockFunctionSetiter = LockFunctionSet.begin(); LockFunctionSetiter != LockFunctionSet.end(); LockFunctionSetiter++){
#ifdef LLVM_11
                              std::string LockFunctionstring = (*LockFunctionSetiter)->getName().str();
#else
                              std::string LockFunctionstring = (*LockFunctionSetiter)->getName();
#endif

                              if ( LockFunctionstring == std::string(inst->getOperand(1)->getName()) ){
                                  std::string SourceLoc = getSourceLoc(inst);
                                  if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
                                    continue;
                                  if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
                                    continue;
                                  std::string tmpstring("./");
                                  if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
                                    SourceLoc.erase(0,2);
                                  }

                                  //outs() << SourceLoc << "\n";
                                  //outs() << LockFunctionstring << "\n";
                                  //outs() << *inst << "\n";

                                  mutexLockSet.insert(SourceLoc);
                                  lockNum ++;
                              }
                          }
                      }

                  }
              }
          }
      }
  }

  CallGraph &CG = Pass::getAnalysis<CallGraphWrapperPass>().getCallGraph(); //获取Call graph

  //根据pthreadAllCalleeSet（初始化为pthreadCallFunction）, 标记所有Callee

  int isFixPoint = 0;
  std::set<llvm::Function*> SearchCalleeFinishSet; //搜索过Callee函数的集合
  bool canSeekCallee_global_flag = false;
  while(isFixPoint == 0) {//不动点算法
    isFixPoint = 1;
    std::set<llvm::Function*>::iterator functionInterestingiter; //定义前向集合迭代器
    for(functionInterestingiter = pthreadAllCalleeSet.begin(); functionInterestingiter != pthreadAllCalleeSet.end(); functionInterestingiter++) {
      if (SearchCalleeFinishSet.find(*functionInterestingiter) == SearchCalleeFinishSet.end()) { //没有被找过Callee
        SearchCalleeFinishSet.insert(*functionInterestingiter); //加入集合保存，用于不动点迭代不重复搜索，后面遇到这个函数就不用再找了
        CallGraphNode *CallerNode = CG.getOrInsertFunction(*functionInterestingiter);
#ifdef WC_DEBUG_2
        errs () << "[DEBUG] Calculating " << (*functionInterestingiter)->getName() << "'s Callee. " << "  #uses=" << CallerNode->getNumReferences() << '\n';
#endif
        // Seeking Callee (use callgraph, it makes mistakes sometimes)
        bool canSeekCallee = false;
        for (const auto &I : *CallerNode) {
          if (Function *FI = I.second->getFunction()){
            if (FI->size()!=0){
#ifdef LLVM_11
              Value *callvalue = I.first.getValue();
#else
              Value *callvalue = (Value*) I.first;
#endif
              if (Instruction *callinst = dyn_cast<Instruction>(callvalue)){
#ifdef WC_DEBUG_2
                  errs() << "[DEBUG]   "<< callinst->getParent()->getName() << " calls function '" << FI->getName() << "'\n";
#endif
                  outs() << "[DEBUGDEBUG]   "<< callinst->getParent()->getName() << " calls function '" << FI->getName() << "'\n";
                  pthreadFunctionMap[FI] = true;
                  pthreadAllCalleeSet.insert(FI);
                  isFixPoint = 0;
                  canSeekCallee = true;
                  canSeekCallee_global_flag = true;
              }
            } else {
              //errs() << "  CS<" << I.first << "> calls " << "external node\n";
              continue;
            }
          }
        }

        // The missing Callee is supplemented by traditional method
        for (Function::iterator basicblock = (*functionInterestingiter)->begin(), BBEnd = (*functionInterestingiter)->end(); basicblock != BBEnd; basicblock++) { //遍历每一个Basic Block
          for(BasicBlock::iterator instruction = basicblock->begin(), IEnd = basicblock->end(); instruction!=IEnd; instruction++) {    //遍历每一条instruction
            if(Instruction *inst = dyn_cast<Instruction>(instruction)) {
              if(inst->getOpcode() == Instruction::Call){
                if(CallInst *callfunInst = dyn_cast<CallInst>(instruction)) {
                  Function *callfun = callfunInst->getCalledFunction();
                  if (callfun){
                    ; // the same as else branch, but is done above (see Seeking Callee)
                  } else {
                    callfun = dyn_cast<Function>(inst->getOperand(inst->getNumOperands()-1)->stripPointerCasts());
                    pthreadFunctionMap[callfun] = true;
                  }
                }
              }
            }
          }
        }

#ifdef WC_DEBUG_2
        if (canSeekCallee == false) {
          errs() << "[DEBUG]   None" << "\n";
        }
#endif
      }
    }
  }

  /*wcventure 打开ConConfig文件*/

  char *Con_PATH = NULL;
  char *ConFileName;
  int ConcurrencyInsteresting = 0;
  Con_PATH = getenv("Con_PATH");

  if (Con_PATH == NULL || strcmp(Con_PATH, "") == 0){
    ConcurrencyInsteresting = 0;
    outs() << "[DEBUG] Will use defult instru\n";
  }

  if (Con_PATH != NULL && Con_PATH[0] != '.' && Con_PATH[0] != ' ') {
    ConFileName = (char*)malloc(strlen(Con_PATH) + 1);
      if (ConFileName == NULL) {
        exit(1);
        return false;
      }
      strcpy(ConFileName, Con_PATH);
      linesNum = CountLines(ConFileName);
  } else {
    outs () << "[DEBUG] Please export Con_PATH" << "\n";
  }

  ifstream read_file;
  read_file.open(ConFileName, ios::binary);

  if (read_file.fail()) {
    outs() << "[DEBUG] Failed to open ConConfig file." << "\n";
    outs() << "[DEBUG] The program quit without execution." << "\n";
    ConcurrencyInsteresting = 0;
    exit(1);
    return false;
  } else {
    ConcurrencyInsteresting = 1;
    outs() << "[DEBUG] The ConConfig file was successfully opened.\n[DEBUG] The file is " << ConFileName << "\n[DEBUG]\n";
  }

  std::set<string>::iterator Coniter; //定义前向集合迭代器
  int lock_index;
  int free_index;

  if (ConcurrencyInsteresting == 1) {
    string* ConFirst = new string[linesNum];
    string line;
    for (int i=0; getline(read_file, line); i++){
      if (!line.empty() && line[line.size() - 1] == '\r'){
        if (line.size() == 1)
          ConFirst[i] = "N.A.";
        else {
          ConFirst[i] = line.erase(line.size() - 1);
		    }
      }
      else if (line.size() == 0 || line.empty())
      {
        continue;
      }
      else {
        ConFirst[i] = line;
      }

      //过滤掉重复的
      lock_index = 0;
      free_index = 0;
      for(Coniter = mutexLockSet.begin(); Coniter != mutexLockSet.end() && lock_index < lockNum; lock_index++){
        if (ConFirst[i] ==  *Coniter){
          Coniter = mutexLockSet.erase(Coniter);
        }else{
	  Coniter++;
	}
      }
      for(Coniter = SoFuncSet.begin(); Coniter != SoFuncSet.end() && free_index < SoNum; free_index++){
        if (ConFirst[i] ==  *Coniter){
          Coniter = SoFuncSet.erase(Coniter);
        } else {
	  Coniter++;
	}
      }
    }

    //将key points和lock组合一下
    lockNum = mutexLockSet.size();
    SoNum = SoFuncSet.size();
    string* ConLine = new string[linesNum + lockNum + SoNum];
    for (int i=0; i < linesNum; i++)
    {
      ConLine[i] = ConFirst[i];
    }

    lock_index = 0;
    free_index = 0;
    for(Coniter = mutexLockSet.begin(); Coniter != mutexLockSet.end() && lock_index < lockNum; Coniter++, lock_index++){
      ConLine[linesNum + lock_index] =  *Coniter;
    }
    for(Coniter = SoFuncSet.begin(); Coniter != SoFuncSet.end() && free_index < SoNum; Coniter++, free_index++){
      ConLine[linesNum + lock_index + free_index] =  *Coniter;
    }

//#ifdef WC_DEBUG
    outs() << "[DEBUG] All the Concurent insteresting line are shown as follow:" << "\n";
    for (int i = 0; i < linesNum + lockNum + SoNum; i++){
      outs() << "[DEBUG]  " << i + 1 << ")\t" << ConLine[i].c_str() << "\n";
    }
//#endif
    free(ConFileName);
    read_file.close();

    /*wcventure 关闭ConConfig文件*/

    for (Module::iterator function = M.begin(), FEnd = M.end(); function != FEnd; function++) { //遍历每一个Function

      if (canSeekCallee_global_flag == false) {
        if (function->isDeclaration() || function->size() == 0){
          //outs() << "[DEBUG] " << function->getName() << " is filtered" << "\n";
          continue;
        }
      } else {
        if (function->isDeclaration() || function->size() == 0 || pthreadFunctionMap[&*function]==false){
          //outs() << "[DEBUG] " << function->getName() << " is filtered" << "\n";
          continue;
        }
      }

      for (Function::iterator basicblock = function->begin(), BBEnd = function->end(); basicblock != BBEnd; basicblock++) { //遍历每一个Basic Block

        for(BasicBlock::iterator instruction = basicblock->begin(), IEnd = basicblock->end(); instruction!=IEnd; instruction++) {	//遍历每一条instruction

          if(Instruction *inst = dyn_cast<Instruction>(instruction)) {

            //指令对应的代码行号
            std::string SourceLoc = getSourceLoc(inst);

            if (SourceLoc.size() == 0) //SourceLoc为空则不用比较了，直接continue
              continue;

            if (SourceLoc.find(":")== std::string::npos) //SourceLoc可能取得有问题
              continue;

            std::string tmpstring("./");
            if (SourceLoc.compare(0, tmpstring.length(), tmpstring) == 0) {//如果SourceLoc前两个字符为"./", 则删除掉
              SourceLoc.erase(0,2);
            }

            for (int i = 0; i < linesNum + lockNum + SoNum; i++){

			        int spaceIndex = ConLine[i].find(" ");
			        std::string splitConLine;
              if (spaceIndex>=0)
                splitConLine = ConLine[i].substr(0,spaceIndex);
              else
                splitConLine = ConLine[i];
#ifdef WC_DEBUG_2
              outs() << splitConLine << "--" << SourceLoc << "\n";
#endif
              if (boost::algorithm::ends_with(splitConLine, SourceLoc)) { //rather than ConLine[i] == SourceLoc
#ifdef WC_DEBUG_2
                outs() << "[DEBUG] Match to diff in function "<< function->getName() << ":" << SourceLoc << "\n";
                outs() << "[DEBUG]   " << *inst << " (in BasicBlock " << basicblock->getName() << ")" << "\n";
#endif
                /* start: Find Sensitive Operations */

                //outs() << SourceLoc << ": " << *inst << "\n";
                int FindFlag = 0;

                //在call指令中搜索
                if(inst->getOpcode() == Instruction::Call) {

                  //outs() << *inst << "\n";

                  //malloc函数
                  std::string instr_malloc1 = "malloc";
                  std::string instr_malloc2 = "xmalloc";
                  std::string instr_malloc3 = "valloc";
                  std::string instr_malloc4 = "safe_malloc";
                  std::string instr_malloc5 = "safemalloc";
                  std::string instr_malloc6 = "safexmalloc";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if ( instr_malloc1 == std::string(inst->getOperand(1)->getName()) ||
                      instr_malloc2 == std::string(inst->getOperand(1)->getName()) ||
                      instr_malloc3 == std::string(inst->getOperand(1)->getName()) ||
                      instr_malloc4 == std::string(inst->getOperand(1)->getName()) ||
                      instr_malloc5 == std::string(inst->getOperand(1)->getName()) ||
                      instr_malloc6 == std::string(inst->getOperand(1)->getName()) ) {
                        outs() << ConLine[i] << " malloc " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                        FindFlag = 1;
                    }
                  }

                  //calloc函数
                  std::string instr_calloc1 = "calloc";
                  std::string instr_calloc2 = "xcalloc";
                  std::string instr_calloc3 = "memalign";
                  std::string instr_calloc4 = "aligned_alloc";
                  std::string instr_calloc5 = "safe_calloc";
                  std::string instr_calloc6 = "safecalloc";
                  std::string instr_calloc7 = "safexcalloc";
                  if(inst->getNumOperands() >= 3 && !FindFlag){ //操作数大于二
                    if ( instr_calloc1 == std::string(inst->getOperand(2)->getName()) ||
                    instr_calloc2 == std::string(inst->getOperand(2)->getName()) ||
                    instr_calloc3 == std::string(inst->getOperand(2)->getName()) ||
                    instr_calloc4 == std::string(inst->getOperand(2)->getName()) ||
                    instr_calloc5 == std::string(inst->getOperand(2)->getName()) ||
                    instr_calloc6 == std::string(inst->getOperand(2)->getName()) ||
                    instr_calloc7 == std::string(inst->getOperand(2)->getName()) ){
                      outs() << ConLine[i] << " malloc " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  //realloc函数
                  std::string instr_realloc1 = "realloc";
                  if(inst->getNumOperands() >= 3 && !FindFlag){ //操作数大于二
                    if ( instr_realloc1 == std::string(inst->getOperand(2)->getName()) ){
                      outs() << ConLine[i] << " realloc " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  //free函数
                  std::string instr_free1 = "free";
                  std::string instr_free2 = "xfree";
                  std::string instr_free3 = "cfree";
                  std::string instr_free4 = "safe_cfree";
                  std::string instr_free5 = "safe_free";
                  std::string instr_free6 = "safefree";
                  std::string instr_free7 = "safexfree";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if ( instr_free1 == std::string(inst->getOperand(1)->getName()) ||
                      instr_free2 == std::string(inst->getOperand(1)->getName()) ||
                    instr_free3 == std::string(inst->getOperand(1)->getName()) ||
                    instr_free4 == std::string(inst->getOperand(1)->getName()) ||
                    instr_free5 == std::string(inst->getOperand(1)->getName()) ||
                    instr_free6 == std::string(inst->getOperand(1)->getName()) ||
                    instr_free7 == std::string(inst->getOperand(1)->getName()) ) {
                      outs() << ConLine[i] << " free " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  //new函数
                  std::string instr_new1 = "_Znwm";
                  std::string instr_new2 = "_Znam";
                  std::string instr_new3 = "_Znaj";
                  std::string instr_new4 = "_Znwj";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if ( instr_new1 == std::string(inst->getOperand(1)->getName()) || instr_new2 == std::string(inst->getOperand(1)->getName()) || instr_new3 == std::string(inst->getOperand(1)->getName()) || instr_new4 == std::string(inst->getOperand(1)->getName()) ){
                      outs() << ConLine[i] << " new " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  //delete函数
                  std::string instr_delete1 = "_ZdaPv";
                  std::string instr_delete2 = "_ZdlPv";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if ( instr_delete1 == std::string(inst->getOperand(1)->getName()) || instr_delete2 == std::string(inst->getOperand(1)->getName()) ){
                      outs() << ConLine[i] << " delete " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

				          //memset函数
				          std::string memsetstring = "llvm.memset.";
				          if(inst->getNumOperands() == 5 && !FindFlag){ //操作数等于5
                    if (boost::algorithm::starts_with(std::string(inst->getOperand(4)->getName()), memsetstring)){
                      outs() << ConLine[i] << " memset " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

				          //memcpy函数
				          std::string memcpystring = "llvm.memcpy.";
				          if(inst->getNumOperands() == 5 && !FindFlag){ //操作数等于5
                    if (boost::algorithm::starts_with(std::string(inst->getOperand(4)->getName()), memcpystring)){
                      outs() << ConLine[i] << " memcpy " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
					            FindFlag = 1;
                    }
                  }

                  //pthread_mutex_lock
				          std::string mutexLockstring = "pthread_mutex_lock";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if ( mutexLockstring == std::string(inst->getOperand(1)->getName()) ){
                      //outs() << *inst << "\n";
                      //outs() << *inst->getOperand(0) << "\n";
                      outs() << ConLine[i] << " lock " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  //lock function
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    std::set<llvm::Function*>::iterator LockFunctionSetiter; //定义前向集合迭代器
                    for(LockFunctionSetiter = LockFunctionSet.begin(); LockFunctionSetiter != LockFunctionSet.end(); LockFunctionSetiter++){
#ifdef LLVM_11
                      std::string LockFunctionstring = (*LockFunctionSetiter)->getName().str();
#else
                      std::string LockFunctionstring = (*LockFunctionSetiter)->getName();
#endif
                      //outs() << LockFunctionstring << "\n";
                      //outs() << *inst << "\n";
                      if ( LockFunctionstring == std::string(inst->getOperand(1)->getName()) ){
                        outs() << ConLine[i] << " lock " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                        FindFlag = 1;
                      }
                    }
                  }

                  //pthread_mutex_unlock
				          std::string mutexUnlockstring = "pthread_mutex_unlock";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if ( mutexUnlockstring == std::string(inst->getOperand(1)->getName()) ){
                      //outs() << *inst << "\n";
                      //outs() << *inst->getOperand(0) << "\n";
                      outs() << ConLine[i] << " unlock " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  //unlock function
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    std::set<llvm::Function*>::iterator UnlockFunctionSetiter; //定义前向集合迭代器
                    for(UnlockFunctionSetiter = UnlockFunctionSet.begin(); UnlockFunctionSetiter != UnlockFunctionSet.end(); UnlockFunctionSetiter++){
#ifdef LLVM_11
                      std::string UnlockFunctionstring = (*UnlockFunctionSetiter)->getName().str();
#else
                      std::string UnlockFunctionstring = (*UnlockFunctionSetiter)->getName();
#endif
                      if ( UnlockFunctionstring == std::string(inst->getOperand(1)->getName()) ){
                        outs() << ConLine[i] << " unlock " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                        FindFlag = 1;
                      }
                    }
                  }

                  std::string str_atomic_fetch_add = "long std::atomic_fetch_add<long>";
                  std::string str_atomic_fetch_sub = "long std::atomic_fetch_sub<long>";
                  std::string str_atomic_exchange1 = "std::atomic<void*>::exchange";
                  std::string str_atomic_exchange2 = "webrtc::SSRCDatabase* std::atomic_exchange<webrtc::SSRCDatabase*>";
				          if((inst->getNumOperands() == 3 || inst->getNumOperands() == 4) && !FindFlag){ //操作数等于5
                    if(CallInst *callfunInst = dyn_cast<CallInst>(instruction)) {
                      string strfname;
                      Function *callfun = callfunInst->getCalledFunction();
                      if (callfun){
#ifdef LLVM_11
                        strfname = callfun->getName().str();
#else
                        strfname = callfun->getName();
#endif
                      } else {
                        if (inst->getNumOperands() == 3) {
#ifdef LLVM_11
                          strfname = inst->getOperand(2)->getName().str();
#else
                          strfname = inst->getOperand(2)->getName();
#endif
                        }
                        else if (inst->getNumOperands() == 4) {
#ifdef LLVM_11
                          strfname = inst->getOperand(3)->getName().str();
#else
                          strfname = inst->getOperand(3)->getName();
#endif
                        }
                      }
                      // C++函数名解码
                      string strfnameDemangled = get_funcname(strfname.c_str());
                      size_t iIndex = strfnameDemangled.rfind("(");
                      if(iIndex != std::string::npos)
                          strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                      //outs() << "[DEBUG] " << strfnameDemangled << "\n";

                      if (boost::algorithm::starts_with(strfnameDemangled, str_atomic_fetch_add) ||
                          boost::algorithm::starts_with(strfnameDemangled, str_atomic_fetch_sub) ||
                          boost::algorithm::starts_with(strfnameDemangled, str_atomic_exchange1) ||
                          boost::algorithm::starts_with(strfnameDemangled, str_atomic_exchange2)
                          ){
                        outs() << ConLine[i] << " std_atomic " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                        FindFlag = 1;
                      }
                    }
                  }

                  //std::Map.size函数
                  std::string str_std_Map_size = "std::map<unsigned int, unsigned int, std::less<unsigned int>, std::allocator<std::pair<unsigned int const, unsigned int> > >::size";
                  if(inst->getNumOperands() == 2 && !FindFlag){ //操作数等于2
                    if(CallInst *callfunInst = dyn_cast<CallInst>(instruction)) {
                      string strfname;
                      Function *callfun = callfunInst->getCalledFunction();
                      if (callfun){
#ifdef LLVM_11
                        strfname = callfun->getName().str();
#else
                        strfname = callfun->getName();
#endif
                      } else {
#ifdef LLVM_11
                        strfname = inst->getOperand(1)->getName().str();
#else
                        strfname = inst->getOperand(1)->getName();
#endif
                      }
                      // C++函数名解码
                      string strfnameDemangled = get_funcname(strfname.c_str());
                      size_t iIndex = strfnameDemangled.rfind("(");
                      if(iIndex != std::string::npos)
                        strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                      if (boost::algorithm::starts_with(strfnameDemangled, str_std_Map_size)
                          ){
                        outs() << ConLine[i] << " std_size " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                        FindFlag = 1;
                      }
                    }
                  }
                }

                //针对有些new在invoke指令中搜索
                if(inst->getOpcode() == Instruction::Invoke) {
                  std::string instr_malloc1 = "malloc";
                  std::string instr_new1 = "_Znwm";
                  std::string instr_new2 = "_Znam";
                  std::string instr_new3 = "_Znaj";
                  std::string instr_new4 = "_Znwj";
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
                    if (instr_malloc1 == std::string(inst->getOperand(1)->getName()) || instr_new1 == std::string(inst->getOperand(1)->getName()) || instr_new2 == std::string(inst->getOperand(1)->getName()) || instr_new3 == std::string(inst->getOperand(1)->getName()) || instr_new4 == std::string(inst->getOperand(1)->getName()) ){
                      outs() << ConLine[i] << " new " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }

                  std::string VecResizeStart = "std::vector<";
                  std::string VecResizeEnd = ">::resize";
                  if(inst->getNumOperands() == 5  && !FindFlag){ //找std::vector<...>::resize
#ifdef LLVM_11
                    string strfname = inst->getOperand(inst->getNumOperands()-1)->getName().str();
#else
                    string strfname = inst->getOperand(inst->getNumOperands()-1)->getName();
#endif
                    string strfnameDemangled = get_funcname(strfname.c_str());// C++函数名解码
                    size_t iIndex = strfnameDemangled.rfind("(");
                    if(iIndex != std::string::npos)
                      strfnameDemangled = strfnameDemangled.substr(0,iIndex);
                    if (boost::algorithm::istarts_with(strfnameDemangled, VecResizeStart)
                      && boost::algorithm::ends_with(strfnameDemangled, VecResizeEnd) ) {
                      outs() << ConLine[i] << " std::vector<...>::resize " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
                      FindFlag = 1;
                    }
                  }
                }

                //在store指令中搜索X=NULL;
                if(inst->getOpcode() == Instruction::Store) {
                  if(inst->getNumOperands() >= 2 && !FindFlag){ //操作数大于二
					          if (ConstantPointerNull *CI = dyn_cast<ConstantPointerNull>(inst->getOperand(0))){
						          outs() << ConLine[i] << " nullptr " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
						          FindFlag = 1;
					          }
                  }
                }

                // 再icmp指令中搜索 cmp null statement. i.e., if (xxx==NULL)
                // Too much redundancy
                /*if (inst->getOpcode() == Instruction::ICmp) {
                  if(inst->getNumOperands() == 2  && !FindFlag){ //操作数等于5
                    if (ConstantPointerNull *CI = dyn_cast<ConstantPointerNull>(inst->getOperand(1))){
                      outs() << ConLine[i] << " cmpnull " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
						          FindFlag = 1;
                    }
                  }
                }*/

				        if(!FindFlag){
					        outs() << ConLine[i] << " R/W " << function->getName() << " " << string_hash_encoding(splitConLine) << "\n";
				        }
                /* end: Find Sensitive Operations */

                break;
              }
            }
          }
        }

      }

    }

  }
  return true;
}

char SensitiveOperations::ID = 0;

static RegisterPass<SensitiveOperations> X("so", "SensitiveOperations Pass");

max_stars_repo_name: SZU-SE/PERIOD

max_issues_repo_name: SZU-SE/PERIOD

max_forks_repo_name: SZU-SE/PERIOD


text:
/* CirKit: A circuit toolkit
 * Copyright (C) 2009-2015  University of Bremen
 * Copyright (C) 2015-2017  EPFL
 *
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 *
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 */

/**
 * @file counterexample.hpp
 *
 * @brief Counterexample
 *
 * @author Heinz Riener
 * @since  2.3
 */

#ifndef COUNTEREXAMPLE_HPP
#define COUNTEREXAMPLE_HPP

#include <boost/dynamic_bitset.hpp>
#include <string>
#include <ostream>

namespace cirkit
{

struct assignment_t
{
  assignment_t()
  {}

  assignment_t( const unsigned size )
    : bits( boost::dynamic_bitset<>( size ) )
    , mask( boost::dynamic_bitset<>( size ) )
  {}

  assignment_t( boost::dynamic_bitset<> bits, boost::dynamic_bitset<> mask )
    : bits( bits )
    , mask( mask )
  {
    assert( bits.size() == mask.size() );
  }

  assignment_t( const std::string& assignment )
    : bits( assignment )
    , mask( std::string( assignment.size(), '1' ) )
  {}

  bool operator==( const assignment_t& other ) const
  {
    return ( bits == other.bits && mask == other.mask );
  }

  unsigned size() const
  {
    assert( bits.size() == mask.size() );
    return bits.size();
  }

  boost::dynamic_bitset<> bits;
  boost::dynamic_bitset<> mask;
}; /* assignment_t */

std::ostream& operator<<( std::ostream& os, const assignment_t& a );

struct counterexample_t
{
  counterexample_t()
  {}

  counterexample_t( const std::size_t num_inputs, const std::size_t num_outputs )
    : in( assignment_t( num_inputs ) )
    , out( assignment_t( num_outputs ) )
    , expected_out( assignment_t( num_outputs ) )
  {}

  inline bool empty() const
  {
    return ( in.size() == 0u && out.size() == 0u && expected_out.size() == 0u );
  }

  inline operator bool() const
  {
    return !empty();
  }

  assignment_t in;
  assignment_t out;
  assignment_t expected_out;
}; /* counterexample_t */

std::ostream& operator<<( std::ostream& os, const counterexample_t& cex );

}

#endif

// Local Variables:
// c-basic-offset: 2
// eval: (c-set-offset 'substatement-open 0)
// eval: (c-set-offset 'innamespace 0)
// End:

max_stars_repo_name: eletesta/cirkit

max_issues_repo_name: eletesta/cirkit

max_forks_repo_name: eletesta/cirkit


text:
#include "stdafx.h"
#include "NoteView.h"

#include "crackers.h"
#include "IAnimator.h"
#include "Rect.h"
#include "resourceppc.h"
#include "Scrolling.h"
#include "Tools.h"

#include <algorithm>
#include <fstream>
#include <iterator>
#include <utility>

#include <boost/scope_exit.hpp>

using namespace boost;
using namespace htmlayout;
using namespace htmlayout::dom;
using namespace std;
using namespace Tools;

//----------
// interface
//----------

NoteView::NoteView
	( HINSTANCE         instance
	, bool              highRes
	, IAnimator       & animator
	, IHtmlDataLoader & htmlDataLoader
	)
	: instance         (instance)
	, isMaximized      (false)
	, gestureProcessor (animator)
	, parent           (NULL)
	, HTMLayoutWindow  (L"note-view.htm", highRes, htmlDataLoader)
{
	gestureProcessor.ConnectDelayedMouseDown (bind(&NoteView::OnDelayedMouseDown, this));
	gestureProcessor.ConnectGestureStart     (bind(&NoteView::OnGestureStart,     this));
	gestureProcessor.ConnectGestureStep      (bind(&NoteView::OnGestureStep,      this));
}

void NoteView::Create(HWND parent)
{
	this->parent = parent;

	wstring wndClass = LoadStringResource(IDC_NOTE_VIEW);

	if (!RegisterClass(wndClass))
		throw std::exception("Class could not be registered.");

	Reset();
}

void NoteView::RegisterEventHandlers()
{
	body    = FindFirstElement("#note");
	vScroll = FindFirstElement("#vscroll");
	hScroll = FindFirstElement("#hscroll");
}

//-------------------------
// INoteView implementation
//-------------------------

static void CALLBACK WriteHtml(LPCBYTE utf8, UINT utf8_length, LPVOID param)
{
	wstring * dst(reinterpret_cast<wstring*>(param));
	ConvertToUnicode(utf8, *dst);
}

void NoteView::GetBody(wstring & html)
{
	const bool outerHtml(false);
	HTMLayoutGetElementHtmlCB
		(FindFirstElement("#body"), outerHtml, &WriteHtml, &html);
}

void NoteView::GetDirtyCheckboxIds(set<int> & dirtyCheckboxIds)
{
	dirtyCheckboxIds.clear();
	dirtyCheckboxIds.insert
		( this->dirtyCheckboxIds.begin()
		, this->dirtyCheckboxIds.end()
		);
}

void NoteView::GetNote(Note & note)
{
	note = this->note;
}

wstring NoteView::GetSavePath
	( const wstring & title
	, const wstring & fileName
	, const wstring & directory
	)
{
	vector<wchar_t> fileNameChars(fileName.begin(), fileName.end());
	fileNameChars.resize(MAX_PATH);
	fileNameChars.back() = L'\0';

	vector<wchar_t> titleChars(title.begin(), title.end());
	titleChars.resize(MAX_PATH);
	titleChars.back() = L'\0';

	OPENFILENAME openFileName = { };
	openFileName.lStructSize     = sizeof(openFileName);
	openFileName.lpstrTitle      = &titleChars[0];
	openFileName.nMaxFileTitle   = titleChars.size();
	openFileName.lpstrFile       = &fileNameChars[0];
	openFileName.nMaxFile        = fileNameChars.size();
	openFileName.lpstrInitialDir = directory.c_str();
	openFileName.hwndOwner       = hwnd_;

	BOOL result(::GetSaveFileName(&openFileName));
	if (0 == result || 6 == result)
		return L"";
	return &fileNameChars[0];
}

Guid NoteView::GetSelectedAttachmentGuid()
{
	const int index(GetSelectedAttachmentIndex());
	if (index >= 0)
		return attachments[index].Guid;
	return Guid::GetEmpty();
}

wstring NoteView::GetSelectedAttachmentName()
{
	const int index(GetSelectedAttachmentIndex());
	if (index >= 0)
		return attachments[index].Text;
	return L"";
}

void NoteView::GetTitle(std::wstring & text)
{
	text = element(FindFirstElement("#title")).text();
}

void NoteView::Hide()
{
	if (!::IsWindowVisible(hwnd_))
		return;

	::EnableWindow(parent, TRUE);
	::ShowWindow(hwnd_,   SW_HIDE);
	::ShowWindow(menuBar, SW_HIDE);

	SignalClose();

	Reset();
}

bool NoteView::IsDirty()
{
	return !dirtyCheckboxIds.empty();
}

bool NoteView::IsMaximized()
{
	return isMaximized;
}

void NoteView::MaximizeWindow()
{
	isMaximized = true;
	UpdateWindowState();
}

void NoteView::Render(Thumbnail & thumbnail)
{
	POINT scrollPos = { 0 };
	SetScrollPos(scrollPos);

	HTMLayoutUpdateElementEx
		( element::root_element(hwnd_)
		, RESET_STYLE_DEEP | MEASURE_DEEP | REDRAW_NOW
		);
	WindowRenderer::RenderThumbnail(hwnd_, thumbnail);
}

void NoteView::RestoreWindow()
{
	isMaximized = false;
	UpdateWindowState();
}

void NoteView::SetNote
	( const Note                   & note
	, const wstring                & titleText
	, const wstring                & subtitleText
	, const wstring                & bodyHtml
	, const AttachmentViewInfoList & attachments
	, const bool                     enableChrome
	)
{
	dirtyCheckboxIds.clear();

	this->note = note;

	SetChrome(enableChrome);

	element title    (FindFirstElement("#title"));
	element subtitle (FindFirstElement("#subtitle"));
	element source   (FindFirstElement("#source"));

	title.set_text    (titleText.c_str(),    titleText.size());
	subtitle.set_text (subtitleText.c_str(), subtitleText.size());

	if (note.SourceUrl.empty())
	{
		source.set_style_attribute("display", L"none");
	}
	else
	{
		source.set_style_attribute("display", L"block");
		source.set_text(note.SourceUrl.c_str(), note.SourceUrl.size());
		source.set_attribute("href", note.SourceUrl.c_str());
	}

	vector<unsigned char> utf8Chars;
	const unsigned char * utf8 = Tools::ConvertToUtf8(bodyHtml, utf8Chars);

	DisconnectBehavior("#body input");
	if (TrySetHtml(utf8, utf8Chars.size()))
	{
		ConnectBehavior("#body input", BUTTON_STATE_CHANGED, &NoteView::OnInput);
		this->attachments.assign(attachments.begin(), attachments.end());
		UpdateAttachments();
	}
	else
	{
		throw std::exception("Note could not be parsed.");
	}
}

void NoteView::SetSubtitle(const wstring & subtitleText)
{
	element(FindFirstElement("#subtitle"))
		.set_text (subtitleText.c_str(), subtitleText.size());
}

void NoteView::SetWindowTitle(const std::wstring & text)
{
	::SetWindowText(hwnd_, text.c_str());
}

void NoteView::Show()
{
	if (::IsWindowVisible(hwnd_))
		return;

	::EnableWindow(parent, FALSE);
	::BringWindowToTop(hwnd_);

	element(element::root_element(hwnd_)).update(MEASURE_DEEP|REDRAW_NOW);

	::ShowWindow(hwnd_,   SW_SHOW);
	::ShowWindow(menuBar, SW_SHOW);
	::UpdateWindow(hwnd_);

	SetScrollPos(POINT());
	UpdateScrollbar();
}

//------------------
// utility functions
//------------------

POINT NoteView::GetScrollPos()
{
	POINT scrollPos;
	RECT  viewRect;
	SIZE  contentSize;
	element body(FindFirstElement("#note"));
	body.get_scroll_info(scrollPos, viewRect, contentSize);
	return scrollPos;
}

int NoteView::GetSelectedAttachmentIndex()
{
	return element(FindFirstElement("#attachments"))
		.get_attribute_int("value", -1);
}

void NoteView::Reset()
{
	if (hwnd_)
	{
		::DestroyWindow(hwnd_);
		hwnd_ = NULL;
	}

	wstring wndTitle = LoadStringResource(IDS_APP_TITLE);
	wstring wndClass = LoadStringResource(IDC_NOTE_VIEW);

	DWORD windowStyle   (WS_POPUP);
	DWORD windowExStyle (WS_EX_CAPTIONOKBTN);

	Rect rect;
	::SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);

	hwnd_ = ::CreateWindowEx
		( windowExStyle    // dwExStyle
		, wndClass.c_str() // lpClassName
		, wndTitle.c_str() // lpWindowName
		, windowStyle      // dwStyle
		, rect.GetX()      // x
		, rect.GetY()      // y
		, rect.GetWidth()  // nWidth
		, rect.GetHeight() // nHeight
		, parent           // hWndParent
		, NULL             // hMenu
		, instance         // hInstance
		, this             // lpParam
		);
	if (!hwnd_)
		throw std::exception("Window creation failed.");

	SHMENUBARINFO menuBarInfo = { sizeof(menuBarInfo) };
	menuBarInfo.hwndParent = hwnd_;
	menuBarInfo.dwFlags    = SHCMBF_HIDDEN | SHCMBF_HIDESIPBUTTON;
	menuBarInfo.nToolBarId = IDR_NOTE_VIEW_MENUBAR;
	menuBarInfo.hInstRes   = instance;
	::SHCreateMenuBar(&menuBarInfo);
	menuBar = menuBarInfo.hwndMB;

	UpdateWindowState();
}

ATOM NoteView::RegisterClass(const wstring & wndClass)
{
	WNDCLASS wc = { 0 };
	wc.style         = CS_HREDRAW | CS_VREDRAW;
	wc.lpfnWndProc   = &NoteView::WndProc<NoteView>;
	wc.hInstance     = instance;
	wc.hIcon         = LoadIcon(instance, MAKEINTRESOURCE(IDI_CLIENT));
	wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
	wc.lpszClassName = wndClass.c_str();
	return ::RegisterClass(&wc);
}

void NoteView::UpdateAttachments()
{
	DisconnectBehavior("#attachments *");

	element list(FindFirstElement("#attachments"));

	vector<element> old;
	list.find_all(old, ":root > option");
	foreach (element & e, old)
		e.destroy();

	for (int i(0), size(attachments.size()); i != size; ++i)
	{
		wchar_t value[16];
		_itow(i, value, 10);

		const AttachmentViewInfo & attachment(attachments[i]);

		wstring guid(ConvertToUnicode(attachment.Guid).c_str());

		element content (element::create("div"));

		element option(element::create("option"));
		option.append(content);

		if (attachment.IsPlayable)
		{
			element play(element::create("img"));
			play.set_attribute("src",   L"play-attachment.png");
			play.set_attribute("value", guid.c_str());
			play.set_attribute("class", L"play");
			option.append(play);

			ConnectBehavior(play, BUTTON_CLICK, &NoteView::OnPlayAttachment);
		}

		list.insert(option, list.children_count() - 1);

		content.set_style_attribute("background-image", attachment.Icon.c_str());
		content.set_attribute("value", value);
		content.set_attribute("class", L"content");
		content.set_text(attachment.Text.c_str());

		ConnectBehavior(content, BUTTON_CLICK, &NoteView::OnAttachment);
	}
}

void NoteView::SetChrome(bool enable)
{
	element blocks[] =
		{ hScroll
		, vScroll
		, element(FindFirstElement("#header"))
		, element(FindFirstElement("#attachments"))
		};
	for (int i(0); i != GetArraySize(blocks); ++i)
		blocks[i].set_style_attribute("display", enable ? L"block" : L"none");

	element body(FindFirstElement("#body"));
	if (enable)
		body.set_attribute("chrome", L"");
	else
		body.remove_attribute("chrome");
}

void NoteView::SetScrollPos(POINT pos)
{
	ScrollHorizontally (body, hScroll, pos.x);
	ScrollVertically   (body, vScroll, pos.y);
}

void NoteView::UpdateScrollbar()
{
	UpdateHorizontalScrollbar (body, hScroll);
	UpdateVerticalScrollbar   (body, vScroll);
}

void NoteView::UpdateWindowState()
{
	::SHFullScreen
		( hwnd_
		, isMaximized
		? SHFS_HIDESIPBUTTON | SHFS_HIDETASKBAR
		: SHFS_HIDESIPBUTTON | SHFS_SHOWTASKBAR
		);
	Rect rect;
	if (isMaximized)
	{
		rect.left   = 0;
		rect.top    = 0;
		rect.right  = GetSystemMetrics(SM_CXSCREEN);
		rect.bottom = GetSystemMetrics(SM_CYSCREEN);
	}
	else
	{
		::SystemParametersInfo(SPI_GETWORKAREA, 0, &rect, FALSE);
	}
	if (menuBar)
	{
		Rect menuBarRect;
		::GetWindowRect(menuBar, &menuBarRect);
		rect.bottom -= menuBarRect.GetHeight();
	}
	::MoveWindow
		( hwnd_
		, rect.GetX()
		, rect.GetY()
		, rect.GetWidth()
		, rect.GetHeight()
		, TRUE
		);
}

bool NoteView::TrySetHtml(const unsigned char * text, size_t textLength)
{
	__try
	{
		HTMLayoutSetElementHtml
			( FindFirstElement("#body")
			, text
			, textLength
			, SIH_REPLACE_CONTENT
			);
		return true;
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		return false;
	}
}

//-------------------------
// gesture message handlers
//-------------------------

void NoteView::OnDelayedMouseDown()
{
	__super::ProcessMessage(*gestureProcessor.GetMouseDownMessage());
}

void NoteView::OnGestureStart()
{
	startScrollPos = GetScrollPos();
}

void NoteView::OnGestureStep()
{
	SIZE offset(gestureProcessor.GetScrollDistance());
	POINT distance =
		{ startScrollPos.x + offset.cx
		, startScrollPos.y + offset.cy
		};
	SetScrollPos(distance);
}

//------------------------
// window message handlers
//------------------------

void NoteView::OnActivate(Msg<WM_ACTIVATE> & msg)
{
	if (msg.GetActiveState() != WA_INACTIVE)
	{
		UpdateWindowState();
		msg.handled_ = true;
	}
}

void NoteView::OnClose(Msg<WM_CLOSE> & msg)
{
	Hide();
	msg.handled_ = true;
}

void NoteView::OnCommand(Msg<WM_COMMAND> & msg)
{
	switch (msg.CtrlId())
	{
	case IDOK:           CloseWindow(hwnd_);     break;
	case IDM_OK:         CloseWindow(hwnd_);     break;
	case IDM_CANCEL:     CloseWindow(hwnd_);     break;
	case ID_DELETE_NOTE: SignalDelete();         break;
	case ID_EDIT_NOTE:   SignalEdit();           break;
	case ID_EDIT_TAGS:   SignalEditTags();       break;
	case ID_FULL_SCREEN: SignalToggleMaximize(); break;
	}
}

void NoteView::OnKeyUp(Msg<WM_KEYUP> & msg)
{
	if (msg.VKey() == 0x1b)
	{
		CloseWindow(hwnd_);
		msg.handled_ = true;
	}
}

void NoteView::OnMouseDown(Msg<WM_LBUTTONDOWN> & msg)
{
	::SetCapture(hwnd_);

	gestureProcessor.OnMouseDown(msg);

	msg.handled_ = true;
}

void NoteView::OnMouseMove(Msg<WM_MOUSEMOVE> & msg)
{
	msg.handled_ = true;

	gestureProcessor.OnMouseMove(msg);
}

void NoteView::OnMouseUp(Msg<WM_LBUTTONUP> & msg)
{
	::ReleaseCapture();

	gestureProcessor.OnMouseUp(msg);
}

void NoteView::OnSettingChange(Msg<WM_SETTINGCHANGE> & msg)
{
	if (msg.Flag() == SPI_SETSIPINFO)
	{
		UpdateWindowState();
		msg.handled_ = true;
	}
}

void NoteView::ProcessMessage(WndMsg &msg)
{
	static Handler mmp[] =
	{
		&NoteView::OnActivate,
		&NoteView::OnClose,
		&NoteView::OnCommand,
		&NoteView::OnKeyUp,
		&NoteView::OnMouseDown,
		&NoteView::OnMouseMove,
		&NoteView::OnMouseUp,
		&NoteView::OnSettingChange,
	};
	try
	{
		if (!Handler::Call(mmp, this, msg))
			__super::ProcessMessage(msg);
	}
	catch (const std::exception & e)
	{
		::NKDbgPrintfW(L"%s\n", ConvertToUnicode(e.what()).c_str());
		throw e;
	}
}

//---------------------------
// HTMLayout message handlers
//---------------------------

void NoteView::OnAttachment(BEHAVIOR_EVENT_PARAMS * params)
{
	const wchar_t * value(element(params->heTarget).get_attribute("value"));
	if (!value)
		return;
	element(FindFirstElement("#attachments")).set_attribute("value", value);
	SignalAttachment();
}

void NoteView::OnInput(BEHAVIOR_EVENT_PARAMS * params)
{
	element e(params->heTarget);
	int id(e.get_attribute_int("uid", -1));
	set<int>::iterator i(dirtyCheckboxIds.find(id));
	if (i == dirtyCheckboxIds.end())
		dirtyCheckboxIds.insert(id);
	else
		dirtyCheckboxIds.erase(i);
}

void NoteView::OnPlayAttachment(BEHAVIOR_EVENT_PARAMS * params)
{
	const wchar_t * value(element(params->heTarget).get_attribute("value"));
	if (!value)
		return;
	element(FindFirstElement("#attachments")).set_attribute("value", value);
	SignalPlayAttachment();
}

max_stars_repo_name: don-reba/peoples-note

max_issues_repo_name: don-reba/peoples-note

max_forks_repo_name: don-reba/peoples-note


text:
/**
 * @file CaptureToCSV.hpp
 *
 * Beherbergt die Funktionalität für das Loggen von Scandaten in eine CSV-Datei in einem Beispielformat.
 *
 * @author Christian Blumberg
 * @date 2012-06-08
 * @version 0.0.1
 * erstes Release
 */

#ifndef CAPTURETOCSV_HPP_
#define CAPTURETOCSV_HPP_

#include "CaptureToFileAbstract.hpp"
#include <boost/thread/mutex.hpp>
#include <boost/thread/locks.hpp>

namespace ibeo{ class IbeoLaserDataAbstract; }

namespace capture
{

/** @brief ermögtlich das Loggen in einem CSV-Format.
 *
 * Die Klasse ermöglicht das Loggen von Scandaten in einem CSV-Format.
 *
 * a@author Christian Blumberg
 * @date 2012-06-07
 * @version 0.0.1
 * erstes Release
 */
class CaptureToCSV : public CaptureToFileAbstract
{
public:
	CaptureToCSV(const std::string& filename, const std::string& separator);
	virtual ~CaptureToCSV();

	virtual void operator<<(ibeo::IbeoLaserDataAbstract& dataObj);
	//virtual void operator<<(ibeo::ibeoLaserDataAbstractSmartPtr& dataObj);

private:
	boost::mutex CSVmutex;
	std::string s;
	std::stringstream ss;
	char *buf;
};

} /* namespace capture */
#endif /* CAPTURETOCSV_HPP_ */

max_stars_repo_name: MechLabEngineering/SICKRPi-Scanner

max_issues_repo_name: MechLabEngineering/SICKRPi-Scanner

max_forks_repo_name: MechLabEngineering/SICKRPi-Scanner


text:
/*
 * Copyright 2011 Inalogic® Inc.
 *
 * This program 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 or 3.0
 * of the License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranties of
 * MERCHANTABILITY, SATISFACTORY QUALITY or FITNESS FOR A PARTICULAR
 * PURPOSE.  See the applicable version of the GNU Lesser General Public
 * License for more details.
 *
 * You should have received a copy of both the GNU Lesser General Public
 * License along with this program. If not, see <http://www.gnu.org/licenses/>
 *
 * Authored by: Tim Penhey <tim.penhey@canonical.com>
 *
 */
#ifndef OPENASR_CORE_LOGGING_WRITER_H
#define OPENASR_CORE_LOGGING_WRITER_H

#include <iosfwd>
#include <ctime>
#include <boost/utility.hpp>

#include "Logger.hpp"
/**
 * The Writer singleton is responsible for controlling where the
 * logging message go.  For testing purposes it is able to define the logging
 * stream, normally a std::stringstream.
 *
 * The default behaviour is to output to std::cout.
 *
 * As far as logging the timestamp goes, we only go to second precision in the
 * logging format itself.  If a high performance timer is needed it should be
 * managed by the caller.
 */

namespace openasr {
namespace logging {

class Writer : boost::noncopyable
{
public:
  static Writer& Instance();
  ~Writer();

  void WriteMessage(Level severity,
                    std::string const& module,
                    std::string const& filename,
                    int line_number,
                    std::time_t timestamp,
                    std::string const& message);

  void SetOutputStream(std::ostream& out);

private:
  Writer();

private:
  class Impl;
  Impl* pimpl;
};

}
}

#endif