/*
* $Id: XDTPTransform.cpp,v 1.21 2006/06/29 07:26:42 ozawa Exp $
*
* Copyright 2005- ONGS Inc. All rights reserved.
*
* author: Masanori OZAWA (ozawa@ongs.co.jp)
* version: $Revision: 1.21 $
*
* 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.
*
* THIS SOFTWARE IS PROVIDED BY ONGS INC ``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 ONGS INC 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.
*
* The views and conclusions contained in the software and documentation are
* those of the authors and should not be interpreted as representing official
* policies, either expressed or implied, of the ONGS Inc.
*
*/
#include "xdtp.h"
#include "XDTPTransform.h"
#include "Exception.h"
#include "Utilities.h"
#include "xmlloader.h"
#include "xmlsaver.h"
#include "XMLTool.h"
#include "modules/GLSDModule.h"
#include "modules/GLSDModuleChecker.h"
#include "modules/GLSDDocumentModule.h"
#include "modules/GLSDDocumentModuleChecker.h"
#include "modules/GLSDBanBunModule.h"
#include "modules/GLSDBanBunModuleChecker.h"
#include <sys/stat.h>
#define RESOURCE_TAG "res:"
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// objectwrapperの解放処理
namespace XDTP {
static void objectwrapper_ustring_destractor(void *value)
{
Glib::ustring *string = (Glib::ustring*)value;
if (string) delete string;
}
static void objectwrapper_mc_destractor(void *value)
{
XDTP_MC *mc = (XDTP_MC*)value;
if (mc) delete mc;
}
static void objectwrapper_module_destractor(void *value)
{
XDTPModule *module = (XDTPModule*)value;
if (module) delete module;
}
static void objectwrapper_checker_destractor(void *value)
{
XDTPChecker *checker = (XDTPChecker*)value;
if (checker) delete checker;
}
};
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 雑多な処理
namespace XDTP {
static Glib::ustring getOptionValue(const Glib::ustring& key,
const StringList& options)
{
int length = key.length();
Glib::ustring result;
StringList::const_iterator iter = options.begin();
StringList::const_iterator end = options.end();
for (; iter != end; iter++) {
if (strncmp(key.c_str(), (*iter).c_str(), length) == 0) {
result = (*iter).substr(length);
if (0 < result.length() && '=' == result.at(0)) {
result = result.substr(1);
break;
}
else {
result.clear();
}
}
}
return result;
}
static mode_t getFileMask(const Glib::ustring& file)
{
struct stat sb;
if (!stat(file.c_str(), &sb)) {
return (sb.st_mode & 0777);
}
return 0600;
}
};
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
using namespace XDTP;
XDTPTransform::XDTPTransform()
{
m_XSL4OutputPos = -1;
m_bSkipXMLCheck = false;
m_nVerbose = 0;
m_OutputType = DEFAULT_OUTPUT_TYPE;
m_OutputEncoding = DEFAULT_OUTPUT_ENCODING;
m_OutputMask = 0;
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_USTRING, objectwrapper_ustring_destractor);
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XSL, objectwrapper_null_destractor);
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_MC, objectwrapper_mc_destractor);
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_EXT_MODULE, objectwrapper_null_destractor);
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_EXT_CHECKER, objectwrapper_null_destractor);
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_LCL_MODULE, objectwrapper_module_destractor);
XDTPObjectWrapper::setDestractor(OBJECT_TYPE_XDTP_LCL_CHECKER, objectwrapper_checker_destractor);
}
XDTPTransform::~XDTPTransform()
{
uninitialize();
}
/**
* 初期化処理を行います。
* 初期化後に set/get 系のメソッドを使用することは避けてください。
* 変換処理中に set/get 系メソッドを使用することはできません。
*
* @return 初期化に成功した場合は true を戻します。
*/
bool XDTPTransform::initialize()
{
bool result = true;
uninitialize();
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// モジュールのロード
if (1 < m_nVerbose) {
fprintf(stdout, "%s: load modules." LINE_SEP, APP_NAME);
fflush(stdout);
}
if (!loadModules(m_libraries, m_modules, m_checkers)) {
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// モジュールの初期化
int count = 0;
const int size = m_modules.size();
XDTPModule *module = NULL;
if (1 < m_nVerbose) {
fprintf(stdout, "%s: initiailze modules." LINE_SEP, APP_NAME);
fflush(stdout);
}
try {
for (; count < size; count++) {
module = (XDTPModule*)m_modules.get(count);
module->setXDTPTransform(this);
module->setOutputType(m_OutputType);
module->setOption(m_OptionList);
module->setInputEncoding(m_InputEncoding);
module->setOutputEncoding(m_OutputEncoding);
}
}
catch (Exception exception) {
uninitialize();
throw exception;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 出力ファイルのアクセス権の決定
char *tmp;
Glib::ustring mask = getOptionValue(OUTPUT_FILE_MASK_KEY, getOptionList());
m_OutputMask = 0;
if (0 < mask.length()) {
m_OutputMask = strtol(mask.c_str(), &tmp, 8);
if ('\0' != *tmp || 0777 < m_OutputMask) {
result = false;
m_OutputMask = 0;
}
}
if (1 < m_nVerbose) {
fprintf(stdout, "%s: output file mask: %03o" LINE_SEP, APP_NAME, m_OutputMask);
fflush(stdout);
}
return result;
}
/**
* オブジェクトを解放する準備を行います。
* 変換処理後、オブジェクトを利用することがない場合や、状態を変更する
* 場合は、事前に呼び出す必要があります。
*/
void XDTPTransform::uninitialize()
{
unloadModules(m_libraries, m_modules, m_checkers);
}
/**
* 変換処理を実行します。
*
* @param anInput 変換元XMLファイル
* @param anOutput 出力先ファイル(既存のファイルは上書きします)
* @return 変換に成功した場合は true を戻します。
*/
bool XDTPTransform::transform(const Glib::ustring& anInput, const Glib::ustring& anOutput)
{
bool result = true;
XMLTool xmltool;
// エラーメッセージをクリア
m_ErrorMsg.clear();
if (0 < m_nVerbose) {
fprintf(stdout, "%s: transform: %s" LINE_SEP, APP_NAME, anInput.c_str());
fflush(stdout);
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// モジュールに入出力ファイルを通知する
int count = 0;
const int modules_size = m_modules.size();
XDTPModule *module = NULL;
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: set input/output file to modules." LINE_SEP, APP_NAME);
fflush(stdout);
}
try {
for (; count < modules_size; count++) {
module = (XDTPModule*)m_modules.get(count);
module->setOutputFile(anOutput);
module->setXMLFile(anInput);
}
}
catch (Exception exception) {
setErrorMsg(exception.what());
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 入力ファイルを複製
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: backup the input file." LINE_SEP, APP_NAME);
fflush(stdout);
}
std::string tmpfile = "_xdtp_temp.XXXXXX";
int fd = Glib::mkstemp(tmpfile);
if (0 > fd) {
setErrorMsg("Unable to create temp file.");
return false;
}
if (!Utilities::copy(anInput, fd)) {
setErrorMsg("Unable to backup the input file. (" + anInput + ")");
close(fd);
remove(tmpfile.c_str());
return false;
}
close(fd);
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// parse前処理
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: treatPreFile." LINE_SEP, APP_NAME);
fflush(stdout);
}
try {
for (count = 0; count < modules_size; count++) {
module = (XDTPModule*)m_modules.get(count);
module->treatPreFile(tmpfile);
}
}
catch (Exception exception) {
setErrorMsg(exception.what());
remove(tmpfile.c_str());
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// parse
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: parse the XML file." LINE_SEP, APP_NAME);
fflush(stdout);
}
xmlDocPtr document = XMLLoader::load(tmpfile);
if (!document) {
setErrorMsg("Unable to parse the input xml file.");
remove(tmpfile.c_str());
return false;
}
remove(tmpfile.c_str());
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// check
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: check the XML file." LINE_SEP, APP_NAME);
fflush(stdout);
}
if (!m_bSkipXMLCheck) {
const int checkers_size = m_checkers.size();
XDTPChecker *checker = NULL;
for (count = 0; count < checkers_size; count++) {
checker = (XDTPChecker*)m_checkers.get(count);
if (!checker->checkFormat(document)) {
setErrorMsg("checkFormat failed.");
xmlFreeDoc(document);
return false;
}
}
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// parse後処理
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: treatPreDocument." LINE_SEP, APP_NAME);
fflush(stdout);
}
try {
for (count = 0; count < modules_size; count++) {
module = (XDTPModule*)m_modules.get(count);
module->treatPreDocument(document);
}
}
catch (Exception exception) {
setErrorMsg(exception.what());
xmlFreeDoc(document);
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// xslt
{
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: do xslt." LINE_SEP, APP_NAME);
fflush(stdout);
}
int count = 0;
const int size = m_XSLObjects.size();
xmlDocPtr doctmp = NULL;
xsltStylesheetPtr xsl = NULL;
for (; document && count < size; count++) {
doctmp = NULL;
xsl = parseXSL(count);
if (xsl) {
doctmp = xmltool.transform(document, xsl);
xmlFreeDoc(document);
xsltFreeStylesheet(xsl);
document = doctmp;
}
if (!doctmp) {
setErrorMsg("XSLT failed.");
}
}
}
if (!document) {
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// xslt後の処理
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: treatPostDocument." LINE_SEP, APP_NAME);
fflush(stdout);
}
try {
for (count = 0; count < modules_size; count++) {
module = (XDTPModule*)m_modules.get(count);
module->treatPostDocument(document);
}
}
catch (Exception exception) {
setErrorMsg(exception.what());
xmlFreeDoc(document);
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 保存
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: save file." LINE_SEP, APP_NAME);
fflush(stdout);
}
tmpfile = "_xdtp_temp.XXXXXX";
fd = Glib::mkstemp(tmpfile);
if (0 > fd) {
setErrorMsg("Unable to create temp file.");
xmlFreeDoc(document);
return false;
}
close(fd);
xsltStylesheetPtr xsl = NULL;
if (0 < m_XSLObjects.size()) {
// 出力形式を保持するXSLファイルを決定
if (0 < m_XSL4OutputPos) xsl = parseXSL(m_XSL4OutputPos);
if (!xsl) xsl = parseXSL(m_XSLObjects.size() -1);
// XSLT変換処理後は、保存にスタイルシート情報が必要。
if (NULL == xsl) {
setErrorMsg("Unable to load xsl file for output.");
xmlFreeDoc(document);
remove(tmpfile.c_str());
return false;
}
}
if (!XMLSaver::save(tmpfile, document, xsl, m_OutputEncoding)) {
setErrorMsg("Unable to save xml file. (" + tmpfile + ")");
if (xsl) xsltFreeStylesheet(xsl);
xmlFreeDoc(document);
remove(tmpfile.c_str());
return false;
}
if (xsl) xsltFreeStylesheet(xsl);
xmlFreeDoc(document);
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 保存後の処理
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: treatPostFile." LINE_SEP, APP_NAME);
fflush(stdout);
}
try {
for (count = 0; count < modules_size; count++) {
module = (XDTPModule*)m_modules.get(count);
module->treatPostFile(tmpfile);
}
}
catch (Exception exception) {
setErrorMsg(exception.what());
remove(tmpfile.c_str());
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 出力
mode_t outputMask = m_OutputMask;
if (1 < m_nVerbose) {
fprintf(stdout, "%s: transform: output file." LINE_SEP, APP_NAME);
fflush(stdout);
}
// 標準出力
if (0 >= anOutput.length() || anOutput == "-") {
if (!Utilities::printFile(tmpfile)) {
setErrorMsg("Unable to print out.");
result = false;
}
remove(tmpfile.c_str());
}
// リネーム
else {
if (!Utilities::move(tmpfile, anOutput)) {
setErrorMsg("Unable to move file. (" + tmpfile + " -> " + anOutput + ")");
remove(tmpfile.c_str());
result = false;
}
else {
/*
* パーミッションを変更
* 変更元ファイルは、mkstempの仕様により、通常は600である。
* リネーム時に同名のファイルが存在する場合は、その限りではない。
*/
if (!outputMask) {
// 変換元ファイルのパーミッションを引き継ぎます。
outputMask = getFileMask(anInput);
}
if (chmod(anOutput.c_str(), outputMask)) {
setErrorMsg(strerror(errno));
//result = false; 現在はエラーとしません。 2006/03/02 ozawa
}
}
}
return result;
}
/**
* 変換処理時に発生したエラーメッセージを出力します。
* エラーが発生しなかった場合は、何も表示しません。
*
* @param out 出力先
*/
void XDTPTransform::showErrorMsg(FILE* out) const
{
if (0 < m_ErrorMsg.length()) {
fprintf(out, "%s: %s" LINE_SEP, APP_NAME, m_ErrorMsg.c_str());
}
}
/**
* エラーメッセージを設定します。
*
* @param aMsg エラーメッセージ
*/
void XDTPTransform::setErrorMsg(const Glib::ustring& aMsg)
{
m_ErrorMsg = aMsg;
}
/**
* XML文章の正当性チェックをスキップします。
*
* @param bCheck スキップする場合は true を指定します。
*/
void XDTPTransform::skipXMLCheck(bool bCheck)
{
m_bSkipXMLCheck = bCheck;
}
/**
* XML文章の正当性チェックをスキップするか調べます。
*
* @return スキップする場合は true を戻します。
*/
bool XDTPTransform::isXMLCheck() const
{
return m_bSkipXMLCheck;
}
/**
* 変換用XSLファイルを追加します。
*
* @param useOutputType 出力形式を保持し、これを利用する場合は true を指定します。
*/
void XDTPTransform::addXSLFile(const Glib::ustring& aPath, bool useOutputType)
{
Glib::ustring *path = new Glib::ustring;
if (!path) THROW("Out of memory!");
*path = aPath;
m_XSLObjects.add(OBJECT_TYPE_USTRING, path);
if (useOutputType) {
m_XSL4OutputPos = m_XSLObjects.size() -1;
}
}
/**
* 変換用XSLオブジェクトを追加します。
*
* @param aXSL XSLオブジェクト
* @param useOutputType オブジェクトが出力形式を保持し、これを利用する場合は true を指定します。
*/
void XDTPTransform::addXSLObject(xsltStylesheetPtr aXSL, bool useOutputType)
{
m_XSLObjects.add(OBJECT_TYPE_XSL, aXSL);
if (useOutputType) {
m_XSL4OutputPos = m_XSLObjects.size() -1;
}
}
/**
* 変換用XSLファイルの一覧をクリアします。
*/
void XDTPTransform::clearXSLFile()
{
m_XSLObjects.clear();
m_XSL4OutputPos = -1;
}
/**
* 変換用XSLファイルの一覧を取得します。
*
* @deprecated
* @return 変換用XSLファイルの一覧
*/
const StringList& XDTPTransform::getXSLFileList()
{
int type;
void *value;
for (int count = 0; count < m_XSLObjects.size(); count++) {
value = m_XSLObjects.get(count, &type);
if (OBJECT_TYPE_USTRING == type) {
__m_XSLFileList.push_back(*((Glib::ustring*)value));
}
}
return __m_XSLFileList;
}
/**
* 変換用XSLファイルおよびオブジェクトの一覧を取得します。
*
* @return 変換用XSLファイルおよびオブジェクトの一覧
*/
const XDTPObjectWrapper& XDTPTransform::getXSLList() const
{
return m_XSLObjects;
}
/**
* 変換用XDTPモジュールを追加します。
*
* @param aPath XDTPモジュールへのパス
*/
void XDTPTransform::addXDTPModule(const Glib::ustring& aPath)
{
Glib::ustring *path = new Glib::ustring;
if (!path) THROW("Out of memory!");
*path = aPath;
m_XDTPModules.add(OBJECT_TYPE_USTRING, path);
}
/**
* 変換用XDTPモジュールを追加します。
*
* @param aModule XDTPモジュール
* @param aChecker XDTPチェッカ。使用しない場合は NULL を指定できます。
*/
void XDTPTransform::addXDTPModule(XDTPModule *aModule, XDTPChecker *aChecker)
{
if (!aModule) THROW("XDTPTransform::addXDTPModule: bad arguments.");
XDTP_MC *mc = new XDTP_MC;
if (!mc) THROW("Out of memory!");
mc->module = aModule;
mc->checker = aChecker;
m_XDTPModules.add(OBJECT_TYPE_MC, mc);
}
/**
* 変換用XDTPモジュールをクリアします。
*/
void XDTPTransform::clearXDTPModule()
{
m_XDTPModules.clear();
}
/**
* 変換用XDTPモジュールの一覧を取得します。
*
* @return 変換用XDTPモジュールの一覧
*/
const StringList& XDTPTransform::getXDTPModuleList()
{
int type;
void *value;
for (int count = 0; count < m_XDTPModules.size(); count++) {
value = m_XDTPModules.get(count, &type);
if (OBJECT_TYPE_USTRING == type) {
__m_XDTPModuleList.push_back(*((Glib::ustring*)value));
}
}
return __m_XDTPModuleList;
}
/**
* 変換用XDTPモジュールの一覧を取得します。
*
* @return 変換用XDTPモジュールの一覧
*/
const XDTPObjectWrapper& XDTPTransform::getXDTPMCList() const
{
return m_XDTPModules;
}
/**
* 変換用XDTPモジュールへのオプションを追加します。
*
* @param anOption 追加オプション
*/
void XDTPTransform::addOption(const Glib::ustring& anOption)
{
m_OptionList.push_back(anOption);
}
/**
* 変換用XDTPモジュールへのオプションをクリアします。
*/
void XDTPTransform::clearOption()
{
m_OptionList.clear();
}
/**
* 変換用XDTPモジュールへのオプションの一覧を取得します。
*
* @return 変換用XDTPモジュールへのオプションの一覧
*/
const StringList& XDTPTransform::getOptionList() const
{
return m_OptionList;
}
/**
* 出力形式を指定します。
*
* @param aType 出力形式
*/
void XDTPTransform::setOutputType(const Glib::ustring& aType)
{
m_OutputType = aType.lowercase();
}
/**
* 出力形式を取得します。
*
* @return 出力形式
*/
const Glib::ustring& XDTPTransform::getOutputType() const
{
return m_OutputType;
}
/**
* メッセージの表示レベルを指定します。
*
* @param aMode メッセージの表示レベル
*/
void XDTPTransform::setVerboseMode(int aMode)
{
m_nVerbose = aMode;
}
/**
* メッセージの表示レベルを取得します。
*/
int XDTPTransform::getVerboseMode() const
{
return m_nVerbose;
}
/**
* 入力ファイルのエンコードを指定します。
*
* @param anEncoding 入力ファイルのエンコード
*/
void XDTPTransform::setInputEncoding(const Glib::ustring& anEncoding)
{
if ("getlocale" == anEncoding.lowercase()) {
std::string encoding;
Glib::get_charset(encoding);
m_InputEncoding = encoding;
}
else {
m_InputEncoding = anEncoding;
}
}
/**
* 入力ファイルのエンコードを取得します。
*
* @return 入力ファイルのエンコード
*/
const Glib::ustring& XDTPTransform::getInputEncoding() const
{
return m_InputEncoding;
}
/**
* 出力ファイルのエンコードを指定します。
*
* @param anEncoding 出力ファイルのエンコード
*/
void XDTPTransform::setOutputEncoding(const Glib::ustring& anEncoding)
{
if ("getlocale" == anEncoding.lowercase()) {
std::string encoding;
Glib::get_charset(encoding);
m_OutputEncoding = encoding;
}
else {
m_OutputEncoding = anEncoding;
}
}
/**
* 出力ファイルのエンコードを取得します。
*
* @return 出力ファイルのエンコード
*/
const Glib::ustring& XDTPTransform::getOutputEncoding() const
{
return m_OutputEncoding;
}
bool XDTPTransform::loadModules(LibraryList& libraries,
XDTPObjectWrapper& modules, XDTPObjectWrapper& checkers)
{
bool result = true;
int count = 0;
int type = 0;
const int size = m_XDTPModules.size();
void *value;
XDTP_MC *mc;
XDTPModuleLibrary *lib = NULL;
XDTPModule *module = NULL;
XDTPChecker *checker = NULL;
Glib::ustring path;
for (; count < size; count++) {
value = m_XDTPModules.get(count, &type);
if (type == OBJECT_TYPE_MC) {
mc = (XDTP_MC*)value;
modules.add(OBJECT_TYPE_XDTP_EXT_MODULE, mc->module);
if (mc->checker) checkers.add(OBJECT_TYPE_XDTP_EXT_CHECKER, mc->checker);
continue;
}
if (type != OBJECT_TYPE_USTRING) continue;
path = *((Glib::ustring*)value);
// 内部モジュールのロード
if (4 < path.length() && path.substr(0, 4).lowercase() == RESOURCE_TAG) {
path = path.substr(4);
result &= loadLocalModule(path, modules, checkers);
continue;
}
// 外部モジュールのロード
lib = XDTPModuleLoader::loadModuleLibrary(path);
if (!lib) {
setErrorMsg("Unable to load module. (" + path + ")");
result = false;
}
else {
module = XDTPModuleLoader::buildModule(lib);
checker = XDTPModuleLoader::buildChecker(lib);
if (!module) {
XDTPModuleLoader::unloadModuleLibrary(lib);
setErrorMsg("Unable to build module. (" + path + ")");
result = false;
}
else {
libraries.push_back(lib);
modules.add(OBJECT_TYPE_XDTP_EXT_MODULE, module);
if (checker) checkers.add(OBJECT_TYPE_XDTP_EXT_CHECKER, checker);
}
}
}
if (!result) {
unloadModules(libraries, modules, checkers);
}
return result;
}
void XDTPTransform::unloadModules(LibraryList& libraries,
XDTPObjectWrapper& modules, XDTPObjectWrapper& checkers)
{
LibraryList::iterator iter = libraries.begin();
LibraryList::iterator end = libraries.end();
for (; iter != end; iter++) {
XDTPModuleLoader::unloadModuleLibrary(*iter);
}
libraries.clear();
modules.clear();
checkers.clear();
}
bool XDTPTransform::loadLocalModule(const Glib::ustring& module,
XDTPObjectWrapper& modules, XDTPObjectWrapper& checkers)
{
if (module.lowercase() == "glsdmodule") {
modules.add(OBJECT_TYPE_XDTP_LCL_MODULE, new GLSDModule());
checkers.add(OBJECT_TYPE_XDTP_LCL_CHECKER, new GLSDModuleChecker());
}
else if (module.lowercase() == "glsddocumentmodule") {
modules.add(OBJECT_TYPE_XDTP_LCL_MODULE, new GLSDDocumentModule());
checkers.add(OBJECT_TYPE_XDTP_LCL_CHECKER, new GLSDDocumentModuleChecker());
}
else if (module.lowercase() == "glsdbanbunmodule") {
modules.add(OBJECT_TYPE_XDTP_LCL_MODULE, new GLSDBanBunModule());
checkers.add(OBJECT_TYPE_XDTP_LCL_CHECKER, new GLSDBanBunModuleChecker());
}
else {
setErrorMsg("Unknown module name. (" + module + ")");
return false;
}
return true;
}
xsltStylesheetPtr XDTPTransform::parseXSL(int pos)
{
int type;
void *value = m_XSLObjects.get(pos, &type);
switch (type) {
case OBJECT_TYPE_USTRING:
return xsltParseStylesheetFile((const xmlChar *)((Glib::ustring*)value)->c_str());
case OBJECT_TYPE_XSL:
return (xsltStylesheetPtr)value;
default:
THROW("XDTPTransform::parseXSL: Internal error! (Unknown object type)");
}
return NULL;
}
syntax highlighted by Code2HTML, v. 0.9.1