<commit_before>////////////////////////////////////////////////////////////////////////////////////
// Authors: Mateus Fogaca
//          (Ph.D. advisor: Ricardo Reis)
//          Jiajia Li
//          Andrew Kahng
// Based on:
//          K. Han, A. B. Kahng and J. Li, "Optimal Generalized H-Tree Topology and
//          Buffering for High-Performance and Low-Power Clock Distribution",
//          IEEE Trans. on CAD (2018), doi:10.1109/TCAD.2018.2889756.
//
//
// BSD 3-Clause License
//
// Copyright (c) 2018, The Regents of the University of California
// 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 copyright holder 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 HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////////

#include "DbWrapper.h"
#include "TritonCTSKernel.h"
#include "HTreeBuilder.h"

// DB includes
#include "db.h"
#include "dbShape.h"
#include "dbTypes.h"

#include <iostream>
#include <sstream>

namespace TritonCTS {

DbWrapper::DbWrapper(CtsOptions& options,
                     TritonCTSKernel& kernel) {
        _options  = &options;
        _kernel = &kernel;
}

void DbWrapper::populateTritonCTS() {
       initDB();
       initAllClocks();
}

void DbWrapper::initDB() {
        _db    = odb::dbDatabase::getDatabase(_options->getDbId());
        _chip  = _db->getChip();
        _block = _chip->getBlock();
        _options->setDbUnits(_block->getDbUnitsPerMicron());
}

void DbWrapper::initAllClocks() {
        std::cout << " Initializing clock nets\n";

        std::vector<std::string> clockNetNames;
        parseClockNames(clockNetNames);

        std::cout << " Looking for clock nets in the design\n";
        for (const std::string& name: clockNetNames) {
                odb::dbNet* net = _block->findNet(name.c_str());
                if (!net) {
                        odb::dbITerm* iterm = _block->findITerm(name.c_str());
                        net = iterm->getNet();
                }
                if (!net) {
                        std::cout << " [WARNING] Net \"" << name << "\" not in design. Skipping...\n";
                        continue;
                }

                std::cout << " Net \"" << name << "\" found\n";
                initClock(net);
        }
}

void DbWrapper::initClock(odb::dbNet* net) {
        std::string driver = "";
        odb::dbITerm* iterm = net->getFirstOutput();
        int xPin, yPin;
        if (!iterm) {
                odb::dbBTerm* bterm = net->get1stBTerm(); // Clock pin
                driver = bterm->getConstName();
                bterm->getFirstPinLocation(xPin, yPin);
         } else {
                odb::dbInst* inst = iterm->getInst();
                odb::dbMTerm* mterm = iterm->getMTerm();
                std::string driver = std::string(inst->getConstName()) + "/" +
                                   std::string(mterm->getConstName());
                DBU xTmp, yTmp;
                computeITermPosition(iterm, xTmp, yTmp);
                xPin = xTmp; yPin = yTmp;
        }

        // Initialize clock net
        std::cout << net->getConstName() << std::endl;

        Clock clockNet(net->getConstName(),
                       driver,
                       xPin, yPin);

        odb::dbSet<odb::dbITerm> iterms = net->getITerms();
        odb::dbSet<odb::dbITerm>::iterator itr;
        for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
                odb::dbITerm* iterm = *itr;
                odb::dbInst* inst = iterm->getInst();
                odb::dbMTerm* mterm = iterm->getMTerm();
                std::string name = std::string(inst->getConstName()) + "/" +
                                   std::string(mterm->getConstName());
                DBU x, y;
                computeITermPosition(iterm, x, y);
                clockNet.addSink(name, x, y);
        }

        if (clockNet.getNumSinks() < 2) {
                std::cout << "    [WARNING] Net \"" << clockNet.getName() << "\""
                          << " has " << clockNet.getNumSinks()  << " sinks. Skipping...\n";
                return;

        }

        _kernel->addBuilder(new HTreeBuilder(*_options, clockNet));
}

void DbWrapper::parseClockNames(std::vector<std::string>& clockNetNames) const {
        std::stringstream allNames(_options->getClockNets());

        std::string tmpName = "";
        while (allNames >> tmpName) {
                clockNetNames.push_back(tmpName);
        }

        unsigned numClocks = clockNetNames.size();
        std::cout << " Number of user-input clocks: " << numClocks;

        if (numClocks > 0) {
                std::cout << " (";
                for (const std::string& name: clockNetNames) {
                        std::cout << " \"" << name << "\"";
                }
                std::cout << " )\n";
        } else {
                std::cout << "\n";
                std::cout << " [ERROR] No clock nets have been found.\n";
                std::exit(1);

        }
}

void DbWrapper::computeITermPosition(odb::dbITerm* term, DBU &x, DBU &y) const {
        odb::dbITermShapeItr itr;

        odb::dbShape shape;
        x = 0;
        y = 0;
        unsigned numShapes = 0;
        for (itr.begin(term); itr.next(shape); ) {
                if (shape.isVia()) {
                        continue;
                } else {
                        x += shape.xMin() + (shape.xMax() - shape.xMin()) / 2;
                        y += shape.yMin() + (shape.yMax() - shape.yMin()) / 2;
                        ++numShapes;
                }
        }

        x /= numShapes;
        y /= numShapes;
};

void DbWrapper::writeClockNetsToDb(const Clock& clockNet) {
        std::cout << " Writing clock net \"" << clockNet.getName() << "\" to DB\n";

        disconnectAllSinksFromNet(clockNet.getName());

        createClockBuffers(clockNet);

        // connect top buffer on the clock pin
        odb::dbNet* topClockNet = _block->findNet(clockNet.getName().c_str());
        std::string topClockInstName = "clkbuf_0_" + clockNet.getName();
        odb::dbInst* topClockInst = _block->findInst(topClockInstName.c_str());
        odb::dbITerm* topClockInstInputPin = getFirstInput(topClockInst);
        odb::dbITerm::connect(topClockInstInputPin, topClockNet);
        topClockNet->setSigType(odb::dbSigType::CLOCK);

        // create subNets
        unsigned numClkNets = 0;
        clockNet.forEachSubNet( [&] (const Clock::SubNet& subNet) {
                        //std::cout << "    SubNet: " << subNet.getName() << "\n";
                        odb::dbNet* clkSubNet = odb::dbNet::create(_block, subNet.getName().c_str());
                        ++numClkNets;
                        clkSubNet->setSigType(odb::dbSigType::CLOCK);

                        //std::cout << "      Driver: " << subNet.getDriver()->getName() << "\n";

                        odb::dbInst* driver = _block->findInst(subNet.getDriver()->getName().c_str());
                        odb::dbITerm* outputPin = driver->getFirstOutput();
                        odb::dbITerm::connect(outputPin, clkSubNet);

                        subNet.forEachSink( [&] (ClockInst *inst) {
                                //std::cout << "      " << inst->getName() << "\n";
                                odb::dbITerm* inputPin = nullptr;
                                if (inst->isClockBuffer()) {
                                        odb::dbInst* sink = _block->findInst(inst->getName().c_str());
                                        inputPin = getFirstInput(sink);
                                } else {
                                        inputPin = _block->findITerm(inst->getName().c_str());
                                }
                                odb::dbITerm::connect(inputPin, clkSubNet);
                        });
                });

        if (_options->writeOnlyClockNets()) {
                removeNonClockNets();
        }

        std::cout << "    Created " << numClkNets << " clock nets.\n";
}

void DbWrapper::disconnectAllSinksFromNet(std::string netName) {
        odb::dbNet* net = _block->findNet(netName.c_str());
        odb::dbSet<odb::dbITerm> iterms = net->getITerms();
        odb::dbSet<odb::dbITerm>::iterator itr;
        for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
                odb::dbITerm* iterm = *itr;
                if (item->getIoType() != INPUT) {
                        continue;
                }
                odb::dbITerm::disconnect(iterm);
        }
}

void DbWrapper::createClockBuffers(const Clock& clockNet) {
        unsigned numBuffers = 0;
        clockNet.forEachClockBuffer([&] (const ClockInst& inst) {
                odb::dbMaster* master = _db->findMaster(inst.getMaster().c_str());
                odb::dbInst* newInst = odb::dbInst::create(_block, master, inst.getName().c_str());
                newInst->setLocation(inst.getX(), inst.getY());
                newInst->setPlacementStatus(odb::dbPlacementStatus::PLACED);
                ++numBuffers;
        });
        std::cout << "    Created " << numBuffers << " clock buffers.\n";
}

odb::dbITerm* DbWrapper::getFirstInput(odb::dbInst* inst) const {
        odb::dbSet<odb::dbITerm> iterms = inst->getITerms();
        odb::dbSet<odb::dbITerm>::iterator itr;

        for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
                odb::dbITerm* iterm = *itr;
                if (iterm->isInputSignal()) {
                        return iterm;
                }
        }

        return nullptr;
}

bool DbWrapper::masterExists(const std::string& master) const {
        return _db->findMaster(master.c_str());
};

void DbWrapper::removeNonClockNets() {
        for (odb::dbNet* net : _block->getNets()) {
                if (net->getSigType() != odb::dbSigType::CLOCK) {
                        odb::dbNet::destroy(net);
                }
        }
}

}
<commit_msg>[TritonCTS] Fix typo<commit_after>////////////////////////////////////////////////////////////////////////////////////
// Authors: Mateus Fogaca
//          (Ph.D. advisor: Ricardo Reis)
//          Jiajia Li
//          Andrew Kahng
// Based on:
//          K. Han, A. B. Kahng and J. Li, "Optimal Generalized H-Tree Topology and
//          Buffering for High-Performance and Low-Power Clock Distribution",
//          IEEE Trans. on CAD (2018), doi:10.1109/TCAD.2018.2889756.
//
//
// BSD 3-Clause License
//
// Copyright (c) 2018, The Regents of the University of California
// 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 copyright holder 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 HOLDER OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
// SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
// CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
////////////////////////////////////////////////////////////////////////////////////

#include "DbWrapper.h"
#include "TritonCTSKernel.h"
#include "HTreeBuilder.h"

// DB includes
#include "db.h"
#include "dbShape.h"
#include "dbTypes.h"

#include <iostream>
#include <sstream>

namespace TritonCTS {

DbWrapper::DbWrapper(CtsOptions& options,
                     TritonCTSKernel& kernel) {
        _options  = &options;
        _kernel = &kernel;
}

void DbWrapper::populateTritonCTS() {
       initDB();
       initAllClocks();
}

void DbWrapper::initDB() {
        _db    = odb::dbDatabase::getDatabase(_options->getDbId());
        _chip  = _db->getChip();
        _block = _chip->getBlock();
        _options->setDbUnits(_block->getDbUnitsPerMicron());
}

void DbWrapper::initAllClocks() {
        std::cout << " Initializing clock nets\n";

        std::vector<std::string> clockNetNames;
        parseClockNames(clockNetNames);

        std::cout << " Looking for clock nets in the design\n";
        for (const std::string& name: clockNetNames) {
                odb::dbNet* net = _block->findNet(name.c_str());
                if (!net) {
                        odb::dbITerm* iterm = _block->findITerm(name.c_str());
                        net = iterm->getNet();
                }
                if (!net) {
                        std::cout << " [WARNING] Net \"" << name << "\" not in design. Skipping...\n";
                        continue;
                }

                std::cout << " Net \"" << name << "\" found\n";
                initClock(net);
        }
}

void DbWrapper::initClock(odb::dbNet* net) {
        std::string driver = "";
        odb::dbITerm* iterm = net->getFirstOutput();
        int xPin, yPin;
        if (!iterm) {
                odb::dbBTerm* bterm = net->get1stBTerm(); // Clock pin
                driver = bterm->getConstName();
                bterm->getFirstPinLocation(xPin, yPin);
         } else {
                odb::dbInst* inst = iterm->getInst();
                odb::dbMTerm* mterm = iterm->getMTerm();
                std::string driver = std::string(inst->getConstName()) + "/" +
                                   std::string(mterm->getConstName());
                DBU xTmp, yTmp;
                computeITermPosition(iterm, xTmp, yTmp);
                xPin = xTmp; yPin = yTmp;
        }

        // Initialize clock net
        std::cout << net->getConstName() << std::endl;

        Clock clockNet(net->getConstName(),
                       driver,
                       xPin, yPin);

        odb::dbSet<odb::dbITerm> iterms = net->getITerms();
        odb::dbSet<odb::dbITerm>::iterator itr;
        for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
                odb::dbITerm* iterm = *itr;
                odb::dbInst* inst = iterm->getInst();
                odb::dbMTerm* mterm = iterm->getMTerm();
                std::string name = std::string(inst->getConstName()) + "/" +
                                   std::string(mterm->getConstName());
                DBU x, y;
                computeITermPosition(iterm, x, y);
                clockNet.addSink(name, x, y);
        }

        if (clockNet.getNumSinks() < 2) {
                std::cout << "    [WARNING] Net \"" << clockNet.getName() << "\""
                          << " has " << clockNet.getNumSinks()  << " sinks. Skipping...\n";
                return;

        }

        _kernel->addBuilder(new HTreeBuilder(*_options, clockNet));
}

void DbWrapper::parseClockNames(std::vector<std::string>& clockNetNames) const {
        std::stringstream allNames(_options->getClockNets());

        std::string tmpName = "";
        while (allNames >> tmpName) {
                clockNetNames.push_back(tmpName);
        }

        unsigned numClocks = clockNetNames.size();
        std::cout << " Number of user-input clocks: " << numClocks;

        if (numClocks > 0) {
                std::cout << " (";
                for (const std::string& name: clockNetNames) {
                        std::cout << " \"" << name << "\"";
                }
                std::cout << " )\n";
        } else {
                std::cout << "\n";
                std::cout << " [ERROR] No clock nets have been found.\n";
                std::exit(1);

        }
}

void DbWrapper::computeITermPosition(odb::dbITerm* term, DBU &x, DBU &y) const {
        odb::dbITermShapeItr itr;

        odb::dbShape shape;
        x = 0;
        y = 0;
        unsigned numShapes = 0;
        for (itr.begin(term); itr.next(shape); ) {
                if (shape.isVia()) {
                        continue;
                } else {
                        x += shape.xMin() + (shape.xMax() - shape.xMin()) / 2;
                        y += shape.yMin() + (shape.yMax() - shape.yMin()) / 2;
                        ++numShapes;
                }
        }

        x /= numShapes;
        y /= numShapes;
};

void DbWrapper::writeClockNetsToDb(const Clock& clockNet) {
        std::cout << " Writing clock net \"" << clockNet.getName() << "\" to DB\n";

        disconnectAllSinksFromNet(clockNet.getName());

        createClockBuffers(clockNet);

        // connect top buffer on the clock pin
        odb::dbNet* topClockNet = _block->findNet(clockNet.getName().c_str());
        std::string topClockInstName = "clkbuf_0_" + clockNet.getName();
        odb::dbInst* topClockInst = _block->findInst(topClockInstName.c_str());
        odb::dbITerm* topClockInstInputPin = getFirstInput(topClockInst);
        odb::dbITerm::connect(topClockInstInputPin, topClockNet);
        topClockNet->setSigType(odb::dbSigType::CLOCK);

        // create subNets
        unsigned numClkNets = 0;
        clockNet.forEachSubNet( [&] (const Clock::SubNet& subNet) {
                        //std::cout << "    SubNet: " << subNet.getName() << "\n";
                        odb::dbNet* clkSubNet = odb::dbNet::create(_block, subNet.getName().c_str());
                        ++numClkNets;
                        clkSubNet->setSigType(odb::dbSigType::CLOCK);

                        //std::cout << "      Driver: " << subNet.getDriver()->getName() << "\n";

                        odb::dbInst* driver = _block->findInst(subNet.getDriver()->getName().c_str());
                        odb::dbITerm* outputPin = driver->getFirstOutput();
                        odb::dbITerm::connect(outputPin, clkSubNet);

                        subNet.forEachSink( [&] (ClockInst *inst) {
                                //std::cout << "      " << inst->getName() << "\n";
                                odb::dbITerm* inputPin = nullptr;
                                if (inst->isClockBuffer()) {
                                        odb::dbInst* sink = _block->findInst(inst->getName().c_str());
                                        inputPin = getFirstInput(sink);
                                } else {
                                        inputPin = _block->findITerm(inst->getName().c_str());
                                }
                                odb::dbITerm::connect(inputPin, clkSubNet);
                        });
                });

        if (_options->writeOnlyClockNets()) {
                removeNonClockNets();
        }

        std::cout << "    Created " << numClkNets << " clock nets.\n";
}

void DbWrapper::disconnectAllSinksFromNet(std::string netName) {
        odb::dbNet* net = _block->findNet(netName.c_str());
        odb::dbSet<odb::dbITerm> iterms = net->getITerms();
        odb::dbSet<odb::dbITerm>::iterator itr;
        for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
                odb::dbITerm* iterm = *itr;
                if (iterm->getIoType() != INPUT) {
                        continue;
                }
                odb::dbITerm::disconnect(iterm);
        }
}

void DbWrapper::createClockBuffers(const Clock& clockNet) {
        unsigned numBuffers = 0;
        clockNet.forEachClockBuffer([&] (const ClockInst& inst) {
                odb::dbMaster* master = _db->findMaster(inst.getMaster().c_str());
                odb::dbInst* newInst = odb::dbInst::create(_block, master, inst.getName().c_str());
                newInst->setLocation(inst.getX(), inst.getY());
                newInst->setPlacementStatus(odb::dbPlacementStatus::PLACED);
                ++numBuffers;
        });
        std::cout << "    Created " << numBuffers << " clock buffers.\n";
}

odb::dbITerm* DbWrapper::getFirstInput(odb::dbInst* inst) const {
        odb::dbSet<odb::dbITerm> iterms = inst->getITerms();
        odb::dbSet<odb::dbITerm>::iterator itr;

        for (itr = iterms.begin(); itr != iterms.end(); ++itr) {
                odb::dbITerm* iterm = *itr;
                if (iterm->isInputSignal()) {
                        return iterm;
                }
        }

        return nullptr;
}

bool DbWrapper::masterExists(const std::string& master) const {
        return _db->findMaster(master.c_str());
};

void DbWrapper::removeNonClockNets() {
        for (odb::dbNet* net : _block->getNets()) {
                if (net->getSigType() != odb::dbSigType::CLOCK) {
                        odb::dbNet::destroy(net);
                }
        }
}

}
<|endoftext|>


<commit_before>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include <XPath/FunctionTranslate.hpp>

FunctionTranslate::FunctionTranslate()
{
}

FunctionTranslate::~FunctionTranslate()
{
}

XObjectPtr
FunctionTranslate::execute(
		XPathExecutionContext&			executionContext,
		XalanNode*						/* context */,
		const XObjectPtr				arg1,
		const XObjectPtr				arg2,
		const XObjectPtr				arg3)
{
	assert(arg1.null() == false && arg2.null() == false && arg3.null() == false);

	const XalanDOMString&	theFirstString = arg1->str();
	const XalanDOMString&	theSecondString = arg2->str();
	const XalanDOMString&	theThirdString = arg3->str();

	const unsigned int		theFirstStringLength = length(theFirstString);
	const unsigned int		theSecondStringLength = length(theSecondString);
	const unsigned int		theThirdStringLength = length(theThirdString);

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<XalanDOMChar>		VectorType;
#else
	typedef std::vector<XalanDOMChar>	VectorType;
#endif

	// A vector to contain the new characters.  We'll use it to construct
	// the result string.
	VectorType	theBuffer;

	// The result string can only be as large as the first string, so
	// just reserve the space now.  Also reserve space for the
	// terminating 0.
	theBuffer.reserve(theFirstStringLength + 1);

	for (unsigned int i = 0; i < theFirstStringLength; i++)
	{
		const XalanDOMChar		theCurrentChar = charAt(theFirstString, i);

		const unsigned int		theIndex = indexOf(theSecondString, theCurrentChar);

		if (theIndex >= theSecondStringLength)
		{
			// Didn't find the character in the second string, so it
			// is not translated.
			theBuffer.push_back(theCurrentChar);
		}
		else if (theIndex < theThirdStringLength)
		{
			// OK, there's a corresponding character in the
			// third string, so do the translation...
			theBuffer.push_back(charAt(theThirdString, theIndex));
		}
		else
		{
			// There's no corresponding character in the
			// third string, since it's shorter than the
			// second string.  In this case, the character
			// is removed from the output string, so don't
			// do anything.
		}
	}

	const VectorType::size_type		theSize = theBuffer.size();

	if (theSize == 0)
	{
		return executionContext.getXObjectFactory().createString(XalanDOMString());
	}
	else
	{
		return executionContext.getXObjectFactory().createString(theBuffer.begin(), theSize);
	}
}

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
Function*
#else
FunctionTranslate*
#endif
FunctionTranslate::clone() const
{
	return new FunctionTranslate(*this);
}

const XalanDOMString
FunctionTranslate::getError() const
{
	return XALAN_STATIC_UCODE_STRING(
		"The translate() function takes three arguments!");
}

<commit_msg>Changes for vector iterator issues.<commit_after>/*
 * The Apache Software License, Version 1.1
 *
 *
 * Copyright (c) 2000 The Apache Software Foundation.  All rights
 * reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 * 2. 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.
 *
 * 3. The end-user documentation included with the redistribution,
 *    if any, must include the following acknowledgment:
 *       "This product includes software developed by the
 *        Apache Software Foundation (http://www.apache.org/)."
 *    Alternately, this acknowledgment may appear in the software itself,
 *    if and wherever such third-party acknowledgments normally appear.
 *
 * 4. The names "Xalan" and "Apache Software Foundation" must
 *    not be used to endorse or promote products derived from this
 *    software without prior written permission. For written
 *    permission, please contact apache@apache.org.
 *
 * 5. Products derived from this software may not be called "Apache",
 *    nor may "Apache" appear in their name, without prior written
 *    permission of the Apache Software Foundation.
 *
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED 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 APACHE SOFTWARE FOUNDATION OR
 * ITS 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.
 * ====================================================================
 *
 * This software consists of voluntary contributions made by many
 * individuals on behalf of the Apache Software Foundation and was
 * originally based on software copyright (c) 1999, International
 * Business Machines, Inc., http://www.ibm.com.  For more
 * information on the Apache Software Foundation, please see
 * <http://www.apache.org/>.
 */
#include <XPath/FunctionTranslate.hpp>

FunctionTranslate::FunctionTranslate()
{
}

FunctionTranslate::~FunctionTranslate()
{
}

XObjectPtr
FunctionTranslate::execute(
		XPathExecutionContext&			executionContext,
		XalanNode*						/* context */,
		const XObjectPtr				arg1,
		const XObjectPtr				arg2,
		const XObjectPtr				arg3)
{
	assert(arg1.null() == false && arg2.null() == false && arg3.null() == false);

	const XalanDOMString&	theFirstString = arg1->str();
	const XalanDOMString&	theSecondString = arg2->str();
	const XalanDOMString&	theThirdString = arg3->str();

	const unsigned int		theFirstStringLength = length(theFirstString);
	const unsigned int		theSecondStringLength = length(theSecondString);
	const unsigned int		theThirdStringLength = length(theThirdString);

#if defined(XALAN_NO_NAMESPACES)
	typedef vector<XalanDOMChar>		VectorType;
#else
	typedef std::vector<XalanDOMChar>	VectorType;
#endif

	// A vector to contain the new characters.  We'll use it to construct
	// the result string.
	VectorType	theBuffer;

	// The result string can only be as large as the first string, so
	// just reserve the space now.  Also reserve space for the
	// terminating 0.
	theBuffer.reserve(theFirstStringLength + 1);

	for (unsigned int i = 0; i < theFirstStringLength; i++)
	{
		const XalanDOMChar		theCurrentChar = charAt(theFirstString, i);

		const unsigned int		theIndex = indexOf(theSecondString, theCurrentChar);

		if (theIndex >= theSecondStringLength)
		{
			// Didn't find the character in the second string, so it
			// is not translated.
			theBuffer.push_back(theCurrentChar);
		}
		else if (theIndex < theThirdStringLength)
		{
			// OK, there's a corresponding character in the
			// third string, so do the translation...
			theBuffer.push_back(charAt(theThirdString, theIndex));
		}
		else
		{
			// There's no corresponding character in the
			// third string, since it's shorter than the
			// second string.  In this case, the character
			// is removed from the output string, so don't
			// do anything.
		}
	}

	const VectorType::size_type		theSize = theBuffer.size();

	if (theSize == 0)
	{
		return executionContext.getXObjectFactory().createString(XalanDOMString());
	}
	else
	{
		return executionContext.getXObjectFactory().createString(&*theBuffer.begin(), theSize);
	}
}

#if defined(XALAN_NO_COVARIANT_RETURN_TYPE)
Function*
#else
FunctionTranslate*
#endif
FunctionTranslate::clone() const
{
	return new FunctionTranslate(*this);
}

const XalanDOMString
FunctionTranslate::getError() const
{
	return XALAN_STATIC_UCODE_STRING(
		"The translate() function takes three arguments!");
}

<|endoftext|>


<commit_before>/**
 * \file bt_icma_core.cpp
 * \brief
 * \date Aug 20, 2010
 * \author Vernkin Chen
 */

#include <boost/test/unit_test.hpp>

#include "icma/icma.h"

#include <string>
#include <vector>

using namespace cma;
using namespace std;

Knowledge* globalKnowledge = NULL;

void createKnowledgeAndAnalyzer(
        Knowledge** knowledge,
        Analyzer** analyzer,
        int analysisType = 3,
        const string dictPath = "../db/icwb/utf8/"
        )
{
    CMA_Factory* factory = CMA_Factory::instance();

    if( globalKnowledge == NULL )
    {
        globalKnowledge = factory->createKnowledge();
        globalKnowledge->loadModel( dictPath.c_str(), true );
    }
    *knowledge = globalKnowledge;

    *analyzer = factory->createAnalyzer();
    (*analyzer)->setKnowledge( *knowledge );
    (*analyzer)->setOption( Analyzer::OPTION_ANALYSIS_TYPE, analysisType );
}

BOOST_AUTO_TEST_SUITE(icma_core_test)

BOOST_AUTO_TEST_CASE(icma_basicapi)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 3 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test Knowledge API
    BOOST_CHECK( Knowledge::decodeEncodeType( "utf8" ) == Knowledge::ENCODE_TYPE_UTF8 );
    BOOST_CHECK( knowledge->isSupportPOS() == true );
    string word = "衣服";
    BOOST_CHECK( knowledge->isExistWord( word.c_str() ) == true );

    vector< string > words;
    words.push_back( word );
    knowledge->disableWords( words );
    BOOST_CHECK( knowledge->isExistWord( word.c_str() ) == false );
    knowledge->enableWords( words );
    BOOST_CHECK( knowledge->isExistWord( word.c_str() ) == true );

    // test Analyzer API
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    BOOST_CHECK( analyzer->getOption( Analyzer::OPTION_TYPE_NBEST) == 3 );

    int posCode;
    string posValue = "N";
    posCode = analyzer->getCodeFromStr( posValue );
    BOOST_CHECK( posCode >= 0 );
    string posRetValue = analyzer->getStrFromCode( posCode );
    BOOST_CHECK( posRetValue == posValue );

    delete analyzer;
    //delete knowledge;
}

// forwards minimum cover
BOOST_AUTO_TEST_CASE(icma_fminconver)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 3 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/P  和/AG  和衣/V  衣/N  衣服/N  服/J  的/A  故事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 1 );
    BOOST_CHECK( sent.getCount( 0 ) == 8 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "和衣" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "V" ) == 0 );

    delete analyzer;
    //delete knowledge;
}

// forwards minimum cover with unigram
BOOST_AUTO_TEST_CASE(icma_fmincover_unigram)
{
	Knowledge* knowledge = NULL;
	Analyzer* analyzer = NULL;
	createKnowledgeAndAnalyzer( &knowledge, &analyzer, 4 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/P  和/AG  和衣/V  衣/N  衣服/N  服/J  的/A  故/C  故事/N  事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 1 );
    BOOST_CHECK( sent.getCount( 0 ) == 10 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "和衣" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "V" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 8 ), "故事" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 8 ), "N" ) == 0 );

    delete analyzer;
}

// forwards maximum matching
BOOST_AUTO_TEST_CASE(icma_fmm)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 2 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/P  和衣/V  服/J  的/A  故事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 1 );
    BOOST_CHECK( sent.getCount( 0 ) == 5 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "服" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "J" ) == 0 );

    delete analyzer;
    //delete knowledge;
}

// maximum entropy model
BOOST_AUTO_TEST_CASE(icma_mmmodel)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 1 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/R  和/C  衣服/N  的/B  故事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 3 );
    BOOST_CHECK( sent.getCount( 0 ) == 5 );
    BOOST_CHECK( sent.getCount( 1 ) == 6 );
    BOOST_CHECK( sent.getCount( 1 ) == 6 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "衣服" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "N" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 4 ), "故" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 1, 4 ), "D" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 2, 2 ), "衣" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 2, 2 ), "NG" ) == 0 );

    delete analyzer;
    //delete knowledge;
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>add the test suit for max-prfix dictionary analyzer matching<commit_after>/**
 * \file bt_icma_core.cpp
 * \brief
 * \date Aug 20, 2010
 * \author Vernkin Chen
 */

#include <boost/test/unit_test.hpp>

#include "icma/icma.h"

#include <string>
#include <vector>

using namespace cma;
using namespace std;

Knowledge* globalKnowledge = NULL;

void createKnowledgeAndAnalyzer(
        Knowledge** knowledge,
        Analyzer** analyzer,
        int analysisType = 3,
        const string dictPath = "../db/icwb/utf8/"
        )
{
    CMA_Factory* factory = CMA_Factory::instance();

    if( globalKnowledge == NULL )
    {
        globalKnowledge = factory->createKnowledge();
        globalKnowledge->loadModel( dictPath.c_str(), true );
    }
    *knowledge = globalKnowledge;

    *analyzer = factory->createAnalyzer();
    (*analyzer)->setKnowledge( *knowledge );
    (*analyzer)->setOption( Analyzer::OPTION_ANALYSIS_TYPE, analysisType );
}

BOOST_AUTO_TEST_SUITE(icma_core_test)

BOOST_AUTO_TEST_CASE(icma_basicapi)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 3 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test Knowledge API
    BOOST_CHECK( Knowledge::decodeEncodeType( "utf8" ) == Knowledge::ENCODE_TYPE_UTF8 );
    BOOST_CHECK( knowledge->isSupportPOS() == true );
    string word = "衣服";
    BOOST_CHECK( knowledge->isExistWord( word.c_str() ) == true );

    vector< string > words;
    words.push_back( word );
    knowledge->disableWords( words );
    BOOST_CHECK( knowledge->isExistWord( word.c_str() ) == false );
    knowledge->enableWords( words );
    BOOST_CHECK( knowledge->isExistWord( word.c_str() ) == true );

    // test Analyzer API
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    BOOST_CHECK( analyzer->getOption( Analyzer::OPTION_TYPE_NBEST) == 3 );

    int posCode;
    string posValue = "N";
    posCode = analyzer->getCodeFromStr( posValue );
    BOOST_CHECK( posCode >= 0 );
    string posRetValue = analyzer->getStrFromCode( posCode );
    BOOST_CHECK( posRetValue == posValue );

    delete analyzer;
    //delete knowledge;
}

// forwards minimum cover
BOOST_AUTO_TEST_CASE(icma_fminconver)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 3 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/P  和/AG  和衣/V  衣/N  衣服/N  服/J  的/A  故事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 1 );
    BOOST_CHECK( sent.getCount( 0 ) == 8 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "和衣" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "V" ) == 0 );

    delete analyzer;
    //delete knowledge;
}

// forwards minimum cover with unigram
BOOST_AUTO_TEST_CASE(icma_fmincover_unigram)
{
	Knowledge* knowledge = NULL;
	Analyzer* analyzer = NULL;
	createKnowledgeAndAnalyzer( &knowledge, &analyzer, 4 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/P  和/AG  和衣/V  衣/N  衣服/N  服/J  的/A  故/C  故事/N  事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 1 );
    BOOST_CHECK( sent.getCount( 0 ) == 10 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "和衣" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "V" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 8 ), "故事" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 8 ), "N" ) == 0 );

    delete analyzer;
}

// forwards maximum matching
BOOST_AUTO_TEST_CASE(icma_fmm)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 2 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/P  和衣/V  服/J  的/A  故事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 1 );
    BOOST_CHECK( sent.getCount( 0 ) == 5 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "服" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "J" ) == 0 );

    delete analyzer;
    //delete knowledge;
}

// maximum entropy model
BOOST_AUTO_TEST_CASE(icma_mmmodel)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    createKnowledgeAndAnalyzer( &knowledge, &analyzer, 1 );
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    // test run with string
    string input = "我和衣服的故事";
    string expected = "我/R  和/C  衣服/N  的/B  故事/N  ";
    const char* ret = analyzer->runWithString( input.c_str() );
    BOOST_CHECK( strcmp( ret, expected.c_str() ) == 0 );

    // test run with sentence
    analyzer->setOption( Analyzer::OPTION_TYPE_NBEST, 3 );
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 3 );
    BOOST_CHECK( sent.getCount( 0 ) == 5 );
    BOOST_CHECK( sent.getCount( 1 ) == 6 );
    BOOST_CHECK( sent.getCount( 1 ) == 6 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 2 ), "衣服" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 0, 2 ), "N" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 4 ), "故" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 1, 4 ), "D" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 2, 2 ), "衣" ) == 0 );
    BOOST_CHECK( strcmp( sent.getStrPOS( 2, 2 ), "NG" ) == 0 );

    delete analyzer;
    //delete knowledge;
}

// maximum prefix in dictionary matching
BOOST_AUTO_TEST_CASE(icma_maxprefix)
{
    Knowledge* knowledge = NULL;
    Analyzer* analyzer = NULL;
    CMA_Factory* factory = CMA_Factory::instance();

    knowledge = factory->createKnowledge();
    analyzer = factory->createAnalyzer();
    BOOST_CHECK( knowledge != NULL );
    BOOST_CHECK( analyzer != NULL );

    knowledge->loadModel( "utf8", "../db/icwb/utf8/fmindex_dic/", false);
    analyzer->setOption( Analyzer::OPTION_ANALYSIS_TYPE, 100);
    analyzer->setOption( Analyzer::OPTION_TYPE_POS_TAGGING, 0);
    analyzer->setKnowledge( knowledge );

    // test run with string
    string input = "几十万";
    string dic_expected = "";
    string ret = analyzer->runWithString( input.c_str() );
    printf("result : %s\n", ret.c_str());
    BOOST_CHECK( ret.empty() );

    // test run with sentence
    Sentence sent;
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 2 );
    BOOST_CHECK( sent.getCount( 0 ) == 0 );
    BOOST_CHECK( sent.getCount( 1 ) == 2 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 0 ), "几十" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 1 ), "十万" ) == 0 );
    //
    // test run with string
    input = "佳能";
    dic_expected = "佳能  ";
    ret = analyzer->runWithString( input.c_str() );
    printf("result : %s\n", ret.c_str());
    BOOST_CHECK( ret == dic_expected );

    // test run with sentence
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 2 );
    BOOST_CHECK( sent.getCount( 0 ) == 1 );
    BOOST_CHECK( sent.getCount( 1 ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 0, 0 ), "佳能" ) == 0 );

    // dictionary are all low-case, so upper-cash must not exist
    input = "佳能(CANON)CANON2";
    dic_expected = "佳能  ";
    ret = analyzer->runWithString( input.c_str() );
    printf("result : %s\n", ret.c_str());
    BOOST_CHECK( ret == dic_expected );

    // test run with sentence
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 2 );
    BOOST_CHECK( sent.getCount( 0 ) == 1 );
    BOOST_CHECK( sent.getCount( 1 ) == 2 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 0 ), "CANON" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 1 ), "CANON2" ) == 0 );

    input = "(Test-non)Testnon佳能";
    dic_expected = "佳能  ";
    ret = analyzer->runWithString( input.c_str() );
    printf("result : %s\n", ret.c_str());
    BOOST_CHECK( ret == dic_expected );

    // test run with sentence
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 2 );
    BOOST_CHECK( sent.getCount( 0 ) == 1 );
    BOOST_CHECK( sent.getCount( 1 ) == 2 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 0 ), "Test-non" ) == 0 );
    BOOST_CHECK( strcmp( sent.getLexicon( 1, 1 ), "Testnon" ) == 0 );

    input = "佳能(canon)test non 单子不存在exist字典(6666) eos 60d单反套机(ef-s 18-135mm f/3.5-5.6is）单反镜头单子不存在";
    dic_expected = "佳能  canon  60d  单反  18-135mm  3.5-5.6  单反镜头  ";
    ret = analyzer->runWithString( input.c_str() );
    printf("result : %s\n", ret.c_str());
    BOOST_CHECK( ret == dic_expected );

    // test run with sentence
    sent.setString( input.c_str() );
    BOOST_CHECK( analyzer->runWithSentence( sent ) == 1 );
    BOOST_CHECK( sent.getListSize() == 2 );
    BOOST_CHECK( sent.getCount( 0 ) == 7 );
    BOOST_CHECK( sent.getCount( 1 ) == 18 );

    delete analyzer;
    delete knowledge;
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: SvFilterOptionsDialog.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: obo $ $Date: 2005-04-13 10:59:53 $
 *
 *  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): _______________________________________
 *
 *
 ************************************************************************/

#include "SvFilterOptionsDialog.hxx"

#ifndef _FILTER_CONFIG_ITEM_HXX_
#include "FilterConfigItem.hxx"
#endif
#ifndef _FILTER_HXX
#include "filter.hxx"
#endif
#ifndef _FILTER_CONFIG_CACHE_HXX_
#include "FilterConfigCache.hxx"
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _VOS_MODULE_HXX_
#include <vos/module.hxx>
#endif
#include "solar.hrc"
#include "fltcall.hxx"
#include "dlgexpor.hxx"
#include "dlgejpg.hxx"
#include "dlgepng.hxx"
#include <uno/mapping.hxx>

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XVIEWDATASUPPLIER_HPP_
#include <com/sun/star/document/XViewDataSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <syslocale.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include "vcl/svapp.hxx"
#endif

#if defined WIN || (defined OS2 && !defined ICC)
#define EXPDLG_FUNCTION_NAME    "_DoExportDialog"
#else
#define EXPDLG_FUNCTION_NAME    "DoExportDialog"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;

// -------------------------
// - SvFilterOptionsDialog -
// -------------------------

uno::Reference< uno::XInterface >
    SAL_CALL SvFilterOptionsDialog_CreateInstance(
        const uno::Reference< lang::XMultiServiceFactory > & _rxFactory )
{
    return static_cast< ::cppu::OWeakObject* > ( new SvFilterOptionsDialog( _rxFactory ) );
}

OUString SvFilterOptionsDialog_getImplementationName()
    throw( uno::RuntimeException )
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.SvFilterOptionsDialog" ) );
}
#define SERVICE_NAME "com.sun.star.ui.dialog.FilterOptionsDialog"
sal_Bool SAL_CALL SvFilterOptionsDialog_supportsService( const OUString& ServiceName )
    throw( uno::RuntimeException )
{
    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SERVICE_NAME ) );
}

uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog_getSupportedServiceNames()
    throw( uno::RuntimeException )
{
    uno::Sequence< OUString > aRet(1);
    OUString* pArray = aRet.getArray();
    pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
    return aRet;
}
#undef SERVICE_NAME

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

SvFilterOptionsDialog::SvFilterOptionsDialog( const uno::Reference< lang::XMultiServiceFactory > & xMgr ) :
    rxMgr       ( xMgr ),
    eFieldUnit  ( FUNIT_CM )
{
}

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

SvFilterOptionsDialog::~SvFilterOptionsDialog()
{
}

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

void SAL_CALL SvFilterOptionsDialog::acquire() throw()
{
    OWeakObject::acquire();
}

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

void SAL_CALL SvFilterOptionsDialog::release() throw()
{
    OWeakObject::release();
}

// XInitialization
void SAL_CALL SvFilterOptionsDialog::initialize( const uno::Sequence< uno::Any > & aArguments )
    throw ( uno::Exception, uno::RuntimeException )
{
}

// XServiceInfo
OUString SAL_CALL SvFilterOptionsDialog::getImplementationName()
    throw( uno::RuntimeException )
{
    return SvFilterOptionsDialog_getImplementationName();
}
sal_Bool SAL_CALL SvFilterOptionsDialog::supportsService( const OUString& rServiceName )
    throw( uno::RuntimeException )
{
    return SvFilterOptionsDialog_supportsService( rServiceName );
}
uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog::getSupportedServiceNames()
    throw ( uno::RuntimeException )
{
    return SvFilterOptionsDialog_getSupportedServiceNames();
}

// XPropertyAccess
uno::Sequence< beans::PropertyValue > SvFilterOptionsDialog::getPropertyValues()
        throw ( uno::RuntimeException )
{
    sal_Int32 i, nCount;
    for ( i = 0, nCount = aMediaDescriptor.getLength(); i < nCount; i++ )
    {
        if ( aMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) )
            break;
    }
    if ( i == nCount )
        aMediaDescriptor.realloc( ++nCount );

    // the "FilterData" Property is an Any that will contain our PropertySequence of Values
    aMediaDescriptor[ i ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterData" ) );
    aMediaDescriptor[ i ].Value <<= aFilterDataSequence;
    return aMediaDescriptor;
}

void SvFilterOptionsDialog::setPropertyValues( const uno::Sequence< beans::PropertyValue > & aProps )
        throw ( beans::UnknownPropertyException, beans::PropertyVetoException,
                lang::IllegalArgumentException, lang::WrappedTargetException,
                uno::RuntimeException )
{
    aMediaDescriptor = aProps;

    sal_Int32 i, nCount;
    for ( i = 0, nCount = aMediaDescriptor.getLength(); i < nCount; i++ )
    {
        if ( aMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) )
        {
            aMediaDescriptor[ i ].Value >>= aFilterDataSequence;
            break;
        }
    }
}

// XExecutableDialog
void SvFilterOptionsDialog::setTitle( const OUString& aTitle )
    throw ( uno::RuntimeException )
{
    aDialogTitle = aTitle;
}

sal_Int16 SvFilterOptionsDialog::execute()
    throw ( uno::RuntimeException )
{
    sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;

    String aFilterName( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
    String aInternalFilterName;
    sal_Int32 i, nCount = aMediaDescriptor.getLength();
    for ( i = 0; i < nCount; i++ )
    {
        if ( aMediaDescriptor[ i ].Name.equals( aFilterName ) )
        {
            OUString aStr;
            aMediaDescriptor[ i ].Value >>= aStr;
            aInternalFilterName = aStr;
            aInternalFilterName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "draw_" ) ), String(), 0 );
            aInternalFilterName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "impress_" ) ), String(), 0 );
            break;
       }
    }
    if ( aInternalFilterName.Len() )
    {
        GraphicFilter aGraphicFilter( sal_True );

        sal_uInt16 nFormat, nFilterCount = aGraphicFilter.pConfig->GetExportFormatCount();
        for ( nFormat = 0; nFormat < nFilterCount; nFormat++ )
        {
            if ( aGraphicFilter.pConfig->GetExportInternalFilterName( nFormat ) == aInternalFilterName )
                break;
        }
        if ( nFormat < nFilterCount )
        {
            FltCallDialogParameter aFltCallDlgPara( Application::GetDefDialogParent(), NULL, eFieldUnit );
            aFltCallDlgPara.aFilterData = aFilterDataSequence;

            String  aFilterName( aGraphicFilter.pConfig->GetExportFilterName( nFormat ) );
            if ( aGraphicFilter.pConfig->IsExportInternalFilter( nFormat ) )
            {
                // Export-Dialog fuer Bitmap's, SVM's und WMF's
                if( ( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) ) )
                {
                    ByteString  aResMgrName( "svt", 3 );
                    ResMgr*     pResMgr;

                    aResMgrName.Append( ByteString::CreateFromInt32( SOLARUPD ) );
                    pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
                    aFltCallDlgPara.pResMgr = pResMgr;
                    // JPEG-Dialog
                    if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
                    {
                        if ( DlgExportEJPG( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
                    {
                        if ( DlgExportEPNG( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    else if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
                    {
                        // Fuer Vektorformate nehmen wir den Vektor-Dialog
                        aFltCallDlgPara.aFilterExt = aGraphicFilter.pConfig->GetExportFormatShortName( nFormat );
                        if ( DlgExportPix( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    else
                    {
                        aFltCallDlgPara.aFilterExt = aGraphicFilter.pConfig->GetExportFormatShortName( nFormat );
                        if ( DlgExportVec( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    delete pResMgr;
                }
            }
            else    // ladbare Filter
            {
                xub_StrLen i, nTokenCount = aGraphicFilter.aFilterPath.GetTokenCount( ';' );
                for ( i = 0; i < nTokenCount; i++ )
                {

                    OUString aPathURL;

                    ::osl::FileBase::getFileURLFromSystemPath( aGraphicFilter.aFilterPath.GetToken( i ), aPathURL );
                    aPathURL += String( '/' );

                    OUString aSystemPath;
                    ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
                    aSystemPath += OUString( aFilterName );

                    ::vos::OModule aLibrary( aSystemPath );
                    PFilterDlgCall  pFunc = (PFilterDlgCall) aLibrary.getSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) );
                    // Dialog in DLL ausfuehren
                    if( pFunc )
                    {
                        if ( (*pFunc)( aFltCallDlgPara ) )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                }
            }
            // taking the out parameter from the dialog
            aFilterDataSequence = aFltCallDlgPara.aFilterData;
        }
    }
    return nRet;
}

// XEmporter
void SvFilterOptionsDialog::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
        throw ( lang::IllegalArgumentException, uno::RuntimeException )
{
    // try to set the corresponding metric unit
    String aConfigPath;
    uno::Reference< lang::XServiceInfo > xServiceInfo
            ( xDoc, uno::UNO_QUERY );
    if ( xServiceInfo.is() )
    {
        if ( xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) ) )
            aConfigPath = String( RTL_CONSTASCII_USTRINGPARAM( "Office.Impress/Layout/Other/MeasureUnit" ) );
        else if ( xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) ) )
            aConfigPath = String( RTL_CONSTASCII_USTRINGPARAM( "Office.Draw/Layout/Other/MeasureUnit" ) );
        if ( aConfigPath.Len() )
        {
            FilterConfigItem aConfigItem( aConfigPath );
            String aPropertyName;
            SvtSysLocale aSysLocale;
            if ( aSysLocale.GetLocaleDataPtr()->getMeasurementSystemEnum() == MEASURE_METRIC )
                aPropertyName = String( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
            else
                aPropertyName = String( RTL_CONSTASCII_USTRINGPARAM( "NonMetric" ) );
            eFieldUnit = (FieldUnit)aConfigItem.ReadInt32( aPropertyName, FUNIT_CM );
        }
    }
}

<commit_msg>INTEGRATION: CWS ooo19126 (1.10.140); FILE MERGED 2005/09/05 14:52:53 rt 1.10.140.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: SvFilterOptionsDialog.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 15:33:13 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#include "SvFilterOptionsDialog.hxx"

#ifndef _FILTER_CONFIG_ITEM_HXX_
#include "FilterConfigItem.hxx"
#endif
#ifndef _FILTER_HXX
#include "filter.hxx"
#endif
#ifndef _FILTER_CONFIG_CACHE_HXX_
#include "FilterConfigCache.hxx"
#endif
#ifndef _OSL_FILE_HXX_
#include <osl/file.hxx>
#endif
#ifndef _VOS_MODULE_HXX_
#include <vos/module.hxx>
#endif
#include "solar.hrc"
#include "fltcall.hxx"
#include "dlgexpor.hxx"
#include "dlgejpg.hxx"
#include "dlgepng.hxx"
#include <uno/mapping.hxx>

#ifndef _COM_SUN_STAR_FRAME_XMODEL_HPP_
#include <com/sun/star/frame/XModel.hpp>
#endif
#ifndef _COM_SUN_STAR_DOCUMENT_XVIEWDATASUPPLIER_HPP_
#include <com/sun/star/document/XViewDataSupplier.hpp>
#endif
#ifndef _COM_SUN_STAR_CONTAINER_XINDEXACCESS_HPP_
#include <com/sun/star/container/XIndexAccess.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEINFO_HPP_
#include <com/sun/star/lang/XServiceInfo.hpp>
#endif
#ifndef _COM_SUN_STAR_UNO_SEQUENCE_H_
#include <com/sun/star/uno/Sequence.h>
#endif
#ifndef _COM_SUN_STAR_UNO_ANY_H_
#include <com/sun/star/uno/Any.h>
#endif
#ifndef INCLUDED_SVTOOLS_SYSLOCALE_HXX
#include <syslocale.hxx>
#endif
#ifndef _SV_SVAPP_HXX
#include "vcl/svapp.hxx"
#endif

#if defined WIN || (defined OS2 && !defined ICC)
#define EXPDLG_FUNCTION_NAME    "_DoExportDialog"
#else
#define EXPDLG_FUNCTION_NAME    "DoExportDialog"
#endif

using namespace ::rtl;
using namespace ::com::sun::star;

// -------------------------
// - SvFilterOptionsDialog -
// -------------------------

uno::Reference< uno::XInterface >
    SAL_CALL SvFilterOptionsDialog_CreateInstance(
        const uno::Reference< lang::XMultiServiceFactory > & _rxFactory )
{
    return static_cast< ::cppu::OWeakObject* > ( new SvFilterOptionsDialog( _rxFactory ) );
}

OUString SvFilterOptionsDialog_getImplementationName()
    throw( uno::RuntimeException )
{
    return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.svtools.SvFilterOptionsDialog" ) );
}
#define SERVICE_NAME "com.sun.star.ui.dialog.FilterOptionsDialog"
sal_Bool SAL_CALL SvFilterOptionsDialog_supportsService( const OUString& ServiceName )
    throw( uno::RuntimeException )
{
    return ServiceName.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( SERVICE_NAME ) );
}

uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog_getSupportedServiceNames()
    throw( uno::RuntimeException )
{
    uno::Sequence< OUString > aRet(1);
    OUString* pArray = aRet.getArray();
    pArray[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICE_NAME ) );
    return aRet;
}
#undef SERVICE_NAME

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

SvFilterOptionsDialog::SvFilterOptionsDialog( const uno::Reference< lang::XMultiServiceFactory > & xMgr ) :
    rxMgr       ( xMgr ),
    eFieldUnit  ( FUNIT_CM )
{
}

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

SvFilterOptionsDialog::~SvFilterOptionsDialog()
{
}

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

void SAL_CALL SvFilterOptionsDialog::acquire() throw()
{
    OWeakObject::acquire();
}

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

void SAL_CALL SvFilterOptionsDialog::release() throw()
{
    OWeakObject::release();
}

// XInitialization
void SAL_CALL SvFilterOptionsDialog::initialize( const uno::Sequence< uno::Any > & aArguments )
    throw ( uno::Exception, uno::RuntimeException )
{
}

// XServiceInfo
OUString SAL_CALL SvFilterOptionsDialog::getImplementationName()
    throw( uno::RuntimeException )
{
    return SvFilterOptionsDialog_getImplementationName();
}
sal_Bool SAL_CALL SvFilterOptionsDialog::supportsService( const OUString& rServiceName )
    throw( uno::RuntimeException )
{
    return SvFilterOptionsDialog_supportsService( rServiceName );
}
uno::Sequence< OUString > SAL_CALL SvFilterOptionsDialog::getSupportedServiceNames()
    throw ( uno::RuntimeException )
{
    return SvFilterOptionsDialog_getSupportedServiceNames();
}

// XPropertyAccess
uno::Sequence< beans::PropertyValue > SvFilterOptionsDialog::getPropertyValues()
        throw ( uno::RuntimeException )
{
    sal_Int32 i, nCount;
    for ( i = 0, nCount = aMediaDescriptor.getLength(); i < nCount; i++ )
    {
        if ( aMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) )
            break;
    }
    if ( i == nCount )
        aMediaDescriptor.realloc( ++nCount );

    // the "FilterData" Property is an Any that will contain our PropertySequence of Values
    aMediaDescriptor[ i ].Name = String( RTL_CONSTASCII_USTRINGPARAM( "FilterData" ) );
    aMediaDescriptor[ i ].Value <<= aFilterDataSequence;
    return aMediaDescriptor;
}

void SvFilterOptionsDialog::setPropertyValues( const uno::Sequence< beans::PropertyValue > & aProps )
        throw ( beans::UnknownPropertyException, beans::PropertyVetoException,
                lang::IllegalArgumentException, lang::WrappedTargetException,
                uno::RuntimeException )
{
    aMediaDescriptor = aProps;

    sal_Int32 i, nCount;
    for ( i = 0, nCount = aMediaDescriptor.getLength(); i < nCount; i++ )
    {
        if ( aMediaDescriptor[ i ].Name.equalsAscii( "FilterData" ) )
        {
            aMediaDescriptor[ i ].Value >>= aFilterDataSequence;
            break;
        }
    }
}

// XExecutableDialog
void SvFilterOptionsDialog::setTitle( const OUString& aTitle )
    throw ( uno::RuntimeException )
{
    aDialogTitle = aTitle;
}

sal_Int16 SvFilterOptionsDialog::execute()
    throw ( uno::RuntimeException )
{
    sal_Int16 nRet = ui::dialogs::ExecutableDialogResults::CANCEL;

    String aFilterName( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
    String aInternalFilterName;
    sal_Int32 i, nCount = aMediaDescriptor.getLength();
    for ( i = 0; i < nCount; i++ )
    {
        if ( aMediaDescriptor[ i ].Name.equals( aFilterName ) )
        {
            OUString aStr;
            aMediaDescriptor[ i ].Value >>= aStr;
            aInternalFilterName = aStr;
            aInternalFilterName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "draw_" ) ), String(), 0 );
            aInternalFilterName.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( "impress_" ) ), String(), 0 );
            break;
       }
    }
    if ( aInternalFilterName.Len() )
    {
        GraphicFilter aGraphicFilter( sal_True );

        sal_uInt16 nFormat, nFilterCount = aGraphicFilter.pConfig->GetExportFormatCount();
        for ( nFormat = 0; nFormat < nFilterCount; nFormat++ )
        {
            if ( aGraphicFilter.pConfig->GetExportInternalFilterName( nFormat ) == aInternalFilterName )
                break;
        }
        if ( nFormat < nFilterCount )
        {
            FltCallDialogParameter aFltCallDlgPara( Application::GetDefDialogParent(), NULL, eFieldUnit );
            aFltCallDlgPara.aFilterData = aFilterDataSequence;

            String  aFilterName( aGraphicFilter.pConfig->GetExportFilterName( nFormat ) );
            if ( aGraphicFilter.pConfig->IsExportInternalFilter( nFormat ) )
            {
                // Export-Dialog fuer Bitmap's, SVM's und WMF's
                if( ( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_SVMETAFILE ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_WMF ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_EMF ) ) ||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )||
                    ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) ) )
                {
                    ByteString  aResMgrName( "svt", 3 );
                    ResMgr*     pResMgr;

                    aResMgrName.Append( ByteString::CreateFromInt32( SOLARUPD ) );
                    pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() );
                    aFltCallDlgPara.pResMgr = pResMgr;
                    // JPEG-Dialog
                    if( aFilterName.EqualsIgnoreCaseAscii( EXP_JPEG ) )
                    {
                        if ( DlgExportEJPG( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    else if ( aFilterName.EqualsIgnoreCaseAscii( EXP_PNG ) )
                    {
                        if ( DlgExportEPNG( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    else if( aFilterName.EqualsIgnoreCaseAscii( EXP_BMP ) )
                    {
                        // Fuer Vektorformate nehmen wir den Vektor-Dialog
                        aFltCallDlgPara.aFilterExt = aGraphicFilter.pConfig->GetExportFormatShortName( nFormat );
                        if ( DlgExportPix( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    else
                    {
                        aFltCallDlgPara.aFilterExt = aGraphicFilter.pConfig->GetExportFormatShortName( nFormat );
                        if ( DlgExportVec( aFltCallDlgPara ).Execute() == RET_OK )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                    delete pResMgr;
                }
            }
            else    // ladbare Filter
            {
                xub_StrLen i, nTokenCount = aGraphicFilter.aFilterPath.GetTokenCount( ';' );
                for ( i = 0; i < nTokenCount; i++ )
                {

                    OUString aPathURL;

                    ::osl::FileBase::getFileURLFromSystemPath( aGraphicFilter.aFilterPath.GetToken( i ), aPathURL );
                    aPathURL += String( '/' );

                    OUString aSystemPath;
                    ::osl::FileBase::getSystemPathFromFileURL( aPathURL, aSystemPath );
                    aSystemPath += OUString( aFilterName );

                    ::vos::OModule aLibrary( aSystemPath );
                    PFilterDlgCall  pFunc = (PFilterDlgCall) aLibrary.getSymbol( UniString::CreateFromAscii( EXPDLG_FUNCTION_NAME ) );
                    // Dialog in DLL ausfuehren
                    if( pFunc )
                    {
                        if ( (*pFunc)( aFltCallDlgPara ) )
                            nRet = ui::dialogs::ExecutableDialogResults::OK;
                    }
                }
            }
            // taking the out parameter from the dialog
            aFilterDataSequence = aFltCallDlgPara.aFilterData;
        }
    }
    return nRet;
}

// XEmporter
void SvFilterOptionsDialog::setSourceDocument( const uno::Reference< lang::XComponent >& xDoc )
        throw ( lang::IllegalArgumentException, uno::RuntimeException )
{
    // try to set the corresponding metric unit
    String aConfigPath;
    uno::Reference< lang::XServiceInfo > xServiceInfo
            ( xDoc, uno::UNO_QUERY );
    if ( xServiceInfo.is() )
    {
        if ( xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.presentation.PresentationDocument" ) ) ) )
            aConfigPath = String( RTL_CONSTASCII_USTRINGPARAM( "Office.Impress/Layout/Other/MeasureUnit" ) );
        else if ( xServiceInfo->supportsService( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.DrawingDocument" ) ) ) )
            aConfigPath = String( RTL_CONSTASCII_USTRINGPARAM( "Office.Draw/Layout/Other/MeasureUnit" ) );
        if ( aConfigPath.Len() )
        {
            FilterConfigItem aConfigItem( aConfigPath );
            String aPropertyName;
            SvtSysLocale aSysLocale;
            if ( aSysLocale.GetLocaleDataPtr()->getMeasurementSystemEnum() == MEASURE_METRIC )
                aPropertyName = String( RTL_CONSTASCII_USTRINGPARAM( "Metric" ) );
            else
                aPropertyName = String( RTL_CONSTASCII_USTRINGPARAM( "NonMetric" ) );
            eFieldUnit = (FieldUnit)aConfigItem.ReadInt32( aPropertyName, FUNIT_CM );
        }
    }
}

<|endoftext|>