?? cdoclinemgr.cpp
字號:
// $Id: CDocLineMgr.cpp,v 1.45 2005/04/17 10:01:02 genta Exp $
/*! @file
@brief 行データの管理
@author Norio Nakatani
@date 1998/03/05 新規作成
@date 2001/06/23 N.Nakatani 単語単位で検索する機能を実裝
@date 2001/06/23 N.Nakatani WhereCurrentWord()変更 WhereCurrentWord_2をコールするようにした
$Revision: 1.45 $
*/
/*
Copyright (C) 1998-2001, Norio Nakatani
Copyright (C) 2001, genta, jepro, hor
Copyright (C) 2002, hor, aroka, MIK, Moca
This source code is designed for sakura editor.
Please contact the copyright holder to use this code for other purpose.
*/
/* for TRACE() of MFC */
//#ifdef _DEBUG
// #include <afx.h>
//#endif
//#ifndef _DEBUG
// #include <windows.h>
//#endif
#include "charcode.h"
#include "CDocLineMgr.h"
#include "debug.h"
#include "charcode.h"
// Oct 6, 2000 ao
#include <stdio.h>
#include <io.h>
// Jun. 26, 2001 genta 正規表現ライブラリの差し替え
#include "CBregexp.h"
#include <commctrl.h>
#include "global.h"
#include "etc_uty.h"
#include "CRunningTimer.h"
// May 15, 2000 genta
#include "CEol.h"
#include "CDocLine.h"// 2002/2/10 aroka ヘッダ整理
#include "CMemory.h"// 2002/2/10 aroka
#include "CFileWrite.h" //2002/05/22 Frozen
#include "CFileLoad.h" // 2002/08/30 Moca
#include "my_icmp.h" // Nov. 29, 2002 genta/moca
/* 文字種類識別子 */
#define CK_NULL 0 /*!< NULL 0x0<=c<=0x0 */
#define CK_TAB 1 /*!< タブ 0x9<=c<=0x9 */
#define CK_CR 2 /*!< CR = 0x0d */
#define CK_LF 3 /*!< LF = 0x0a */
#define CK_SPACE 4 /*!< 半角のスペース 0x20<=c<=0x20 */
#define CK_CSYM 5 /*!< 半角の英字、アンダースコア、數字のいずれか */
#define CK_KATA 6 /*!< 半角のカタカナ 0xA1<=c<=0xFD */
#define CK_ETC 7 /*!< 半角のその他 */
#define CK_MBC_SPACE 12 /*!< 2バイトのスペース */
/*!< 0x8140<=c<=0x8140 全角スペース */
#define CK_MBC_NOVASU 13 /*!< 伸ばす記號 0x815B<=c<=0x815B 'ー' */
#define CK_MBC_CSYM 14 /*!< 2バイトの英字、アンダースコア、數字のいずれか */
/*!< 0x8151<=c<=0x8151 全角アンダースコア */
/*!< 0x824F<=c<=0x8258 全角數字 */
/*!< 0x8260<=c<=0x8279 全角英字大文字 */
/*!< 0x8281<=c<=0x829a 全角英字小文字 */
#define CK_MBC_KIGO 15 /*!< 2バイトの記號 */
/*!< 0x8141<=c<=0x81FD */
#define CK_MBC_HIRA 16 /*!< 2バイトのひらがな */
/*!< 0x829F<=c<=0x82F1 全角ひらがな */
#define CK_MBC_KATA 17 /*!< 2バイトのカタカナ */
/*!< 0x8340<=c<=0x8396 全角カタカナ */
#define CK_MBC_GIRI 18 /*!< 2バイトのギリシャ文字 */
/*!< 0x839F<=c<=0x83D6 全角ギリシャ文字 */
#define CK_MBC_ROS 19 /*!< 2バイトのロシア文字: */
/*!< 0x8440<=c<=0x8460 全角ロシア文字大文字 */
/*!< 0x8470<=c<=0x8491 全角ロシア文字小文字 */
#define CK_MBC_SKIGO 20 /*!< 2バイトの特殊記號 */
/*!< 0x849F<=c<=0x879C 全角特殊記號 */
#define CK_MBC_ETC 21 /*!< 2バイトのその他(漢字など) */
CDocLineMgr::CDocLineMgr()
{
Init();
}
CDocLineMgr::~CDocLineMgr()
{
Empty();
}
void CDocLineMgr::Init()
{
m_pDocLineTop = NULL;
m_pDocLineBot = NULL;
m_nLines = 0;
m_nPrevReferLine = 0;
m_pCodePrevRefer = NULL;
m_bIsDiffUse = false; /* DIFF使用中 */ //@@@ 2002.05.25 MIK
return;
}
/*!
データのクリア
全ての行を削除する
*/
void CDocLineMgr::Empty()
{
CDocLine* pDocLine;
CDocLine* pDocLineNext;
pDocLine = m_pDocLineTop;
while( NULL != pDocLine ){
pDocLineNext = pDocLine->m_pNext;
delete pDocLine;
pDocLine = pDocLineNext;
}
return;
}
const char* CDocLineMgr::GetLineStr( int nLine, int* pnLineLen )
{
CDocLine* pDocLine;
pDocLine = GetLineInfo( nLine );
if( NULL == pDocLine ){
*pnLineLen = 0;
return NULL;
}
// 2002/2/10 aroka CMemory のメンバ変數に直接アクセスしない(inline化されているので速度的な問題はない)
return pDocLine->m_pLine->GetPtr( pnLineLen );
// *pnLineLen = pDocLine->m_pLine->m_nDataLen;
// return pDocLine->m_pLine->m_pData;
}
/*!
指定された行番號の文字列と改行コードを除く長さを取得
@author Moca
@date 2003.06.22
*/
const char* CDocLineMgr::GetLineStrWithoutEOL( int nLine, int* pnLineLen )
{
const CDocLine* pDocLine = GetLineInfo( nLine );
if( NULL == pDocLine ){
*pnLineLen = 0;
return NULL;
}
*pnLineLen = pDocLine->GetLengthWithoutEOL();
return pDocLine->m_pLine->GetPtr();
}
/*!
指定された番號の行へのポインタを返す
@param nLine [in] 行番號
@return 行オブジェクトへのポインタ。該當行がない場合はNULL。
*/
CDocLine* CDocLineMgr::GetLineInfo( int nLine )
{
int nCounter;
CDocLine* pDocLine;
if( 0 == m_nLines ){
return NULL;
}
// 2004.03.28 Moca nLineが負の場合のチェックを追加
if( 0 > nLine || nLine >= m_nLines ){
return NULL;
}
// 2004.03.28 Moca m_pCodePrevReferより、Top,Botのほうが近い場合は、そちらを利用する
int nPrevToLineNumDiff = abs( m_nPrevReferLine - nLine );
if( m_pCodePrevRefer == NULL
|| nLine < nPrevToLineNumDiff
|| m_nLines - nLine < nPrevToLineNumDiff
){
if( m_pCodePrevRefer == NULL ){
MY_RUNNINGTIMER( cRunningTimer, "CDocLineMgr::GetLineInfo() m_pCodePrevRefer == NULL" );
}
#if 0 ///////// 1999.12.22
nCounter = 0;
pDocLine = m_pDocLineTop;
do{
if( nLine == nCounter ){
m_nPrevReferLine = nLine;
m_pCodePrevRefer = pDocLine;
m_pDocLineCurrent = pDocLine->m_pNext;
return pDocLine;
}
pDocLine = pDocLine->m_pNext;
++nCounter;
}while( NULL != pDocLine );
#endif ///////////////
if( nLine < (m_nLines / 2) ){
nCounter = 0;
pDocLine = m_pDocLineTop;
while( NULL != pDocLine ){
if( nLine == nCounter ){
m_nPrevReferLine = nLine;
m_pCodePrevRefer = pDocLine;
m_pDocLineCurrent = pDocLine->m_pNext;
return pDocLine;
}
pDocLine = pDocLine->m_pNext;
nCounter++;
}
}else{
nCounter = m_nLines - 1;
pDocLine = m_pDocLineBot;
while( NULL != pDocLine ){
if( nLine == nCounter ){
m_nPrevReferLine = nLine;
m_pCodePrevRefer = pDocLine;
m_pDocLineCurrent = pDocLine->m_pNext;
return pDocLine;
}
pDocLine = pDocLine->m_pPrev;
nCounter--;
}
}
}else{
if( nLine == m_nPrevReferLine ){
m_nPrevReferLine = nLine;
m_pDocLineCurrent = m_pCodePrevRefer->m_pNext;
return m_pCodePrevRefer;
}else
if( nLine > m_nPrevReferLine ){
nCounter = m_nPrevReferLine + 1;
pDocLine = m_pCodePrevRefer->m_pNext;
while( NULL != pDocLine ){
if( nLine == nCounter ){
m_nPrevReferLine = nLine;
m_pCodePrevRefer = pDocLine;
m_pDocLineCurrent = pDocLine->m_pNext;
return pDocLine;
}
pDocLine = pDocLine->m_pNext;
++nCounter;
}
}else{
nCounter = m_nPrevReferLine - 1;
pDocLine = m_pCodePrevRefer->m_pPrev;
while( NULL != pDocLine ){
if( nLine == nCounter ){
m_nPrevReferLine = nLine;
m_pCodePrevRefer = pDocLine;
m_pDocLineCurrent = pDocLine->m_pNext;
return pDocLine;
}
pDocLine = pDocLine->m_pPrev;
nCounter--;
}
}
}
return NULL;
}
/*! 順アクセスモード:先頭行を得る
@param pnLineLen [out] 行の長さが返る。
@return 1行目の先頭へのポインタ。
データが1行もないときは、長さ0、ポインタNULLが返る。
*/
const char* CDocLineMgr::GetFirstLinrStr( int* pnLineLen )
{
char* pszLine;
if( 0 == m_nLines ){
pszLine = NULL;
*pnLineLen = 0;
}else{
pszLine = m_pDocLineTop->m_pLine->GetPtr( pnLineLen );
m_pDocLineCurrent = m_pDocLineTop->m_pNext;
}
return (const char*)pszLine;
}
/*!
順アクセスモード:次の行を得る
@param pnLineLen [out] 行の長さが返る。
@return 次行の先頭へのポインタ。
GetFirstLinrStr()が呼び出されていないとNULLが返る
*/
const char* CDocLineMgr::GetNextLinrStr( int* pnLineLen )
{
char* pszLine;
if( NULL == m_pDocLineCurrent ){
pszLine = NULL;
*pnLineLen = 0;
}else{
pszLine = m_pDocLineCurrent->m_pLine->GetPtr( pnLineLen );
m_pDocLineCurrent = m_pDocLineCurrent->m_pNext;
}
return (const char*)pszLine;
}
#if 0
/* 末尾に行を追加 Ver0 */
void CDocLineMgr::AddLineStrSz( const char* pszStr )
{
#ifdef _DEBUG
CRunningTimer cRunningTimer( (const char*)"CDocLineMgr::AddLineStrSz" );
#endif
CDocLine* pDocLine;
if( 0 == m_nLines ){
m_pDocLineBot = m_pDocLineTop = new CDocLine;
m_pDocLineTop->m_pPrev = NULL;
m_pDocLineTop->m_pNext = NULL;
m_pDocLineTop->m_pLine = new CMemory( pszStr, lstrlen( pszStr ) );
}else{
pDocLine = new CDocLine;
pDocLine->m_pPrev = m_pDocLineBot;
pDocLine->m_pNext = NULL;
pDocLine->m_pLine = new CMemory( pszStr, lstrlen( pszStr ) );
m_pDocLineBot->m_pNext = pDocLine;
m_pDocLineBot = pDocLine;
}
++m_nLines;
}
/* 末尾に行を追加 Ver1 */
void CDocLineMgr::AddLineStr( const char* pData, int nDataLen )
{
#ifdef _DEBUG
CRunningTimer cRunningTimer( (const char*)"CDocLineMgr::AddLineStr(const char*, int)" );
#endif
CDocLine* pDocLine;
if( 0 == m_nLines ){
m_pDocLineBot = m_pDocLineTop = new CDocLine;
m_pDocLineTop->m_pPrev = NULL;
m_pDocLineTop->m_pNext = NULL;
m_pDocLineTop->m_pLine = new CMemory( pData, nDataLen );
}else{
pDocLine = new CDocLine;
pDocLine->m_pPrev = m_pDocLineBot;
pDocLine->m_pNext = NULL;
pDocLine->m_pLine = new CMemory( pData, nDataLen );
m_pDocLineBot->m_pNext = pDocLine;
m_pDocLineBot = pDocLine;
}
++m_nLines;
}
/* 末尾に行を追加 Ver2 */
void CDocLineMgr::AddLineStr( CMemory& cmemData )
{
//#ifdef _DEBUG
// CRunningTimer cRunningTimer( (const char*)"CDocLineMgr::AddLineStr(CMemory&)" );
//#endif
char* pData;
int nDataLen;
pData = cmemData.GetPtr( &nDataLen );
// AddLineStr( pData, nDataLen );
CDocLine* pDocLine;
if( 0 == m_nLines ){
m_pDocLineBot = m_pDocLineTop = new CDocLine;
m_pDocLineTop->m_pPrev = NULL;
m_pDocLineTop->m_pNext = NULL;
m_pDocLineTop->m_pLine = new CMemory( pData, nDataLen );
}else{
pDocLine = new CDocLine;
pDocLine->m_pPrev = m_pDocLineBot;
pDocLine->m_pNext = NULL;
pDocLine->m_pLine = new CMemory( pData, nDataLen );
m_pDocLineBot->m_pNext = pDocLine;
m_pDocLineBot = pDocLine;
}
++m_nLines;
return;
}
#endif
/*!
末尾に行を追加
@version 1.5
@param pData [in] 追加する文字列へのポインタ
@param nDataLen [in] 文字列の長さ
@param cEol [in] 行末コード
*/
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -