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

  Program:   Visualization Toolkit
  Module:    vtkPNMReader.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 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 "vtkPNMReader.h"
#include <stdio.h>

char vtkPNMReaderGetChar(FILE *fp)
{
  char c;
  int result;

  if ((result = getc(fp)) == EOF )
    {
    return '\0';
    }

  c = (char)result;
  if (c == '#')
    {
    do
      {
      if ((result = getc(fp)) == EOF )
	{
	return '\0';
	}
      c = (char)result;
      }
    while (c != '\n');
    }

  return c;
}

int vtkPNMReaderGetInt(FILE *fp)
{
  char c;
  int result = 0;

  do
    {
    c = vtkPNMReaderGetChar(fp);
    }
  while ((c < '1')||(c > '9'));
  do
    {
    result = result * 10 + (c - '0');
    c = vtkPNMReaderGetChar(fp);
    }
  while ((c >= '0')&&(c <= '9'));

  // put the CR/LF or whitespace back.....
  ungetc(c, fp);
  return result;
}

void vtkPNMReader::UpdateImageInformation()
{
  int xsize, ysize, comp;
  char magic[80];
  char c;
  FILE *fp;

  // if the user has not set the extent, but has set the VOI
  // set the zaxis extent to the VOI z axis
  if (this->DataExtent[4]==0 && this->DataExtent[5] == 0 &&
      (this->DataVOI[4] || this->DataVOI[5]))
    {
    this->DataExtent[4] = this->DataVOI[4];
    this->DataExtent[5] = this->DataVOI[5];
    }

  // Allocate the space for the filename
  this->ComputeInternalFileName(this->DataExtent[4]);

  // get the magic number by reading in a file
  fp = fopen(this->InternalFileName,"rb");
  if (!fp)
    {
    vtkErrorMacro("Unable to open file " << this->InternalFileName);
    return;
    }

  do
    {
    c = vtkPNMReaderGetChar(fp);
    }
  while (c != 'P');
  magic[0] = c;
  magic[1] = vtkPNMReaderGetChar(fp);
  magic[2] = '\0';

  // now get the dimensions
  xsize = vtkPNMReaderGetInt(fp);
  ysize = vtkPNMReaderGetInt(fp);

  // read max pixel value into comp for now
  comp = vtkPNMReaderGetInt(fp);
  do
    {
    c = getc(fp);
    }
  while (c != 0x0a);

  // Set the header size now that we have parsed it
  this->SetHeaderSize(ftell(fp));

  fclose(fp);

  // compare magic number to determine file type
  if ( ! strcmp(magic,"P5") )
    {
    comp = 1;
    }
  else if ( ! strcmp(magic,"P6") )
    {
    comp = 3;
    }
  else
    {
    vtkErrorMacro(<<"Unknown file type! Not a binary PGM or PPM");
    return;
    }

  // if the user has set the VOI, just make sure its valid
  if (this->DataVOI[0] || this->DataVOI[1] ||
      this->DataVOI[2] || this->DataVOI[3] ||
      this->DataVOI[4] || this->DataVOI[5])
    {
    if ((this->DataVOI[0] < 0) ||
	(this->DataVOI[1] >= xsize) ||
	(this->DataVOI[2] < 0) ||
	(this->DataVOI[3] >= ysize))
      {
      vtkWarningMacro("The requested VOI is larger than the file's (" << this->InternalFileName << ") extent ");
      this->DataVOI[0] = 0;
      this->DataVOI[1] = xsize - 1;
      this->DataVOI[2] = 0;
      this->DataVOI[3] = ysize - 1;
      }
    }

  this->DataExtent[0] = 0;
  this->DataExtent[1] = xsize - 1;
  this->DataExtent[2] = 0;
  this->DataExtent[3] = ysize - 1;

  this->SetDataScalarTypeToUnsignedChar();
  this->SetNumberOfScalarComponents(comp);

  vtkImageReader::UpdateImageInformation();
}

<commit_msg>FIX: refined end of header detection for binary files...<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkPNMReader.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-1998 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 "vtkPNMReader.h"
#include <stdio.h>

char vtkPNMReaderGetChar(FILE *fp)
{
  char c;
  int result;

  if ((result = getc(fp)) == EOF )
    {
    return '\0';
    }

  c = (char)result;
  if (c == '#')
    {
    do
      {
      if ((result = getc(fp)) == EOF )
	{
	return '\0';
	}
      c = (char)result;
      }
    while (c != '\n');
    }

  return c;
}

int vtkPNMReaderGetInt(FILE *fp)
{
  char c;
  int result = 0;

  do
    {
    c = vtkPNMReaderGetChar(fp);
    }
  while ((c < '1')||(c > '9'));
  do
    {
    result = result * 10 + (c - '0');
    c = vtkPNMReaderGetChar(fp);
    }
  while ((c >= '0')&&(c <= '9'));

  // put the CR/LF or whitespace back.....
  ungetc(c, fp);
  return result;
}

void vtkPNMReader::UpdateImageInformation()
{
  int xsize, ysize, comp;
  char magic[80];
  char c;
  FILE *fp;

  // if the user has not set the extent, but has set the VOI
  // set the zaxis extent to the VOI z axis
  if (this->DataExtent[4]==0 && this->DataExtent[5] == 0 &&
      (this->DataVOI[4] || this->DataVOI[5]))
    {
    this->DataExtent[4] = this->DataVOI[4];
    this->DataExtent[5] = this->DataVOI[5];
    }

  // Allocate the space for the filename
  this->ComputeInternalFileName(this->DataExtent[4]);

  // get the magic number by reading in a file
  fp = fopen(this->InternalFileName,"rb");
  if (!fp)
    {
    vtkErrorMacro("Unable to open file " << this->InternalFileName);
    return;
    }

  do
    {
    c = vtkPNMReaderGetChar(fp);
    }
  while (c != 'P');
  magic[0] = c;
  magic[1] = vtkPNMReaderGetChar(fp);
  magic[2] = '\0';

  // now get the dimensions
  xsize = vtkPNMReaderGetInt(fp);
  ysize = vtkPNMReaderGetInt(fp);

  // read max pixel value into comp for now
  comp = vtkPNMReaderGetInt(fp);

  // if file is ascii, any amount of whitespace may follow.
  // if file is binary, a single whitespace character will follow.
  // We only support binary ppm and pgm files right now.  So the next
  // character IS always ignored.
  c = getc(fp);

  // if this file was "written" on the PC, then a CR will have been
  // written as a CR/LF combination.  So, if this single whitespace
  // character is a CR and it is followed by a LF, then swallow the
  // linefeed character as well. (Not part of the PPM standard, but a
  // a hard fact of life.
  if ( c == 0x0d )
     {
     c = getc(fp);
     if ( c != 0x0a )
        {
	ungetc( c, fp );
        }
     }

  // Set the header size now that we have parsed it
  this->SetHeaderSize(ftell(fp));

  fclose(fp);

  // compare magic number to determine file type
  if ( ! strcmp(magic,"P5") )
    {
    comp = 1;
    }
  else if ( ! strcmp(magic,"P6") )
    {
    comp = 3;
    }
  else
    {
    vtkErrorMacro(<<"Unknown file type! Not a binary PGM or PPM");
    return;
    }

  // if the user has set the VOI, just make sure its valid
  if (this->DataVOI[0] || this->DataVOI[1] ||
      this->DataVOI[2] || this->DataVOI[3] ||
      this->DataVOI[4] || this->DataVOI[5])
    {
    if ((this->DataVOI[0] < 0) ||
	(this->DataVOI[1] >= xsize) ||
	(this->DataVOI[2] < 0) ||
	(this->DataVOI[3] >= ysize))
      {
      vtkWarningMacro("The requested VOI is larger than the file's (" << this->InternalFileName << ") extent ");
      this->DataVOI[0] = 0;
      this->DataVOI[1] = xsize - 1;
      this->DataVOI[2] = 0;
      this->DataVOI[3] = ysize - 1;
      }
    }

  this->DataExtent[0] = 0;
  this->DataExtent[1] = xsize - 1;
  this->DataExtent[2] = 0;
  this->DataExtent[3] = ysize - 1;

  this->SetDataScalarTypeToUnsignedChar();
  this->SetNumberOfScalarComponents(comp);

  vtkImageReader::UpdateImageInformation();
}

<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: AccessibleCellBase.cxx,v $
 *
 *  $Revision: 1.21 $
 *
 *  last change: $Author: obo $ $Date: 2007-03-05 14:44:09 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

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

#include "AccessibleCellBase.hxx"
#ifndef SC_SCATTR_HXX
#include "attrib.hxx"
#endif
#ifndef SC_ITEMS_HXX
#include "scitems.hxx"
#endif
#ifndef SC_MISCUNO_HXX
#include "miscuno.hxx"
#endif
#ifndef SC_DOCUMENT_HXX
#include "document.hxx"
#endif
#ifndef SC_DOCFUNC_HXX
#include "docfunc.hxx"
#endif
#ifndef SC_CELL_HXX
#include "cell.hxx"
#endif
#ifndef SC_UNOGUARD_HXX
#include "unoguard.hxx"
#endif
#ifndef SC_SCRESID_HXX
#include "scresid.hxx"
#endif
#ifndef SC_SC_HRC
#include "sc.hrc"
#endif
#ifndef SC_UNONAMES_HXX
#include "unonames.hxx"
#endif

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif

#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEETDOCUMENT_HPP_
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#endif
#ifndef _COM_SUN_STAR_SHEET_XSPREADSHEET_HPP_
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#endif

#ifndef _TOOLS_DEBUG_HXX
#include <tools/debug.hxx>
#endif
#ifndef _SVX_BRSHITEM_HXX
#include <svx/brshitem.hxx>
#endif
#ifndef _RTL_UUID_H_
#include <rtl/uuid.h>
#endif
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
#endif
#include <sfx2/objsh.hxx>

#include <float.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::accessibility;

//=====  internal  ============================================================

ScAccessibleCellBase::ScAccessibleCellBase(
        const uno::Reference<XAccessible>& rxParent,
        ScDocument* pDoc,
        const ScAddress& rCellAddress,
        sal_Int32 nIndex)
    :
    ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL),
    maCellAddress(rCellAddress),
    mpDoc(pDoc),
    mnIndex(nIndex)
{
}

ScAccessibleCellBase::~ScAccessibleCellBase()
{
}

    //=====  XAccessibleComponent  ============================================

sal_Bool SAL_CALL ScAccessibleCellBase::isVisible(  )
        throw (uno::RuntimeException)
{
     ScUnoGuard aGuard;
    IsObjectValid();
    // test whether the cell is hidden (column/row - hidden/filtered)
    sal_Bool bVisible(sal_True);
    if (mpDoc)
    {
        BYTE nColFlags = mpDoc->GetColFlags(maCellAddress.Col(), maCellAddress.Tab());
        BYTE nRowFlags = mpDoc->GetRowFlags(maCellAddress.Row(), maCellAddress.Tab());
        if (((nColFlags & CR_HIDDEN) == CR_HIDDEN) || ((nColFlags & CR_FILTERED) == CR_FILTERED) ||
            ((nRowFlags & CR_HIDDEN) == CR_HIDDEN) || ((nRowFlags & CR_FILTERED) == CR_FILTERED))
            bVisible = sal_False;
    }
    return bVisible;
}

sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground()
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    sal_Int32 nColor(0);
    if (mpDoc)
    {
        SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
        if ( pObjSh )
        {
            uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
            if ( xSpreadDoc.is() )
            {
                uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
                uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
                if ( xIndex.is() )
                {
                    uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
                    uno::Reference<sheet::XSpreadsheet> xTable;
                    if (aTable>>=xTable)
                    {
                        uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
                        if (xCell.is())
                        {
                            uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
                            if (xCellProps.is())
                            {
                                uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CCOLOR)));
                                aAny >>= nColor;
                            }
                        }
                    }
                }
            }
        }
    }
    return nColor;
}

sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground()
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    sal_Int32 nColor(0);

    if (mpDoc)
    {
        SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
        if ( pObjSh )
        {
            uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
            if ( xSpreadDoc.is() )
            {
                uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
                uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
                if ( xIndex.is() )
                {
                    uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
                    uno::Reference<sheet::XSpreadsheet> xTable;
                    if (aTable>>=xTable)
                    {
                        uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
                        if (xCell.is())
                        {
                            uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
                            if (xCellProps.is())
                            {
                                uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLBACK)));
                                aAny >>= nColor;
                            }
                        }
                    }
                }
            }
        }
    }

    return nColor;
}

    //=====  XInterface  =====================================================

uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType )
    throw (uno::RuntimeException)
{
    uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType));
    return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
}

void SAL_CALL ScAccessibleCellBase::acquire()
    throw ()
{
    ScAccessibleContextBase::acquire();
}

void SAL_CALL ScAccessibleCellBase::release()
    throw ()
{
    ScAccessibleContextBase::release();
}

    //=====  XAccessibleContext  ==============================================

sal_Int32
    ScAccessibleCellBase::getAccessibleIndexInParent(void)
        throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    return mnIndex;
}

::rtl::OUString SAL_CALL
    ScAccessibleCellBase::createAccessibleDescription(void)
    throw (uno::RuntimeException)
{
    rtl::OUString sDescription = String(ScResId(STR_ACC_CELL_DESCR));

    return sDescription;
}

::rtl::OUString SAL_CALL
    ScAccessibleCellBase::createAccessibleName(void)
    throw (uno::RuntimeException)
{
    String sName( ScResId(STR_ACC_CELL_NAME) );
    String sAddress;
    // Document not needed, because only the cell address, but not the tablename is needed
    // always us OOO notation
    maCellAddress.Format( sAddress, SCA_VALID, NULL );
    sName.SearchAndReplaceAscii("%1", sAddress);
    /*  #i65103# ZoomText merges cell address and contents, e.g. if value 2 is
        contained in cell A1, ZT reads "cell A twelve" instead of "cell A1 - 2".
        Simple solution: Append a space character to the cell address. */
    sName.Append( ' ' );
    return rtl::OUString(sName);
}

    //=====  XAccessibleValue  ================================================

uno::Any SAL_CALL
    ScAccessibleCellBase::getCurrentValue(  )
    throw (uno::RuntimeException)
{
     ScUnoGuard aGuard;
    IsObjectValid();
    uno::Any aAny;
    if (mpDoc)
        aAny <<= mpDoc->GetValue(maCellAddress);

    return aAny;
}

sal_Bool SAL_CALL
    ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber )
    throw (uno::RuntimeException)
{
     ScUnoGuard aGuard;
    IsObjectValid();
    double fValue = 0;
    sal_Bool bResult(sal_False);
    if((aNumber >>= fValue) && mpDoc && mpDoc->GetDocumentShell())
    {
        uno::Reference<XAccessibleStateSet> xParentStates;
        if (getAccessibleParent().is())
        {
            uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
            xParentStates = xParentContext->getAccessibleStateSet();
        }
        if (IsEditable(xParentStates))
        {
            ScDocShell* pDocShell = (ScDocShell*) mpDoc->GetDocumentShell();
            ScDocFunc aFunc(*pDocShell);
            bResult = aFunc.PutCell( maCellAddress, new ScValueCell(fValue), TRUE );
        }
    }
    return bResult;
}

uno::Any SAL_CALL
    ScAccessibleCellBase::getMaximumValue(  )
    throw (uno::RuntimeException)
{
    uno::Any aAny;
    aAny <<= DBL_MAX;

    return aAny;
}

uno::Any SAL_CALL
    ScAccessibleCellBase::getMinimumValue(  )
    throw (uno::RuntimeException)
{
    uno::Any aAny;
    aAny <<= -DBL_MAX;

    return aAny;
}

    //=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL ScAccessibleCellBase::getImplementationName(void)
        throw (uno::RuntimeException)
{
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCellBase"));
}

    //=====  XTypeProvider  ===================================================

uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes()
        throw (uno::RuntimeException)
{
    return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
}

uno::Sequence<sal_Int8> SAL_CALL
    ScAccessibleCellBase::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    static uno::Sequence<sal_Int8> aId;
    if (aId.getLength() == 0)
    {
        aId.realloc (16);
        rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
    }
    return aId;
}

sal_Bool ScAccessibleCellBase::IsEditable(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    sal_Bool bEditable(sal_False);
    if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE))
        bEditable = sal_True;
    return bEditable;
}
<commit_msg>INTEGRATION: CWS changefileheader (1.21.320); FILE MERGED 2008/04/01 15:30:34 thb 1.21.320.3: #i85898# Stripping all external header guards 2008/04/01 12:36:36 thb 1.21.320.2: #i85898# Stripping all external header guards 2008/03/31 17:15:06 rt 1.21.320.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: AccessibleCellBase.cxx,v $
 * $Revision: 1.22 $
 *
 * 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_sc.hxx"

#include "AccessibleCellBase.hxx"
#include "attrib.hxx"
#include "scitems.hxx"
#include "miscuno.hxx"
#include "document.hxx"
#include "docfunc.hxx"
#include "cell.hxx"
#include "unoguard.hxx"
#include "scresid.hxx"
#ifndef SC_SC_HRC
#include "sc.hrc"
#endif
#include "unonames.hxx"

#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
#include <com/sun/star/accessibility/AccessibleRole.hpp>
#endif
#ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
#include <com/sun/star/accessibility/AccessibleStateType.hpp>
#endif
#include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
#include <com/sun/star/sheet/XSpreadsheet.hpp>
#include <tools/debug.hxx>
#include <svx/brshitem.hxx>
#include <rtl/uuid.h>
#include <comphelper/sequence.hxx>
#include <sfx2/objsh.hxx>

#include <float.h>

using namespace ::com::sun::star;
using namespace ::com::sun::star::accessibility;

//=====  internal  ============================================================

ScAccessibleCellBase::ScAccessibleCellBase(
        const uno::Reference<XAccessible>& rxParent,
        ScDocument* pDoc,
        const ScAddress& rCellAddress,
        sal_Int32 nIndex)
    :
    ScAccessibleContextBase(rxParent, AccessibleRole::TABLE_CELL),
    maCellAddress(rCellAddress),
    mpDoc(pDoc),
    mnIndex(nIndex)
{
}

ScAccessibleCellBase::~ScAccessibleCellBase()
{
}

    //=====  XAccessibleComponent  ============================================

sal_Bool SAL_CALL ScAccessibleCellBase::isVisible(  )
        throw (uno::RuntimeException)
{
     ScUnoGuard aGuard;
    IsObjectValid();
    // test whether the cell is hidden (column/row - hidden/filtered)
    sal_Bool bVisible(sal_True);
    if (mpDoc)
    {
        BYTE nColFlags = mpDoc->GetColFlags(maCellAddress.Col(), maCellAddress.Tab());
        BYTE nRowFlags = mpDoc->GetRowFlags(maCellAddress.Row(), maCellAddress.Tab());
        if (((nColFlags & CR_HIDDEN) == CR_HIDDEN) || ((nColFlags & CR_FILTERED) == CR_FILTERED) ||
            ((nRowFlags & CR_HIDDEN) == CR_HIDDEN) || ((nRowFlags & CR_FILTERED) == CR_FILTERED))
            bVisible = sal_False;
    }
    return bVisible;
}

sal_Int32 SAL_CALL ScAccessibleCellBase::getForeground()
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    sal_Int32 nColor(0);
    if (mpDoc)
    {
        SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
        if ( pObjSh )
        {
            uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
            if ( xSpreadDoc.is() )
            {
                uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
                uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
                if ( xIndex.is() )
                {
                    uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
                    uno::Reference<sheet::XSpreadsheet> xTable;
                    if (aTable>>=xTable)
                    {
                        uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
                        if (xCell.is())
                        {
                            uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
                            if (xCellProps.is())
                            {
                                uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CCOLOR)));
                                aAny >>= nColor;
                            }
                        }
                    }
                }
            }
        }
    }
    return nColor;
}

sal_Int32 SAL_CALL ScAccessibleCellBase::getBackground()
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    sal_Int32 nColor(0);

    if (mpDoc)
    {
        SfxObjectShell* pObjSh = mpDoc->GetDocumentShell();
        if ( pObjSh )
        {
            uno::Reference <sheet::XSpreadsheetDocument> xSpreadDoc( pObjSh->GetModel(), uno::UNO_QUERY );
            if ( xSpreadDoc.is() )
            {
                uno::Reference<sheet::XSpreadsheets> xSheets = xSpreadDoc->getSheets();
                uno::Reference<container::XIndexAccess> xIndex( xSheets, uno::UNO_QUERY );
                if ( xIndex.is() )
                {
                    uno::Any aTable = xIndex->getByIndex(maCellAddress.Tab());
                    uno::Reference<sheet::XSpreadsheet> xTable;
                    if (aTable>>=xTable)
                    {
                        uno::Reference<table::XCell> xCell = xTable->getCellByPosition(maCellAddress.Col(), maCellAddress.Row());
                        if (xCell.is())
                        {
                            uno::Reference<beans::XPropertySet> xCellProps(xCell, uno::UNO_QUERY);
                            if (xCellProps.is())
                            {
                                uno::Any aAny = xCellProps->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_CELLBACK)));
                                aAny >>= nColor;
                            }
                        }
                    }
                }
            }
        }
    }

    return nColor;
}

    //=====  XInterface  =====================================================

uno::Any SAL_CALL ScAccessibleCellBase::queryInterface( uno::Type const & rType )
    throw (uno::RuntimeException)
{
    uno::Any aAny (ScAccessibleCellBaseImpl::queryInterface(rType));
    return aAny.hasValue() ? aAny : ScAccessibleContextBase::queryInterface(rType);
}

void SAL_CALL ScAccessibleCellBase::acquire()
    throw ()
{
    ScAccessibleContextBase::acquire();
}

void SAL_CALL ScAccessibleCellBase::release()
    throw ()
{
    ScAccessibleContextBase::release();
}

    //=====  XAccessibleContext  ==============================================

sal_Int32
    ScAccessibleCellBase::getAccessibleIndexInParent(void)
        throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    return mnIndex;
}

::rtl::OUString SAL_CALL
    ScAccessibleCellBase::createAccessibleDescription(void)
    throw (uno::RuntimeException)
{
    rtl::OUString sDescription = String(ScResId(STR_ACC_CELL_DESCR));

    return sDescription;
}

::rtl::OUString SAL_CALL
    ScAccessibleCellBase::createAccessibleName(void)
    throw (uno::RuntimeException)
{
    String sName( ScResId(STR_ACC_CELL_NAME) );
    String sAddress;
    // Document not needed, because only the cell address, but not the tablename is needed
    // always us OOO notation
    maCellAddress.Format( sAddress, SCA_VALID, NULL );
    sName.SearchAndReplaceAscii("%1", sAddress);
    /*  #i65103# ZoomText merges cell address and contents, e.g. if value 2 is
        contained in cell A1, ZT reads "cell A twelve" instead of "cell A1 - 2".
        Simple solution: Append a space character to the cell address. */
    sName.Append( ' ' );
    return rtl::OUString(sName);
}

    //=====  XAccessibleValue  ================================================

uno::Any SAL_CALL
    ScAccessibleCellBase::getCurrentValue(  )
    throw (uno::RuntimeException)
{
     ScUnoGuard aGuard;
    IsObjectValid();
    uno::Any aAny;
    if (mpDoc)
        aAny <<= mpDoc->GetValue(maCellAddress);

    return aAny;
}

sal_Bool SAL_CALL
    ScAccessibleCellBase::setCurrentValue( const uno::Any& aNumber )
    throw (uno::RuntimeException)
{
     ScUnoGuard aGuard;
    IsObjectValid();
    double fValue = 0;
    sal_Bool bResult(sal_False);
    if((aNumber >>= fValue) && mpDoc && mpDoc->GetDocumentShell())
    {
        uno::Reference<XAccessibleStateSet> xParentStates;
        if (getAccessibleParent().is())
        {
            uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
            xParentStates = xParentContext->getAccessibleStateSet();
        }
        if (IsEditable(xParentStates))
        {
            ScDocShell* pDocShell = (ScDocShell*) mpDoc->GetDocumentShell();
            ScDocFunc aFunc(*pDocShell);
            bResult = aFunc.PutCell( maCellAddress, new ScValueCell(fValue), TRUE );
        }
    }
    return bResult;
}

uno::Any SAL_CALL
    ScAccessibleCellBase::getMaximumValue(  )
    throw (uno::RuntimeException)
{
    uno::Any aAny;
    aAny <<= DBL_MAX;

    return aAny;
}

uno::Any SAL_CALL
    ScAccessibleCellBase::getMinimumValue(  )
    throw (uno::RuntimeException)
{
    uno::Any aAny;
    aAny <<= -DBL_MAX;

    return aAny;
}

    //=====  XServiceInfo  ====================================================

::rtl::OUString SAL_CALL ScAccessibleCellBase::getImplementationName(void)
        throw (uno::RuntimeException)
{
    return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleCellBase"));
}

    //=====  XTypeProvider  ===================================================

uno::Sequence< uno::Type > SAL_CALL ScAccessibleCellBase::getTypes()
        throw (uno::RuntimeException)
{
    return comphelper::concatSequences(ScAccessibleCellBaseImpl::getTypes(), ScAccessibleContextBase::getTypes());
}

uno::Sequence<sal_Int8> SAL_CALL
    ScAccessibleCellBase::getImplementationId(void)
    throw (uno::RuntimeException)
{
    ScUnoGuard aGuard;
    IsObjectValid();
    static uno::Sequence<sal_Int8> aId;
    if (aId.getLength() == 0)
    {
        aId.realloc (16);
        rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
    }
    return aId;
}

sal_Bool ScAccessibleCellBase::IsEditable(
    const uno::Reference<XAccessibleStateSet>& rxParentStates)
{
    sal_Bool bEditable(sal_False);
    if (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::EDITABLE))
        bEditable = sal_True;
    return bEditable;
}
<|endoftext|>


<commit_before>#include "SpliceGraph.h"
#include "sjAlignSplit.h"

void SpliceGraph::findSuperTr(const char *readSeq, const char *readSeqRevCompl, const uint32 readLen, const string &readName, Genome &mapGen)
{//find the candidate superTranscripts: seed-and-rank algorithm implemented

	//hardcoded for now
	float seedCoverageThreshold = 0.1;
	float seedCoverageMinToMax = 0.1;
	uint32 seedMultMax = 200;

	//readLen, readSeq
    uint32 seedLen=mapGen.pGe.gSAindexNbases; //TODO: make user-definable
    memset(superTrSeedCount,0,sizeof(superTrSeedCount[0])*2*superTr.N);

    for (uint32 iseed=0; iseed<readLen/seedLen; iseed++) {//loop through seeds
        //calculate index
        uint64 ind1=0;
        for (uint32 ii=iseed*seedLen; ii<(iseed+1)*seedLen; ii++) {
            uint b=(uint64) readSeq[ii];
            if (b>3) {//N
                continue; //no mapping for seeds with Ns
            } else {
                ind1 <<= 2;
                ind1 += b;
            };
        };
        //find seed boundaries in SA
        uint64 iSA1=mapGen.SAi[mapGen.genomeSAindexStart[seedLen-1]+ind1]; // starting point for suffix array search.
        if ( (iSA1 & mapGen.SAiMarkAbsentMaskC) != 0) {//prefix does not exist, skip this seed
            continue;
        };
        uint64 iSA2;
        if (mapGen.genomeSAindexStart[seedLen-1]+ind1+1 < mapGen.genomeSAindexStart[seedLen]) {//we are not at the end of the SA
            iSA2=((mapGen.SAi[mapGen.genomeSAindexStart[seedLen-1]+ind1+1] & mapGen.SAiMarkNmask) & mapGen.SAiMarkAbsentMask) - 1;
        } else {
            iSA2=mapGen.nSA-1;
        };

		if (iSA2-iSA1>=seedMultMax) //this seed map too many times
			continue;

        for (uint64 isa=iSA1;isa<=iSA2;isa++) {//loop through seed SA boundaries
            uint64 a1 = mapGen.SA[isa];
            uint64 aStr = a1 >> mapGen.GstrandBit;
            a1 = a1 & mapGen.GstrandMask; //remove strand bit
            if (aStr==1)
                a1 = mapGen.nGenome - (seedLen+a1);

            if (a1>=mapGen.sjGstart) {//this is sj align. Probably do not need it...
                uint64 a1D, aLengthD, a1A, aLengthA, sj1;
                if ( sjAlignSplit(a1, seedLen, mapGen, a1D, aLengthD, a1A, aLengthA, sj1) ) {//if align crosses the junction, replace a1 with a1D
                    a1=a1D;
                } else {
                    continue;//this align does not cross the junction, no need to contine
                };
            };

            superTrSeedCount[aStr*superTr.N  + mapGen.chrBin[a1 >> mapGen.pGe.gChrBinNbits]]++;
        };//loop through seed SA boundaries
    };//loop through seeds

    //find max coverage
    typeSuperTrSeedCount countMax=0;
	//float countOverSuperTrLenMax=0;
    for (uint32 ii=0; ii<2*superTr.N; ii++) {
        countMax=max(superTrSeedCount[ii], countMax);
		//countOverSuperTrLenMax=max(superTrSeedCount[ii]/float(superTr.length[ii%superTr.N]), countOverSuperTrLenMax);
    };

    if (countMax*seedLen<readLen*seedCoverageThreshold)//no good candidates, hard-coded for now
        return;

    for (uint32 ii=0; ii<superTr.N; ii++) {//selection cycle

        uint32 sutr1=ii%superTr.N;
        uint32 str1=ii/superTr.N;

        if (superTrSeedCount[ii]<countMax*seedCoverageMinToMax)
		//if (superTrSeedCount[ii]<countOverSuperTrLenMax*superTr.length[sutr1]*seedCoverageMinToMax)
			continue;

		if (superTr.length[sutr1]>=100000) //temporary restriction: will lift after redoing the scoringMatrix
			continue;

        array<uint32,2> alignEnds, alignStarts;

		uint32 swScore = 0;
        //swScore = swScoreSpliced((str1==0 ? readSeq : readSeqRevCompl), readLen, sutr1, alignEnds);

        //swTraceBack(alignEnds, alignStarts);
		//float(superTrSeedCount[ii])/countMax
		//float(superTrSeedCount[ii])/superTr.length[sutr1]/countOverSuperTrLenMax <<'\t'<<

		cout << readName <<'\t'<< sutr1 <<'\t'<< str1 <<'\t'<< superTr.length[sutr1] <<'\t'<< readLen <<'\t'<< float(superTrSeedCount[ii])/readLen*seedLen <<'\t'<<
				float(superTrSeedCount[ii])/countMax <<'\t'<<
                swScore <<'\t'<< float(swScore)/readLen <<'\t'<< alignStarts[0] <<'\t'<< alignEnds[0] <<'\t'<< alignStarts[1] <<'\t'<< alignEnds[1] << endl;

    };

    return;
};

<commit_msg>Multiple seed matches to the same superTr are counted only once. Minor improvement in performance.<commit_after>#include "SpliceGraph.h"
#include "sjAlignSplit.h"

void SpliceGraph::findSuperTr(const char *readSeq, const char *readSeqRevCompl, const uint32 readLen, const string &readName, Genome &mapGen)
{//find the candidate superTranscripts: seed-and-rank algorithm implemented

	//hardcoded for now
	float seedCoverageThreshold = 0.1;
	float seedCoverageMinToMax = 0.1;
	uint32 seedMultMax = 200;

	vector<uint32> seedSuperTr;
	seedSuperTr.reserve(seedMultMax);

	//readLen, readSeq
    uint32 seedLen=mapGen.pGe.gSAindexNbases; //TODO: make user-definable
    memset(superTrSeedCount,0,sizeof(superTrSeedCount[0])*2*superTr.N);

    for (uint32 iseed=0; iseed<readLen/seedLen; iseed++) {//loop through seeds
        //calculate index
        uint64 ind1=0;
        for (uint32 ii=iseed*seedLen; ii<(iseed+1)*seedLen; ii++) {
            uint b=(uint64) readSeq[ii];
            if (b>3) {//N
                continue; //no mapping for seeds with Ns
            } else {
                ind1 <<= 2;
                ind1 += b;
            };
        };
        //find seed boundaries in SA
        uint64 iSA1=mapGen.SAi[mapGen.genomeSAindexStart[seedLen-1]+ind1]; // starting point for suffix array search.
        if ( (iSA1 & mapGen.SAiMarkAbsentMaskC) != 0) {//prefix does not exist, skip this seed
            continue;
        };
        uint64 iSA2;
        if (mapGen.genomeSAindexStart[seedLen-1]+ind1+1 < mapGen.genomeSAindexStart[seedLen]) {//we are not at the end of the SA
            iSA2=((mapGen.SAi[mapGen.genomeSAindexStart[seedLen-1]+ind1+1] & mapGen.SAiMarkNmask) & mapGen.SAiMarkAbsentMask) - 1;
        } else {
            iSA2=mapGen.nSA-1;
        };

		if (iSA2-iSA1>=seedMultMax) //this seed map too many times
			continue;

		seedSuperTr.clear();
		seedSuperTr.resize(iSA2-iSA1+1);
        for (uint64 isa=iSA1;isa<=iSA2;isa++) {//loop through seed SA boundaries
            uint64 a1 = mapGen.SA[isa];
            uint64 aStr = a1 >> mapGen.GstrandBit;
            a1 = a1 & mapGen.GstrandMask; //remove strand bit
            if (aStr==1)
                a1 = mapGen.nGenome - (seedLen+a1);

            if (a1>=mapGen.sjGstart) {//this is sj align. Probably do not need it...
                uint64 a1D, aLengthD, a1A, aLengthA, sj1;
                if ( sjAlignSplit(a1, seedLen, mapGen, a1D, aLengthD, a1A, aLengthA, sj1) ) {//if align crosses the junction, replace a1 with a1D
                    a1=a1D;
                } else {
                    continue;//this align does not cross the junction, no need to contine
                };
            };

            seedSuperTr[isa-iSA1]=(uint32)(aStr*superTr.N  + mapGen.chrBin[a1 >> mapGen.pGe.gChrBinNbits]);
        };//loop through seed SA boundaries

		sort(seedSuperTr.begin(),seedSuperTr.end());
		uint32 su1prev=(uint32)-1;
		for (auto &su1 : seedSuperTr) {//this will eliminate multiple matches of the same seed into the same suTr
			if (su1!=su1prev) {
				superTrSeedCount[su1]++;
				su1prev=su1;
			};
		};

    };//loop through seeds

    //find max coverage
    typeSuperTrSeedCount countMax=0;
	//float countOverSuperTrLenMax=0;
    for (uint32 ii=0; ii<2*superTr.N; ii++) {
        countMax=max(superTrSeedCount[ii], countMax);
		//countOverSuperTrLenMax=max(superTrSeedCount[ii]/float(superTr.length[ii%superTr.N]), countOverSuperTrLenMax);
    };

    if (countMax*seedLen<readLen*seedCoverageThreshold)//no good candidates, hard-coded for now
        return;

    for (uint32 ii=0; ii<superTr.N; ii++) {//selection cycle

        uint32 sutr1=ii%superTr.N;
        uint32 str1=ii/superTr.N;

        if (superTrSeedCount[ii]<countMax*seedCoverageMinToMax)
		//if (superTrSeedCount[ii]<countOverSuperTrLenMax*superTr.length[sutr1]*seedCoverageMinToMax)
			continue;

		if (superTr.length[sutr1]>=100000) //temporary restriction: will lift after redoing the scoringMatrix
			continue;

        array<uint32,2> alignEnds, alignStarts;

		uint32 swScore = 0;
        //swScore = swScoreSpliced((str1==0 ? readSeq : readSeqRevCompl), readLen, sutr1, alignEnds);

        //swTraceBack(alignEnds, alignStarts);
		//float(superTrSeedCount[ii])/countMax
		//float(superTrSeedCount[ii])/superTr.length[sutr1]/countOverSuperTrLenMax <<'\t'<<

		cout << readName <<'\t'<< sutr1 <<'\t'<< str1 <<'\t'<< superTr.length[sutr1] <<'\t'<< readLen <<'\t'<< float(superTrSeedCount[ii])/readLen*seedLen <<'\t'<<
				float(superTrSeedCount[ii])/countMax <<'\t'<<
                swScore <<'\t'<< float(swScore)/readLen <<'\t'<< alignStarts[0] <<'\t'<< alignEnds[0] <<'\t'<< alignStarts[1] <<'\t'<< alignEnds[1] << endl;

    };

    return;
};

<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <queue>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <google/protobuf/io/coded_stream.h>
#include "message.pb.h"

using namespace boost::asio;
using ru::spbau::chat::commons::protocol::Message;
using google::protobuf::io::CodedInputStream;
using google::protobuf::io::CodedOutputStream;
using google::protobuf::uint8;
using google::protobuf::uint32;

typedef std::pair<size_t, std::shared_ptr<uint8>> serialized_message;

#ifdef DEBUG
static size_t const INITIAL_BUFFER_SIZE = 1 << 2; // 4 b
#else
static size_t const INITIAL_BUFFER_SIZE = 1 << 12; // 4 Kb
#endif
static size_t const MESSAGES_IN_QUEUE_TO_FALLBACK = 1 << 8; // 256
static size_t const MESSAGES_SUM_SIZE_TO_FALLBACK = 1 << 12; // 4 Kb
static size_t const MAX_VARINT_BYTES = 10;

class chat_user
{
public:
    virtual void accept_message_size() = 0;
    virtual bool deliver_message(serialized_message const &message) = 0;
};
typedef std::shared_ptr<chat_user> user_ptr;

serialized_message serialize_message(Message const &message)
{
    size_t msg_size = message.ByteSize();
    size_t size = msg_size + MAX_VARINT_BYTES;
    std::shared_ptr<uint8> buffer(new uint8[size]);
    auto it = CodedOutputStream::WriteVarint32ToArray(msg_size, buffer.get());
    bool written = message.SerializeToArray(it, msg_size);
    assert(written);
    return serialized_message(msg_size + (it - buffer.get()), buffer);
}

class chat_room
{
public:
    chat_room()
    {
    }

    void add_new_user(user_ptr user)
    {
        rw_mutex.lock();
        users.push_back(user);
        rw_mutex.unlock();
#ifdef DEBUG
        std::cout << "User connected" << std::endl;
#endif
        user->accept_message_size();
    }

    void on_user_leave(user_ptr user)
    {
        rw_mutex.lock();
        auto pos = std::find_if(users.begin(), users.end(), [user](user_ptr &ptr)
        {
            return ptr.get() == user.get();
        });
        if (pos != users.end())
        {
            users.erase(pos);
        }
        rw_mutex.unlock();
#ifdef DEBUG
        std::cout << "User leaved" << std::endl;
#endif
    }

    size_t deliver_message_to_all(Message const &message, chat_user const *from_user)
    {
        serialized_message message_serialized(serialize_message(message));
        size_t overflow_queues = 0;
        rw_mutex.lock_shared();
        for(auto &user_p: users)
        {
            if (user_p.get() == from_user)
            {
                continue;
            }
            overflow_queues += user_p->deliver_message(message_serialized);
        }
        rw_mutex.unlock_shared();
        return overflow_queues;
    }

private:
    std::vector<user_ptr> users;
    boost::shared_mutex rw_mutex;
};

class user :
        public chat_user,
        public std::enable_shared_from_this<user>
{
public:
    user(ip::tcp::socket sock, chat_room &chat, io_service &service)
        :
            socket(std::move(sock)),
            chat(chat),
            service(service),
            message_buffer(std::max(INITIAL_BUFFER_SIZE, MAX_VARINT_BYTES)),
            buffer_offset(0),
            buffer_red(0),
            write_buffer(std::max(INITIAL_BUFFER_SIZE, MAX_VARINT_BYTES)),
            messages_sum_size(0),
            write_in_progress(false)
    {
    }

    void accept_message_size()
    {
        check_enougth_space(MAX_VARINT_BYTES);

        if (buffer_red)
        {
            bool read_succ;
            size_t read_bytes_count;
            uint32 message_size;
            {
                CodedInputStream input(message_buffer.data() + buffer_offset, buffer_red);
                read_succ = input.ReadVarint32(&message_size);
                read_bytes_count = input.CurrentPosition();
            }
            if (read_succ)
            {
                buffer_offset += read_bytes_count;
                buffer_red -= read_bytes_count;
                accept_message(message_size);
                return;
            }
            if (buffer_red > MAX_VARINT_BYTES)
            {
#ifdef DEBUG
                std::cout << "invalid varint: " << std::endl;
#endif
                chat.on_user_leave(shared_from_this());
                return;
            }
        }

        auto ancor(shared_from_this());
        async_read(socket, buffer(message_buffer.data() + buffer_offset + buffer_red,
                                  message_buffer.size() - buffer_offset - buffer_red),
            transfer_at_least(1),
            [this, ancor](boost::system::error_code ec, std::size_t bytes_red)
            {
#ifdef DEBUG
                std::cout << "Reading message size: bytes red "
                          << buffer_red + bytes_red << std::endl;
#endif
                if (ec)
                {
#ifdef DEBUG
                    std::cout << "error on reading message_size: " << ec.message() << std::endl;
#endif
                    chat.on_user_leave(shared_from_this());
                    return;
                } else {
                    buffer_red += bytes_red;
                    accept_message_size();
                }
            });
    }

    void accept_message(uint32 message_size)
    {
        check_enougth_space(message_size);

        if (buffer_red >= message_size)
        {
            Message message;
            try
            {
                message.ParseFromArray(message_buffer.data() + buffer_offset,
                                       message_size);
            } catch (std::exception &) {
    #ifdef DEBUG
                std::cout << "Failed to parse protobuf message" << std::endl;
    #endif
                chat.on_user_leave(shared_from_this());
                return;
            }
            buffer_offset += message_size;
            buffer_red -= message_size;

#ifdef DEBUG
            std::cout << "message red ["
                      << (message.has_type() ? message.type() : -1) << ", "
                      << (message.has_author() ? message.author() : "no author") << ", "
                      << (message.text_size() ? message.text(0) : "no text")
                      << "]" << std::endl;
#endif
            if (message.type() == Message::COMMAND)
            {
                std::cout << "Command!!" << std::endl;
            } else {
                size_t busy_factor = chat.deliver_message_to_all(message, this);
                for (size_t idx = 0; idx < busy_factor; ++idx)
                {
                    if (!service.poll_one())
                    {
                        break;
                    }
                }
            }
            accept_message_size();
            return;
        }

        auto ancor(shared_from_this());
        async_read(socket, buffer(message_buffer.data() + buffer_offset + buffer_red,
                                  message_buffer.size() - buffer_offset - buffer_red),
            transfer_at_least(message_size - buffer_red),
            [this, ancor, message_size](boost::system::error_code ec, std::size_t bytes_red)
            {
#ifdef DEBUG
                std::cout << "Reading message: bytes red "
                          << buffer_red + bytes_red << " from "
                          << message_size << std::endl;
#endif
                if (ec)
                {
#ifdef DEBUG
                    std::cout << "error: " << ec.message() << std::endl;
#endif
                    chat.on_user_leave(shared_from_this());
                    return;
                } else {
                    buffer_red += bytes_red;
                    accept_message(message_size);
                }
            });
    }

    bool deliver_message(serialized_message const &message)
    {
        boost::lock_guard<boost::mutex> guard(deliver_queue_mutex);
        messages_to_deliver.push(message);
        if (!write_in_progress)
        {
            write_in_progress = true;
            auto ancor(shared_from_this());
            service.post([this, ancor](){do_write();});
        }
        messages_sum_size += message.first;
        return messages_to_deliver.size() >= MESSAGES_IN_QUEUE_TO_FALLBACK ||
               messages_sum_size >= MESSAGES_SUM_SIZE_TO_FALLBACK;
    }

    ~user()
    {
#ifdef DEBUG
        std::cout << "user destroyed" << std::endl;
#endif
    }

private:
    void check_enougth_space(size_t space_needed)
    {
        assert(buffer_offset + buffer_red <= message_buffer.size());
        if (!buffer_red)
        {
            buffer_offset = 0;
        }
        if (buffer_offset + space_needed <= message_buffer.size())
        {
            return;
        }
        memmove(message_buffer.data(), message_buffer.data() + buffer_offset, buffer_red);
        buffer_offset = 0;
        if (space_needed > message_buffer.size())
        {
            message_buffer.resize(space_needed);
        }
    }

    void do_write()
    {
        boost::lock_guard<boost::mutex> guard(deliver_queue_mutex);
        size_t min_size = messages_to_deliver.front().first;
        if (write_buffer.size() < min_size)
        {
            write_buffer.resize(min_size);
        }
        size_t write_buffer_offset = 0;
        while (!messages_to_deliver.empty())
        {
            serialized_message const &message = messages_to_deliver.front();
            if (message.first > write_buffer.size() - write_buffer_offset)
            {
                break;
            }
#ifdef DEBUG
            std::cout << "message written" << std::endl;
#endif
            memcpy(write_buffer.data() + write_buffer_offset, message.second.get(), message.first);
            write_buffer_offset += message.first;
            messages_sum_size -= message.first;
            messages_to_deliver.pop();
        }

        auto ancor(shared_from_this());
        async_write(socket, buffer(write_buffer.data(), write_buffer_offset),
                    [this, ancor](boost::system::error_code ec, std::size_t)
        {
            if (ec)
            {
#ifdef DEBUG
                std::cout << "error writing: " << ec.message() << std::endl;
#endif
                chat.on_user_leave(shared_from_this());
                return;
            } else {
                {
                    boost::lock_guard<boost::mutex> guard(deliver_queue_mutex);
                    if (messages_to_deliver.empty())
                    {
                        write_in_progress = false;
                        return;
                    }
                }
                do_write();
            }
        });

    }

private:
    ip::tcp::socket socket;
    chat_room &chat;
    io_service &service;
    std::vector<uint8> message_buffer;
    size_t buffer_offset;
    size_t buffer_red;
    std::vector<uint8> write_buffer;
    std::queue<serialized_message> messages_to_deliver;
    boost::mutex deliver_queue_mutex;
    size_t messages_sum_size;
    bool write_in_progress;
};

class connection_handler
{
public:
    connection_handler(io_service &service, int port, chat_room &chat)
        :
          sock(service),
          service(service),
          acc(service, ip::tcp::endpoint(ip::tcp::v4(), port)),
          chat(chat)
    {
    }

public:
    void accept_new_connection()
    {
        acc.async_accept(sock, [this](boost::system::error_code)
        {
            if (sock.is_open())
            {
                sock.set_option(ip::tcp::no_delay(true));
                chat.add_new_user(std::make_shared<user>(std::move(sock), chat, service));
            }
            accept_new_connection();
        });
    }

private:
    ip::tcp::socket sock;
    io_service &service;
    ip::tcp::acceptor acc;
    chat_room &chat;
};

int main(int argc, char *argv[])
{
    if (argc < 3) {
        std::cout
                << "Usage: ./chat_server $PORT_NUMBER$ $CONCURRENCY_LEVEL$"
                << std::endl
                << "Where $CONCURRENCY_LEVEL$ - number of the worker threads"
                << std::endl;
        return -1;
    }
    size_t port = std::atoi(argv[1]);
    size_t concurrency_level = std::atoi(argv[2]);

    try
    {
        std::cout << "Starting chat server on port "
                  << port
                  << " with concurrency level "
                  << concurrency_level
                  << " ..."
                  << std::endl;

        io_service service(concurrency_level);
        chat_room chat;

        connection_handler handler(service, port, chat);
        handler.accept_new_connection();

        boost::thread_group workers;
        auto const worker =
                boost::bind(&io_service::run, &service);
        for (size_t idx = 0; idx < concurrency_level; ++idx)
        {
            workers.create_thread(worker);
        }

        std::cout << "The server is started" << std::endl;
        std::cout << "Press 'enter' to stop the server"
                  << std::endl;
        std::cin.get();
        std::cout << "Stopping the server..." << std::endl;
        service.stop();
        workers.join_all();
        std::cout << "The server is stopped" << std::endl;
    } catch(std::exception &e) {
        std::cerr << "An exception occured with ";
        if (e.what()) {
            std::cerr << "message: \"" << e.what() << '"';
        } else {
            std::cerr << "no message";
        }
        std::cerr << std::endl;
        google::protobuf::ShutdownProtobufLibrary();
        return -1;
    }

    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}

<commit_msg>Command execution implemented<commit_after>#include <iostream>
#include <vector>
#include <set>
#include <algorithm>
#include <queue>
#include <boost/thread/executors/basic_thread_pool.hpp>
#include <boost/asio.hpp>
#include <boost/thread.hpp>
#include <google/protobuf/io/coded_stream.h>
#include "message.pb.h"

/*******************************************************************
 * Configuration****************************************************
********************************************************************/
static std::string const CHAT_SERVER_AUTOR = "Chat server";
#ifdef DEBUG
static size_t const INITIAL_BUFFER_SIZE = 1 << 2; // 4 b
#else
static size_t const INITIAL_BUFFER_SIZE = 1 << 12; // 4 Kb
#endif
static size_t const MESSAGES_IN_QUEUE_TO_FALLBACK = 1 << 8; // 256
static size_t const MESSAGES_SUM_SIZE_TO_FALLBACK = 1 << 12; // 4 Kb
static size_t const MAX_VARINT_BYTES = 10;
/*******************************************************************/

using namespace boost::asio;
using ru::spbau::chat::commons::protocol::Message;
using google::protobuf::io::CodedInputStream;
using google::protobuf::io::CodedOutputStream;
using google::protobuf::uint8;
using google::protobuf::uint32;

typedef std::pair<size_t, std::shared_ptr<uint8>> serialized_message;

class chat_user
{
public:
    virtual void accept_message_size() = 0;
    virtual bool deliver_message(serialized_message const &message) = 0;
};
typedef std::shared_ptr<chat_user> user_ptr;

serialized_message serialize_message(Message const &message)
{
    size_t msg_size = message.ByteSize();
    size_t size = msg_size + MAX_VARINT_BYTES;
    std::shared_ptr<uint8> buffer(new uint8[size]);
    auto it = CodedOutputStream::WriteVarint32ToArray(msg_size, buffer.get());
    bool written = message.SerializeToArray(it, msg_size);
    assert(written);
    return serialized_message(msg_size + (it - buffer.get()), buffer);
}

class chat_room
{
public:
    chat_room()
        :
          command_executor(1)
    {
    }

    void add_new_user(user_ptr user)
    {
        rw_mutex.lock();
        users.push_back(user);
        rw_mutex.unlock();
#ifdef DEBUG
        std::cout << "User connected" << std::endl;
#endif
        user->accept_message_size();
    }

    void on_user_leave(user_ptr user)
    {
        rw_mutex.lock();
        auto pos = std::find_if(users.begin(), users.end(), [user](user_ptr &ptr)
        {
            return ptr.get() == user.get();
        });
        if (pos != users.end())
        {
            users.erase(pos);
        }
        rw_mutex.unlock();
#ifdef DEBUG
        std::cout << "User leaved" << std::endl;
#endif
    }

    size_t deliver_message_to_all(Message const &message, chat_user const *from_user)
    {
        serialized_message message_serialized(serialize_message(message));
        size_t overflow_queues = 0;
        rw_mutex.lock_shared();
        for(auto &user_p: users)
        {
            if (user_p.get() == from_user)
            {
                continue;
            }
            overflow_queues += user_p->deliver_message(message_serialized);
        }
        rw_mutex.unlock_shared();
        return overflow_queues;
    }

    void execute_command(std::string cmd, user_ptr user_to_send_result)
    {
        command_executor.submit([user_to_send_result, cmd]()
        {
            Message result;
            result.set_type(Message::MESSAGE);
            result.set_author(CHAT_SERVER_AUTOR);

            std::shared_ptr<FILE> pipe(popen(cmd.c_str(), "r"), pclose);
            char buffer[128];
            std::string result_str;
            if (pipe)
            {
                while (!feof(pipe.get())) {
                    if (fgets(buffer, 128, pipe.get()) == NULL)
                    {
                        break;
                    }
                    result_str += buffer;
                    if (result_str.back() == '\n')
                    {
                        result_str.pop_back();
                        result.add_text(std::move(result_str));
                        result_str.clear();
                    }
                }
                if (result_str.size())
                {
                    result.add_text(result_str);
                }
            } else {
                result.add_text("Command '" + cmd + "'' execution failed!");
            }

            user_to_send_result->deliver_message(serialize_message(result));
        });
    }

private:
    std::vector<user_ptr> users;
    boost::shared_mutex rw_mutex;
    boost::executors::basic_thread_pool command_executor;
};

class user :
        public chat_user,
        public std::enable_shared_from_this<user>
{
public:
    user(ip::tcp::socket sock, chat_room &chat, io_service &service)
        :
            socket(std::move(sock)),
            chat(chat),
            service(service),
            message_buffer(std::max(INITIAL_BUFFER_SIZE, MAX_VARINT_BYTES)),
            buffer_offset(0),
            buffer_red(0),
            write_buffer(std::max(INITIAL_BUFFER_SIZE, MAX_VARINT_BYTES)),
            messages_sum_size(0),
            write_in_progress(false)
    {
    }

    void accept_message_size()
    {
        check_enougth_space(MAX_VARINT_BYTES);

        if (buffer_red)
        {
            bool read_succ;
            size_t read_bytes_count;
            uint32 message_size;
            {
                CodedInputStream input(message_buffer.data() + buffer_offset, buffer_red);
                read_succ = input.ReadVarint32(&message_size);
                read_bytes_count = input.CurrentPosition();
            }
            if (read_succ)
            {
                buffer_offset += read_bytes_count;
                buffer_red -= read_bytes_count;
                accept_message(message_size);
                return;
            }
            if (buffer_red > MAX_VARINT_BYTES)
            {
#ifdef DEBUG
                std::cout << "invalid varint: " << std::endl;
#endif
                chat.on_user_leave(shared_from_this());
                return;
            }
        }

        auto ancor(shared_from_this());
        async_read(socket, buffer(message_buffer.data() + buffer_offset + buffer_red,
                                  message_buffer.size() - buffer_offset - buffer_red),
            transfer_at_least(1),
            [this, ancor](boost::system::error_code ec, std::size_t bytes_red)
            {
#ifdef DEBUG
                std::cout << "Reading message size: bytes red "
                          << buffer_red + bytes_red << std::endl;
#endif
                if (ec)
                {
#ifdef DEBUG
                    std::cout << "error on reading message_size: " << ec.message() << std::endl;
#endif
                    chat.on_user_leave(shared_from_this());
                    return;
                } else {
                    buffer_red += bytes_red;
                    accept_message_size();
                }
            });
    }

    void accept_message(uint32 message_size)
    {
        check_enougth_space(message_size);

        if (buffer_red >= message_size)
        {
            Message message;
            try
            {
                message.ParseFromArray(message_buffer.data() + buffer_offset,
                                       message_size);
            } catch (std::exception &) {
    #ifdef DEBUG
                std::cout << "Failed to parse protobuf message" << std::endl;
    #endif
                chat.on_user_leave(shared_from_this());
                return;
            }
            buffer_offset += message_size;
            buffer_red -= message_size;

#ifdef DEBUG
            std::cout << "message red ["
                      << (message.has_type() ? message.type() : -1) << ", "
                      << (message.has_author() ? message.author() : "no author") << ", "
                      << (message.text_size() ? message.text(0) : "no text")
                      << "]" << std::endl;
#endif
            if (message.type() == Message::COMMAND)
            {
                chat.execute_command(message.text(0), shared_from_this());
            } else {
                size_t busy_factor = chat.deliver_message_to_all(message, this);
                for (size_t idx = 0; idx < busy_factor; ++idx)
                {
                    if (!service.poll_one())
                    {
                        break;
                    }
                }
            }
            accept_message_size();
            return;
        }

        auto ancor(shared_from_this());
        async_read(socket, buffer(message_buffer.data() + buffer_offset + buffer_red,
                                  message_buffer.size() - buffer_offset - buffer_red),
            transfer_at_least(message_size - buffer_red),
            [this, ancor, message_size](boost::system::error_code ec, std::size_t bytes_red)
            {
#ifdef DEBUG
                std::cout << "Reading message: bytes red "
                          << buffer_red + bytes_red << " from "
                          << message_size << std::endl;
#endif
                if (ec)
                {
#ifdef DEBUG
                    std::cout << "error: " << ec.message() << std::endl;
#endif
                    chat.on_user_leave(shared_from_this());
                    return;
                } else {
                    buffer_red += bytes_red;
                    accept_message(message_size);
                }
            });
    }

    bool deliver_message(serialized_message const &message)
    {
        boost::lock_guard<boost::mutex> guard(deliver_queue_mutex);
        messages_to_deliver.push(message);
        if (!write_in_progress)
        {
            write_in_progress = true;
            auto ancor(shared_from_this());
            service.post([this, ancor](){do_write();});
        }
        messages_sum_size += message.first;
        return messages_to_deliver.size() >= MESSAGES_IN_QUEUE_TO_FALLBACK ||
               messages_sum_size >= MESSAGES_SUM_SIZE_TO_FALLBACK;
    }

    ~user()
    {
#ifdef DEBUG
        std::cout << "user destroyed" << std::endl;
#endif
    }

private:
    void check_enougth_space(size_t space_needed)
    {
        assert(buffer_offset + buffer_red <= message_buffer.size());
        if (!buffer_red)
        {
            buffer_offset = 0;
        }
        if (buffer_offset + space_needed <= message_buffer.size())
        {
            return;
        }
        memmove(message_buffer.data(), message_buffer.data() + buffer_offset, buffer_red);
        buffer_offset = 0;
        if (space_needed > message_buffer.size())
        {
            message_buffer.resize(space_needed);
        }
    }

    void do_write()
    {
        boost::lock_guard<boost::mutex> guard(deliver_queue_mutex);
        size_t min_size = messages_to_deliver.front().first;
        if (write_buffer.size() < min_size)
        {
            write_buffer.resize(min_size);
        }
        size_t write_buffer_offset = 0;
        while (!messages_to_deliver.empty())
        {
            serialized_message const &message = messages_to_deliver.front();
            if (message.first > write_buffer.size() - write_buffer_offset)
            {
                break;
            }
#ifdef DEBUG
            std::cout << "message written" << std::endl;
#endif
            memcpy(write_buffer.data() + write_buffer_offset, message.second.get(), message.first);
            write_buffer_offset += message.first;
            messages_sum_size -= message.first;
            messages_to_deliver.pop();
        }

        auto ancor(shared_from_this());
        async_write(socket, buffer(write_buffer.data(), write_buffer_offset),
                    [this, ancor](boost::system::error_code ec, std::size_t)
        {
            if (ec)
            {
#ifdef DEBUG
                std::cout << "error writing: " << ec.message() << std::endl;
#endif
                chat.on_user_leave(shared_from_this());
                return;
            } else {
                {
                    boost::lock_guard<boost::mutex> guard(deliver_queue_mutex);
                    if (messages_to_deliver.empty())
                    {
                        write_in_progress = false;
                        return;
                    }
                }
                do_write();
            }
        });

    }

private:
    ip::tcp::socket socket;
    chat_room &chat;
    io_service &service;
    std::vector<uint8> message_buffer;
    size_t buffer_offset;
    size_t buffer_red;
    std::vector<uint8> write_buffer;
    std::queue<serialized_message> messages_to_deliver;
    boost::mutex deliver_queue_mutex;
    size_t messages_sum_size;
    bool write_in_progress;
};

class connection_handler
{
public:
    connection_handler(io_service &service, int port, chat_room &chat)
        :
          sock(service),
          service(service),
          acc(service, ip::tcp::endpoint(ip::tcp::v4(), port)),
          chat(chat)
    {
    }

public:
    void accept_new_connection()
    {
        acc.async_accept(sock, [this](boost::system::error_code)
        {
            if (sock.is_open())
            {
                sock.set_option(ip::tcp::no_delay(true));
                chat.add_new_user(std::make_shared<user>(std::move(sock), chat, service));
            }
            accept_new_connection();
        });
    }

private:
    ip::tcp::socket sock;
    io_service &service;
    ip::tcp::acceptor acc;
    chat_room &chat;
};

int main(int argc, char *argv[])
{
    if (argc < 3) {
        std::cout
                << "Usage: ./chat_server $PORT_NUMBER$ $CONCURRENCY_LEVEL$"
                << std::endl
                << "Where $CONCURRENCY_LEVEL$ - number of the worker threads"
                << std::endl;
        return -1;
    }
    size_t port = std::atoi(argv[1]);
    size_t concurrency_level = std::atoi(argv[2]);

    try
    {
        std::cout << "Starting chat server on port "
                  << port
                  << " with concurrency level "
                  << concurrency_level
                  << " ..."
                  << std::endl;

        io_service service(concurrency_level);
        chat_room chat;

        connection_handler handler(service, port, chat);
        handler.accept_new_connection();

        boost::thread_group workers;
        auto const worker =
                boost::bind(&io_service::run, &service);
        for (size_t idx = 0; idx < concurrency_level; ++idx)
        {
            workers.create_thread(worker);
        }

        std::cout << "The server is started" << std::endl;
        std::cout << "Press 'enter' to stop the server"
                  << std::endl;
        std::cin.get();
        std::cout << "Stopping the server..." << std::endl;
        service.stop();
        workers.join_all();
        std::cout << "The server is stopped" << std::endl;
    } catch(std::exception &e) {
        std::cerr << "An exception occured with ";
        if (e.what()) {
            std::cerr << "message: \"" << e.what() << '"';
        } else {
            std::cerr << "no message";
        }
        std::cerr << std::endl;
        google::protobuf::ShutdownProtobufLibrary();
        return -1;
    }

    google::protobuf::ShutdownProtobufLibrary();
    return 0;
}

<|endoftext|>


<commit_before>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    // make MTL
    MTL M=make_MTL(G,F);

    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);

    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());

	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates P = read_plate_centers(F);
    F.Nplate=P.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		if(j%1000==0)diagnostic(M,G,F,A);
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");
		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==1000 || j==3000) {
            printf ( "Redistribute and improve at j = %d\n",j);
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            //diagnostic(M,G,F,A);
		}

    }
	print_time(time,"# ... took :");

    //diagnostic check on SS and SF
    for (int j=0;j<F.Nplate;++j){
        for (int p=0; p<F.Npetal; ++p){
            if(P[j].SS_in_petal[p]!=F.MaxSS){printf("SS j= %d p= %d number = P[j].SS_in_petal[p]\n");}
            if(P[j].SF_in_petal[p]!=F.MaxSF){printf("SF j= %d p= %d number = P[j].SS_in_petal[p]\n");}
        }
    }

	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) write_FAtile_ascii(j,F.outDir,M,P,pp,F,A); // Write output
	display_results("doc/figs/",G,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<commit_msg>check on SF, SS<commit_after>#include	<cstdlib>
#include	<cmath>
#include	<fstream>
#include	<sstream>
#include	<iostream>
#include	<iomanip>
#include	<string>
#include	<vector>
#include	<algorithm>
#include	<exception>
#include	<sys/time.h>
#include	"modules/htmTree.h"
#include	"modules/kdTree.h"
#include        "misc.h"
#include        "feat.h"
#include        "structs.h"
#include        "collision.h"
#include        "global.h"
//reduce redistributes, updates  07/02/15 rnc
int main(int argc, char **argv) {
	//// Initializations ---------------------------------------------
	srand48(1234); // Make sure we have reproducability
	check_args(argc);
	Time t, time; // t for global, time for local
	init_time(t);
	Feat F;

	// Read parameters file //
	F.readInputFile(argv[1]);
	printFile(argv[1]);
	// Read galaxies
	Gals G;
    if(F.Ascii){
        G=read_galaxies_ascii(F);}
    else{
        G = read_galaxies(F);
    }
	F.Ngal = G.size();
	printf("# Read %s galaxies from %s \n",f(F.Ngal).c_str(),F.galFile.c_str());
    std::vector<int> count;
    count=count_galaxies(G);
    printf(" Number of galaxies by type, QSO-Ly-a, QSO-tracers, LRG, ELG, fake QSO, fake LRG, SS, SF\n");
    for(int i=0;i<8;i++){printf (" type %d number  %d  \n",i, count[i]);}
    // make MTL
    MTL M=make_MTL(G,F);

    assign_priority_class(M);
    //find available SS and SF galaxies on each petal

    std::vector <int> count_class(M.priority_list.size(),0);

    printf("Number in each priority class.  The last two are SF and SS.\n");
    for(int i;i<M.size();++i){
        count_class[M[i].priority_class]+=1;
    }
    for(int i;i<M.priority_list.size();++i){
        printf("  class  %d  number  %d\n",i,count_class[i]);
    }

    printf(" number of MTL galaxies  %d\n",M.size());

	PP pp;
	pp.read_fiber_positions(F);
	F.Nfiber = pp.fp.size()/2;
	F.Npetal = max(pp.spectrom)+1;
    F.Nfbp = (int) (F.Nfiber/F.Npetal);// fibers per petal = 500
	pp.get_neighbors(F); pp.compute_fibsofsp(F);
	Plates P = read_plate_centers(F);
    F.Nplate=P.size();
	printf("# Read %s plate centers from %s and %d fibers from %s\n",f(F.Nplate).c_str(),F.tileFile.c_str(),F.Nfiber,F.fibFile.c_str());

	// Computes geometries of cb and fh: pieces of positioner - used to determine possible collisions
	F.cb = create_cb(); // cb=central body
	F.fh = create_fh(); // fh=fiber holder

	//// Collect available galaxies <-> tilefibers --------------------
	// HTM Tree of galaxies
	const double MinTreeSize = 0.01;
	init_time_at(time,"# Start building HTM tree",t);
	htmTree<struct target> T(M,MinTreeSize);
	print_time(time,"# ... took :");//T.stats();

	// For plates/fibers, collect available galaxies; done in parallel  P[plate j].av_gal[k]=[g1,g2,..]
	collect_galaxies_for_all(M,T,P,pp,F);

	// For each galaxy, computes available tilefibers  G[i].av_tfs = [(j1,k1),(j2,k2),..]
	collect_available_tilefibers(M,P,F);

	//results_on_inputs("doc/figs/",G,P,F,true);

	//// Assignment |||||||||||||||||||||||||||||||||||||||||||||||||||
	Assignment A(M,F);
	print_time(t,"# Start assignment at : ");

	// Make a plan ----------------------------------------------------
	//new_assign_fibers(G,P,pp,F,A); // Plans whole survey without sky fibers, standard stars
                                   // assumes maximum number of observations needed for QSOs, LRGs
    printf(" Nplate %d  Ngal %d   Nfiber %d \n", F.Nplate, F.Ngal, F.Nfiber);

    simple_assign(M,P,pp,F,A);
    diagnostic(M,G,F,A);
    print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false); // Hist of unused fibs
                                    // Want to have even distribution of unused fibers
                                    // so we can put in sky fibers and standard stars

	// Smooth out distribution of free fibers, and increase the number of assignments

	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);// more iterations will improve performance slightly
	for (int i=0; i<1; i++) {                           // more iterations will improve performance slightly
		improve(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
		redistribute_tf(M,P,pp,F,A);
	}
	for (int i=0; i<1; i++) redistribute_tf(M,P,pp,F,A);

	print_hist("Unused fibers",5,histogram(A.unused_fbp(pp,F),5),false);

	// Still not updated, so all QSO targets have multiple observations etc
	// Apply and update the plan --------------------------------------
	init_time_at(time,"# Begin real time assignment",t);
	for (int jj=0; jj<F.Nplate; jj++) {
		int j = A.next_plate;

		if(j%1000==0)diagnostic(M,G,F,A);
        assign_sf_ss(j,M,P,pp,F,A); // Assign SS and SF just before an observation
		assign_unused(j,M,P,pp,F,A);
		//if (j%2000==0) pyplotTile(j,"doc/figs",G,P,pp,F,A); // Picture of positioners, galaxies

		if (0<=j-F.Analysis) update_plan_from_one_obs(G,M,P,pp,F,A,F.Nplate-1); else printf("\n");
		A.next_plate++;
		// Redistribute and improve on various occasions  add more times if desired

		if ( j==1000 || j==3000) {
            printf ( "Redistribute and improve at j = %d\n",j);
			redistribute_tf(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
			improve(M,P,pp,F,A);
			redistribute_tf(M,P,pp,F,A);
            //diagnostic(M,G,F,A);
		}

    }
	print_time(time,"# ... took :");

    //diagnostic check on SS and SF
    for (int j=0;j<F.Nplate;++j){
        for (int p=0; p<F.Npetal; ++p){
            if(P[j].SS_in_petal[p]!=F.MaxSS){printf("SS j= %d p= %d number = %d\n");j,p,P[j].SS_in_petal[p]}
            if(P[j].SF_in_petal[p]!=F.MaxSF){printf("SF j= %d p= %d number = %d\n");j,p,P[j].SF_in_petal[p]}
        }
    }

	// Results -------------------------------------------------------
	if (F.Output) for (int j=0; j<F.Nplate; j++) write_FAtile_ascii(j,F.outDir,M,P,pp,F,A); // Write output
	display_results("doc/figs/",G,M,P,pp,F,A,true);
	if (F.Verif) A.verif(P,M,pp,F); // Verification that the assignment is sane

	print_time(t,"# Finished !... in");

	return(0);

}
<|endoftext|>