<commit_before>/*************************************************************************
 *
 *  $RCSfile: simpleioerrorrequest.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: kso $ $Date: 2001-05-29 13:01:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif

#ifndef _UCBHELPER_SIMPLEIOERRORREQUEST_HXX
#include <ucbhelper/simpleioerrorrequest.hxx>
#endif

using namespace com::sun::star;
using namespace ucbhelper;

//=========================================================================
SimpleIOErrorRequest::SimpleIOErrorRequest(
                            const uno::Reference< ucb::XContent > & xContent,
                            const com::sun::star::ucb::IOErrorCode eError )
{
    // Fill request...
    ucb::InteractiveIOException aRequest;
//    aRequest.Message        = // OUString
    aRequest.Context         = xContent;
    aRequest.Classification  = task::InteractionClassification_ERROR;
    aRequest.Code            = eError;

    setRequest( uno::makeAny( aRequest ) );

    // Fill continuations...
    uno::Sequence< uno::Reference<
            task::XInteractionContinuation > > aContinuations( 1 );
    aContinuations[ 0 ] = new InteractionAbort( this );

    setContinuations( aContinuations );
}

<commit_msg>#87187# - Added another continuation (approve) to the request.<commit_after>/*************************************************************************
 *
 *  $RCSfile: simpleioerrorrequest.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: kso $ $Date: 2001-06-06 11:21:42 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _COM_SUN_STAR_UCB_INTERACTIVEIOEXCEPTION_HPP_
#include <com/sun/star/ucb/InteractiveIOException.hpp>
#endif

#ifndef _UCBHELPER_SIMPLEIOERRORREQUEST_HXX
#include <ucbhelper/simpleioerrorrequest.hxx>
#endif

using namespace com::sun::star;
using namespace ucbhelper;

//=========================================================================
SimpleIOErrorRequest::SimpleIOErrorRequest(
                            const uno::Reference< ucb::XContent > & xContent,
                            const com::sun::star::ucb::IOErrorCode eError )
{
    // Fill request...
    ucb::InteractiveIOException aRequest;
//    aRequest.Message        = // OUString
    aRequest.Context         = xContent;
    aRequest.Classification  = task::InteractionClassification_ERROR;
    aRequest.Code            = eError;

    setRequest( uno::makeAny( aRequest ) );

    // Fill continuations...
    uno::Sequence< uno::Reference<
            task::XInteractionContinuation > > aContinuations( 2 );
    aContinuations[ 0 ] = new InteractionApprove( this );
    aContinuations[ 1 ] = new InteractionAbort( this );

    setContinuations( aContinuations );
}

<|endoftext|>


<commit_before>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007      Inge Wallin  <ingwa@kde.org>
// Copyright 2010      Harshit Jain <hjain.itbhu@gmail.com>
//

// #include <zlib.h>

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QStringList>

QString escapeXml( const QString &str )
{
    QString xml = str;
    xml.replace('&', "&");
    xml.replace('<', "<");
    xml.replace('>', ">");
    xml.replace('\'', "'");
    xml.replace('"', """);

    return xml;
}

int main(int argc, char *argv[])
{
    QString  sourcefilename;
    QString  targetfilename;
    QString  supportfilename;
    QString  timezonefilename;

    QCoreApplication  app( argc, argv );

    for ( int i = 1; i < argc; ++i ) {
        if ( strcmp( argv[ i ], "-o" ) != 0 )
            continue;

        targetfilename   = QString( argv[i+1] );
        sourcefilename   = QString( argv[i+2] );
        supportfilename  = QString( argv[i+3] );
        timezonefilename = QString( argv[i+4] );

        qDebug() << "Source: " << sourcefilename;
        qDebug() << "Support: " << supportfilename;
        qDebug() << "Target: " << targetfilename;
        qDebug() << "Timezone: " << timezonefilename;

        QFile  sourcefile( sourcefilename );
        sourcefile.open( QIODevice::ReadOnly );

        // Read the data serialized from the file.
        QTextStream  sourcestream( &sourcefile );
        sourcestream.setCodec("UTF-8");

        QFile  targetfile( targetfilename );
        targetfile.open( QIODevice::WriteOnly );

        QTextStream  targetstream( &targetfile );
        targetstream.setCodec("UTF-8");

        QFile  supportfile( supportfilename );
        supportfile.open( QIODevice::ReadOnly );

        QTextStream  supportstream( &supportfile );
        supportstream.setCodec("UTF-8");

        QFile  timezonefile( timezonefilename );
        timezonefile.open( QIODevice::ReadOnly );

        QTextStream  timezonestream( &timezonefile );
        timezonestream.setCodec("UTF-8");

        // gzFile gzDoc = gzopen( targetfilename.toLatin1(), "w");
        // QTextStream targetstream( new QString() );

        targetstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n"
                     << "<kml xmlns=\"http://earth.google.com/kml/2.1\"> \n"
                     << "<Document> \n";
        QString  rawline;
        QString  name;
    	QString  elestring;
        QString  state;
        QString  statecode;
        QString  country;
        QString  role;
        QString  popstring;
        QString  latstring;
        QString  lngstring;
        QString  timezone;
        QString  gmt;
        QString	 dst;
        int      dstoffset;
        int      gmtoffset;
        QStringList  splitline;

        while ( !sourcestream.atEnd() ) {

            rawline=sourcestream.readLine();
            splitline = rawline.split('\t');

            name       = splitline[1];
            latstring  = splitline[4];
            lngstring  = splitline[5];
            role       = splitline[7];
            country    = splitline[8];
            statecode  = splitline[10];
            popstring  = splitline[14];
            elestring  = splitline[16];
            timezone   = splitline[17];

            supportstream.seek(0);
            while ( !supportstream.atEnd() ) {
                QString supportrawline;
                QStringList supportsplitline;
                supportrawline = supportstream.readLine();
                supportsplitline = supportrawline.split('\t');
                if(supportsplitline[0] == (country + '.' +statecode))
                {
                    state = supportsplitline[1];
                    break;
                }
            }

            timezonestream.seek(0);
            timezonestream.readLine();
            while ( !timezonestream.atEnd() ) {
                    QString timezonerawline;
                    QStringList timezonesplitline;
                    timezonerawline = timezonestream.readLine();
                    timezonesplitline = timezonerawline.split('\t');

                    if( timezonesplitline[0] == timezone )
                    {
                        gmt = timezonesplitline[1];
                        dst = timezonesplitline[2];
                        break;
                    }
            }

            gmtoffset = ( int ) ( gmt.toFloat() * 100 );
            dstoffset = ( int ) ( dst.toFloat() * 100 ) - gmtoffset;

            if(role != "PPLX")
            {
	            targetstream << "    <Placemark> \n";
         	    targetstream << "        <name>" << escapeXml( name ) << "</name> \n";
                    targetstream << "        <state>" << escapeXml( state ) << "</state> \n";
      	        targetstream << "        <CountryNameCode>" << escapeXml( country.toUpper() ) << "</CountryNameCode>\n";
        	    targetstream << "        <role>" << escapeXml( role ) << "</role> \n";
        	    targetstream << "        <pop>"
                             << escapeXml( popstring ) << "</pop> \n";
           	    targetstream << "        <Point>\n"
                        	 << "            <coordinates>"
                      		 << escapeXml( lngstring )
                        	 << ","
                        	 << escapeXml( latstring )
				<< ","
                             << escapeXml( elestring )
	                         << "</coordinates> \n"
	                         << "        </Point> \n";
		        targetstream << "        <ExtendedData>\n"
                                 << "            <Data name=\"gmt\">\n"
                                 << "                <value>" << escapeXml( QString::number( gmtoffset ) ) << "</value>\n"
                                 << "            </Data>\n";
                    if( dstoffset )
                    {
                        targetstream << "            <Data name=\"dst\">\n"
                                 << "                <value>" << escapeXml( QString::number( dstoffset) ) << "</value>\n"
                                 << "            </Data>\n";
                    }
                    targetstream << "        </ExtendedData>\n";
	            targetstream << "    </Placemark> \n";
            }
        }

        targetstream << "</Document> \n"
                     << "</kml> \n";
        qDebug("Putting");

        // gzputs( gzDoc, targetstream.readAll().toUtf8() );
        // gzclose( gzDoc );

        sourcefile.close();
        targetfile.close();
        supportfile.close();
        timezonefile.close();
        qDebug("Finished!");
        return 0;
    }

    qDebug(" asc2kml -o targetfile sourcefile supporfile timezonefile");
    app.exit();
}
<commit_msg>const'ify<commit_after>//
// This file is part of the Marble Virtual Globe.
//
// This program is free software licensed under the GNU LGPL. You can
// find a copy of this license in LICENSE.txt in the top directory of
// the source code.
//
// Copyright 2006-2007 Torsten Rahn <tackat@kde.org>
// Copyright 2007      Inge Wallin  <ingwa@kde.org>
// Copyright 2010      Harshit Jain <hjain.itbhu@gmail.com>
//

#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QStringList>

QString escapeXml( const QString &str )
{
    QString xml = str;
    xml.replace('&', "&");
    xml.replace('<', "<");
    xml.replace('>', ">");
    xml.replace('\'', "'");
    xml.replace('"', """);

    return xml;
}

int main(int argc, char *argv[])
{
    QCoreApplication  app( argc, argv );

    for ( int i = 1; i < argc; ++i ) {
        if ( strcmp( argv[ i ], "-o" ) != 0 )
            continue;

        const QString targetfilename   = QString( argv[i+1] );
        const QString sourcefilename   = QString( argv[i+2] );
        const QString supportfilename  = QString( argv[i+3] );
        const QString timezonefilename = QString( argv[i+4] );

        qDebug() << "Source: " << sourcefilename;
        qDebug() << "Support: " << supportfilename;
        qDebug() << "Target: " << targetfilename;
        qDebug() << "Timezone: " << timezonefilename;

        QFile  sourcefile( sourcefilename );
        sourcefile.open( QIODevice::ReadOnly );

        // Read the data serialized from the file.
        QTextStream  sourcestream( &sourcefile );
        sourcestream.setCodec("UTF-8");

        QFile  targetfile( targetfilename );
        targetfile.open( QIODevice::WriteOnly );

        QTextStream  targetstream( &targetfile );
        targetstream.setCodec("UTF-8");

        QFile  supportfile( supportfilename );
        supportfile.open( QIODevice::ReadOnly );

        QTextStream  supportstream( &supportfile );
        supportstream.setCodec("UTF-8");

        QFile  timezonefile( timezonefilename );
        timezonefile.open( QIODevice::ReadOnly );

        QTextStream  timezonestream( &timezonefile );
        timezonestream.setCodec("UTF-8");

        // gzFile gzDoc = gzopen( targetfilename.toLatin1(), "w");
        // QTextStream targetstream( new QString() );

        targetstream << "<?xml version=\"1.0\" encoding=\"UTF-8\"?> \n"
                     << "<kml xmlns=\"http://earth.google.com/kml/2.1\"> \n"
                     << "<Document> \n";
        QString  state;
        QString  gmt;
        QString	 dst;

        while ( !sourcestream.atEnd() ) {

            const QString rawline = sourcestream.readLine();
            const QStringList splitline = rawline.split('\t');

            const QString name       = splitline[1];
            const QString latstring  = splitline[4];
            const QString lngstring  = splitline[5];
            const QString role       = splitline[7];
            const QString country    = splitline[8];
            const QString statecode  = splitline[10];
            const QString popstring  = splitline[14];
            const QString elestring  = splitline[16];
            const QString timezone   = splitline[17];

            supportstream.seek(0);
            while ( !supportstream.atEnd() ) {
                const QString supportrawline = supportstream.readLine();
                const QStringList supportsplitline = supportrawline.split('\t');
                if(supportsplitline[0] == (country + '.' +statecode))
                {
                    state = supportsplitline[1];
                    break;
                }
            }

            timezonestream.seek(0);
            timezonestream.readLine();
            while ( !timezonestream.atEnd() ) {
                    const QString timezonerawline = timezonestream.readLine();
                    const QStringList timezonesplitline = timezonerawline.split('\t');

                    if( timezonesplitline[0] == timezone )
                    {
                        gmt = timezonesplitline[1];
                        dst = timezonesplitline[2];
                        break;
                    }
            }

            const int gmtoffset = ( int ) ( gmt.toFloat() * 100 );
            const int dstoffset = ( int ) ( dst.toFloat() * 100 ) - gmtoffset;

            if(role != "PPLX")
            {
	            targetstream << "    <Placemark> \n";
         	    targetstream << "        <name>" << escapeXml( name ) << "</name> \n";
                targetstream << "        <state>" << escapeXml( state ) << "</state> \n";
      	        targetstream << "        <CountryNameCode>" << escapeXml( country.toUpper() ) << "</CountryNameCode>\n";
        	    targetstream << "        <role>" << escapeXml( role ) << "</role> \n";
        	    targetstream << "        <pop>"
                             << escapeXml( popstring ) << "</pop> \n";
           	    targetstream << "        <Point>\n"
                        	 << "            <coordinates>"
                      		 << escapeXml( lngstring )
                        	 << ","
                        	 << escapeXml( latstring )
				<< ","
                             << escapeXml( elestring )
	                         << "</coordinates> \n"
	                         << "        </Point> \n";
		        targetstream << "        <ExtendedData>\n"
                                 << "            <Data name=\"gmt\">\n"
                                 << "                <value>" << escapeXml( QString::number( gmtoffset ) ) << "</value>\n"
                                 << "            </Data>\n";
                    if( dstoffset )
                    {
                        targetstream << "            <Data name=\"dst\">\n"
                                 << "                <value>" << escapeXml( QString::number( dstoffset) ) << "</value>\n"
                                 << "            </Data>\n";
                    }
                    targetstream << "        </ExtendedData>\n";
	            targetstream << "    </Placemark> \n";
            }
        }

        targetstream << "</Document> \n"
                     << "</kml> \n";
        qDebug("Putting");

        // gzputs( gzDoc, targetstream.readAll().toUtf8() );
        // gzclose( gzDoc );

        sourcefile.close();
        targetfile.close();
        supportfile.close();
        timezonefile.close();
        qDebug("Finished!");
        return 0;
    }

    qDebug(" asc2kml -o targetfile sourcefile supporfile timezonefile");
    app.exit();
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: rscdep.cxx,v $
 *
 *  $Revision: 1.13 $
 *
 *  last change: $Author: hr $ $Date: 2002-02-21 14:23:26 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/***************************************************************
*
*   rscdep.cxx
*
*   (c) Martin Hollmichel 1998
*   added intern simple_getopt Vladimir Glazounov 2002
*
***************************************************************/

#ifdef UNX
#include <unistd.h>
#endif

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

#include "prj.hxx"

#if SUPD < 356
#include <tools.hxx>
#else
#include <string.hxx>
#include <list.hxx>
#include <fsys.hxx>
#include <stream.hxx>
#endif

#include "cppdep.hxx"

class RscHrcDep : public CppDep
{
public:
                    RscHrcDep();
    virtual         ~RscHrcDep();

    virtual void    Execute();
};

RscHrcDep::RscHrcDep()  :
    CppDep()
{
}

RscHrcDep::~RscHrcDep()
{
}

void RscHrcDep::Execute()
{
    CppDep::Execute();
}

//static String aDelim;

/* poor man's getopt() */
int     simple_getopt(int argc, char *argv[], const char *optstring);
#ifdef WNT
static char *optarg = NULL;
static int  optind = 1;
static int  optopt = 0;
static int  opterr = 0;
#endif

int
#ifdef WNT
_cdecl
#endif
main( int argc, char **argv )
{
    int c;
    int digit_optind = 0;
    char aBuf[255];
    char pOutputFileName[255];
    String aSrsBaseName;
    BOOL bSource = FALSE;
    ByteString aRespArg;
    String aDelim = String(DirEntry::GetAccessDelimiter());

    RscHrcDep *pDep = new RscHrcDep;

    for ( int i=1; i<argc; i++)
    {
        strcpy( aBuf, (const char *)argv[i] );
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' )
        {
            strcpy(pOutputFileName, &aBuf[3]);
            //break;
        }
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' )
        {
            strcpy(pOutputFileName, &aBuf[3]);
            String aName( pOutputFileName, gsl_getSystemTextEncoding());
            USHORT nPos = 0;
            DirEntry aDest( aName );
            aSrsBaseName = aDest.GetBase();
            //break;
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'i' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'I' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '@' )
        {
            ByteString aToken;
            String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
            SimpleConfig aConfig( aRespName );
            while ( (aToken = aConfig.GetNext()) != "")
            {
                char aBuf2[255];
                (void) strcpy( aBuf2, aToken.GetBuffer());
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    //break;
                }
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    String aName( pOutputFileName, gsl_getSystemTextEncoding());
                    USHORT nPos = 0;
                    DirEntry aDest( aName );
                    aSrsBaseName = aDest.GetBase();
                    //break;
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'i' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'I' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
                {
                    pDep->AddSource( &aBuf2[0] );
                    aRespArg += " ";
                    aRespArg += &aBuf2[0];
                    bSource = TRUE;
                }
            }
        }
    }

    while( 1 )
    {
        int this_option_optind = optind ? optind : 1;
        c = simple_getopt( argc, argv,
        "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
        if ( c == -1 )
            break;

        switch( c )
        {
            case 0:
                break;
            case 'a' :
#ifdef DEBUG_VERBOSE
                printf("option a\n");
#endif
                break;

            case 'l' :
#ifdef DEBUG_VERBOSE
                printf("option l with Value %s\n", optarg );
#endif
                pDep->AddSource( optarg );
                break;

            case 'h' :
            case 'H' :
            case '?' :
                printf("RscDep 1.0 (c)2000 StarOffice\n");
                break;

            default:
#ifdef DEBUG_VERBOSE
                printf("Unknown getopt error\n");
#endif
                ;
        }
    }

    DirEntry aEntry(".");
    aEntry.ToAbs();
    String aCwd = aEntry.GetName();
/*  USHORT nPos;
#ifndef UNX
    while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND  ))
#else
    while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND  ))
#endif
    {
        String attt = aCwd.Copy( 0, nPos );
        aCwd.Erase( 0, nPos );
    } */
    SvFileStream aOutStream;
    String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
    DirEntry aOutEntry( aOutputFileName );
    String aOutPath = aOutEntry.GetPath().GetFull();

    String aFileName( aOutPath );
    aFileName += aDelim;
    aFileName += aCwd;
    aFileName += String(".", gsl_getSystemTextEncoding());
    aFileName += aSrsBaseName;
    aFileName += String(".dpr", gsl_getSystemTextEncoding());
    //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
    aOutStream.Open( aFileName, STREAM_WRITE );

    ByteString aString;
    if ( optind < argc )
    {
#ifdef DEBUG_VERBOSE
        printf("further arguments : ");
#endif
        aString = ByteString( pOutputFileName );
        aString += ByteString(" : " );

        while ( optind < argc )
        {
            if (!bSource )
            {
                aString += ByteString(" " );
                aString += ByteString( argv[optind]);
                pDep->AddSource( argv[optind++]);
            }
            else
            {
                optind++;
            }
        }
    }
    aString += aRespArg;
    pDep->Execute();
    ByteStringList *pLst = pDep->GetDepList();
    ULONG nCount = pLst->Count();
    if ( nCount == 0 )
    {
        aOutStream.WriteLine( aString );
    }
    else
    {
        aString += ByteString( "\\" );
        aOutStream.WriteLine( aString );
    }

    for ( ULONG j=0; j<nCount; j++ )
    {
        ByteString *pStr = pLst->GetObject(j);
#ifdef UNX
        pStr->SearchAndReplaceAll('\\', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
#ifdef WNT
        pStr->SearchAndReplaceAll('/', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
        if ( j != (nCount-1) )
            *pStr += ByteString( "\\" );
        aOutStream.WriteLine( *pStr );
    }
    delete pDep;
    aOutStream.Close();

    return 0;
}

/* my very simple minded implementation of getopt()
 * it's too sad that getopt() is not available everywhere
 * note: this is not a full POSIX conforming getopt()
 */
simple_getopt(int argc, char *argv[], const char *optstring)
{
    char *arg = argv[optind];

    /* skip all response file arguments */
    if ( arg ) {
        while ( *arg == '@' )
            arg = argv[++optind];

        if ( arg[0] == '-' && arg[1] != '\0' ) {
            const char *popt;
            int c = arg[1];
            if ( (popt = strchr(optstring, c)) == NULL ) {
                optopt = c;
                if ( opterr )
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                return '?';
            }
            if ( *(++popt) == ':') {
                 if ( arg[2] != '\0' ) {
                     optarg = ++arg;
                 } else {
                     optarg = argv[++optind];
                 }
             } else {
                 optarg = NULL;
             }
             ++optind;
             return c;
        }
    }
    return -1;
}

<commit_msg>INTEGRATION: CWS mh11rc (1.13.90); FILE MERGED 2003/06/06 10:33:12 mh 1.13.90.1: join: from beta2<commit_after>/*************************************************************************
 *
 *  $RCSfile: rscdep.cxx,v $
 *
 *  $Revision: 1.14 $
 *
 *  last change: $Author: vg $ $Date: 2003-06-12 10:30:17 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/
/***************************************************************
*
*   rscdep.cxx
*
*   (c) Martin Hollmichel 1998
*   added intern simple_getopt Vladimir Glazounov 2002
*
***************************************************************/

#ifdef UNX
#include <unistd.h>
#endif

#include <sys/stat.h>
#include <stdio.h>
#include <string.h>

#include "prj.hxx"

#if SUPD < 356
#include <tools.hxx>
#else
#include <string.hxx>
#include <list.hxx>
#include <fsys.hxx>
#include <stream.hxx>
#endif

#include "cppdep.hxx"

class RscHrcDep : public CppDep
{
public:
                    RscHrcDep();
    virtual         ~RscHrcDep();

    virtual void    Execute();
};

RscHrcDep::RscHrcDep()  :
    CppDep()
{
}

RscHrcDep::~RscHrcDep()
{
}

void RscHrcDep::Execute()
{
    CppDep::Execute();
}

//static String aDelim;

/* poor man's getopt() */
int     simple_getopt(int argc, char *argv[], const char *optstring);
#ifdef WNT
static char *optarg = NULL;
static int  optind = 1;
static int  optopt = 0;
static int  opterr = 0;
#endif

int
#ifdef WNT
_cdecl
#endif
main( int argc, char **argv )
{
    int c;
    int digit_optind = 0;
    char aBuf[255];
    char pOutputFileName[255];
    String aSrsBaseName;
    BOOL bSource = FALSE;
    ByteString aRespArg;
    String aDelim = String(DirEntry::GetAccessDelimiter());

    RscHrcDep *pDep = new RscHrcDep;

    for ( int i=1; i<argc; i++)
    {
        strcpy( aBuf, (const char *)argv[i] );
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'o' )
        {
            strcpy(pOutputFileName, &aBuf[3]);
            //break;
        }
        if ( aBuf[0] == '-' && aBuf[1] == 'f' && aBuf[2] == 'p' )
        {
            strcpy(pOutputFileName, &aBuf[3]);
            String aName( pOutputFileName, gsl_getSystemTextEncoding());
            USHORT nPos = 0;
            DirEntry aDest( aName );
            aSrsBaseName = aDest.GetBase();
            //break;
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'i' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '-' &&  aBuf[1] == 'I' )
        {
            //printf("Include : %s\n", &aBuf[2] );
            pDep->AddSearchPath( &aBuf[2] );
        }
        if (aBuf[0] == '@' )
        {
            ByteString aToken;
            String aRespName( &aBuf[1], gsl_getSystemTextEncoding());
            SimpleConfig aConfig( aRespName );
            while ( (aToken = aConfig.GetNext()) != "")
            {
                char aBuf2[255];
                (void) strcpy( aBuf2, aToken.GetBuffer());
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'o' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    //break;
                }
                if ( aBuf2[0] == '-' && aBuf2[1] == 'f' && aBuf2[2] == 'p' )
                {
                    strcpy(pOutputFileName, &aBuf2[3]);
                    String aName( pOutputFileName, gsl_getSystemTextEncoding());
                    USHORT nPos = 0;
                    DirEntry aDest( aName );
                    aSrsBaseName = aDest.GetBase();
                    //break;
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'i' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (aBuf2[0] == '-' &&  aBuf2[1] == 'I' )
                {
                    //printf("Include : %s\n", &aBuf[2] );
                    pDep->AddSearchPath( &aBuf2[2] );
                }
                if (( aBuf2[0] != '-' ) && ( aBuf2[0] != '@' ))
                {
                    pDep->AddSource( &aBuf2[0] );
                    aRespArg += " ";
                    aRespArg += &aBuf2[0];
                    bSource = TRUE;
                }
            }
        }
    }

    while( 1 )
    {
        int this_option_optind = optind ? optind : 1;
        c = simple_getopt( argc, argv,
        "_abcdefghi:jklmnopqrstuvwxyzABCDEFGHI:JKLMNOPQRSTUVWXYZ1234567890/-+=.\\()\"");
        if ( c == -1 )
            break;

        switch( c )
        {
            case 0:
                break;
            case 'a' :
#ifdef DEBUG_VERBOSE
                printf("option a\n");
#endif
                break;

            case 'l' :
#ifdef DEBUG_VERBOSE
                printf("option l with Value %s\n", optarg );
#endif
                pDep->AddSource( optarg );
                break;

            case 'h' :
            case 'H' :
            case '?' :
                printf("RscDep 1.0 (c)2000 StarOffice\n");
                break;

            default:
#ifdef DEBUG_VERBOSE
                printf("Unknown getopt error\n");
#endif
                ;
        }
    }

    DirEntry aEntry(".");
    aEntry.ToAbs();
    String aCwd = aEntry.GetName();
/*  USHORT nPos;
#ifndef UNX
    while ( (nPos = aCwd.Search('\\') != STRING_NOTFOUND  ))
#else
    while ( (nPos = aCwd.Search('/') != STRING_NOTFOUND  ))
#endif
    {
        String attt = aCwd.Copy( 0, nPos );
        aCwd.Erase( 0, nPos );
    } */
    SvFileStream aOutStream;
    String aOutputFileName( pOutputFileName, gsl_getSystemTextEncoding());
    DirEntry aOutEntry( aOutputFileName );
    String aOutPath = aOutEntry.GetPath().GetFull();

    String aFileName( aOutPath );
    aFileName += aDelim;
    aFileName += aCwd;
    aFileName += String(".", gsl_getSystemTextEncoding());
    aFileName += aSrsBaseName;
    aFileName += String(".dpr", gsl_getSystemTextEncoding());
    //fprintf( stderr, "OutFileName : %s \n",aFileName.GetStr());
    aOutStream.Open( aFileName, STREAM_WRITE );

    ByteString aString;
    if ( optind < argc )
    {
#ifdef DEBUG_VERBOSE
        printf("further arguments : ");
#endif
        aString = ByteString( pOutputFileName );
        aString += ByteString(" : " );

        while ( optind < argc )
        {
            if (!bSource )
            {
                aString += ByteString(" " );
                aString += ByteString( argv[optind]);
                pDep->AddSource( argv[optind++]);
            }
            else
            {
                optind++;
            }
        }
    }
    aString += aRespArg;
    pDep->Execute();
    ByteStringList *pLst = pDep->GetDepList();
    ULONG nCount = pLst->Count();
    if ( nCount == 0 )
    {
        aOutStream.WriteLine( aString );
    }
    else
    {
        aString += ByteString( "\\" );
        aOutStream.WriteLine( aString );
    }

    for ( ULONG j=0; j<nCount; j++ )
    {
        ByteString *pStr = pLst->GetObject(j);
#ifdef UNX
        pStr->SearchAndReplaceAll('\\', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
#ifdef WNT
        pStr->SearchAndReplaceAll('/', ByteString( aDelim,  RTL_TEXTENCODING_ASCII_US ));
#endif
        if ( j != (nCount-1) )
            *pStr += ByteString( "\\" );
        aOutStream.WriteLine( *pStr );
    }
    delete pDep;
    aOutStream.Close();

    return 0;
}

/* my very simple minded implementation of getopt()
 * it's too sad that getopt() is not available everywhere
 * note: this is not a full POSIX conforming getopt()
 */
int simple_getopt(int argc, char *argv[], const char *optstring)
{
    char *arg = argv[optind];

    /* skip all response file arguments */
    if ( arg ) {
        while ( *arg == '@' )
            arg = argv[++optind];

        if ( arg[0] == '-' && arg[1] != '\0' ) {
            const char *popt;
            int c = arg[1];
            if ( (popt = strchr(optstring, c)) == NULL ) {
                optopt = c;
                if ( opterr )
                    fprintf(stderr, "Unknown option character `\\x%x'.\n", optopt);
                return '?';
            }
            if ( *(++popt) == ':') {
                 if ( arg[2] != '\0' ) {
                     optarg = ++arg;
                 } else {
                     optarg = argv[++optind];
                 }
             } else {
                 optarg = NULL;
             }
             ++optind;
             return c;
        }
    }
    return -1;
}

<|endoftext|>


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

#include <list>
#include <map>
#include <iterator>
#include <cstdlib>
#include <cassert>

namespace diffpp {

	struct point {
		point( void ) : x(0), y(0) {}
		point( int X, int Y ) : x(X), y(Y) {}
		int x,y;
	};

	struct edit {
		typedef enum { INSERT, DELETE } command_t;

		edit ( const point &Start, const point &Mid, const point &End ) : start(Start) {
			assert( Start.x <= End.x && Start.y <= End.y );
			command = Start.x < Mid.x ? DELETE : INSERT;
			matches = End.x - Mid.x;
		}
		const point &get_start( void ) const { return start; }
		unsigned get_matches( void ) const { return matches; }
		command_t get_command( void ) const { return command; }
	private:
		command_t command;
		unsigned matches;
		point start;
	};

	namespace algorithms {

		namespace detail {

			typedef std::map< int, unsigned > k_path_map;
			typedef std::vector< k_path_map > path_maps_t;

			struct longestpath_fordistance_fwd {
				template < typename fwdItA, typename fwdItB > inline
				static bool exec ( const fwdItA A0, const fwdItB B0, const int sizeA, const int sizeB, k_path_map &kmap, const int distance ) {
					const int inv_distance = distance * -1;
					for ( int kline = inv_distance; kline <= distance; kline += 2 ) {
						bool down = ( inv_distance == kline || ( kline != distance && kmap[kline-1] < kmap[kline+1] ) );

						int prev_kline = kline + ( down ? 1 : -1 );

						point start; start.x = kmap[prev_kline];
						start.y = start.x - prev_kline;

						point end; end.x = start.x + ( down ? 0 : 1 );
						end.y = end.x - kline;

						fwdItA itA( A0 ); fwdItB itB( B0 );
						std::advance( itA, end.x );
						std::advance( itB, end.y );

						while ( end.x < sizeA && end.y < sizeB && *itA == *itB ) {
							++end.x;
							++end.y;
							++itA; ++itB;
						}

						kmap[kline] = end.x;

						if ( end.x >= sizeA && end.y >= sizeB ) return true; // solution found
					}
					return false;
				}
			};

			struct longestpath_fordistance_bwd {
				template < typename fwdItA, typename fwdItB > inline
				static bool exec ( fwdItA A0, fwdItB B0, const int sizeA, const int sizeB, k_path_map &kmap, int distance ) {
					return false;
				}
			};

			struct solver_greedyfwd {
				template < typename container_t >
				static void solve ( path_maps_t &kdmaps, container_t &sln, const int sizeA, const int sizeB ) {
					point current( sizeA, sizeB );
					for ( int distance = ( kdmaps.size()-1); current.x > 0 || current.y > 0; --distance ) {
						k_path_map &kmap( kdmaps[distance] );
						const int inv_dist(distance * -1);
						const int kline = current.x - current.y;

						point end; end.x = kmap[kline];
						end.y = end.x - kline;

						bool down = ( inv_dist == kline || ( kline != distance && kmap[kline-1] < kmap[kline+1] ) );

						int prev_kline = kline + ( down ? 1 : -1 );

						point start; start.x = kmap[prev_kline];
						start.y = start.x - prev_kline;

						point mid; mid.x = start.x + ( down ? 0 : 1 );
						mid.y = mid.x - kline;

						sln.push_back( edit(start, mid, end) );

						current = start;
					}
				}
			};

			struct solver_greedybwd {
				template < typename container_t >
				static void solve ( const path_maps_t &kdmaps, container_t &sln, const int sizeA, const int sizeB ) {

				}
			};

			template < typename calc_longestpath, typename calc_solutionfct, typename fwdItA, typename fwdItB, typename container_t  > inline
			void diff_greedy ( fwdItA A0, fwdItA An, fwdItB B0, fwdItB Bm, container_t &solution_out ) {
				const int sizeA = std::distance(A0,An);
				const int sizeB = std::distance(B0,Bm);

				k_path_map kmap;
				kmap[1] = 0;

				path_maps_t path_maps;
				bool solution_found = false;
				const int worst_case = sizeA + sizeB;

				for ( int distance(0); distance <= worst_case; ++distance ) {
					solution_found = calc_longestpath::exec(A0, B0, sizeA, sizeB, kmap, distance);
					path_maps.push_back(kmap);
					if ( solution_found ) break;
				}

				if ( solution_found )
					calc_solutionfct::solve( path_maps, solution_out, sizeA, sizeB );

			}
		}

		template < typename fwdItA, typename fwdItB, typename container_t > inline
		void diff_greedyfwd ( fwdItA A0, fwdItA An, fwdItB B0, fwdItB Bm, container_t &sln ) {
			detail::diff_greedy<detail::longestpath_fordistance_fwd,
								detail::solver_greedyfwd> ( A0, An, B0, Bm, sln );
		}

		template < typename fwdItA, typename fwdItB, typename container_t > inline
		void diff_greedybwd ( fwdItA A0, fwdItA An, fwdItB B0, fwdItB Bm, container_t &sln ) {
			detail::diff_greedy<detail::longestpath_fordistance_bwd,
								detail::solver_greedybwd> ( A0, An, B0, Bm, sln );
		}

	}	//::diff::algorithms

} // ::diffpp

#endif //SCRIPT_HPP_INCLUDED
<commit_msg>naive implementation of myers algorithm, backward greedy variationw<commit_after>
/**
*
*  The MIT License (MIT)
*
*  Copyright (c) 2013 tfbogdan
*
*  Permission is hereby granted, free of charge, to any person obtaining a copy of
*  this software and associated documentation files (the "Software"), to deal in
*  the Software without restriction, including without limitation the rights to
*  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
*  the Software, and to permit persons to whom the Software is furnished to do so,
*  subject to the following conditions:
*
*  The above copyright notice and this permission notice shall be included in all
*  copies or substantial portions of the Software.
*
*  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
*  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
*  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
*  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
*  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef SCRIPT_HPP_INCLUDED
#define SCRIPT_HPP_INCLUDED

#include <list>
#include <map>
#include <iterator>
#include <cstdlib>
#include <cassert>

namespace diffpp {

	struct point {
		point( void ) : x(0), y(0) {}
		point( int X, int Y ) : x(X), y(Y) {}
		int x,y;
	};

	struct edit {
		typedef enum { INSERT, DELETE } command_t;

		edit ( const point &Start, const point &End ) : start(Start), end(End) {}
		const point &get_start(void) const { return start; }
		const point &get_end  (void) const { return end; }
		unsigned get_matches  (void) const { return std::abs( get_command() == DELETE ? start.y - end.y : start.x - end.x ); }
		command_t get_command (void) const { return std::abs( end.x - start.x ) > std::abs( end.y - start.y ) ? DELETE : INSERT; }
		int get_direction			(void) const { return end.x > start.x || end.y > start.y ? 1 : -1; }
	private:
		point start;
		point end;
	};

	namespace algorithms {

		namespace detail {

			typedef std::map< int, int > k_path_map;
			typedef std::vector< k_path_map > path_maps_t;

			struct longestpath_fordistance_fwd {
				template < typename fwdItA, typename fwdItB > inline
				static bool exec ( const fwdItA A0, const fwdItB B0, const int sizeA, const int sizeB, k_path_map &kmap, const int distance ) {
					const int inv_dist = distance * -1;
					for ( int kline = inv_dist; kline <= distance; kline += 2 ) {
						bool down = ( inv_dist == kline || ( kline != distance && kmap[kline-1] < kmap[kline+1] ) );

						int prev_kline = kline + ( down ? 1 : -1 );

						point start; start.x = kmap[prev_kline];
						start.y = start.x - prev_kline;

						point end; end.x = start.x + ( down ? 0 : 1 );
						end.y = end.x - kline;

						fwdItA itA( A0 ); fwdItB itB( B0 );
						std::advance( itA, end.x );
						std::advance( itB, end.y );

						while ( end.x < sizeA && end.y < sizeB && *itA == *itB ) {
							++end.x;
							++end.y;
							++itA; ++itB;
						}

						kmap[kline] = end.x;

						if ( end.x >= sizeA && end.y >= sizeB ) return true; // solution found
					}
					return false;
				}
			};

			struct longestpath_fordistance_bwd {
				template < typename fwdItA, typename fwdItB > inline
				static bool exec ( const fwdItA A0, const fwdItB B0, const int sizeA, const int sizeB, k_path_map &kmap, int distance ) {
					const int delta = sizeA - sizeB;
					const int inv_dist = distance * -1;

					for ( int kline = inv_dist + delta; kline <= distance + delta; kline += 2 ) {
						bool up = ( kline == distance + delta || ( kline != (inv_dist + delta) && kmap[kline-1] < kmap[kline+1] ) );

						const int prev_kline = kline + ( up ? -1 : 1 );

						point start;start.x = kmap[ prev_kline ];
						start.y = start.x - prev_kline;

						point end; end.x = up ? start.x : start.x - 1;
						end.y = end.x - kline;

						fwdItA itA(A0);
						fwdItB itB(B0);
						std::advance(itA, end.x-1);
						std::advance(itB, end.y-1);

						while ( end.x > 0 && end.y > 0 && *itA==*itB ) {
							--end.x;
							--end.y;
							--itA;--itB;
						}

						kmap[kline] = end.x;

						if ( end.x <= 0 && end.y <= 0 ) return true;
					}
					return false;
				}
			};

			struct solver_greedyfwd {
				template < typename container_t >
				static void solve ( path_maps_t &kdmaps, container_t &sln, const int sizeA, const int sizeB ) {
					point current( sizeA, sizeB );
					for ( int distance = ( kdmaps.size()-1); current.x > 0 || current.y > 0; --distance ) {
						k_path_map &kmap( kdmaps[distance] );
						const int inv_dist(distance * -1);
						const int kline = current.x - current.y;

						point end; end.x = kmap[kline];
						end.y = end.x - kline;

						bool down = ( inv_dist == kline || ( kline != distance && kmap[kline-1] < kmap[kline+1] ) );

						int prev_kline = kline + ( down ? 1 : -1 );

						point start; start.x = kmap[prev_kline];
						start.y = start.x - prev_kline;

						//sln.push_back( edit(start, end) );
						sln.insert( sln.begin(), 1, edit(start, end) );

						current = start;
					}
				}
			};

			struct solver_greedybwd {
				template < typename container_t >
				static void solve ( path_maps_t &kdmaps, container_t &sln, const int sizeA, const int sizeB ) {
					point current(0,0);
					const int delta = sizeA-sizeB;

          for ( int distance = kdmaps.size() -1; current.x < sizeA || current.y < sizeB; --distance ) {
						k_path_map &kmap( kdmaps[distance] );
            const int kline = current.x - current.y;
						const int inv_dist = distance * -1;

						point end; end.x = kmap[kline];
						end.y = end.x - kline;

						bool up = ( kline == distance + delta || ( kline != (inv_dist + delta) && kmap[kline-1] < kmap[kline+1] ) );
						const int prev_kline = kline - ( up ? 1 : -1 );

						point start; start.x = kmap[prev_kline];
						start.y = start.x - prev_kline;

						//sln.push_back( edit(start, end) );
						sln.insert( sln.end(), 1, edit(start, end) );

						current = start;

					}
				}
			};

			template < typename calc_longestpath, typename calc_solutionfct, typename fwdItA, typename fwdItB, typename container_t  > inline
			void diff_greedy ( fwdItA A0, fwdItB B0, container_t &solution_out, k_path_map &kmap, const int sizeA, const int sizeB ) {
				path_maps_t path_maps;
				bool solution_found = false;
				const int worst_case = sizeA + sizeB;

				for ( int distance(0); distance <= worst_case; ++distance ) {
					solution_found = calc_longestpath::exec(A0, B0, sizeA, sizeB, kmap, distance);
					path_maps.push_back(kmap);
					if ( solution_found ) break;
				}

				if ( solution_found )
					calc_solutionfct::solve( path_maps, solution_out, sizeA, sizeB );

			}
		}

		template < typename fwdItA, typename fwdItB, typename container_t > inline
		void diff_greedyfwd ( fwdItA A0, fwdItA An, fwdItB B0, fwdItB Bm, container_t &sln ) {
			static const int sizeA = std::distance( A0, An );
			static const int sizeB = std::distance( B0, Bm );
			detail::k_path_map kmap;
			kmap[1] = 0;
			detail::diff_greedy<detail::longestpath_fordistance_fwd,
								detail::solver_greedyfwd> ( A0, B0, sln, kmap, sizeA, sizeB );
		}

		template < typename fwdItA, typename fwdItB, typename container_t > inline
		void diff_greedybwd ( fwdItA A0, fwdItA An, fwdItB B0, fwdItB Bm, container_t &sln ) {
			static const int sizeA = std::distance( A0, An );
			static const int sizeB = std::distance( B0, Bm );
			detail::k_path_map kmap;
			kmap[ sizeA - sizeB - 1 ] = sizeA;
			detail::diff_greedy<detail::longestpath_fordistance_bwd,
								detail::solver_greedybwd> ( A0, B0, sln, kmap, sizeA, sizeB );
		}

	}	//::diff::algorithms

} // ::diffpp

#endif //SCRIPT_HPP_INCLUDED
<|endoftext|>


<commit_before>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED

#include "libtorrent/config.hpp"
#include "libtorrent/io_service_fwd.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/error_code.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/function/function3.hpp>
#include <list>

namespace libtorrent
{

	TORRENT_EXPORT bool is_local(address const& a);
	TORRENT_EXPORT bool is_loopback(address const& addr);
	TORRENT_EXPORT bool is_multicast(address const& addr);
	TORRENT_EXPORT bool is_any(address const& addr);
	TORRENT_EXPORT bool is_teredo(address const& addr);
	TORRENT_EXPORT int cidr_distance(address const& a1, address const& a2);

	// determines if the operating system supports IPv6
	TORRENT_EXPORT bool supports_ipv6();

	TORRENT_EXPORT int common_bits(unsigned char const* b1
		, unsigned char const* b2, int n);

	TORRENT_EXPORT address guess_local_address(io_service&);

	typedef boost::function<void(udp::endpoint const& from
		, char* buffer, int size)> receive_handler_t;

	class TORRENT_EXPORT broadcast_socket
	{
	public:
		broadcast_socket(io_service& ios, udp::endpoint const& multicast_endpoint
			, receive_handler_t const& handler, bool loopback = true);
		~broadcast_socket() { close(); }

		enum flags_t { broadcast = 1 };
		void send(char const* buffer, int size, error_code& ec, int flags = 0);

		void close();
		int num_send_sockets() const { return m_unicast_sockets.size(); }
		void enable_ip_broadcast(bool e);

	private:

		struct socket_entry
		{
			socket_entry(boost::shared_ptr<datagram_socket> const& s)
				: socket(s), broadcast(false) {}
			socket_entry(boost::shared_ptr<datagram_socket> const& s
				, address_v4 const& mask): socket(s), netmask(mask), broadcast(false) {}
			boost::shared_ptr<datagram_socket> socket;
			char buffer[1500];
			udp::endpoint remote;
			address_v4 netmask;
			bool broadcast;
			void close()
			{
				if (!socket) return;
				error_code ec;
				socket->close(ec);
			}
			bool can_broadcast() const
			{
				error_code ec;
				return broadcast
					&& netmask != address_v4()
					&& socket->local_endpoint(ec).address().is_v4();
			}
			address_v4 broadcast_address() const
			{
				error_code ec;
				return address_v4::broadcast(socket->local_endpoint(ec).address().to_v4(), netmask);
			}
		};

		void on_receive(socket_entry* s, error_code const& ec
			, std::size_t bytes_transferred);
		void open_unicast_socket(io_service& ios, address const& addr
			, address_v4 const& mask);
		void open_multicast_socket(io_service& ios, address const& addr
			, bool loopback, error_code& ec);

		// if we're aborting, destruct the handler and return true
		bool maybe_abort();

		// these sockets are used to
		// join the multicast group (on each interface)
		// and receive multicast messages
		std::list<socket_entry> m_sockets;
		// these sockets are not bound to any
		// specific port and are used to
		// send messages to the multicast group
		// and receive unicast responses
		std::list<socket_entry> m_unicast_sockets;
		udp::endpoint m_multicast_endpoint;
		receive_handler_t m_on_receive;

		// the number of outstanding async operations
		// we have on these sockets. The m_on_receive
		// handler may not be destructed until this reaches
		// 0, since it may be holding references to
		// the broadcast_socket itself.
		int m_outstanding_operations;
		// when set to true, we're trying to shut down
		// don't initiate new operations and once the
		// outstanding counter reaches 0, destruct
		// the handler object
		bool m_abort;
	};
}

#endif

<commit_msg>workaround an old asio bug on 64 bit machines<commit_after>/*

Copyright (c) 2007, Arvid Norberg
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in
      the documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.

*/

#ifndef TORRENT_BROADCAST_SOCKET_HPP_INCLUDED
#define TORRENT_BROADCAST_SOCKET_HPP_INCLUDED

#include "libtorrent/config.hpp"
#include "libtorrent/io_service_fwd.hpp"
#include "libtorrent/socket.hpp"
#include "libtorrent/address.hpp"
#include "libtorrent/error_code.hpp"
#include <boost/shared_ptr.hpp>
#include <boost/function/function3.hpp>
#include <list>

namespace libtorrent
{

	TORRENT_EXPORT bool is_local(address const& a);
	TORRENT_EXPORT bool is_loopback(address const& addr);
	TORRENT_EXPORT bool is_multicast(address const& addr);
	TORRENT_EXPORT bool is_any(address const& addr);
	TORRENT_EXPORT bool is_teredo(address const& addr);
	TORRENT_EXPORT int cidr_distance(address const& a1, address const& a2);

	// determines if the operating system supports IPv6
	TORRENT_EXPORT bool supports_ipv6();

	TORRENT_EXPORT int common_bits(unsigned char const* b1
		, unsigned char const* b2, int n);

	TORRENT_EXPORT address guess_local_address(io_service&);

	typedef boost::function<void(udp::endpoint const& from
		, char* buffer, int size)> receive_handler_t;

	class TORRENT_EXPORT broadcast_socket
	{
	public:
		broadcast_socket(io_service& ios, udp::endpoint const& multicast_endpoint
			, receive_handler_t const& handler, bool loopback = true);
		~broadcast_socket() { close(); }

		enum flags_t { broadcast = 1 };
		void send(char const* buffer, int size, error_code& ec, int flags = 0);

		void close();
		int num_send_sockets() const { return m_unicast_sockets.size(); }
		void enable_ip_broadcast(bool e);

	private:

		struct socket_entry
		{
			socket_entry(boost::shared_ptr<datagram_socket> const& s)
				: socket(s), broadcast(false) {}
			socket_entry(boost::shared_ptr<datagram_socket> const& s
				, address_v4 const& mask): socket(s), netmask(mask), broadcast(false) {}
			boost::shared_ptr<datagram_socket> socket;
			char buffer[1500];
			udp::endpoint remote;
			address_v4 netmask;
			bool broadcast;
			void close()
			{
				if (!socket) return;
				error_code ec;
				socket->close(ec);
			}
			bool can_broadcast() const
			{
				error_code ec;
				return broadcast
					&& netmask != address_v4()
					&& socket->local_endpoint(ec).address().is_v4();
			}
			address_v4 broadcast_address() const
			{
				error_code ec;
#if BOOST_VERSION < 104700
				return address_v4(socket->local_endpoint(ec).address().to_v4().to_ulong() | ((~netmask.to_ulong()) & 0xffffffff));
#else
				return address_v4::broadcast(socket->local_endpoint(ec).address().to_v4(), netmask);
#endif
			}
		};

		void on_receive(socket_entry* s, error_code const& ec
			, std::size_t bytes_transferred);
		void open_unicast_socket(io_service& ios, address const& addr
			, address_v4 const& mask);
		void open_multicast_socket(io_service& ios, address const& addr
			, bool loopback, error_code& ec);

		// if we're aborting, destruct the handler and return true
		bool maybe_abort();

		// these sockets are used to
		// join the multicast group (on each interface)
		// and receive multicast messages
		std::list<socket_entry> m_sockets;
		// these sockets are not bound to any
		// specific port and are used to
		// send messages to the multicast group
		// and receive unicast responses
		std::list<socket_entry> m_unicast_sockets;
		udp::endpoint m_multicast_endpoint;
		receive_handler_t m_on_receive;

		// the number of outstanding async operations
		// we have on these sockets. The m_on_receive
		// handler may not be destructed until this reaches
		// 0, since it may be holding references to
		// the broadcast_socket itself.
		int m_outstanding_operations;
		// when set to true, we're trying to shut down
		// don't initiate new operations and once the
		// outstanding counter reaches 0, destruct
		// the handler object
		bool m_abort;
	};
}

#endif

<|endoftext|>


<commit_before>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

#include "RuntimePlatformAgnosticPch.h"
#include "UnicodeText.h"
#include <unicode/uchar.h>
#include <unicode/ustring.h>
#include <unicode/normalizer2.h>

namespace PlatformAgnostic
{
    namespace UnicodeText
    {
#if DBG
        static UErrorCode g_lastErrorCode = U_ZERO_ERROR;
#endif

        // Helper ICU conversion facilities
        static const Normalizer2* TranslateToICUNormalizer(NormalizationForm normalizationForm)
        {
            UErrorCode errorCode = U_ZERO_ERROR;
            const Normalizer2* normalizer;

            switch (normalizationForm)
            {
                case NormalizationForm::C:
                    normalizer = Normalizer2::getNFCInstance(errorCode);
                    break;
                case NormalizationForm::D:
                    normalizer = Normalizer2::getNFDInstance(errorCode);
                    break;
                case NormalizationForm::KC:
                    normalizer = Normalizer2::getNFKCInstance(errorCode);
                    break;
                case NormalizationForm::KD:
                    normalizer = Normalizer2::getNFKDInstance(errorCode);
                    break;
                default:
                    AssertMsg(false, "Unsupported normalization form");
            };

            AssertMsg(U_SUCCESS(errorCode), (char*) u_errorName(errorCode));

            return normalizer;
        }

        static bool IsUtf16StringValid(const UChar* str, int* invalidIndex)
        {
            // ask ICU to scan through the string and see if it can be
            // converted to utf8. If it can't, see if the error is that
            // the string is malformed.

            Assert(invalidIndex != nullptr);
            *invalidIndex = -1;
            int32_t length = u_strlen(str);
            int32_t i = 0;

            for (;;)
            {
                // Iterate through the UTF16-LE string
                // If we are at the end of the null terminated string, return true
                // since the string is valid
                // If not, check if the codepoint we have is a surrogate code unit.
                // If it is, the string is malformed since U16_NEXT would have returned
                // is the full codepoint if both code units in the surrogate pair were present
                UChar32 c;
                U16_NEXT(str, i, length, c);
                if (c == 0)
                {
                    return true;
                }
                if (U_IS_SURROGATE(c))
                {
                    if (U16_IS_LEAD(c))
                    {
                        *invalidIndex = i;
                    }
                    else
                    {
                        *invalidIndex = i - 1;
                    }

                    return false;
                }
            }
        }

        static ApiError TranslateUErrorCode(UErrorCode icuError)
        {
#if DBG
            g_lastErrorCode = icuError;
#endif

            switch (icuError)
            {
                case U_BUFFER_OVERFLOW_ERROR:
                    return ApiError::InsufficientBuffer;
                case U_ILLEGAL_ARGUMENT_ERROR:
                case U_UNSUPPORTED_ERROR:
                    return ApiError::InvalidParameter;
                case U_INVALID_CHAR_FOUND:
                case U_TRUNCATED_CHAR_FOUND:
                case U_ILLEGAL_CHAR_FOUND:
                    return ApiError::InvalidUnicodeText;
                default:
                    return ApiError::UntranslatedError;
            }
        }

        // Linux ICU implementation of platform-agnostic Unicode interface
        int32 NormalizeString(NormalizationForm normalizationForm, const char16* sourceString, uint32 sourceLength, char16* destString, int32 destLength, ApiError* pErrorOut)
        {
            // Assert pointers
            Assert(sourceString != nullptr);
            Assert(destString != nullptr || destLength == 0);

            // This is semantically different than the Win32 NormalizeString API
            // For our usage, we always pass in the length rather than letting Windows
            // calculate the length for us
            Assert(sourceLength > 0);
            Assert(destLength >= 0);

            *pErrorOut = NoError;

            // On Windows, IsNormalizedString returns failure if the string
            // is a malformed utf16 string. Maintain the same behavior here.
            // Note that Windows returns this failure only if the dest buffer
            // is passed in, not in the estimation case
            int invalidIndex = 0;
            if (destString != nullptr && !IsUtf16StringValid((const UChar*) sourceString, &invalidIndex))
            {
                *pErrorOut = InvalidUnicodeText;
                return -1 * invalidIndex; // mimicking the behavior of Win32 NormalizeString
            }

            const Normalizer2* normalizer = TranslateToICUNormalizer(normalizationForm);
            Assert(normalizer != nullptr);

            const UnicodeString sourceUniStr((const UChar*) sourceString, sourceLength);

            UErrorCode errorCode = U_ZERO_ERROR;
            const UnicodeString destUniStr = normalizer->normalize(sourceUniStr, errorCode);

            if (U_FAILURE(errorCode))
            {
                *pErrorOut = TranslateUErrorCode(errorCode);
            }

            // xplat-todo: we could possibly make this more efficient and save the buffer copy
            // that destUniStr causes
            int32_t normalizedStringLength = destUniStr.length();
            if (destLength == 0 && normalizedStringLength >= 0)
            {
                *pErrorOut = ApiError::InsufficientBuffer;
                return normalizedStringLength;
            }

            destUniStr.extract((UChar*) destString, destLength, errorCode);
            if (U_FAILURE(errorCode))
            {
                *pErrorOut = TranslateUErrorCode(errorCode);
                return -1;
            }

            return normalizedStringLength;
        }

        bool IsNormalizedString(NormalizationForm normalizationForm, const char16* testString, int32 testStringLength)
        {
            Assert(testString != nullptr);
            UErrorCode errorCode = U_ZERO_ERROR;

            // On Windows, IsNormalizedString returns failure if the string
            // is a malformed utf16 string. Maintain the same behavior here.
            int invalidIndex = 0;
            if (!IsUtf16StringValid((const UChar*) testString, &invalidIndex))
            {
                return false;
            }

            const Normalizer2* normalizer = TranslateToICUNormalizer(normalizationForm);
            Assert(normalizer != nullptr);

            const UnicodeString testUniStr((const UChar*) testString, testStringLength);
            bool isNormalized = normalizer->isNormalized(testUniStr, errorCode);

            Assert(U_SUCCESS(errorCode));
            return isNormalized;
        }

        // Since we're using the ICU here, this is trivially true
        bool IsExternalUnicodeLibraryAvailable()
        {
            return true;
        }

        bool IsWhitespace(codepoint_t ch)
        {
            return u_isUWhiteSpace(ch) == 1;
        }

        bool IsIdStart(codepoint_t ch)
        {
            if (u_isIDStart(ch))
            {
                return true;
            }

            // Following codepoints are treated as part of ID_Start
            // for backwards compatibility as per section 2.5 of the Unicode 8 spec
            // See http://www.unicode.org/reports/tr31/tr31-23.html#Backward_Compatibility
            // The exact list is in PropList.txt in the Unicode database
            switch (ch)
            {
            case 0x2118: return true; // SCRIPT CAPITAL P
            case 0x212E: return true; // ESTIMATED SYMBOL
            case 0x309B: return true; // KATAKANA-HIRAGANA VOICED SOUND MARK
            case 0x309C: return true; // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
            default: return false;
            }
        }

        bool IsIdContinue(codepoint_t ch)
        {
            if (u_hasBinaryProperty(ch, UCHAR_ID_CONTINUE) == 1)
            {
                return true;
            }

            // Following codepoints are treated as part of ID_Continue
            // for backwards compatibility as per section 2.5 of the Unicode 8 spec
            // See http://www.unicode.org/reports/tr31/tr31-23.html#Backward_Compatibility
            // The exact list is in PropList.txt in the Unicode database
            switch (ch)
            {
            case 0x00B7: return true; // MIDDLE DOT
            case 0x0387: return true; // GREEK ANO TELEIA
            case 0x1369: return true; // ETHIOPIC DIGIT ONE
            case 0x136A: return true; // ETHIOPIC DIGIT TWO
            case 0x136B: return true; // ETHIOPIC DIGIT THREE
            case 0x136C: return true; // ETHIOPIC DIGIT FOUR
            case 0x136D: return true; // ETHIOPIC DIGIT FIVE
            case 0x136E: return true; // ETHIOPIC DIGIT SIX
            case 0x136F: return true; // ETHIOPIC DIGIT SEVEN
            case 0x1370: return true; // ETHIOPIC DIGIT EIGHT
            case 0x1371: return true; // ETHIOPIC DIGIT NINE
            case 0x19DA: return true; // NEW TAI LUE THAM DIGIT ONE
            default: return false;
            }
        }

        UnicodeGeneralCategoryClass GetGeneralCategoryClass(codepoint_t ch)
        {
            int8_t charType = u_charType(ch);

            if (charType == U_LOWERCASE_LETTER ||
                charType == U_UPPERCASE_LETTER ||
                charType == U_TITLECASE_LETTER ||
                charType == U_MODIFIER_LETTER ||
                charType == U_OTHER_LETTER ||
                charType == U_LETTER_NUMBER)
            {
                return UnicodeGeneralCategoryClass::CategoryClassLetter;
            }

            if (charType == U_DECIMAL_DIGIT_NUMBER)
            {
                return UnicodeGeneralCategoryClass::CategoryClassDigit;
            }

            if (charType == U_LINE_SEPARATOR)
            {
                return UnicodeGeneralCategoryClass::CategoryClassLineSeparator;
            }

            if (charType == U_PARAGRAPH_SEPARATOR)
            {
                return UnicodeGeneralCategoryClass::CategoryClassParagraphSeparator;
            }

            if (charType == U_SPACE_SEPARATOR)
            {
                return UnicodeGeneralCategoryClass::CategoryClassSpaceSeparator;
            }

            if (charType == U_COMBINING_SPACING_MARK)
            {
                return UnicodeGeneralCategoryClass::CategoryClassSpacingCombiningMark;
            }

            if (charType == U_NON_SPACING_MARK)
            {
                return UnicodeGeneralCategoryClass::CategoryClassNonSpacingMark;
            }

            if (charType == U_CONNECTOR_PUNCTUATION)
            {
                return UnicodeGeneralCategoryClass::CategoryClassConnectorPunctuation;
            }

            return UnicodeGeneralCategoryClass::CategoryClassOther;
        }

        // We actually don't care about the legacy behavior on Linux since no one
        // has a dependency on it. So this actually is different between
        // Windows and Linux
        CharacterClassificationType GetLegacyCharacterClassificationType(char16 character)
        {
            auto charTypeMask = U_GET_GC_MASK(character);

            if ((charTypeMask & U_GC_L_MASK) != 0)
            {
                return CharacterClassificationType::Letter;
            }

            if ((charTypeMask & (U_GC_ND_MASK | U_GC_P_MASK)) != 0)
            {
                return CharacterClassificationType::DigitOrPunct;
            }

            // As per http://archives.miloush.net/michkap/archive/2007/06/11/3230072.html
            //  * C1_SPACE corresponds to the Unicode Zs category.
            //  * C1_BLANK corresponds to a hardcoded list thats ill-defined.
            // We'll skip that compatibility here and just check for Zs.
            // We explicitly check for 0xFEFF to satisfy the unit test in es5/Lex_u3.js
            if ((charTypeMask & U_GC_ZS_MASK) != 0 ||
                character == 0xFEFF)
            {
                return CharacterClassificationType::Whitespace;
            }

            return CharacterClassificationType::Invalid;
        }

        int32 ChangeStringLinguisticCase(CaseFlags caseFlags, const char16* sourceString, uint32 sourceLength, char16* destString, uint32 destLength, ApiError* pErrorOut)
        {
            int32_t resultStringLength = 0;
            UErrorCode errorCode = U_ZERO_ERROR;

            static_assert(sizeof(UChar) == sizeof(char16), "Unexpected char type from ICU, function might have to be updated");
            if (caseFlags == CaseFlagsUpper)
            {
                resultStringLength = u_strToUpper((UChar*) destString, destLength,
                    (UChar*) sourceString, sourceLength, NULL, &errorCode);
            }
            else if (caseFlags == CaseFlagsLower)
            {
                resultStringLength = u_strToLower((UChar*) destString, destLength,
                    (UChar*) sourceString, sourceLength, NULL, &errorCode);
            }
            else
            {
                Assert(false);
            }

            if (U_FAILURE(errorCode))
            {
                *pErrorOut = TranslateUErrorCode(errorCode);
                return -1;
            }

            // Todo: check for resultStringLength > destLength
            // Return insufficient buffer in that case
            return resultStringLength;
        }

        uint32 ChangeStringCaseInPlace(CaseFlags caseFlags, char16* stringToChange, uint32 bufferLength)
        {
            // Assert pointers
            Assert(stringToChange != nullptr);
            ApiError error = NoError;

            if (bufferLength == 0 || stringToChange == nullptr)
            {
                return 0;
            }

            int32 ret = ChangeStringLinguisticCase(caseFlags, stringToChange, bufferLength, stringToChange, bufferLength, &error);

            // Callers to this function don't expect any errors
            Assert(error == ApiError::NoError);
            Assert(ret > 0);
            return (uint32) ret;
        }

        int LogicalStringCompare(const char16* string1, const char16* string2)
        {
            return PlatformAgnostic::UnicodeText::Internal::LogicalStringCompareImpl<char16>(string1, string2);
        }
    };
};
<commit_msg>Incorporate code review comments<commit_after>//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------

#include "RuntimePlatformAgnosticPch.h"
#include "UnicodeText.h"
#include <unicode/uchar.h>
#include <unicode/ustring.h>
#include <unicode/normalizer2.h>

namespace PlatformAgnostic
{
    namespace UnicodeText
    {
#if DBG
        static UErrorCode g_lastErrorCode = U_ZERO_ERROR;
#endif

        static_assert(sizeof(char16) == sizeof(UChar),
            "This implementation depends on ICU char size matching char16's size");

        // Helper ICU conversion facilities
        static const Normalizer2* TranslateToICUNormalizer(NormalizationForm normalizationForm)
        {
            UErrorCode errorCode = U_ZERO_ERROR;
            const Normalizer2* normalizer;

            switch (normalizationForm)
            {
                case NormalizationForm::C:
                    normalizer = Normalizer2::getNFCInstance(errorCode);
                    break;
                case NormalizationForm::D:
                    normalizer = Normalizer2::getNFDInstance(errorCode);
                    break;
                case NormalizationForm::KC:
                    normalizer = Normalizer2::getNFKCInstance(errorCode);
                    break;
                case NormalizationForm::KD:
                    normalizer = Normalizer2::getNFKDInstance(errorCode);
                    break;
                default:
                    AssertMsg(false, "Unsupported normalization form");
            };

            AssertMsg(U_SUCCESS(errorCode), (char*) u_errorName(errorCode));

            return normalizer;
        }

        //
        // Check if a UTF16 string is valid according to the UTF16 standard
        // Specifically, check that we don't have any invalid surrogate pairs
        // If the string is valid, we return true.
        // If not, we set invalidIndex to the index of the first invalid char index
        // and return false
        // If the invalid char is a lead surrogate pair, we return its index
        // Otherwise, we treat the char before as the invalid one and return index - 1
        // This function has defined behavior only for null-terminated strings.
        // If the string is not null terminated, the behavior is undefined (likely hang)
        //
        static bool IsUtf16StringValid(const UChar* str, size_t length, size_t* invalidIndex)
        {
            Assert(invalidIndex != nullptr);
            *invalidIndex = -1;

            size_t i = 0;

            for (;;)
            {
                // Iterate through the UTF16-LE string
                // If we are at the end of the null terminated string, return true
                // since the string is valid
                // If not, check if the codepoint we have is a surrogate code unit.
                // If it is, the string is malformed since U16_NEXT would have returned
                // is the full codepoint if both code units in the surrogate pair were present
                UChar32 c;
                U16_NEXT(str, i, length, c);
                if (c == 0)
                {
                    return true;
                }
                if (U_IS_SURROGATE(c))
                {
                    if (U16_IS_LEAD(c))
                    {
                        *invalidIndex = i;
                    }
                    else
                    {
                        Assert(i > 0);
                        *invalidIndex = i - 1;
                    }

                    return false;
                }

                if (i >= length)
                {
                    return true;
                }
            }
        }

        static ApiError TranslateUErrorCode(UErrorCode icuError)
        {
#if DBG
            g_lastErrorCode = icuError;
#endif

            switch (icuError)
            {
                case U_BUFFER_OVERFLOW_ERROR:
                    return ApiError::InsufficientBuffer;
                case U_ILLEGAL_ARGUMENT_ERROR:
                case U_UNSUPPORTED_ERROR:
                    return ApiError::InvalidParameter;
                case U_INVALID_CHAR_FOUND:
                case U_TRUNCATED_CHAR_FOUND:
                case U_ILLEGAL_CHAR_FOUND:
                    return ApiError::InvalidUnicodeText;
                default:
                    return ApiError::UntranslatedError;
            }
        }

        // Linux ICU implementation of platform-agnostic Unicode interface
        int32 NormalizeString(NormalizationForm normalizationForm, const char16* sourceString, uint32 sourceLength, char16* destString, int32 destLength, ApiError* pErrorOut)
        {
            // Assert pointers
            Assert(sourceString != nullptr);
            Assert(destString != nullptr || destLength == 0);

            // This is semantically different than the Win32 NormalizeString API
            // For our usage, we always pass in the length rather than letting Windows
            // calculate the length for us
            Assert(sourceLength > 0);
            Assert(destLength >= 0);

            *pErrorOut = NoError;

            // On Windows, IsNormalizedString returns failure if the string
            // is a malformed utf16 string. Maintain the same behavior here.
            // Note that Windows returns this failure only if the dest buffer
            // is passed in, not in the estimation case
            size_t invalidIndex = 0;
            if (destString != nullptr && !IsUtf16StringValid((const UChar*) sourceString, sourceLength, &invalidIndex))
            {
                *pErrorOut = InvalidUnicodeText;
                return -1 * invalidIndex; // mimicking the behavior of Win32 NormalizeString
            }

            const Normalizer2* normalizer = TranslateToICUNormalizer(normalizationForm);
            Assert(normalizer != nullptr);

            const UnicodeString sourceUniStr((const UChar*) sourceString, sourceLength);

            UErrorCode errorCode = U_ZERO_ERROR;
            const UnicodeString destUniStr = normalizer->normalize(sourceUniStr, errorCode);

            if (U_FAILURE(errorCode))
            {
                *pErrorOut = TranslateUErrorCode(errorCode);
            }

            // xplat-todo: we could possibly make this more efficient and save the buffer copy
            // that destUniStr causes
            int32_t normalizedStringLength = destUniStr.length();
            if (destLength == 0 && normalizedStringLength >= 0)
            {
                *pErrorOut = ApiError::InsufficientBuffer;
                return normalizedStringLength;
            }

            destUniStr.extract((UChar*) destString, destLength, errorCode);
            if (U_FAILURE(errorCode))
            {
                *pErrorOut = TranslateUErrorCode(errorCode);
                return -1;
            }

            return normalizedStringLength;
        }

        bool IsNormalizedString(NormalizationForm normalizationForm, const char16* testString, int32 testStringLength)
        {
            Assert(testString != nullptr);
            UErrorCode errorCode = U_ZERO_ERROR;

            size_t length = static_cast<size_t>(testStringLength);
            if (testStringLength < 0)
            {
                length = u_strlen((const UChar*) testString);
            }

            // On Windows, IsNormalizedString returns failure if the string
            // is a malformed utf16 string. Maintain the same behavior here.
            size_t invalidIndex = 0;
            if (!IsUtf16StringValid((const UChar*) testString, length, &invalidIndex))
            {
                return false;
            }

            const Normalizer2* normalizer = TranslateToICUNormalizer(normalizationForm);
            Assert(normalizer != nullptr);

            const UnicodeString testUniStr((const UChar*) testString, length);
            bool isNormalized = normalizer->isNormalized(testUniStr, errorCode);

            Assert(U_SUCCESS(errorCode));
            return isNormalized;
        }

        // Since we're using the ICU here, this is trivially true
        bool IsExternalUnicodeLibraryAvailable()
        {
            return true;
        }

        bool IsWhitespace(codepoint_t ch)
        {
            return u_isUWhiteSpace(ch) == 1;
        }

        bool IsIdStart(codepoint_t ch)
        {
            if (u_isIDStart(ch))
            {
                return true;
            }

            // Following codepoints are treated as part of ID_Start
            // for backwards compatibility as per section 2.5 of the Unicode 8 spec
            // See http://www.unicode.org/reports/tr31/tr31-23.html#Backward_Compatibility
            // The exact list is in PropList.txt in the Unicode database
            switch (ch)
            {
            case 0x2118: return true; // SCRIPT CAPITAL P
            case 0x212E: return true; // ESTIMATED SYMBOL
            case 0x309B: return true; // KATAKANA-HIRAGANA VOICED SOUND MARK
            case 0x309C: return true; // KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK
            default: return false;
            }
        }

        bool IsIdContinue(codepoint_t ch)
        {
            if (u_hasBinaryProperty(ch, UCHAR_ID_CONTINUE) == 1)
            {
                return true;
            }

            // Following codepoints are treated as part of ID_Continue
            // for backwards compatibility as per section 2.5 of the Unicode 8 spec
            // See http://www.unicode.org/reports/tr31/tr31-23.html#Backward_Compatibility
            // The exact list is in PropList.txt in the Unicode database
            switch (ch)
            {
            case 0x00B7: return true; // MIDDLE DOT
            case 0x0387: return true; // GREEK ANO TELEIA
            case 0x1369: return true; // ETHIOPIC DIGIT ONE
            case 0x136A: return true; // ETHIOPIC DIGIT TWO
            case 0x136B: return true; // ETHIOPIC DIGIT THREE
            case 0x136C: return true; // ETHIOPIC DIGIT FOUR
            case 0x136D: return true; // ETHIOPIC DIGIT FIVE
            case 0x136E: return true; // ETHIOPIC DIGIT SIX
            case 0x136F: return true; // ETHIOPIC DIGIT SEVEN
            case 0x1370: return true; // ETHIOPIC DIGIT EIGHT
            case 0x1371: return true; // ETHIOPIC DIGIT NINE
            case 0x19DA: return true; // NEW TAI LUE THAM DIGIT ONE
            default: return false;
            }
        }

        UnicodeGeneralCategoryClass GetGeneralCategoryClass(codepoint_t ch)
        {
            int8_t charType = u_charType(ch);

            if (charType == U_LOWERCASE_LETTER ||
                charType == U_UPPERCASE_LETTER ||
                charType == U_TITLECASE_LETTER ||
                charType == U_MODIFIER_LETTER ||
                charType == U_OTHER_LETTER ||
                charType == U_LETTER_NUMBER)
            {
                return UnicodeGeneralCategoryClass::CategoryClassLetter;
            }

            if (charType == U_DECIMAL_DIGIT_NUMBER)
            {
                return UnicodeGeneralCategoryClass::CategoryClassDigit;
            }

            if (charType == U_LINE_SEPARATOR)
            {
                return UnicodeGeneralCategoryClass::CategoryClassLineSeparator;
            }

            if (charType == U_PARAGRAPH_SEPARATOR)
            {
                return UnicodeGeneralCategoryClass::CategoryClassParagraphSeparator;
            }

            if (charType == U_SPACE_SEPARATOR)
            {
                return UnicodeGeneralCategoryClass::CategoryClassSpaceSeparator;
            }

            if (charType == U_COMBINING_SPACING_MARK)
            {
                return UnicodeGeneralCategoryClass::CategoryClassSpacingCombiningMark;
            }

            if (charType == U_NON_SPACING_MARK)
            {
                return UnicodeGeneralCategoryClass::CategoryClassNonSpacingMark;
            }

            if (charType == U_CONNECTOR_PUNCTUATION)
            {
                return UnicodeGeneralCategoryClass::CategoryClassConnectorPunctuation;
            }

            return UnicodeGeneralCategoryClass::CategoryClassOther;
        }

        // We actually don't care about the legacy behavior on Linux since no one
        // has a dependency on it. So this actually is different between
        // Windows and Linux
        CharacterClassificationType GetLegacyCharacterClassificationType(char16 character)
        {
            auto charTypeMask = U_GET_GC_MASK(character);

            if ((charTypeMask & U_GC_L_MASK) != 0)
            {
                return CharacterClassificationType::Letter;
            }

            if ((charTypeMask & (U_GC_ND_MASK | U_GC_P_MASK)) != 0)
            {
                return CharacterClassificationType::DigitOrPunct;
            }

            // As per http://archives.miloush.net/michkap/archive/2007/06/11/3230072.html
            //  * C1_SPACE corresponds to the Unicode Zs category.
            //  * C1_BLANK corresponds to a hardcoded list thats ill-defined.
            // We'll skip that compatibility here and just check for Zs.
            // We explicitly check for 0xFEFF to satisfy the unit test in es5/Lex_u3.js
            if ((charTypeMask & U_GC_ZS_MASK) != 0 ||
                character == 0xFEFF ||
                character == 0xFFFE)
            {
                return CharacterClassificationType::Whitespace;
            }

            return CharacterClassificationType::Invalid;
        }

        int32 ChangeStringLinguisticCase(CaseFlags caseFlags, const char16* sourceString, uint32 sourceLength, char16* destString, uint32 destLength, ApiError* pErrorOut)
        {
            int32_t resultStringLength = 0;
            UErrorCode errorCode = U_ZERO_ERROR;

            static_assert(sizeof(UChar) == sizeof(char16), "Unexpected char type from ICU, function might have to be updated");
            if (caseFlags == CaseFlagsUpper)
            {
                resultStringLength = u_strToUpper((UChar*) destString, destLength,
                    (UChar*) sourceString, sourceLength, NULL, &errorCode);
            }
            else if (caseFlags == CaseFlagsLower)
            {
                resultStringLength = u_strToLower((UChar*) destString, destLength,
                    (UChar*) sourceString, sourceLength, NULL, &errorCode);
            }
            else
            {
                Assert(false);
            }

            if (U_FAILURE(errorCode))
            {
                *pErrorOut = TranslateUErrorCode(errorCode);
                return -1;
            }

            // Todo: check for resultStringLength > destLength
            // Return insufficient buffer in that case
            return resultStringLength;
        }

        uint32 ChangeStringCaseInPlace(CaseFlags caseFlags, char16* stringToChange, uint32 bufferLength)
        {
            // Assert pointers
            Assert(stringToChange != nullptr);
            ApiError error = NoError;

            if (bufferLength == 0 || stringToChange == nullptr)
            {
                return 0;
            }

            int32 ret = ChangeStringLinguisticCase(caseFlags, stringToChange, bufferLength, stringToChange, bufferLength, &error);

            // Callers to this function don't expect any errors
            Assert(error == ApiError::NoError);
            Assert(ret > 0);
            return (uint32) ret;
        }

        int LogicalStringCompare(const char16* string1, const char16* string2)
        {
            return PlatformAgnostic::UnicodeText::Internal::LogicalStringCompareImpl<char16>(string1, string2);
        }
    };
};
<|endoftext|>