<commit_before>#include "tcp_socket.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <util/string_type.h>

using namespace std;

void
TcpSocket::init_socket_lib()
{
#ifdef YBUTIL_WINDOWS
    static bool did_it = false;
    static WSAData wsaData;
    if (!did_it) {
        WORD versionRequested = MAKEWORD(1, 1);
        int err = WSAStartup(versionRequested, &wsaData);
        if (err != 0) {
            throw SocketEx("init_socket_lib",
                    "WSAStartup failed with error: " +
                    Yb::to_stdstring(err));
        }
        did_it = true;
    }
#endif
}

SOCKET
TcpSocket::create()
{
    SOCKET s = ::socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == s)
        throw SocketEx("create", get_last_error());
    return s;
}

string
TcpSocket::get_last_error()
{
    char buf[1024];
    size_t buf_sz = sizeof(buf);
#ifdef YBUTIL_WINDOWS
    int err;
    LPTSTR msg_buf;
    err = GetLastError();
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&msg_buf,
        0,
        NULL);
    CharToOemBuff(msg_buf, buf, buf_sz);
    LocalFree(msg_buf);
#else
#if ! _GNU_SOURCE
    strerror_r(errno, buf, buf_sz);
#else
    strncpy(buf, strerror_r(errno, buf, buf_sz), buf_sz);
#endif
#endif
    buf[buf_sz - 1] = 0;
    return string(buf);
}

void
TcpSocket::create_if_needed()
{
    if (!ok()) {
        buf_pos_ = 0;
        buf_.clear();
        s_ = create();
    }
}

void
TcpSocket::bind(const string &ip_addr, int port)
{
    create_if_needed();
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip_addr.c_str());
    addr.sin_port = htons(port);
    SockOpt yes = 1;
    setsockopt(s_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes));
    if (::bind(s_, (struct sockaddr *)&addr, sizeof(addr)) == -1)
        throw SocketEx("bind", get_last_error());
}

void
TcpSocket::listen(int back_log)
{
    ::listen(s_, back_log);
}

#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif // _MSC_VER

SOCKET
TcpSocket::accept(string *ip_addr, int *port)
{
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    struct sockaddr *p_addr = NULL;
#ifdef YBUTIL_WINDOWS
    typedef int socklen_t;
#endif
    socklen_t addr_len = sizeof(addr), *p_addr_len = NULL;
    if (ip_addr || port) {
        p_addr = (struct sockaddr *)&addr;
        p_addr_len = &addr_len;
    }
    SOCKET s2 = ::accept(s_, p_addr, p_addr_len);
    if (INVALID_SOCKET == s2)
        throw SocketEx("accept", get_last_error());
    if (port)
        *port = ntohs(addr.sin_port);
    if (ip_addr) {
        unsigned ip = ntohl(addr.sin_addr.s_addr);
        char buf[100];
        sprintf(buf, "%d.%d.%d.%d",
                ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
        *ip_addr = string(buf);
    }
    return s2;
}

void
TcpSocket::connect(const string &ip_addr, int port)
{
    create_if_needed();
    struct sockaddr_in addr;
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip_addr.c_str());
    addr.sin_port = htons(port);
    if (INVALID_SOCKET == ::connect(s_, (struct sockaddr *)&addr, sizeof(addr)))
        throw SocketEx("connect", get_last_error());
}

bool
TcpSocket::read_chunk()
{
    if (buf_pos_ < buf_.size())
        return true;
    buf_pos_ = 0;
    buf_.clear();
    fd_set rfds, efds;
    FD_ZERO(&rfds);
    FD_ZERO(&efds);
    FD_SET(s_, &rfds);
    FD_SET(s_, &efds);
    struct timeval t;
    t.tv_sec = timeout_ / 1000;
    t.tv_usec = (timeout_ % 1000) * 1000;
    int res = ::select(s_ + 1, &rfds, NULL, &efds, &t);
    if (!res)
        throw SocketEx("select", "timeout");
    if (res != 1 && res != 2)
        throw SocketEx("select", get_last_error());
    if (FD_ISSET(s_, &efds))
        throw SocketEx("select", "socket exception");
    int max_chunk = 2500;
    buf_.resize(max_chunk);
    res = ::recv(s_, &buf_[0], max_chunk, 0);
    if (res < 0 || res > max_chunk)
        throw SocketEx("read", get_last_error());
    buf_.resize(res);
    return buf_pos_ < buf_.size();
}

const string
TcpSocket::readline()
{
    string req;
    req.reserve(40);
    while (1) {
        while (buf_pos_ < buf_.size()) {
            char c = buf_[buf_pos_++];
            req.push_back(c);
            if (c == '\n')
                return req;
        }
        if (!read_chunk())
            return req;
    }
}

const string
TcpSocket::read(size_t n)
{
    string r;
    r.reserve(n);
    size_t pos = 0;
    while (pos < n) {
        if (buf_pos_ < buf_.size()) {
            size_t min_sz = buf_.size() - buf_pos_;
            if (n - pos < min_sz)
                min_sz = n - pos;
            r.append(buf_, buf_pos_, min_sz);
            buf_pos_ += min_sz;
            pos += min_sz;
        }
        if (pos < n) {
            if (!read_chunk())
                throw SocketEx("read", "short read");
        }
    }
    return r;
}

void
TcpSocket::write(const string &msg)
{
    int count = ::send(s_, msg.c_str(), msg.size(), 0);
    if (-1 == count)
        throw SocketEx("write", get_last_error());
    if (static_cast<size_t>(count) < msg.size())
        throw SocketEx("write", "short write");
}

void
TcpSocket::close(bool shut_down)
{
    if (!ok())
        return;
    if (shut_down)
        ::shutdown(s_, 2);
#ifdef YBUTIL_WINDOWS
    ::closesocket(s_);
#else
    ::close(s_);
#endif
    s_ = INVALID_SOCKET;
    buf_pos_ = 0;
    buf_.clear();
}

// vim:ts=4:sts=4:sw=4:et:
<commit_msg>CWE-457: tcp_socket.cpp:138; CWE-252: tcp_socket.cpp:90;<commit_after>#include "tcp_socket.h"
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <cstdio>
#include <util/string_type.h>

using namespace std;

void
TcpSocket::init_socket_lib()
{
#ifdef YBUTIL_WINDOWS
    static bool did_it = false;
    static WSAData wsaData;
    if (!did_it) {
        WORD versionRequested = MAKEWORD(1, 1);
        int err = WSAStartup(versionRequested, &wsaData);
        if (err != 0) {
            throw SocketEx("init_socket_lib",
                    "WSAStartup failed with error: " +
                    Yb::to_stdstring(err));
        }
        did_it = true;
    }
#endif
}

SOCKET
TcpSocket::create()
{
    SOCKET s = ::socket(AF_INET, SOCK_STREAM, 0);
    if (INVALID_SOCKET == s)
        throw SocketEx("create", get_last_error());
    return s;
}

string
TcpSocket::get_last_error()
{
    char buf[1024];
    size_t buf_sz = sizeof(buf);
#ifdef YBUTIL_WINDOWS
    int err;
    LPTSTR msg_buf;
    err = GetLastError();
    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER |
        FORMAT_MESSAGE_FROM_SYSTEM |
        FORMAT_MESSAGE_IGNORE_INSERTS,
        NULL,
        err,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR)&msg_buf,
        0,
        NULL);
    CharToOemBuff(msg_buf, buf, buf_sz);
    LocalFree(msg_buf);
#else
#if ! _GNU_SOURCE
    strerror_r(errno, buf, buf_sz);
#else
    strncpy(buf, strerror_r(errno, buf, buf_sz), buf_sz);
#endif
#endif
    buf[buf_sz - 1] = 0;
    return string(buf);
}

void
TcpSocket::create_if_needed()
{
    if (!ok()) {
        buf_pos_ = 0;
        buf_.clear();
        s_ = create();
    }
}

void
TcpSocket::bind(const string &ip_addr, int port)
{
    create_if_needed();
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip_addr.c_str());
    addr.sin_port = htons(port);
    SockOpt yes = 1;
    if (::setsockopt(s_, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) != 0)
        throw SocketEx("setsockopt(SO_REUSEADDR)", get_last_error());
    if (::bind(s_, (struct sockaddr *)&addr, sizeof(addr)) == -1)
        throw SocketEx("bind", get_last_error());
}

void
TcpSocket::listen(int back_log)
{
    ::listen(s_, back_log);
}

#ifdef _MSC_VER
#pragma warning(disable:4996)
#endif // _MSC_VER

SOCKET
TcpSocket::accept(string *ip_addr, int *port)
{
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    struct sockaddr *p_addr = NULL;
#ifdef YBUTIL_WINDOWS
    typedef int socklen_t;
#endif
    socklen_t addr_len = sizeof(addr), *p_addr_len = NULL;
    if (ip_addr || port) {
        p_addr = (struct sockaddr *)&addr;
        p_addr_len = &addr_len;
    }
    SOCKET s2 = ::accept(s_, p_addr, p_addr_len);
    if (INVALID_SOCKET == s2)
        throw SocketEx("accept", get_last_error());
    if (port)
        *port = ntohs(addr.sin_port);
    if (ip_addr) {
        unsigned ip = ntohl(addr.sin_addr.s_addr);
        char buf[100];
        sprintf(buf, "%d.%d.%d.%d",
                ip >> 24, (ip >> 16) & 255, (ip >> 8) & 255, ip & 255);
        *ip_addr = string(buf);
    }
    return s2;
}

void
TcpSocket::connect(const string &ip_addr, int port)
{
    create_if_needed();
    struct sockaddr_in addr;
    memset(&addr, 0, sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip_addr.c_str());
    addr.sin_port = htons(port);
    if (INVALID_SOCKET == ::connect(s_, (struct sockaddr *)&addr, sizeof(addr)))
        throw SocketEx("connect", get_last_error());
}

bool
TcpSocket::read_chunk()
{
    if (buf_pos_ < buf_.size())
        return true;
    buf_pos_ = 0;
    buf_.clear();
    fd_set rfds, efds;
    FD_ZERO(&rfds);
    FD_ZERO(&efds);
    FD_SET(s_, &rfds);
    FD_SET(s_, &efds);
    struct timeval t;
    t.tv_sec = timeout_ / 1000;
    t.tv_usec = (timeout_ % 1000) * 1000;
    int res = ::select(s_ + 1, &rfds, NULL, &efds, &t);
    if (!res)
        throw SocketEx("select", "timeout");
    if (res != 1 && res != 2)
        throw SocketEx("select", get_last_error());
    if (FD_ISSET(s_, &efds))
        throw SocketEx("select", "socket exception");
    int max_chunk = 2500;
    buf_.resize(max_chunk);
    res = ::recv(s_, &buf_[0], max_chunk, 0);
    if (res < 0 || res > max_chunk)
        throw SocketEx("read", get_last_error());
    buf_.resize(res);
    return buf_pos_ < buf_.size();
}

const string
TcpSocket::readline()
{
    string req;
    req.reserve(40);
    while (1) {
        while (buf_pos_ < buf_.size()) {
            char c = buf_[buf_pos_++];
            req.push_back(c);
            if (c == '\n')
                return req;
        }
        if (!read_chunk())
            return req;
    }
}

const string
TcpSocket::read(size_t n)
{
    string r;
    r.reserve(n);
    size_t pos = 0;
    while (pos < n) {
        if (buf_pos_ < buf_.size()) {
            size_t min_sz = buf_.size() - buf_pos_;
            if (n - pos < min_sz)
                min_sz = n - pos;
            r.append(buf_, buf_pos_, min_sz);
            buf_pos_ += min_sz;
            pos += min_sz;
        }
        if (pos < n) {
            if (!read_chunk())
                throw SocketEx("read", "short read");
        }
    }
    return r;
}

void
TcpSocket::write(const string &msg)
{
    int count = ::send(s_, msg.c_str(), msg.size(), 0);
    if (-1 == count)
        throw SocketEx("write", get_last_error());
    if (static_cast<size_t>(count) < msg.size())
        throw SocketEx("write", "short write");
}

void
TcpSocket::close(bool shut_down)
{
    if (!ok())
        return;
    if (shut_down)
        ::shutdown(s_, 2);
#ifdef YBUTIL_WINDOWS
    ::closesocket(s_);
#else
    ::close(s_);
#endif
    s_ = INVALID_SOCKET;
    buf_pos_ = 0;
    buf_.clear();
}

// vim:ts=4:sts=4:sw=4:et:
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTransformFilter.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkTransformFilter.hh"
#include "vtkFloatNormals.hh"
#include "vtkFloatVectors.hh"

void vtkTransformFilter::Execute()
{
  vtkPoints *inPts;
  vtkFloatPoints *newPts;
  vtkPointData *pd, *outPD;
  vtkVectors *inVectors;
  vtkFloatVectors *newVectors=NULL;
  vtkNormals *inNormals;
  vtkFloatNormals *newNormals=NULL;
  int numPts;
  vtkPointSet *input=(vtkPointSet *)this->Input;
  vtkPointSet *output=(vtkPointSet *)this->Output;

  vtkDebugMacro(<<"Executing transformation");
//
// Check input
//
  if ( this->Transform == NULL )
    {
    vtkErrorMacro(<<"No transform defined!");
    return;
    }

  inPts = input->GetPoints();
  pd = input->GetPointData();
  inVectors = pd->GetVectors();
  inNormals = pd->GetNormals();

  if ( !inPts )
    {
    vtkErrorMacro(<<"No input data");
    return;
    }

  numPts = inPts->GetNumberOfPoints();
  newPts = new vtkFloatPoints(numPts);
  if ( inVectors ) newVectors = new vtkFloatVectors(numPts);
  if ( inNormals ) newNormals = new vtkFloatNormals(numPts);
//
// Loop over all points, updating position
//
  this->Transform->MultiplyPoints(inPts,newPts);
//
// Ditto for vectors and normals
//
  if ( inVectors )
    {
    this->Transform->MultiplyVectors(inVectors,newVectors);
    }

  if ( inNormals )
    {
    this->Transform->MultiplyNormals(inNormals,newNormals);
    }
//
// Update ourselves
//
  outPD->CopyVectorsOff();
  outPD->CopyNormalsOff();
  outPD->PassData(input->GetPointData());

  output->SetPoints(newPts);
  newPts->Delete();

  if (newNormals)
    {
    outPD->SetNormals(newNormals);
    newNormals->Delete();
    }

  if (newVectors)
    {
    outPD->SetVectors(newVectors);
    newVectors->Delete();
    }
}

unsigned long vtkTransformFilter::GetMTime()
{
  unsigned long mTime=this->MTime.GetMTime();
  unsigned long transMTime;

  if ( this->Transform )
    {
    transMTime = this->Transform->GetMTime();
    mTime = ( transMTime > mTime ? transMTime : mTime );
    }

  return mTime;
}

void vtkTransformFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPointSetToPointSetFilter::PrintSelf(os,indent);

  os << indent << "Transform: " << this->Transform << "\n";
}
<commit_msg>fixed bad bug<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkTransformFilter.cc
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1995 Ken Martin, Will Schroeder, Bill Lorensen.

This software is copyrighted by Ken Martin, Will Schroeder and Bill Lorensen.
The following terms apply to all files associated with the software unless
explicitly disclaimed in individual files. This copyright specifically does
not apply to the related textbook "The Visualization Toolkit" ISBN
013199837-4 published by Prentice Hall which is covered by its own copyright.

The authors hereby grant permission to use, copy, and distribute this
software and its documentation for any purpose, provided that existing
copyright notices are retained in all copies and that this notice is included
verbatim in any distributions. Additionally, the authors grant permission to
modify this software and its documentation for any purpose, provided that
such modifications are not distributed without the explicit consent of the
authors and that existing copyright notices are retained in all copies. Some
of the algorithms implemented by this software are patented, observe all
applicable patent law.

IN NO EVENT SHALL THE AUTHORS OR DISTRIBUTORS BE LIABLE TO ANY PARTY FOR
DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
OF THE USE OF THIS SOFTWARE, ITS DOCUMENTATION, OR ANY DERIVATIVES THEREOF,
EVEN IF THE AUTHORS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

THE AUTHORS AND DISTRIBUTORS SPECIFICALLY DISCLAIM ANY WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE, AND NON-INFRINGEMENT.  THIS SOFTWARE IS PROVIDED ON AN
"AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO PROVIDE
MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

=========================================================================*/
#include "vtkTransformFilter.hh"
#include "vtkFloatNormals.hh"
#include "vtkFloatVectors.hh"

void vtkTransformFilter::Execute()
{
  vtkPoints *inPts;
  vtkFloatPoints *newPts;
  vtkPointData *pd, *outPD;
  vtkVectors *inVectors;
  vtkFloatVectors *newVectors=NULL;
  vtkNormals *inNormals;
  vtkFloatNormals *newNormals=NULL;
  int numPts;
  vtkPointSet *input=(vtkPointSet *)this->Input;
  vtkPointSet *output= this->GetOutput();

  vtkDebugMacro(<<"Executing transformation");
  //
  // Check input
  //
  if ( this->Transform == NULL )
    {
    vtkErrorMacro(<<"No transform defined!");
    return;
    }

  inPts = input->GetPoints();
  pd = input->GetPointData();
  outPD = output->GetPointData();
  inVectors = pd->GetVectors();
  inNormals = pd->GetNormals();

  if ( !inPts )
    {
    vtkErrorMacro(<<"No input data");
    return;
    }

  numPts = inPts->GetNumberOfPoints();
  newPts = new vtkFloatPoints(numPts);
  if ( inVectors ) newVectors = new vtkFloatVectors(numPts);
  if ( inNormals ) newNormals = new vtkFloatNormals(numPts);
  //
  // Loop over all points, updating position
  //
  this->Transform->MultiplyPoints(inPts,newPts);
//
// Ditto for vectors and normals
//
  if ( inVectors )
    {
    this->Transform->MultiplyVectors(inVectors,newVectors);
    }

  if ( inNormals )
    {
    this->Transform->MultiplyNormals(inNormals,newNormals);
    }
//
// Update ourselves
//
  outPD->CopyVectorsOff();
  outPD->CopyNormalsOff();
  outPD->PassData(input->GetPointData());

  output->SetPoints(newPts);
  newPts->Delete();

  if (newNormals)
    {
    outPD->SetNormals(newNormals);
    newNormals->Delete();
    }

  if (newVectors)
    {
    outPD->SetVectors(newVectors);
    newVectors->Delete();
    }
}

unsigned long vtkTransformFilter::GetMTime()
{
  unsigned long mTime=this->MTime.GetMTime();
  unsigned long transMTime;

  if ( this->Transform )
    {
    transMTime = this->Transform->GetMTime();
    mTime = ( transMTime > mTime ? transMTime : mTime );
    }

  return mTime;
}

void vtkTransformFilter::PrintSelf(ostream& os, vtkIndent indent)
{
  vtkPointSetToPointSetFilter::PrintSelf(os,indent);

  os << indent << "Transform: " << this->Transform << "\n";
}
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"

#define _TOOLS_TOOLSIN_CXX

#include <string.h>
#include <tools/debug.hxx>

#if defined WNT
#include <dll.hxx>
#endif

// =======================================================================

void InitTools()
{
    DBG_DEBUGSTART();
}

// -----------------------------------------------------------------------

void DeInitTools()
{
    DBG_DEBUGEND();
}

// -----------------------------------------------------------------------

void GlobalDeInitTools()
{
    DBG_GLOBALDEBUGEND();

#if defined WNT
    ImpDeInitWinTools();
#endif
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>include tools/tools.h for visibility markup<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2000, 2010 Oracle and/or its affiliates.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_tools.hxx"

#include <tools/tools.h>

#include <string.h>
#include <tools/debug.hxx>

#if defined WNT
#include <dll.hxx>
#endif

// =======================================================================

void InitTools()
{
    DBG_DEBUGSTART();
}

// -----------------------------------------------------------------------

void DeInitTools()
{
    DBG_DEBUGEND();
}

// -----------------------------------------------------------------------

void GlobalDeInitTools()
{
    DBG_GLOBALDEBUGEND();

#if defined WNT
    ImpDeInitWinTools();
#endif
}

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


<commit_before>#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <stdlib.h>
#include <map>
#include "omp.h"
#include <time.h>
#include <chrono>
#include <ctime>
#include <ratio>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "boost/lexical_cast.hpp"

using namespace boost::algorithm;

#include "pass_runner.h"

#define NUM_THREADS 8 // default number of threads
#if(0)
#ifdef DEBUG
#ifndef TIME
#define TIME
#endif
#endif
#endif

using namespace std;
using namespace std::chrono;

/*------- GLOBAL VARIABES --------*/
// vector with permutations of passorder
vector<string> passOrder;
char *binaryName;
char *binaryArgs;
char *input_combination_file;
string dir_name;

#define _SYSTEM_CALL( CMD ) ( {            \
    int err = ( system( CMD.c_str() ) );   \
    if ( err < 0  ) {                      \
        fprintf(stderr, #CMD, " failed."); \
        abort();                           \
    }                                      \
    err;                                   \
})                                         \

struct COMMAND {
    string opt;
    string lli;

    // constructor
    COMMAND(string, long double);
};

inline COMMAND::COMMAND(string pass_order, long double threadId) {
    // opt -pass1 -pass2 ./bcfile -o temp.out.threadId >> /dev/null

    string pname = " ";// = A::PASS_MAP[0];
    vector<string> strs;
    boost::split(strs,pass_order,boost::is_any_of(" "));

    for(vector<string>::iterator pit = strs.begin(); pit != strs.end(); ++pit){
        string pass_num_string = *pit;
        int pnumber = atoi(pass_num_string.c_str());
        pname = pname + " " + A::PASS_MAP[pnumber];
    }
#ifdef DEBUG
    cout << pname << endl;
#endif
    // combination_file_name/temp.out.input_combination_filename
    string temp_name = dir_name + string("/temp.out.") + input_combination_file;

    opt = string("opt ") + pname + " ./"  + binaryName + " -o "+ temp_name  + "" + to_string(threadId) + " >> /dev/null";
    // Command to execute the file.
    lli = string("lli ") + temp_name + to_string(threadId) + " " + binaryArgs + to_string(threadId);
}

/*--------- General Purpose Methods --------*/

// print operator for vector<string>
void operator<<(ostream& os, vector<string> V) {
    for( vector<string>::iterator it = V.begin(); it != V.end(); ++it ) {
        os << *it << endl;
    }
}

void cleanUpTheMess() {
    string rm_command = string("rm -rf ") + dir_name;

#ifdef DEBUG
    cout << "Cleaning temporary files.." << endl;
    cout << "Running Command: " << rm_command << endl;
#endif
    _SYSTEM_CALL ( rm_command) ;
}

void runOptimizationPasses() {
    map<string, double> optExecMap;
    clock_t t1,t2;
    float diff;
    long double tid;
#pragma omp parallel for private(t1, t2, diff, tid)
    for( int i = 0; i < passOrder.size() ; ++i ) {
        tid = omp_get_thread_num();

        // Run the passes with order from file.
        COMMAND Cmd(passOrder[i], tid);

#ifdef DEBUG
        cout << "Running Command: " << Cmd.opt << "\n" << Cmd.lli  << " in thread number " << tid << endl;
#endif

        _SYSTEM_CALL( Cmd.opt );

        double start = omp_get_wtime( );
        _SYSTEM_CALL( Cmd.lli );
        double end = omp_get_wtime( );

//        optExecMap.insert( pair<string, double>(passOrder[i], (end-start) ) );
    }

#ifdef TIME
    for (map<string, double>::iterator it = optExecMap.begin(); it != optExecMap.end() ; ++it) {
        std::cout << it->first << " : " << it->second << std::endl;
    }
#endif

    cleanUpTheMess();
}

int main(int argc, char** argv) {

    int numThreads = NUM_THREADS;

    if(argc > 1) {
        binaryName = argv[1];
        input_combination_file = argv[2];
        binaryArgs = argv[3];
        numThreads = atoi(argv[4]);
//        std::cout << binaryName << " " << binaryArgs << " " << numThreads << " " <<input_combination_file << endl;
    } else {
        std::cout << "Usage: pass_runner <Binary Name> <NumThreads(optional)>" << std::endl;
        abort();
    }

    // open a file in read mode.
    ifstream infile;
    infile.open(input_combination_file);

    string opt_order;
    while(getline(infile, opt_order)) {
        passOrder.push_back(opt_order);
    }

    // this will potentially print the contents of events.1 file
#ifdef VERBOSE
    cout << passOrder;
#endif

    // set openmp number of threads
    omp_set_num_threads(numThreads);

    dir_name = string(input_combination_file) + "dir";
     string create_dir_cmd = string("mkdir ") + dir_name;
    _SYSTEM_CALL(create_dir_cmd );

    runOptimizationPasses();

    return EXIT_SUCCESS;
}
<commit_msg>code for adding limited size priority queue for each thread and merging at the end<commit_after>#include <chrono>
#include <ctime>
#include <fstream>
#include <iostream>
#include <map>
#include <queue>
#include <ratio>
#include <string>
#include <stdlib.h>
#include <time.h>
#include "omp.h"
#include <vector>

#include <boost/algorithm/string.hpp>
#include <boost/algorithm/string/classification.hpp>
#include "boost/lexical_cast.hpp"

using namespace boost::algorithm;

#include "pass_runner.h"

#define NUM_THREADS 8 // default number of threads
#define MAX_NUM_PER_THREAD 16

#if(0)
#ifdef DEBUG
#ifndef TIME
#define TIME
#endif
#endif
#endif

using namespace std;
using namespace std::chrono;

/*------- GLOBAL VARIABES --------*/
// vector with permutations of passorder
vector<string> passOrder;
char *binaryName;
char *binaryArgs;
char *input_combination_file;
string dir_name;

#define _SYSTEM_CALL( CMD ) ( {            \
    int err = ( system( CMD.c_str() ) );   \
    if ( err < 0  ) {                      \
        fprintf(stderr, #CMD, " failed."); \
        abort();                           \
    }                                      \
    err;                                   \
})                                         \

struct RECORD
{
  string pass_order;
  double exec_time;

  RECORD(string s, double d) :  pass_order(s), exec_time(d){}
};

class Comparator
{
  public:
    bool operator()(RECORD& n1, RECORD& n2)
    {
      if (n1.exec_time < n2.exec_time)
        return true;
      else
        return false;
    }
};

typedef priority_queue< RECORD, vector< RECORD >, Comparator> PQUEUE;

class BoundMap {
  public:
      BoundMap() { };

      bool in_range(){
        if(pq.size() < MAX_NUM_PER_THREAD) return true;
        return false;
      }

      void insert(string s, double d){
        if(in_range()){
            pq.push(RECORD(s,d));

        } else if(pq.top().exec_time > d) {
            pq.pop();
            pq.push(RECORD(s,d));
        }

#ifdef BMAP_DEBUG
            std::cout << "Inserting new element with time "<< d << ". Size " << pq.size() << " Worst time " << pq.top().exec_time << " Sequence: " << pq.top().pass_order << std::endl;
#endif

      } /* end of function insert */

      void insert(RECORD r){
        if(in_range()){
            pq.push(r);

        } else if(pq.top().exec_time > r.exec_time) {
            pq.pop();
            pq.push(r);
        }
      }

     PQUEUE pq;
};

struct COMMAND {
    string opt;
    string lli;

    // constructor
    COMMAND(string, long double);
};

inline COMMAND::COMMAND(string pass_order, long double threadId) {
    // opt -pass1 -pass2 ./bcfile -o temp.out.threadId >> /dev/null

    string pname = " ";// = A::PASS_MAP[0];
    vector<string> strs;
    boost::split(strs,pass_order,boost::is_any_of(" "));

    for(vector<string>::iterator pit = strs.begin(); pit != strs.end(); ++pit){
        string pass_num_string = *pit;
        int pnumber = atoi(pass_num_string.c_str());
        pname = pname + " " + A::PASS_MAP[pnumber];
    }
#ifdef DEBUG
    cout << pname << endl;
#endif
    // combination_file_name/temp.out.input_combination_filename
    string temp_name = dir_name + string("/temp.out.") + input_combination_file;

    opt = string("opt ") + pname + " ./"  + binaryName + " -o "+ temp_name  + "" + to_string(threadId) + " >> /dev/null";
    // Command to execute the file.
    //
//    lli = string("lli ") + temp_name + to_string(threadId) + " " + binaryArgs + to_string(threadId);
    lli = string("/Users/ankit/DevelopmentKits/build/bin/lli ") + temp_name + to_string(threadId) + " " + binaryArgs + to_string(threadId);
}

/*--------- General Purpose Methods --------*/

// print operator for vector<string>
void operator<<(ostream& os, vector<string> V) {
    for( vector<string>::iterator it = V.begin(); it != V.end(); ++it ) {
        os << *it << endl;
    }
}

void cleanUpTheMess() {
    string rm_command = string("rm -rf ") + dir_name;

#ifdef DEBUG
    cout << "Cleaning temporary files.." << endl;
    cout << "Running Command: " << rm_command << endl;
#endif
    _SYSTEM_CALL ( rm_command) ;
}

void runOptimizationPasses() {
    //map<string, double> optExecMap;

    map<long double, BoundMap> boundMaps;
    BoundMap bmap;
    clock_t t1,t2;
    float diff;
    long double tid;

#pragma omp parallel for private(t1, t2, diff, tid, bmap)
    for( int i = 0; i < passOrder.size() ; ++i ) {
        tid = omp_get_thread_num();
        clock_t t1,t2;

        // Run the passes with order from file.
        COMMAND Cmd(passOrder[i], tid);

#ifdef DEBUG
        cout << "Running Command: " << Cmd.opt << "\n" << Cmd.lli  << " in thread number " << tid << endl;
#endif

//        _SYSTEM_CALL( Cmd.opt );

        double start = omp_get_wtime( );

t1 = clock();
        _SYSTEM_CALL( (Cmd.opt + " && " +Cmd.lli) );

     t2 = clock();
     double diff = (double)t2 - (double)t1;

        double end = omp_get_wtime( );

        bmap.insert( passOrder[i], (end-start) );
        boundMaps[tid] = bmap;
        //optExecMap.insert( pair<string, double>(passOrder[i], (32.4) ) );
    }

    // Merge data from all threads
    BoundMap finalBmap;

    for (map<long double, BoundMap>::iterator it = boundMaps.begin(); it != boundMaps.end(); ++it) {
        BoundMap BM = it->second;
        PQUEUE pq = BM.pq;
        while(!pq.empty()){
            RECORD rec = pq.top();
            pq.pop();
            finalBmap.insert(rec);
        }
    }

    std::cout << finalBmap.pq.size() << std::endl;

#ifdef TIME
    for (map<string, double>::iterator it = optExecMap.begin(); it != optExecMap.end() ; ++it) {
        std::cout << it->first << " : " << it->second << std::endl;
    }
#endif

    cleanUpTheMess();
}

int main(int argc, char** argv) {

    int numThreads = NUM_THREADS;

    if(argc > 1) {
        binaryName = argv[1];
        input_combination_file = argv[2];
        binaryArgs = argv[3];
        numThreads = atoi(argv[4]);
//        std::cout << binaryName << " " << binaryArgs << " " << numThreads << " " <<input_combination_file << endl;
    } else {
        std::cout << "Usage: pass_runner <Binary Name> <NumThreads(optional)>" << std::endl;
        abort();
    }

    // open a file in read mode.
    ifstream infile;
    infile.open(input_combination_file);

    string opt_order;
    while(getline(infile, opt_order)) {
        passOrder.push_back(opt_order);
    }

    // this will potentially print the contents of events.1 file
#ifdef VERBOSE
    cout << passOrder;
#endif

    // set openmp number of threads
    omp_set_num_threads(numThreads);

    dir_name = string(input_combination_file) + "dir";
     string create_dir_cmd = string("mkdir ") + dir_name;
    _SYSTEM_CALL(create_dir_cmd );

    runOptimizationPasses();

    return EXIT_SUCCESS;
}
<|endoftext|>


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

#include <zippylog/envelope.hpp>
#include <zippylog/platform.hpp>
#include <zippylog/message_registrar.hpp>

#include <google/protobuf/text_format.h>

#include <stdio.h>
#include <sstream>
#include <vector>

namespace zippylog {

using ::google::protobuf::Message;
using ::std::invalid_argument;
using ::std::string;
using ::std::stringstream;
using ::std::vector;
using ::zmq::message_t;

Envelope::Envelope() : messages(NULL), messages_size(0)
{
    platform::Time t;
    platform::TimeNow(t);

    this->envelope.set_create_time(t.epoch_micro);
}

Envelope::Envelope(message_t &msg, uint32 offset)
{
    if (!msg.size()) throw invalid_argument("0MQ message is empty");
    if (offset + 1 >= msg.size()) throw invalid_argument("specified offset is larger than message");

    this->InitializeFromBuffer((const void *)((char *)msg.data() + offset), msg.size() - offset);
}

Envelope::Envelope( const void * data, int size) : messages(NULL), messages_size(0)
{
    if (!data) throw invalid_argument("NULL data pointer");
    if (!size) throw invalid_argument("0 size data buffer");
    if (size < 0) throw invalid_argument("size <0: " + size);

    this->InitializeFromBuffer(data, size);
}

Envelope::Envelope(const string &s) :
    messages(NULL),
    messages_size(0)
{
    platform::Time t;
    platform::TimeNow(t);

    this->envelope.set_create_time(t.epoch_micro);
    this->envelope.set_string_value(s);
}

Envelope::~Envelope()
{
    if (this->messages) {
        for (int i = 0; i < this->messages_size; i++) {
            if (this->messages[i]) {
                delete this->messages[i];
            }
            this->messages[i] = NULL;
        }
    }

    delete [] this->messages;
    this->messages = NULL;
}

Envelope::Envelope(const Envelope &e)
{
    if (e.messages_size > 0) {
        this->messages_size = e.messages_size;
        this->messages = new Message *[this->messages_size];
        for (int i = 0; i < this->messages_size; i++) {
            this->messages[i] = NULL;
        }
    }
    else {
        this->messages_size = 0;
        this->messages = NULL;
    }

    this->envelope = e.envelope;
}

Envelope & Envelope::operator=(const Envelope &orig)
{
    if (this == &orig) return *this;

    if (orig.messages_size > 0) {
        this->messages_size = orig.messages_size;
        this->messages = new Message *[this->messages_size];
        for (int i = 0; i < this->messages_size; i++) {
            this->messages[i] = NULL;
        }
    }
    else {
        this->messages_size = 0;
        this->messages = NULL;
    }

    this->envelope = orig.envelope;

    return *this;
}

bool Envelope::operator==(const Envelope &other) const
{
    if (this == &other) return true;

    string s1, s2;
    this->Serialize(s1);
    other.Serialize(s2);

    return s1.compare(s2) == 0;
}

bool Envelope::operator!=(const Envelope &other) const
{
    return !(*this == other);
}

void Envelope::InitializeFromBuffer(const void * data, int size)
{
    if (!this->envelope.ParseFromArray(data, size)) {
        throw DeserializeException();
    }

    int count = this->MessageCount();

    this->messages = new Message *[count];
    this->messages_size = count;
    for (int i = 0; i < count; i++) {
        this->messages[i] = NULL;
    }
}

bool Envelope::Serialize(string &s) const
{
    return this->envelope.AppendToString(&s);
}

bool Envelope::AddMessage(Message &m, uint32 ns, uint32 enumeration)
{
    if (!this->messages) {
        assert(this->MessageCount() == 0);

        this->messages = new Message *[1];
        this->messages_size = 1;
        // don't bother caching it, cuz that would take memory
        this->messages[0] = NULL;
    }
    else {
        // we need to resize the array
        Message **old = this->messages;

        this->messages = new Message *[this->messages_size + 1];
        this->messages[this->messages_size+1] = NULL;

        for (int i = 0; i < this->messages_size; i++) {
            this->messages[i] = old[i];
        }

        delete [] old;
    }

    string buffer;
    if (!m.SerializeToString(&buffer)) return false;

    this->envelope.add_message_namespace(ns);
    this->envelope.add_message_type(enumeration);
    this->envelope.add_message(buffer);

    return true;
}

bool Envelope::ParseFromCodedInputStream(::google::protobuf::io::CodedInputStream &cis)
{
    if (this->messages) {
        for (int i = 0; i < this->messages_size; i++) {
            if (this->messages[i]) {
                delete this->messages[i];
            }
        }

        delete [] this->messages;
        this->messages = NULL;
        this->messages_size = 0;
    }

    bool result = this->envelope.ParseFromCodedStream(&cis) && cis.ConsumedEntireMessage();

    if (result) {
        int count = this->MessageCount();

        this->messages = new Message *[count];
        for (int i = 0; i < count; i++) {
            this->messages[i] = NULL;
        }
        this->messages_size = count;
    }

    return result;
}

bool Envelope::ToZmqMessage(message_t &msg)
{
    string buffer;
    if (!this->envelope.AppendToString(&buffer)) return false;
    msg.rebuild(buffer.length());
    memcpy(msg.data(), buffer.data(), buffer.length());

    return true;
}

bool Envelope::ToProtocolZmqMessage(message_t &msg) const
{
    string buffer(1, 0x01);
    if (!this->envelope.AppendToString(&buffer)) return false;
    msg.rebuild(buffer.length());
    memcpy(msg.data(), buffer.data(), buffer.length());

    return true;
}

int Envelope::MessageCount()
{
    return this->envelope.message_size();
}

Message * Envelope::GetMessage(int index)
{
    if (index < 0) throw invalid_argument("index must be non-negative");

    if (this->MessageCount() < index + 1) return NULL;
    if (this->envelope.message_namespace_size() < index + 1) return NULL;
    if (this->envelope.message_type_size() < index + 1) return NULL;

    // the messages cache should be initialized at construction time and
    // modified whenever messages are added
    assert(this->messages);

    if (this->messages[index])
        return this->messages[index];

    uint32 ns = this->envelope.message_namespace(index);
    uint32 enumeration = this->envelope.message_type(index);

    Message *msg = MessageRegistrar::instance()->GetMessage(ns, enumeration);
    if (!msg) return NULL;

    string buffer = envelope.message(index);
    if (!msg->ParseFromString(buffer)) {
        delete msg;
        return NULL;
    }

    this->messages[index] = msg;

    return this->messages[index];
}

bool Envelope::CopyMessage(int index, Envelope &dest) const
{
    if (this->envelope.message_size() < index + 1) return false;

    dest.envelope.add_message(this->envelope.message(index));
    dest.envelope.add_message_namespace(this->envelope.message_namespace(index));
    dest.envelope.add_message_type(this->envelope.message_type(index));

    return true;
}

string Envelope::ToString()
{
    ::google::protobuf::TextFormat::Printer printer = ::google::protobuf::TextFormat::Printer();
    printer.SetInitialIndentLevel(4);

    stringstream ss(stringstream::out);

    ss << "Envelope" << ::std::endl;

    if (this->envelope.has_create_time()) {
        platform::Time t;
        platform::UnixMicroTimeToZippyTime(this->envelope.create_time(), t);

        string date = string(30, 0);
        sprintf((char *)date.data(), "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC", t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec);
        ss << "  create_time: " << date << ::std::endl;
    }

    if (this->envelope.has_string_value()) {
        ss << "  string: " << this->envelope.string_value() << ::std::endl;
    }

    for (int i = 0; i < this->MessageCount(); i++) {
        string s;
        ::google::protobuf::Message *m = this->GetMessage(i);
        if (m) {
            printer.PrintToString(*m, &s);
            ss << "  " << m->GetTypeName() << ::std::endl << s;
        }
    }

    return ss.str();
}

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

#include <zippylog/envelope.hpp>
#include <zippylog/platform.hpp>
#include <zippylog/message_registrar.hpp>

#include <google/protobuf/text_format.h>

#include <stdio.h>
#include <sstream>
#include <vector>

namespace zippylog {

using ::google::protobuf::Message;
using ::std::invalid_argument;
using ::std::string;
using ::std::stringstream;
using ::std::vector;
using ::zmq::message_t;

Envelope::Envelope() : messages(NULL), messages_size(0)
{
    platform::Time t;
    platform::TimeNow(t);

    this->envelope.set_create_time(t.epoch_micro);
}

Envelope::Envelope(message_t &msg, uint32 offset)
{
    if (!msg.size()) throw invalid_argument("0MQ message is empty");
    if (offset + 1 >= msg.size()) throw invalid_argument("specified offset is larger than message");

    this->InitializeFromBuffer((const void *)((char *)msg.data() + offset), msg.size() - offset);
}

Envelope::Envelope(const void * data, int size) : messages(NULL), messages_size(0)
{
    if (!data) throw invalid_argument("NULL data pointer");
    if (!size) throw invalid_argument("0 size data buffer");
    if (size < 0) throw invalid_argument("size <0: " + size);

    this->InitializeFromBuffer(data, size);
}

Envelope::Envelope(const string &s) :
    messages(NULL),
    messages_size(0)
{
    platform::Time t;
    platform::TimeNow(t);

    this->envelope.set_create_time(t.epoch_micro);
    this->envelope.set_string_value(s);
}

Envelope::~Envelope()
{
    if (this->messages) {
        for (int i = 0; i < this->messages_size; i++) {
            if (this->messages[i]) {
                delete this->messages[i];
            }
            this->messages[i] = NULL;
        }
    }

    delete [] this->messages;
    this->messages = NULL;
}

Envelope::Envelope(const Envelope &e)
{
    if (e.messages_size > 0) {
        this->messages_size = e.messages_size;
        this->messages = new Message *[this->messages_size];
        for (int i = 0; i < this->messages_size; i++) {
            this->messages[i] = NULL;
        }
    }
    else {
        this->messages_size = 0;
        this->messages = NULL;
    }

    this->envelope = e.envelope;
}

Envelope & Envelope::operator=(const Envelope &orig)
{
    if (this == &orig) return *this;

    if (orig.messages_size > 0) {
        this->messages_size = orig.messages_size;
        this->messages = new Message *[this->messages_size];
        for (int i = 0; i < this->messages_size; i++) {
            this->messages[i] = NULL;
        }
    }
    else {
        this->messages_size = 0;
        this->messages = NULL;
    }

    this->envelope = orig.envelope;

    return *this;
}

bool Envelope::operator==(const Envelope &other) const
{
    if (this == &other) return true;

    string s1, s2;
    this->Serialize(s1);
    other.Serialize(s2);

    return s1.compare(s2) == 0;
}

bool Envelope::operator!=(const Envelope &other) const
{
    return !(*this == other);
}

void Envelope::InitializeFromBuffer(const void * data, int size)
{
    if (!this->envelope.ParseFromArray(data, size)) {
        throw DeserializeException();
    }

    int count = this->MessageCount();

    this->messages = new Message *[count];
    this->messages_size = count;
    for (int i = 0; i < count; i++) {
        this->messages[i] = NULL;
    }
}

bool Envelope::Serialize(string &s) const
{
    return this->envelope.AppendToString(&s);
}

bool Envelope::AddMessage(Message &m, uint32 ns, uint32 enumeration)
{
    if (!this->messages) {
        assert(this->MessageCount() == 0);

        this->messages = new Message *[1];
        this->messages_size = 1;
        // don't bother caching it, cuz that would take memory
        this->messages[0] = NULL;
    }
    else {
        // we need to resize the array
        Message **old = this->messages;

        this->messages = new Message *[this->messages_size + 1];
        this->messages[this->messages_size+1] = NULL;

        for (int i = 0; i < this->messages_size; i++) {
            this->messages[i] = old[i];
        }

        delete [] old;
    }

    string buffer;
    if (!m.SerializeToString(&buffer)) return false;

    this->envelope.add_message_namespace(ns);
    this->envelope.add_message_type(enumeration);
    this->envelope.add_message(buffer);

    return true;
}

bool Envelope::ParseFromCodedInputStream(::google::protobuf::io::CodedInputStream &cis)
{
    if (this->messages) {
        for (int i = 0; i < this->messages_size; i++) {
            if (this->messages[i]) {
                delete this->messages[i];
            }
        }

        delete [] this->messages;
        this->messages = NULL;
        this->messages_size = 0;
    }

    bool result = this->envelope.ParseFromCodedStream(&cis) && cis.ConsumedEntireMessage();

    if (result) {
        int count = this->MessageCount();

        this->messages = new Message *[count];
        for (int i = 0; i < count; i++) {
            this->messages[i] = NULL;
        }
        this->messages_size = count;
    }

    return result;
}

bool Envelope::ToZmqMessage(message_t &msg)
{
    string buffer;
    if (!this->envelope.AppendToString(&buffer)) return false;
    msg.rebuild(buffer.length());
    memcpy(msg.data(), buffer.data(), buffer.length());

    return true;
}

bool Envelope::ToProtocolZmqMessage(message_t &msg) const
{
    string buffer(1, 0x01);
    if (!this->envelope.AppendToString(&buffer)) return false;
    msg.rebuild(buffer.length());
    memcpy(msg.data(), buffer.data(), buffer.length());

    return true;
}

int Envelope::MessageCount()
{
    return this->envelope.message_size();
}

Message * Envelope::GetMessage(int index)
{
    if (index < 0) throw invalid_argument("index must be non-negative");

    if (this->MessageCount() < index + 1) return NULL;
    if (this->envelope.message_namespace_size() < index + 1) return NULL;
    if (this->envelope.message_type_size() < index + 1) return NULL;

    // the messages cache should be initialized at construction time and
    // modified whenever messages are added
    assert(this->messages);

    if (this->messages[index])
        return this->messages[index];

    uint32 ns = this->envelope.message_namespace(index);
    uint32 enumeration = this->envelope.message_type(index);

    Message *msg = MessageRegistrar::instance()->GetMessage(ns, enumeration);
    if (!msg) return NULL;

    string buffer = envelope.message(index);
    if (!msg->ParseFromString(buffer)) {
        delete msg;
        return NULL;
    }

    this->messages[index] = msg;

    return this->messages[index];
}

bool Envelope::CopyMessage(int index, Envelope &dest) const
{
    if (this->envelope.message_size() < index + 1) return false;

    dest.envelope.add_message(this->envelope.message(index));
    dest.envelope.add_message_namespace(this->envelope.message_namespace(index));
    dest.envelope.add_message_type(this->envelope.message_type(index));

    return true;
}

string Envelope::ToString()
{
    ::google::protobuf::TextFormat::Printer printer = ::google::protobuf::TextFormat::Printer();
    printer.SetInitialIndentLevel(4);

    stringstream ss(stringstream::out);

    ss << "Envelope" << ::std::endl;

    if (this->envelope.has_create_time()) {
        platform::Time t;
        platform::UnixMicroTimeToZippyTime(this->envelope.create_time(), t);

        string date = string(30, 0);
        sprintf((char *)date.data(), "%04d-%02d-%02d %02d:%02d:%02d.%06d UTC", t.year, t.mon, t.mday, t.hour, t.min, t.sec, t.usec);
        ss << "  create_time: " << date << ::std::endl;
    }

    if (this->envelope.has_string_value()) {
        ss << "  string: " << this->envelope.string_value() << ::std::endl;
    }

    for (int i = 0; i < this->MessageCount(); i++) {
        string s;
        ::google::protobuf::Message *m = this->GetMessage(i);
        if (m) {
            printer.PrintToString(*m, &s);
            ss << "  " << m->GetTypeName() << ::std::endl << s;
        }
    }

    return ss.str();
}

} // namespace<|endoftext|>


<commit_before>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <sstream>
#include <cmath>
#include "modules/std/core/int.h"
#include "modules/std/core/function.h"

namespace clever {

CLEVER_TYPE_OPERATOR(IntType::add)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() + rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() + rhs->getDouble());
	} else if (rhs->isStr()) {
		std::stringstream ss;

		ss << lhs->getInt();

		result->setStr(new StrObject(ss.str() + *rhs->getStr()));
	}
}

CLEVER_TYPE_OPERATOR(IntType::sub)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() - rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() - rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::mul)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() * rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() * rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::div)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() / rhs->getInt());
	} else if (EXPECTED(rhs->isDouble())) {
		result->setDouble(lhs->getInt() / rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::mod)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() % rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(fmod(lhs->getInt(), rhs->getDouble()));
	}
}

CLEVER_TYPE_OPERATOR(IntType::greater)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() > rhs->getInt());
	} else if (EXPECTED(rhs->isDouble())) {
		result->setDouble(lhs->getInt() > rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::greater_equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() >= rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() >= rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::less)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() < rhs->getInt());
	}  else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() < rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::less_equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() <= rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() <= rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() == rhs->getInt());
	}  else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() == rhs->getDouble());
	}
}

CLEVER_TYPE_OPERATOR(IntType::not_equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() != rhs->getInt());
	}  else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() != rhs->getDouble());
	}
}

CLEVER_TYPE_UNARY_OPERATOR(IntType::not_op)
{
	result->setBool(!lhs->asBool());
}

CLEVER_TYPE_OPERATOR(IntType::bw_and)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() & rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() & long(rhs->getDouble()));
	}
}

CLEVER_TYPE_OPERATOR(IntType::bw_or)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() | rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() | long(rhs->getDouble()));
	}
}

CLEVER_TYPE_OPERATOR(IntType::bw_xor)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() ^ rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() ^ long(rhs->getDouble()));
	}
}

CLEVER_TYPE_UNARY_OPERATOR(IntType::bw_not)
{
	result->setInt(~lhs->getInt());
}

CLEVER_TYPE_OPERATOR(IntType::bw_ls)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() << rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() << long(rhs->getDouble()));
	}
}

CLEVER_TYPE_OPERATOR(IntType::bw_rs)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() >> rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() >> long(rhs->getDouble()));
	}
}

// Int::Int([Number value])
CLEVER_METHOD(IntType::ctor)
{
	if (!clever_check_args("|n")) {
		return;
	}

	if (args.empty()) {
		result->setInt(0);
	} else if (args[0]->isInt()) {
		result->setInt(args[0]->getInt());
	} else {
		result->setInt(long(args[0]->getDouble()));
	}
}

// Int::toString()
CLEVER_METHOD(IntType::toString)
{
	if (!clever_check_no_args()) {
		return;
	}

	std::ostringstream str;

	str << CLEVER_THIS()->getInt();

	result->setStr(CSTRING(str.str()));
}

CLEVER_TYPE_INIT(IntType::init)
{
	setConstructor((MethodPtr) &IntType::ctor);

	// Methods
	addMethod(new Function("toString", (MethodPtr) &IntType::toString));

	// Properties
	addProperty(CSTRING("SIZE"), new Value((long)sizeof(long), true));
}

} // clever
<commit_msg>- Spread some comments<commit_after>/**
 * Clever programming language
 * Copyright (c) Clever Team
 *
 * This file is distributed under the MIT license. See LICENSE for details.
 */

#include <sstream>
#include <cmath>
#include "modules/std/core/int.h"
#include "modules/std/core/function.h"

namespace clever {

// + operator
CLEVER_TYPE_OPERATOR(IntType::add)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() + rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() + rhs->getDouble());
	} else if (rhs->isStr()) {
		std::stringstream ss;

		ss << lhs->getInt();

		result->setStr(new StrObject(ss.str() + *rhs->getStr()));
	}
}

// - operator
CLEVER_TYPE_OPERATOR(IntType::sub)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() - rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() - rhs->getDouble());
	}
}

// * operator
CLEVER_TYPE_OPERATOR(IntType::mul)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() * rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() * rhs->getDouble());
	}
}

// / operator
CLEVER_TYPE_OPERATOR(IntType::div)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() / rhs->getInt());
	} else if (EXPECTED(rhs->isDouble())) {
		result->setDouble(lhs->getInt() / rhs->getDouble());
	}
}

// % operator
CLEVER_TYPE_OPERATOR(IntType::mod)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() % rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(fmod(lhs->getInt(), rhs->getDouble()));
	}
}

// > operator
CLEVER_TYPE_OPERATOR(IntType::greater)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() > rhs->getInt());
	} else if (EXPECTED(rhs->isDouble())) {
		result->setDouble(lhs->getInt() > rhs->getDouble());
	}
}

// >= operator
CLEVER_TYPE_OPERATOR(IntType::greater_equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() >= rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() >= rhs->getDouble());
	}
}

// < operator
CLEVER_TYPE_OPERATOR(IntType::less)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() < rhs->getInt());
	}  else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() < rhs->getDouble());
	}
}

// <= operator
CLEVER_TYPE_OPERATOR(IntType::less_equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() <= rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() <= rhs->getDouble());
	}
}

// == operator
CLEVER_TYPE_OPERATOR(IntType::equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() == rhs->getInt());
	}  else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() == rhs->getDouble());
	}
}

// != operator
CLEVER_TYPE_OPERATOR(IntType::not_equal)
{
	if (EXPECTED(rhs->isInt())) {
		result->setBool(lhs->getInt() != rhs->getInt());
	}  else if (rhs->isDouble()) {
		result->setDouble(lhs->getInt() != rhs->getDouble());
	}
}

// ! operator
CLEVER_TYPE_UNARY_OPERATOR(IntType::not_op)
{
	result->setBool(!lhs->asBool());
}

// & operator
CLEVER_TYPE_OPERATOR(IntType::bw_and)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() & rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() & long(rhs->getDouble()));
	}
}

// | operator
CLEVER_TYPE_OPERATOR(IntType::bw_or)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() | rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() | long(rhs->getDouble()));
	}
}

// ^ operator
CLEVER_TYPE_OPERATOR(IntType::bw_xor)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() ^ rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() ^ long(rhs->getDouble()));
	}
}

// ~ operator
CLEVER_TYPE_UNARY_OPERATOR(IntType::bw_not)
{
	result->setInt(~lhs->getInt());
}

// << operator
CLEVER_TYPE_OPERATOR(IntType::bw_ls)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() << rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() << long(rhs->getDouble()));
	}
}

// >> operator
CLEVER_TYPE_OPERATOR(IntType::bw_rs)
{
	if (EXPECTED(rhs->isInt())) {
		result->setInt(lhs->getInt() >> rhs->getInt());
	} else if (rhs->isDouble()) {
		result->setInt(lhs->getInt() >> long(rhs->getDouble()));
	}
}

// Int::Int([Number value])
CLEVER_METHOD(IntType::ctor)
{
	if (!clever_check_args("|n")) {
		return;
	}

	if (args.empty()) {
		result->setInt(0);
	} else if (args[0]->isInt()) {
		result->setInt(args[0]->getInt());
	} else {
		result->setInt(long(args[0]->getDouble()));
	}
}

// Int::toString()
CLEVER_METHOD(IntType::toString)
{
	if (!clever_check_no_args()) {
		return;
	}

	std::ostringstream str;

	str << CLEVER_THIS()->getInt();

	result->setStr(CSTRING(str.str()));
}

// Int type initialization
CLEVER_TYPE_INIT(IntType::init)
{
	setConstructor((MethodPtr) &IntType::ctor);

	// Methods
	addMethod(new Function("toString", (MethodPtr) &IntType::toString));

	// Properties
	addProperty(CSTRING("SIZE"), new Value((long)sizeof(long), true));
}

} // clever
<|endoftext|>


<commit_before>#include "tracking/protocol.hpp"

#include "coding/traffic.hpp"

#include "pyhelpers/pair.hpp"
#include "pyhelpers/vector_uint8.hpp"

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

BOOST_PYTHON_MODULE(pytracking)
{
  using namespace boost::python;
  using tracking::Protocol;

  // Register the to-python converters.
  pair_to_python_converter<Protocol::PacketType, size_t>();
  to_python_converter<vector<uint8_t>, vector_uint8t_to_str>();
  vector_uint8t_from_python_str();

  class_<Protocol::DataElementsVec>("DataElementsVec")
      .def(vector_indexing_suite<Protocol::DataElementsVec>());

  class_<ms::LatLon>("LatLon")
      .def_readwrite("lat", &ms::LatLon::lat)
      .def_readwrite("lon", &ms::LatLon::lon);

  class_<coding::TrafficGPSEncoder::DataPoint>("DataPoint")
      .def(init<uint64_t, ms::LatLon const &>())
      .def_readwrite("timestamp", &coding::TrafficGPSEncoder::DataPoint::m_timestamp)
      .def_readwrite("coords", &coding::TrafficGPSEncoder::DataPoint::m_latLon)
      .def_readwrite("traffic", &coding::TrafficGPSEncoder::DataPoint::m_traffic);

  enum_<Protocol::PacketType>("PacketType")
      .value("AuthV0", Protocol::PacketType::AuthV0)
      .value("DataV0", Protocol::PacketType::DataV0)
      .value("DataV1", Protocol::PacketType::DataV1)
      .value("CurrentAuth", Protocol::PacketType::CurrentAuth)
      .value("CurrentData", Protocol::PacketType::CurrentData);

  vector<uint8_t> (*CreateDataPacket1)(Protocol::DataElementsCirc const &) =
      &Protocol::CreateDataPacket;
  vector<uint8_t> (*CreateDataPacket2)(Protocol::DataElementsVec const &) =
      &Protocol::CreateDataPacket;

  class_<Protocol>("Protocol")
      .def("CreateAuthPacket", &Protocol::CreateAuthPacket)
      .staticmethod("CreateAuthPacket")
      .def("CreateDataPacket", CreateDataPacket1)
      .def("CreateDataPacket", CreateDataPacket2)
      .staticmethod("CreateDataPacket")
      .def("CreateHeader", &Protocol::CreateHeader)
      .staticmethod("CreateHeader")
      .def("DecodeHeader", &Protocol::DecodeHeader)
      .staticmethod("DecodeHeader")
      .def("DecodeDataPacket", &Protocol::DecodeDataPacket)
      .staticmethod("DecodeDataPacket");
}
<commit_msg>Fix pybinding build errors<commit_after>#include "tracking/protocol.hpp"

#include "coding/traffic.hpp"

#include "pyhelpers/pair.hpp"
#include "pyhelpers/vector_uint8.hpp"

#include <boost/python.hpp>
#include <boost/python/suite/indexing/vector_indexing_suite.hpp>

BOOST_PYTHON_MODULE(pytracking)
{
  using namespace boost::python;
  using tracking::Protocol;

  // Register the to-python converters.
  pair_to_python_converter<Protocol::PacketType, size_t>();
  to_python_converter<vector<uint8_t>, vector_uint8t_to_str>();
  vector_uint8t_from_python_str();

  class_<Protocol::DataElementsVec>("DataElementsVec")
      .def(vector_indexing_suite<Protocol::DataElementsVec>());

  class_<ms::LatLon>("LatLon")
      .def_readwrite("lat", &ms::LatLon::lat)
      .def_readwrite("lon", &ms::LatLon::lon);

  class_<coding::TrafficGPSEncoder::DataPoint>("DataPoint")
      .def(init<uint64_t, ms::LatLon const &, uint8_t>())
      .def_readwrite("timestamp", &coding::TrafficGPSEncoder::DataPoint::m_timestamp)
      .def_readwrite("coords", &coding::TrafficGPSEncoder::DataPoint::m_latLon)
      .def_readwrite("traffic", &coding::TrafficGPSEncoder::DataPoint::m_traffic);

  enum_<Protocol::PacketType>("PacketType")
      .value("AuthV0", Protocol::PacketType::AuthV0)
      .value("DataV0", Protocol::PacketType::DataV0)
      .value("DataV1", Protocol::PacketType::DataV1)
      .value("CurrentAuth", Protocol::PacketType::CurrentAuth)
      .value("CurrentData", Protocol::PacketType::CurrentData);

  vector<uint8_t> (*CreateDataPacket1)(Protocol::DataElementsCirc const &,
                                       tracking::Protocol::PacketType) =
      &Protocol::CreateDataPacket;
  vector<uint8_t> (*CreateDataPacket2)(Protocol::DataElementsVec const &,
                                       tracking::Protocol::PacketType) =
      &Protocol::CreateDataPacket;

  class_<Protocol>("Protocol")
      .def("CreateAuthPacket", &Protocol::CreateAuthPacket)
      .staticmethod("CreateAuthPacket")
      .def("CreateDataPacket", CreateDataPacket1)
      .def("CreateDataPacket", CreateDataPacket2)
      .staticmethod("CreateDataPacket")
      .def("CreateHeader", &Protocol::CreateHeader)
      .staticmethod("CreateHeader")
      .def("DecodeHeader", &Protocol::DecodeHeader)
      .staticmethod("DecodeHeader")
      .def("DecodeDataPacket", &Protocol::DecodeDataPacket)
      .staticmethod("DecodeDataPacket");
}
<|endoftext|>


<commit_before>#include "stdafx.h"
#include "picond.h"
#include "popup.h"

#include <Wtsapi32.h>
#include <shellapi.h>

NOTIFYICONDATA nid = { 0 };
UINT iWMTASKCREATE;

extern HINSTANCE hInst;
extern HWND      hMainWnd;
extern HMENU     hMenu;
extern TCHAR szTitle[MAX_LOADSTRING];
extern TCHAR szTrayWindowClass[MAX_LOADSTRING];

LRESULT CALLBACK	TrayWndProc(HWND, UINT, WPARAM, LPARAM);

ATOM MyRegisterTrayClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = TrayWndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PICOND));
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = szTrayWindowClass;
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
BOOL InitTrayInstance(HINSTANCE hInstance, int nCmdShow)
{
	hInst = hInstance;

	hMainWnd = CreateWindow(szTrayWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hMainWnd)
	{
		return FALSE;
	}

	//
	// Create task tray icon
	//

	iWMTASKCREATE = RegisterWindowMessage(_T("TaskbarCreated"));

	nid.cbSize = sizeof(NOTIFYICONDATA);
	nid.uFlags = (NIF_ICON | NIF_MESSAGE | NIF_TIP);
	nid.hWnd = hMainWnd;
	nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_PICOND));
	nid.uID = 1;
	nid.uCallbackMessage = WM_TASKTRAY;
	lstrcpy(nid.szTip, szTitle);
	nid.uTimeout = 10000;
	nid.dwState = NIS_HIDDEN;

	Shell_NotifyIcon(NIM_ADD, &nid);

	return TRUE;
}

LRESULT CALLBACK TrayWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;

	switch (message)
	{
	case WM_CREATE:
		WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
		break;
	case WM_COPYDATA:
		{
			COPYDATASTRUCT* cd;
			cd = (COPYDATASTRUCT *)lParam;
			InitPopupInstance(cd->dwData, (wchar_t *)cd->lpData);
		}
		break;
	case WM_DISPLAYCHANGE:
		ReorderWnd();
		break;
	case WM_TASKTRAY:
		switch (lParam)
		{
		case WM_RBUTTONDOWN:
			POINT pt;
			HMENU hPopupMenu = GetSubMenu(hMenu, 0);
			if (hPopupMenu == NULL)
			{
				SendMessage(hWnd, WM_CLOSE, 0, 0);
				break;
			}

			GetCursorPos(&pt);
			SetForegroundWindow(hWnd);
			TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hWnd, NULL);

			break;
		}
		break;
	case WM_COMMAND:
		wmId = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch (wmId)
		{
		case IDM_ABOUT:
			ShellExecute(NULL, _T("open"), _T("https://github.com/tochiz/picond"), NULL, NULL, SW_SHOWNORMAL);
			break;
		case IDM_EXIT:
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_DESTROY:
		Shell_NotifyIcon(NIM_DELETE, &nid);
		WTSUnRegisterSessionNotification(hWnd);
		PostQuitMessage(0);
		break;
	default:
		if (message == iWMTASKCREATE)
		{
			Shell_NotifyIcon(NIM_DELETE, &nid);
			Shell_NotifyIcon(NIM_ADD, &nid);
			break;
		}
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
<commit_msg>When Remote or Local Login or Session Unlock, reorder window.<commit_after>#include "stdafx.h"
#include "picond.h"
#include "popup.h"

#include <Wtsapi32.h>
#include <shellapi.h>

NOTIFYICONDATA nid = { 0 };
UINT iWMTASKCREATE;

extern HINSTANCE hInst;
extern HWND      hMainWnd;
extern HMENU     hMenu;
extern TCHAR szTitle[MAX_LOADSTRING];
extern TCHAR szTrayWindowClass[MAX_LOADSTRING];

LRESULT CALLBACK	TrayWndProc(HWND, UINT, WPARAM, LPARAM);

ATOM MyRegisterTrayClass(HINSTANCE hInstance)
{
	WNDCLASSEX wcex;

	wcex.cbSize = sizeof(WNDCLASSEX);

	wcex.style = CS_HREDRAW | CS_VREDRAW;
	wcex.lpfnWndProc = TrayWndProc;
	wcex.cbClsExtra = 0;
	wcex.cbWndExtra = 0;
	wcex.hInstance = hInstance;
	wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_PICOND));
	wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
	wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
	wcex.lpszMenuName = NULL;
	wcex.lpszClassName = szTrayWindowClass;
	wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

	return RegisterClassEx(&wcex);
}

//
BOOL InitTrayInstance(HINSTANCE hInstance, int nCmdShow)
{
	hInst = hInstance;

	hMainWnd = CreateWindow(szTrayWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hMainWnd)
	{
		return FALSE;
	}

	//
	// Create task tray icon
	//

	iWMTASKCREATE = RegisterWindowMessage(_T("TaskbarCreated"));

	nid.cbSize = sizeof(NOTIFYICONDATA);
	nid.uFlags = (NIF_ICON | NIF_MESSAGE | NIF_TIP);
	nid.hWnd = hMainWnd;
	nid.hIcon = LoadIcon(hInst, MAKEINTRESOURCE(IDI_PICOND));
	nid.uID = 1;
	nid.uCallbackMessage = WM_TASKTRAY;
	lstrcpy(nid.szTip, szTitle);
	nid.uTimeout = 10000;
	nid.dwState = NIS_HIDDEN;

	Shell_NotifyIcon(NIM_ADD, &nid);

	return TRUE;
}

LRESULT CALLBACK TrayWndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;

	switch (message)
	{
	case WM_CREATE:
		WTSRegisterSessionNotification(hWnd, NOTIFY_FOR_THIS_SESSION);
		break;
	case WM_COPYDATA:
		{
			COPYDATASTRUCT* cd;
			cd = (COPYDATASTRUCT *)lParam;
			InitPopupInstance(cd->dwData, (wchar_t *)cd->lpData);
		}
		break;
	case WM_WTSSESSION_CHANGE:
		switch (wParam)
		{
		case WTS_CONSOLE_CONNECT:
		case WTS_REMOTE_CONNECT:
		case WTS_SESSION_LOGON:
		case WTS_SESSION_UNLOCK:
			ReorderWnd();
			break;
		}
		break;
	case WM_DISPLAYCHANGE:
		ReorderWnd();
		break;
	case WM_TASKTRAY:
		switch (lParam)
		{
		case WM_RBUTTONDOWN:
			POINT pt;
			HMENU hPopupMenu = GetSubMenu(hMenu, 0);
			if (hPopupMenu == NULL)
			{
				SendMessage(hWnd, WM_CLOSE, 0, 0);
				break;
			}

			GetCursorPos(&pt);
			SetForegroundWindow(hWnd);
			TrackPopupMenu(hPopupMenu, 0, pt.x, pt.y, 0, hWnd, NULL);

			break;
		}
		break;
	case WM_COMMAND:
		wmId = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		switch (wmId)
		{
		case IDM_ABOUT:
			ShellExecute(NULL, _T("open"), _T("https://github.com/tochiz/picond"), NULL, NULL, SW_SHOWNORMAL);
			break;
		case IDM_EXIT:
			SendMessage(hWnd, WM_CLOSE, 0, 0);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_DESTROY:
		Shell_NotifyIcon(NIM_DELETE, &nid);
		WTSUnRegisterSessionNotification(hWnd);
		PostQuitMessage(0);
		break;
	default:
		if (message == iWMTASKCREATE)
		{
			Shell_NotifyIcon(NIM_DELETE, &nid);
			Shell_NotifyIcon(NIM_ADD, &nid);
			break;
		}
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}
<|endoftext|>


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

#include "content/ppapi_plugin/ppapi_thread.h"

#include <limits>

#include "base/command_line.h"
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stringprintf.h"
#include "content/common/child_process.h"
#include "content/common/content_switches.h"
#include "content/common/sandbox_init_wrapper.h"
#include "content/ppapi_plugin/broker_process_dispatcher.h"
#include "content/ppapi_plugin/plugin_process_dispatcher.h"
#include "content/ppapi_plugin/ppapi_webkit_thread.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_sync_channel.h"
#include "ppapi/c/dev/ppp_network_state_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppp.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/interface_list.h"
#include "webkit/plugins/ppapi/webkit_forwarding_impl.h"

#if defined(OS_WIN)
#include "sandbox/src/sandbox.h"
#endif

#if defined(OS_WIN)
extern sandbox::TargetServices* g_target_services;
#else
extern void* g_target_services;
#endif

typedef int32_t (*InitializeBrokerFunc)
    (PP_ConnectInstance_Func* connect_instance_func);

PpapiThread::PpapiThread(bool is_broker)
    : is_broker_(is_broker),
      get_plugin_interface_(NULL),
      connect_instance_func_(NULL),
      local_pp_module_(
          base::RandInt(0, std::numeric_limits<PP_Module>::max())),
      next_plugin_dispatcher_id_(1) {
}

PpapiThread::~PpapiThread() {
  if (!library_.is_valid())
    return;

  // The ShutdownModule/ShutdownBroker function is optional.
  ppapi::proxy::ProxyChannel::ShutdownModuleFunc shutdown_function =
      is_broker_ ?
      reinterpret_cast<ppapi::proxy::ProxyChannel::ShutdownModuleFunc>(
          library_.GetFunctionPointer("PPP_ShutdownBroker")) :
      reinterpret_cast<ppapi::proxy::ProxyChannel::ShutdownModuleFunc>(
          library_.GetFunctionPointer("PPP_ShutdownModule"));
  if (shutdown_function)
    shutdown_function();
}

// The "regular" ChildThread implements this function and does some standard
// dispatching, then uses the message router. We don't actually need any of
// this so this function just overrides that one.
//
// Note that this function is called only for messages from the channel to the
// browser process. Messages from the renderer process are sent via a different
// channel that ends up at Dispatcher::OnMessageReceived.
bool PpapiThread::OnMessageReceived(const IPC::Message& msg) {
  IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
    IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin)
    IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnMsgCreateChannel)
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_ConnectACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_SSLHandshakeACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_ReadACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_WriteACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnMsgSetNetworkState)
  IPC_END_MESSAGE_MAP()
  return true;
}

base::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() {
  return ChildProcess::current()->io_message_loop_proxy();
}

base::WaitableEvent* PpapiThread::GetShutdownEvent() {
  return ChildProcess::current()->GetShutDownEvent();
}

std::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() {
  return &globally_seen_instance_ids_;
}

ppapi::WebKitForwarding* PpapiThread::GetWebKitForwarding() {
  if (!webkit_forwarding_.get())
    webkit_forwarding_.reset(new webkit::ppapi::WebKitForwardingImpl);
  return webkit_forwarding_.get();
}

void PpapiThread::PostToWebKitThread(const tracked_objects::Location& from_here,
                                     const base::Closure& task) {
  if (!webkit_thread_.get())
    webkit_thread_.reset(new PpapiWebKitThread);
  webkit_thread_->PostTask(from_here, task);
}

bool PpapiThread::SendToBrowser(IPC::Message* msg) {
  return Send(msg);
}

uint32 PpapiThread::Register(ppapi::proxy::PluginDispatcher* plugin_dispatcher) {
  if (!plugin_dispatcher ||
      plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
    return 0;
  }

  uint32 id = 0;
  do {
    // Although it is unlikely, make sure that we won't cause any trouble when
    // the counter overflows.
    id = next_plugin_dispatcher_id_++;
  } while (id == 0 ||
           plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
  plugin_dispatchers_[id] = plugin_dispatcher;
  return id;
}

void PpapiThread::Unregister(uint32 plugin_dispatcher_id) {
  plugin_dispatchers_.erase(plugin_dispatcher_id);
}

void PpapiThread::OnMsgLoadPlugin(const FilePath& path) {
  base::ScopedNativeLibrary library(base::LoadNativeLibrary(path, NULL));

#if defined(OS_WIN)
  // Once we lower the token the sandbox is locked down and no new modules
  // can be loaded. TODO(cpu): consider changing to the loading style of
  // regular plugins.
  if (g_target_services) {
    // Cause advapi32 to load before the sandbox is turned on.
    unsigned int dummy_rand;
    rand_s(&dummy_rand);
    // Warm up language subsystems before the sandbox is turned on.
    ::GetUserDefaultLangID();
    ::GetUserDefaultLCID();

    g_target_services->LowerToken();
  }
#endif

  if (!library.is_valid()) {
    LOG(ERROR) << "Failed to load pepper module";
    return;
  }

  if (is_broker_) {
    // Get the InitializeBroker function (required).
    InitializeBrokerFunc init_broker =
        reinterpret_cast<InitializeBrokerFunc>(
            library.GetFunctionPointer("PPP_InitializeBroker"));
    if (!init_broker) {
      LOG(WARNING) << "No PPP_InitializeBroker in plugin library";
      return;
    }

    int32_t init_error = init_broker(&connect_instance_func_);
    if (init_error != PP_OK) {
      LOG(WARNING) << "InitBroker failed with error " << init_error;
      return;
    }
    if (!connect_instance_func_) {
      LOG(WARNING) << "InitBroker did not provide PP_ConnectInstance_Func";
      return;
    }
  } else {
    // Get the GetInterface function (required).
    get_plugin_interface_ =
        reinterpret_cast<ppapi::proxy::Dispatcher::GetInterfaceFunc>(
            library.GetFunctionPointer("PPP_GetInterface"));
    if (!get_plugin_interface_) {
      LOG(WARNING) << "No PPP_GetInterface in plugin library";
      return;
    }

#if defined(OS_MACOSX)
    // We need to do this after getting |PPP_GetInterface()| (or presumably
    // doing something nontrivial with the library), else the sandbox
    // intercedes.
    CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
    SandboxInitWrapper sandbox_wrapper;
    if (!sandbox_wrapper.InitializeSandbox(*parsed_command_line,
                                           switches::kPpapiPluginProcess))
      LOG(WARNING) << "Failed to initialize sandbox";
#endif

    // Get the InitializeModule function (required).
    ppapi::proxy::Dispatcher::InitModuleFunc init_module =
        reinterpret_cast<ppapi::proxy::Dispatcher::InitModuleFunc>(
            library.GetFunctionPointer("PPP_InitializeModule"));
    if (!init_module) {
      LOG(WARNING) << "No PPP_InitializeModule in plugin library";
      return;
    }
    int32_t init_error = init_module(
        local_pp_module_,
        &ppapi::proxy::PluginDispatcher::GetBrowserInterface);
    if (init_error != PP_OK) {
      LOG(WARNING) << "InitModule failed with error " << init_error;
      return;
    }
  }

  library_.Reset(library.Release());
}

void PpapiThread::OnMsgCreateChannel(base::ProcessHandle host_process_handle,
                                     int renderer_id) {
  IPC::ChannelHandle channel_handle;
  if (!library_.is_valid() ||  // Plugin couldn't be loaded.
      !SetupRendererChannel(host_process_handle, renderer_id,
                            &channel_handle)) {
    Send(new PpapiHostMsg_ChannelCreated(IPC::ChannelHandle()));
    return;
  }

  Send(new PpapiHostMsg_ChannelCreated(channel_handle));
}

void PpapiThread::OnMsgSetNetworkState(bool online) {
  if (!get_plugin_interface_)
    return;
  const PPP_NetworkState_Dev* ns = static_cast<const PPP_NetworkState_Dev*>(
      get_plugin_interface_(PPP_NETWORK_STATE_DEV_INTERFACE));
  if (ns)
    ns->SetOnLine(PP_FromBool(online));
}

void PpapiThread::OnPluginDispatcherMessageReceived(const IPC::Message& msg) {
  // The first parameter should be a plugin dispatcher ID.
  void* iter = NULL;
  uint32 id = 0;
  if (!msg.ReadUInt32(&iter, &id)) {
    NOTREACHED();
    return;
  }
  std::map<uint32, ppapi::proxy::PluginDispatcher*>::iterator dispatcher =
      plugin_dispatchers_.find(id);
  if (dispatcher != plugin_dispatchers_.end())
    dispatcher->second->OnMessageReceived(msg);
}

bool PpapiThread::SetupRendererChannel(base::ProcessHandle host_process_handle,
                                       int renderer_id,
                                       IPC::ChannelHandle* handle) {
  DCHECK(is_broker_ == (connect_instance_func_ != NULL));
  DCHECK(is_broker_ == (get_plugin_interface_ == NULL));
  IPC::ChannelHandle plugin_handle;
  plugin_handle.name = StringPrintf("%d.r%d", base::GetCurrentProcId(),
                                    renderer_id);

  ppapi::proxy::ProxyChannel* dispatcher = NULL;
  bool init_result = false;
  if (is_broker_) {
    BrokerProcessDispatcher* broker_dispatcher =
        new BrokerProcessDispatcher(host_process_handle,
                                    connect_instance_func_);
    init_result = broker_dispatcher->InitBrokerWithChannel(this,
                                                           plugin_handle,
                                                           false);
    dispatcher = broker_dispatcher;
  } else {
    PluginProcessDispatcher* plugin_dispatcher =
        new PluginProcessDispatcher(host_process_handle, get_plugin_interface_);
    init_result = plugin_dispatcher->InitPluginWithChannel(this,
                                                           plugin_handle,
                                                           false);
    dispatcher = plugin_dispatcher;
  }

  if (!init_result) {
    delete dispatcher;
    return false;
  }

  handle->name = plugin_handle.name;
#if defined(OS_POSIX)
  // On POSIX, pass the renderer-side FD.
  handle->socket = base::FileDescriptor(::dup(dispatcher->GetRendererFD()),
                                        true);
#endif

  // From here, the dispatcher will manage its own lifetime according to the
  // lifetime of the attached channel.
  return true;
}
<commit_msg>PPAPI: better output in case of failure to load library.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/ppapi_plugin/ppapi_thread.h"

#include <limits>

#include "base/command_line.h"
#include "base/process_util.h"
#include "base/rand_util.h"
#include "base/stringprintf.h"
#include "content/common/child_process.h"
#include "content/common/content_switches.h"
#include "content/common/sandbox_init_wrapper.h"
#include "content/ppapi_plugin/broker_process_dispatcher.h"
#include "content/ppapi_plugin/plugin_process_dispatcher.h"
#include "content/ppapi_plugin/ppapi_webkit_thread.h"
#include "ipc/ipc_channel_handle.h"
#include "ipc/ipc_sync_channel.h"
#include "ppapi/c/dev/ppp_network_state_dev.h"
#include "ppapi/c/pp_errors.h"
#include "ppapi/c/ppp.h"
#include "ppapi/proxy/ppapi_messages.h"
#include "ppapi/proxy/interface_list.h"
#include "webkit/plugins/ppapi/webkit_forwarding_impl.h"

#if defined(OS_WIN)
#include "sandbox/src/sandbox.h"
#endif

#if defined(OS_WIN)
extern sandbox::TargetServices* g_target_services;
#else
extern void* g_target_services;
#endif

typedef int32_t (*InitializeBrokerFunc)
    (PP_ConnectInstance_Func* connect_instance_func);

PpapiThread::PpapiThread(bool is_broker)
    : is_broker_(is_broker),
      get_plugin_interface_(NULL),
      connect_instance_func_(NULL),
      local_pp_module_(
          base::RandInt(0, std::numeric_limits<PP_Module>::max())),
      next_plugin_dispatcher_id_(1) {
}

PpapiThread::~PpapiThread() {
  if (!library_.is_valid())
    return;

  // The ShutdownModule/ShutdownBroker function is optional.
  ppapi::proxy::ProxyChannel::ShutdownModuleFunc shutdown_function =
      is_broker_ ?
      reinterpret_cast<ppapi::proxy::ProxyChannel::ShutdownModuleFunc>(
          library_.GetFunctionPointer("PPP_ShutdownBroker")) :
      reinterpret_cast<ppapi::proxy::ProxyChannel::ShutdownModuleFunc>(
          library_.GetFunctionPointer("PPP_ShutdownModule"));
  if (shutdown_function)
    shutdown_function();
}

// The "regular" ChildThread implements this function and does some standard
// dispatching, then uses the message router. We don't actually need any of
// this so this function just overrides that one.
//
// Note that this function is called only for messages from the channel to the
// browser process. Messages from the renderer process are sent via a different
// channel that ends up at Dispatcher::OnMessageReceived.
bool PpapiThread::OnMessageReceived(const IPC::Message& msg) {
  IPC_BEGIN_MESSAGE_MAP(PpapiThread, msg)
    IPC_MESSAGE_HANDLER(PpapiMsg_LoadPlugin, OnMsgLoadPlugin)
    IPC_MESSAGE_HANDLER(PpapiMsg_CreateChannel, OnMsgCreateChannel)
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_ConnectACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_SSLHandshakeACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_ReadACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER_GENERIC(PpapiMsg_PPBFlashTCPSocket_WriteACK,
                                OnPluginDispatcherMessageReceived(msg))
    IPC_MESSAGE_HANDLER(PpapiMsg_SetNetworkState, OnMsgSetNetworkState)
  IPC_END_MESSAGE_MAP()
  return true;
}

base::MessageLoopProxy* PpapiThread::GetIPCMessageLoop() {
  return ChildProcess::current()->io_message_loop_proxy();
}

base::WaitableEvent* PpapiThread::GetShutdownEvent() {
  return ChildProcess::current()->GetShutDownEvent();
}

std::set<PP_Instance>* PpapiThread::GetGloballySeenInstanceIDSet() {
  return &globally_seen_instance_ids_;
}

ppapi::WebKitForwarding* PpapiThread::GetWebKitForwarding() {
  if (!webkit_forwarding_.get())
    webkit_forwarding_.reset(new webkit::ppapi::WebKitForwardingImpl);
  return webkit_forwarding_.get();
}

void PpapiThread::PostToWebKitThread(const tracked_objects::Location& from_here,
                                     const base::Closure& task) {
  if (!webkit_thread_.get())
    webkit_thread_.reset(new PpapiWebKitThread);
  webkit_thread_->PostTask(from_here, task);
}

bool PpapiThread::SendToBrowser(IPC::Message* msg) {
  return Send(msg);
}

uint32 PpapiThread::Register(ppapi::proxy::PluginDispatcher* plugin_dispatcher) {
  if (!plugin_dispatcher ||
      plugin_dispatchers_.size() >= std::numeric_limits<uint32>::max()) {
    return 0;
  }

  uint32 id = 0;
  do {
    // Although it is unlikely, make sure that we won't cause any trouble when
    // the counter overflows.
    id = next_plugin_dispatcher_id_++;
  } while (id == 0 ||
           plugin_dispatchers_.find(id) != plugin_dispatchers_.end());
  plugin_dispatchers_[id] = plugin_dispatcher;
  return id;
}

void PpapiThread::Unregister(uint32 plugin_dispatcher_id) {
  plugin_dispatchers_.erase(plugin_dispatcher_id);
}

void PpapiThread::OnMsgLoadPlugin(const FilePath& path) {
  std::string error;
  base::ScopedNativeLibrary library(base::LoadNativeLibrary(path, &error));

#if defined(OS_WIN)
  // Once we lower the token the sandbox is locked down and no new modules
  // can be loaded. TODO(cpu): consider changing to the loading style of
  // regular plugins.
  if (g_target_services) {
    // Cause advapi32 to load before the sandbox is turned on.
    unsigned int dummy_rand;
    rand_s(&dummy_rand);
    // Warm up language subsystems before the sandbox is turned on.
    ::GetUserDefaultLangID();
    ::GetUserDefaultLCID();

    g_target_services->LowerToken();
  }
#endif

  if (!library.is_valid()) {
    LOG(ERROR) << "Failed to load Pepper module from "
      << path.value() << " (error: " << error << ")";
    return;
  }

  if (is_broker_) {
    // Get the InitializeBroker function (required).
    InitializeBrokerFunc init_broker =
        reinterpret_cast<InitializeBrokerFunc>(
            library.GetFunctionPointer("PPP_InitializeBroker"));
    if (!init_broker) {
      LOG(WARNING) << "No PPP_InitializeBroker in plugin library";
      return;
    }

    int32_t init_error = init_broker(&connect_instance_func_);
    if (init_error != PP_OK) {
      LOG(WARNING) << "InitBroker failed with error " << init_error;
      return;
    }
    if (!connect_instance_func_) {
      LOG(WARNING) << "InitBroker did not provide PP_ConnectInstance_Func";
      return;
    }
  } else {
    // Get the GetInterface function (required).
    get_plugin_interface_ =
        reinterpret_cast<ppapi::proxy::Dispatcher::GetInterfaceFunc>(
            library.GetFunctionPointer("PPP_GetInterface"));
    if (!get_plugin_interface_) {
      LOG(WARNING) << "No PPP_GetInterface in plugin library";
      return;
    }

#if defined(OS_MACOSX)
    // We need to do this after getting |PPP_GetInterface()| (or presumably
    // doing something nontrivial with the library), else the sandbox
    // intercedes.
    CommandLine* parsed_command_line = CommandLine::ForCurrentProcess();
    SandboxInitWrapper sandbox_wrapper;
    if (!sandbox_wrapper.InitializeSandbox(*parsed_command_line,
                                           switches::kPpapiPluginProcess))
      LOG(WARNING) << "Failed to initialize sandbox";
#endif

    // Get the InitializeModule function (required).
    ppapi::proxy::Dispatcher::InitModuleFunc init_module =
        reinterpret_cast<ppapi::proxy::Dispatcher::InitModuleFunc>(
            library.GetFunctionPointer("PPP_InitializeModule"));
    if (!init_module) {
      LOG(WARNING) << "No PPP_InitializeModule in plugin library";
      return;
    }
    int32_t init_error = init_module(
        local_pp_module_,
        &ppapi::proxy::PluginDispatcher::GetBrowserInterface);
    if (init_error != PP_OK) {
      LOG(WARNING) << "InitModule failed with error " << init_error;
      return;
    }
  }

  library_.Reset(library.Release());
}

void PpapiThread::OnMsgCreateChannel(base::ProcessHandle host_process_handle,
                                     int renderer_id) {
  IPC::ChannelHandle channel_handle;
  if (!library_.is_valid() ||  // Plugin couldn't be loaded.
      !SetupRendererChannel(host_process_handle, renderer_id,
                            &channel_handle)) {
    Send(new PpapiHostMsg_ChannelCreated(IPC::ChannelHandle()));
    return;
  }

  Send(new PpapiHostMsg_ChannelCreated(channel_handle));
}

void PpapiThread::OnMsgSetNetworkState(bool online) {
  if (!get_plugin_interface_)
    return;
  const PPP_NetworkState_Dev* ns = static_cast<const PPP_NetworkState_Dev*>(
      get_plugin_interface_(PPP_NETWORK_STATE_DEV_INTERFACE));
  if (ns)
    ns->SetOnLine(PP_FromBool(online));
}

void PpapiThread::OnPluginDispatcherMessageReceived(const IPC::Message& msg) {
  // The first parameter should be a plugin dispatcher ID.
  void* iter = NULL;
  uint32 id = 0;
  if (!msg.ReadUInt32(&iter, &id)) {
    NOTREACHED();
    return;
  }
  std::map<uint32, ppapi::proxy::PluginDispatcher*>::iterator dispatcher =
      plugin_dispatchers_.find(id);
  if (dispatcher != plugin_dispatchers_.end())
    dispatcher->second->OnMessageReceived(msg);
}

bool PpapiThread::SetupRendererChannel(base::ProcessHandle host_process_handle,
                                       int renderer_id,
                                       IPC::ChannelHandle* handle) {
  DCHECK(is_broker_ == (connect_instance_func_ != NULL));
  DCHECK(is_broker_ == (get_plugin_interface_ == NULL));
  IPC::ChannelHandle plugin_handle;
  plugin_handle.name = StringPrintf("%d.r%d", base::GetCurrentProcId(),
                                    renderer_id);

  ppapi::proxy::ProxyChannel* dispatcher = NULL;
  bool init_result = false;
  if (is_broker_) {
    BrokerProcessDispatcher* broker_dispatcher =
        new BrokerProcessDispatcher(host_process_handle,
                                    connect_instance_func_);
    init_result = broker_dispatcher->InitBrokerWithChannel(this,
                                                           plugin_handle,
                                                           false);
    dispatcher = broker_dispatcher;
  } else {
    PluginProcessDispatcher* plugin_dispatcher =
        new PluginProcessDispatcher(host_process_handle, get_plugin_interface_);
    init_result = plugin_dispatcher->InitPluginWithChannel(this,
                                                           plugin_handle,
                                                           false);
    dispatcher = plugin_dispatcher;
  }

  if (!init_result) {
    delete dispatcher;
    return false;
  }

  handle->name = plugin_handle.name;
#if defined(OS_POSIX)
  // On POSIX, pass the renderer-side FD.
  handle->socket = base::FileDescriptor(::dup(dispatcher->GetRendererFD()),
                                        true);
#endif

  // From here, the dispatcher will manage its own lifetime according to the
  // lifetime of the attached channel.
  return true;
}
<|endoftext|>