⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cprofile.cpp

📁 日本的开源编辑器源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//	$Id: CProfile.cpp,v 1.16 2004/04/11 07:07:52 genta Exp $
/*!	@file
	@brief INIファイル入出力

	@author D.S.Koba
	$Revision: 1.16 $
	@date 2003-10-21 D.S.Koba メンバ関数の名前と引数をそのままにしてメンバ変数,関数の中身を書き直し
	@date 2004-01-10 D.S.Koba 返値をBOOLからboolへ変更。IOProfileDataを型別の関数に分け,引数を減らす
*/
/*
	Copyright (C) 2003, D.S.Koba

	This software is provided 'as-is', without any express or implied
	warranty. In no event will the authors be held liable for any damages
	arising from the use of this software.

	Permission is granted to anyone to use this software for any purpose, 
	including commercial applications, and to alter it and redistribute it 
	freely, subject to the following restrictions:

		1. The origin of this software must not be misrepresented;
		   you must not claim that you wrote the original software.
		   If you use this software in a product, an acknowledgment
		   in the product documentation would be appreciated but is
		   not required.

		2. Altered source versions must be plainly marked as such, 
		   and must not be misrepresented as being the original software.

		3. This notice may not be removed or altered from any source
		   distribution.
*/
#ifdef USE_STREAM
#  include <fstream>
#else
#  include <stdio.h>
#  include <string.h>
#endif
//#include <sstream>
#include <algorithm>
#include "CProfile.h"
#include "Debug.h"


/*! Profileを初期化
	
	@date 2003-10-21 D.S.Koba STLで書き直す
*/
void CProfile::Init( void )
{
	m_strProfileName = _T("");
	m_ProfileData.clear();
	return;
}

/*!
	sakura.iniの1行を処理する.

	1行の読み込みが完了するごとに呼ばれる.
	
	@param line [in] 読み込んだ行
*/
void CProfile::ReadOneline(
	const std::basic_string< TCHAR >& line
)
{
	//	空行を読み飛ばす
	if( line.empty() )
		return;

	//コメント行を読みとばす
	if( 0 == line.compare( 0, 2, _T("//") ))
		return;

	// セクション取得
	//	Jan. 29, 2004 genta compare使用
	if( line.compare( 0, 1, _T("[") ) == 0 
		&& line.find( _T("=") ) == line.npos
		&& line.find( _T("]") ) == ( line.size() - 1 ) )
	{
		Section Buffer;
		Buffer.strSectionName = line.substr( 1, line.size() - 1 - 1 );
		m_ProfileData.push_back( Buffer );
	}
	// エントリ取得
	else if( !m_ProfileData.empty() )	//最初のセクション以前の行のエントリは無視
	{
		std::basic_string< TCHAR >::size_type idx = line.find( _T("=") );
		if( line.npos != idx )
		{
			m_ProfileData.back().Data.insert( PAIR_STR_STR( line.substr(0,idx), line.substr(idx+1) ) );
		}
	}
}

/*! Profileをファイルから読み出す
	
	@param pszProfileName [in] ファイル名

	@retval true  成功
	@retval false 失敗

	@date 2003-10-21 D.S.Koba STLで書き直す
	@date 2003-10-26 D.S.Koba ReadProfile()から分離
	@date 2004-01-29 genta stream使用をやめてCライブラリ使用に.
	@date 2004-01-31 genta 行の解析の方を別関数にしてReadFileをReadProfileに
		
*/
bool CProfile::ReadProfile( const TCHAR* pszProfileName )
{
	m_strProfileName = pszProfileName;
#ifdef USE_STREAM
	std::basic_ifstream< TCHAR > ifs( m_strProfileName.c_str() );
	if(!ifs.is_open()) return false;
	
	std::basic_string< TCHAR > strWork;
	try
	{
		for(;;)
		{
			std::getline( ifs, strWork );
			ReadOneline( strWork );
			if(ifs.eof()) break;
		}
	} //try
	catch(...)
	{
		//ファイルの読み込み失敗
		ifs.close();
		return false;
	}
	ifs.close();
#else
	FILE* fp = _tfopen( m_strProfileName.c_str(), _T( "r" ));
	if( fp == NULL ){
		return false;
	}

	const int CHUNK_SIZE = 2048;			// てきと~
	TCHAR* buf = new TCHAR[ CHUNK_SIZE ];	//	読み込み用
	std::basic_string< TCHAR > bstr;		//	作業用
	unsigned int offset = 0;				//	出力済み領域チェック用

	try {
		while( !feof( fp )){
			int length = fread( buf, sizeof( TCHAR ), CHUNK_SIZE, fp );
			
			//	エラーチェック
			if( ferror( fp )){
				delete [] buf;
				fclose( fp );
				return false;
			}
			
			bstr = bstr.substr( offset ) + std::basic_string< TCHAR >( buf, length );
			offset = 0;
			
			int pos;
			//	\nが見つかる間ループ
			while(( pos = bstr.find( _T('\n' ), offset ) ) != bstr.npos ){
				//	改行コードは渡さない
				ReadOneline( bstr.substr( offset, pos - offset ) );
				offset = pos + 1;
			}

			if( feof( fp )){
				if( offset < bstr.size() ){
					//	最終行は\nが無くてもとりあえず
					ReadOneline( bstr.substr( offset ) );
				}
				break;
			}
		}
	}
	catch( ... ){
		delete [] buf;
		fclose( fp );
		return false;
	}
	delete [] buf;
	fclose( fp );
#endif

#ifdef _DEBUG
	//DUMP();
#endif
	return true;
}


/*! Profileをファイルへ書き出す
	
	@param pszProfileName [in] ファイル名(NULL=最後に読み書きしたファイル)
	@param pszComment [in] コメント文(NULL=コメント省略)

	@retval true  成功
	@retval false 失敗

	@date 2003-10-21 D.S.Koba STLで書き直す
	@date 2004-01-28 D.S.Koba ファイル書き込み部を分離
*/
bool CProfile::WriteProfile(
	const TCHAR* pszProfileName,
	const TCHAR* pszComment
)
{
	if( NULL != pszProfileName )
	{
		m_strProfileName = pszProfileName;
	}
    
	std::vector< std::basic_string< TCHAR > > vecLine;
	if( NULL != pszComment )
	{
		vecLine.push_back( _T("//") + std::basic_string< TCHAR >( pszComment ) );
		vecLine.push_back( _T("") );
	}
	std::vector< Section >::iterator iter;
	std::vector< Section >::iterator iterEnd = m_ProfileData.end();
	MAP_STR_STR_ITER mapiter;
	MAP_STR_STR_ITER mapiterEnd;
	for( iter = m_ProfileData.begin(); iter != iterEnd; iter++ )
	{
		//セクション名を書き込む
		vecLine.push_back( _T("[") + iter->strSectionName + _T("]") );
		mapiterEnd = iter->Data.end();
		for( mapiter = iter->Data.begin(); mapiter != mapiterEnd; mapiter++ )
		{
			//エントリを書き込む
			vecLine.push_back( mapiter->first + _T("=") + mapiter->second );
		}
		vecLine.push_back( _T("") );
	}

	return WriteFile( m_strProfileName, vecLine );
}

/*! ファイルへ書き込む
	
	@param strFilename [in] ファイル名
	@param vecLine [out] 文字列格納先

	@retval true  成功
	@retval false 失敗

	@date 2004-01-28 D.S.Koba WriteProfile()から分離
	@date 2004-01-29 genta stream使用をやめてCライブラリ使用に.
*/
bool CProfile::WriteFile(
	const std::basic_string< TCHAR >& strFilename,
	std::vector< std::basic_string< TCHAR > >& vecLine
)
{
#ifdef USE_STREAM
	std::basic_ofstream< TCHAR > ofs( strFilename.c_str() );
	if(!ofs.is_open()) return false;

	std::vector< std::basic_string< TCHAR > >::iterator iter;
	std::vector< std::basic_string< TCHAR > >::iterator iterEnd = vecLine.end();

	try
	{
		for( iter = vecLine.begin(); iter != iterEnd; iter++ )
		{
			ofs << iter->c_str() << _T("\n");
		}
	}
	catch(...)
	{
		ofs.close();
		return false;
	}
	ofs.close();

#else
	//	Jan. 29, 2004 genta standard i/o version
	FILE* fp = _tfopen( strFilename.c_str(), _T( "w" ));
	if( fp == NULL ){
		return false;
	}

	std::vector< std::basic_string< TCHAR > >::iterator iter;
	std::vector< std::basic_string< TCHAR > >::iterator iterEnd = vecLine.end();

	for( iter = vecLine.begin(); iter != iterEnd; iter++ )
	{
		//	文字列に\0を含む場合を考慮してバイナリ出力
		if( fwrite( iter->data(), sizeof( TCHAR ), iter->size(), fp ) != iter->size() ){
			fclose( fp );
			return false;
		}
		if( _fputtc( _T('\n'), fp ) == _TEOF ){
			fclose( fp );
			return false;
		}
	}
	fclose( fp );
#endif
	return true;
}


/*! エントリ値(bool型)をProfileから読み込む,又はProfileへ書き込む
	
	@param bRead [in] モード(true=読み込み, false=書き込み)
	@param pszSectionName [in] セクション名
	@param pszEntryKey [in] エントリ名
	@param EntryValue [i/o] エントリ値

	@retval true  成功
	@retval false 失敗

	@date 2004-01-10 D.S.Koba エントリの型別に関数を分離
*/
bool CProfile::IOProfileData(
	const bool&		bRead,
	const TCHAR*	pszSectionName,
	const TCHAR*	pszEntryKey,
	bool&			EntryValue
)
{
	// 「読み込み」か「書き込み」か
	if( bRead )
	{
		std::basic_string< TCHAR > strWork;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -