CTextOutputStream::CTextOutputStream(const TCHAR* tszPath, ECodeType eCodeType, bool bExceptionMode, bool bBom) : COutputStream(tszPath,_T("wb"),bExceptionMode) { m_pcCodeBase = CCodeFactory::CreateCodeBase(eCodeType,0); if(Good() && bBom){ //BOM付加 CMemory cmemBom; m_pcCodeBase->GetBom(&cmemBom); if(cmemBom.GetRawLength()>0){ fwrite(cmemBom.GetRawPtr(),cmemBom.GetRawLength(),1,GetFp()); } } }
void CTextOutputStream::WriteString( const wchar_t* szData, //!< 書き込む文字列 int nLen //!< 書き込む文字列長。-1を渡すと自動計算。 ) { //$$メモ: 文字変換時にいちいちコピーを作ってるので効率が悪い。後々効率改善予定。 int nDataLen = nLen; if(nDataLen<0)nDataLen = wcslen(szData); const wchar_t* pData = szData; const wchar_t* pEnd = szData + nDataLen; //1行毎にカキコ。"\n"は"\r\n"に変換しながら出力。ただし、"\r\n"は"\r\r\n"に変換しない。 const wchar_t* p = pData; for (;;) { //\nを検出。ただし\r\nは除外。 const wchar_t* q = p; while(q<pEnd){ if(*q==L'\n' && !((q-1)>=p && *(q-1)==L'\r') )break; q++; } const wchar_t* lf; if(q<pEnd)lf = q; else lf = NULL; if(lf){ //\nの前まで(p~lf)出力 CNativeW cSrc(p,lf-p); CMemory cDst; m_pcCodeBase->UnicodeToCode(cSrc,&cDst); //コード変換 fwrite(cDst.GetRawPtr(),1,cDst.GetRawLength(),GetFp()); //\r\nを出力 cSrc.SetString(L"\r\n"); m_pcCodeBase->UnicodeToCode(cSrc,&cDst); fwrite(cDst.GetRawPtr(),1,cDst.GetRawLength(),GetFp()); //次へ p=lf+1; } else{ //残りぜんぶ出力 CNativeW cSrc(p,pEnd-p); CMemory cDst; m_pcCodeBase->UnicodeToCode(cSrc,&cDst); //コード変換 fwrite(cDst.GetRawPtr(),1,cDst.GetRawLength(),GetFp()); break; } } }
/*! バッファ内容をファイルに書き出す (テスト用) @note Windows用にコーディングしてある @date 2003.07.26 ryoji BOM引数追加 */ EConvertResult CWriteManager::WriteFile_From_CDocLineMgr( const CDocLineMgr& pcDocLineMgr, //!< [in] const SSaveInfo& sSaveInfo //!< [in] ) { EConvertResult nRetVal = RESULT_COMPLETE; std::auto_ptr<CCodeBase> pcCodeBase( CCodeFactory::CreateCodeBase(sSaveInfo.eCharCode,0) ); { // 変換テスト CNativeW buffer = L"abcde"; CMemory tmp; EConvertResult e = pcCodeBase->UnicodeToCode( buffer, &tmp ); if(e==RESULT_FAILURE){ nRetVal=RESULT_FAILURE; ErrorMessage( CEditWnd::getInstance()->GetHwnd(), LS(STR_FILESAVE_CONVERT_ERROR), sSaveInfo.cFilePath.c_str() ); return nRetVal; } } try { //ファイルオープン CBinaryOutputStream out(sSaveInfo.cFilePath,true); //各行出力 int nLineNumber = 0; const CDocLine* pcDocLine = pcDocLineMgr.GetDocLineTop(); // 1行目 { ++nLineNumber; CMemory cmemOutputBuffer; { CNativeW cstrSrc; CMemory cstrBomCheck; pcCodeBase->GetBom( &cstrBomCheck ); if( sSaveInfo.bBomExist && 0 < cstrBomCheck.GetRawLength() ){ // 1行目にはBOMを付加する。エンコーダでbomがある場合のみ付加する。 CUnicode().GetBom( cstrSrc._GetMemory() ); } if( pcDocLine ){ cstrSrc.AppendNativeData( pcDocLine->_GetDocLineDataWithEOL() ); } EConvertResult e = pcCodeBase->UnicodeToCode( cstrSrc, &cmemOutputBuffer ); if(e==RESULT_LOSESOME){ nRetVal=RESULT_LOSESOME; } if(e==RESULT_FAILURE){ nRetVal=RESULT_FAILURE; ErrorMessage( CEditWnd::getInstance()->GetHwnd(), LS(STR_FILESAVE_CONVERT_ERROR), sSaveInfo.cFilePath.c_str() ); throw CError_FileWrite(); } } out.Write(cmemOutputBuffer.GetRawPtr(), cmemOutputBuffer.GetRawLength()); if( pcDocLine ){ pcDocLine = pcDocLine->GetNextLine(); } } CMemory cmemOutputBuffer; while( pcDocLine ){ ++nLineNumber; //経過通知 if(pcDocLineMgr.GetLineCount()>0 && nLineNumber%1024==0){ NotifyProgress(nLineNumber * 100 / pcDocLineMgr.GetLineCount()); // 処理中のユーザー操作を可能にする if( !::BlockingHook( NULL ) ){ throw CAppExitException(); //中断検出 } } //1行出力 -> cmemOutputBuffer { // 書き込み時のコード変換 cstrSrc -> cmemOutputBuffer EConvertResult e = pcCodeBase->UnicodeToCode( pcDocLine->_GetDocLineDataWithEOL(), &cmemOutputBuffer ); if(e==RESULT_LOSESOME){ if(nRetVal==RESULT_COMPLETE)nRetVal=RESULT_LOSESOME; } if(e==RESULT_FAILURE){ nRetVal=RESULT_FAILURE; ErrorMessage( CEditWnd::getInstance()->GetHwnd(), LS(STR_FILESAVE_CONVERT_ERROR), sSaveInfo.cFilePath.c_str() ); break; } } //ファイルに出力 cmemOutputBuffer -> fp out.Write(cmemOutputBuffer.GetRawPtr(), cmemOutputBuffer.GetRawLength()); //次の行へ pcDocLine = pcDocLine->GetNextLine(); } //ファイルクローズ out.Close(); } catch(CError_FileOpen){ //########### 現時点では、この例外が発生した場合は正常に動作できない ErrorMessage( CEditWnd::getInstance()->GetHwnd(), LS(STR_SAVEAGENT_OTHER_APP), sSaveInfo.cFilePath.c_str() ); nRetVal = RESULT_FAILURE; } catch(CError_FileWrite){ nRetVal = RESULT_FAILURE; } catch(CAppExitException){ //中断検出 return RESULT_FAILURE; } return nRetVal; }