Skip to content

Commit

Permalink
Iconv: Change convert() return type to const std::string& (#1099)
Browse files Browse the repository at this point in the history
`JDLIB::Iconv`クラスで使うバッファを`std::vector<char>`から
`std::string`に変更します。`convert()`の引数と戻り値を整理して
内部バッファのconst参照を直接返すように修正します。合わせて
`convert()`を呼び出すコードを整理します。
  • Loading branch information
ma8ma committed Feb 4, 2023
1 parent dc47c4f commit b0d746c
Show file tree
Hide file tree
Showing 12 changed files with 82 additions and 99 deletions.
7 changes: 3 additions & 4 deletions src/dbtree/boardbase.cpp
Expand Up @@ -1079,17 +1079,16 @@ void BoardBase::receive_data( const char* data, size_t size )
if( byte_in != std::string::npos ) {
byte_in += 1; // 改行まで含める

int byte_out;
const char* rawdata_utf8 = m_iconv->convert( &*m_rawdata_left.begin(), byte_in, byte_out );
const std::string& rawdata_utf8 = m_iconv->convert( m_rawdata_left.data(), byte_in );

parse_subject( rawdata_utf8 );
parse_subject( rawdata_utf8.c_str() );

// 残りを先頭に移動
m_rawdata_left.erase( 0, byte_in );

#ifdef _DEBUG
std::cout << "BoardBase::receive_data rawdata.size = " << m_rawdata.size() << " size = " << size
<< " byte_in = " << byte_in << " byte_out = " << byte_out
<< " byte_in = " << byte_in << " byte_out = " << rawdata_utf8.size()
<< " rawdata_left.size = " << m_rawdata_left.size() << std::endl;
#endif
}
Expand Down
10 changes: 7 additions & 3 deletions src/dbtree/nodetree2chcompati.cpp
Expand Up @@ -12,6 +12,9 @@

#include "config/globalconf.h"

#include <cstring>


using namespace DBTREE;


Expand Down Expand Up @@ -115,8 +118,7 @@ char* NodeTree2chCompati::skip_status_line( char* pos, int status )

// エラー
if( status != 1 ){
int byte;
std::string ext_err = std::string( m_iconv->convert( pos_msg, pos - pos_msg, byte ) );
const std::string& ext_err = m_iconv->convert( pos_msg, pos - pos_msg );
set_ext_err( ext_err );
MISC::ERRMSG( ext_err );
}
Expand All @@ -137,7 +139,9 @@ const char* NodeTree2chCompati::raw2dat( char* rawlines, int& byte )
assert( m_iconv != nullptr );

// バッファ自体はiconvクラスの中で持っているのでポインタだけもらう
return m_iconv->convert( rawlines, strlen( rawlines ), byte );
const std::string& result = m_iconv->convert( rawlines, std::strlen( rawlines ) );
byte = result.size();
return result.c_str();
}


Expand Down
24 changes: 12 additions & 12 deletions src/dbtree/nodetreejbbs.cpp
Expand Up @@ -13,6 +13,7 @@

#include "global.h"

#include <cstring>
#include <sstream>


Expand All @@ -22,7 +23,7 @@ constexpr std::size_t kBufSizeDecodedLines = 512 * 1024;

#define APPEND_SECTION( num ) do {\
if( lng_sec[ num ] ){ \
m_decoded_lines.append( lines + pos_sec[ num ], lng_sec[ num ] ); \
m_decoded_lines.append( lines.data() + pos_sec[ num ], lng_sec[ num ] ); \
} } while( 0 )


Expand Down Expand Up @@ -134,33 +135,32 @@ const char* NodeTreeJBBS::raw2dat( char* rawlines, int& byte )
{
assert( m_iconv != nullptr );

int byte_lines;
const char* lines = m_iconv->convert( rawlines, strlen( rawlines ), byte_lines );
const std::string& lines = m_iconv->convert( rawlines, std::strlen( rawlines ) );

int number = id_header() + 1;

#ifdef _DEBUG
std::cout << "NodeTreeJBBS::raw2dat : byte_lines = " << byte_lines << std::endl;
std::cout << "NodeTreeJBBS::raw2dat : byte_lines = " << lines.size() << std::endl;
#endif

// セクション分けして再合成する
m_decoded_lines.clear();
byte = 0;
int pos = 0;
std::size_t pos = 0;
int section = 0;
int pos_sec[ MAX_SECTION ];
std::size_t pos_sec[ MAX_SECTION ];
int lng_sec[ MAX_SECTION ];
memset( lng_sec, 0, sizeof( int ) * MAX_SECTION );

while( pos < byte_lines ){
while( pos < lines.size() ){

// セクション分け
pos_sec[ section ] = pos;
while( !( lines[ pos ] == '<' && lines[ pos +1 ] == '>' ) && lines[ pos ] != '\n' && pos < byte_lines ) ++pos;
while( pos < lines.size() && lines.compare( pos, 2, "<>", 2 ) != 0 && lines[pos] != '\n' ) ++pos;
lng_sec[ section ] = pos - pos_sec[ section ];

// 最後の行で、かつ壊れている場合
if( pos >= byte_lines ){
if( pos >= lines.size() ){
set_broken( true );
break;
}
Expand All @@ -174,7 +174,7 @@ const char* NodeTreeJBBS::raw2dat( char* rawlines, int& byte )
// 透明あぼーんの判定
char number_str[ 64 ];
memset( number_str, 0, 64 );
memcpy( number_str, lines + pos_sec[ 0 ], MIN( lng_sec[ 0 ], 64 -1 ) );
memcpy( number_str, lines.data() + pos_sec[ 0 ], MIN( lng_sec[ 0 ], 64 -1 ) );
int number_in = atoi( number_str );

while( number_in > number ){
Expand Down Expand Up @@ -203,7 +203,7 @@ const char* NodeTreeJBBS::raw2dat( char* rawlines, int& byte )

m_decoded_lines.append( " ID:" );

m_decoded_lines.append( lines + pos_sec[ i ], lng_sec[ i ] );
m_decoded_lines.append( lines.data() + pos_sec[ i ], lng_sec[ i ] );
}
m_decoded_lines.append( "<>" );

Expand Down Expand Up @@ -239,7 +239,7 @@ const char* NodeTreeJBBS::raw2dat( char* rawlines, int& byte )
set_broken( true );

// その行は飛ばす
while( pos < byte_lines && lines[ pos ] != '\n' ) ++pos;
while( pos < lines.size() && lines[ pos ] != '\n' ) ++pos;
++pos;
section = 0;
memset( lng_sec, 0, sizeof( int ) * MAX_SECTION );
Expand Down
6 changes: 2 additions & 4 deletions src/dbtree/nodetreemachi.cpp
Expand Up @@ -240,8 +240,7 @@ const char* NodeTreeMachi::raw2dat( char* rawlines, int& byte )
std::string buffer;

// 文字コード変換
int byte_lines;
const char* str_lines = m_iconv->convert( rawlines, strlen( rawlines ), byte_lines );
const std::string& str_lines = m_iconv->convert( rawlines, std::strlen( rawlines ) );

std::list< std::string > lines = MISC::get_lines( str_lines );
for( std::string& line : lines ) {
Expand Down Expand Up @@ -357,8 +356,7 @@ void NodeTreeMachi::receive_finish()
if( m_buffer_for_200.size() >= 2 && m_buffer_for_200[ 0 ] == '<'
&& ( m_buffer_for_200[ 1 ] == 'E' || m_buffer_for_200[ 1 ] == 'h' ) ) {

int byte_lines;
std::string str_lines( m_iconv->convert( &*m_buffer_for_200.begin(), m_buffer_for_200.size(), byte_lines ) );
const std::string& str_lines = m_iconv->convert( m_buffer_for_200.data(), m_buffer_for_200.size() );

#ifdef _DEBUG
std::cout << str_lines << std::endl;
Expand Down
3 changes: 1 addition & 2 deletions src/dbtree/root.cpp
Expand Up @@ -399,8 +399,7 @@ void Root::receive_finish()

// 文字コードを変換してXML作成
JDLIB::Iconv libiconv{ "UTF-8", "MS932" };
int byte_out;
const std::string rawdata_utf8 = libiconv.convert( &*m_rawdata.begin(), m_rawdata.size(), byte_out );
const std::string& rawdata_utf8 = libiconv.convert( m_rawdata.data(), m_rawdata.size() );
bbsmenu2xml( rawdata_utf8 );

if( m_xml_document.hasChildNodes() )
Expand Down
18 changes: 10 additions & 8 deletions src/jdlib/jdiconv.cpp
Expand Up @@ -88,17 +88,19 @@ Iconv::~Iconv()
* @details UTF-8から別のエンコーディングに変換するときは表現できない文字をHTML数値文字参照(10進数表記)に置き換える。
* @param[in] str_in 変換するテキストへのポインター
* @param[in] size_in 変換するテキストの長さ
* @param[out] size_out 変換した結果の長さ
* @return 変換したテキストへのポインター。
* @note 返り値は Iconv オブジェクトを破棄、または convert() を再び呼び出すとdangling pointerになる。
* @return 変換したテキストへの参照
* @note 返り値は Iconv オブジェクトを破棄、または convert() を再び呼び出すとdangling referenceになる。
*/
const char* Iconv::convert( char* str_in, int size_in, int& size_out )
const std::string& Iconv::convert( char* str_in, std::size_t size_in )
{
#ifdef _DEBUG
std::cout << "Iconv::convert size_in = " << size_in << std::endl;
#endif

if( m_cd == ( GIConv ) -1 ) return nullptr;
if( m_cd == ( GIConv ) -1 ) {
m_buf.clear();
return m_buf;
}

if( const std::size_t size_in_x2 = size_in * 2;
size_in_x2 >= m_buf.size() ) {
Expand Down Expand Up @@ -345,11 +347,11 @@ const char* Iconv::convert( char* str_in, int size_in, int& size_out )

} while( buf_in_tmp < buf_in_end );

size_out = buf_out_tmp - m_buf.data();
*buf_out_tmp = '\0';
const std::size_t size_out = buf_out_tmp - m_buf.data();
m_buf.resize( size_out );

#ifdef _DEBUG
std::cout << "Iconv::convert size_out = " << size_out << std::endl;
#endif
return m_buf.data();
return m_buf;
}
4 changes: 2 additions & 2 deletions src/jdlib/jdiconv.h
Expand Up @@ -16,7 +16,7 @@ namespace JDLIB
{
GIConv m_cd; ///< iconv実装は環境で違いがあるためGlibのラッパーAPIを利用する

std::vector<char> m_buf; ///< 出力バッファ
std::string m_buf; ///< 出力バッファ

std::string m_coding_from; ///< 変換元の文字エンコーディング
bool m_coding_to_is_utf8; ///< 変換先の文字エンコーディングがUTF-8ならtrue
Expand All @@ -29,7 +29,7 @@ namespace JDLIB
~Iconv();

// テキストの文字エンコーディングを変換する
const char* convert( char* str_in, int size_in, int& size_out );
const std::string& convert( char* str_in, std::size_t size_in );
};
}

Expand Down
4 changes: 1 addition & 3 deletions src/jdlib/miscutil.cpp
Expand Up @@ -1489,9 +1489,7 @@ std::string MISC::Iconv( const std::string& str, const std::string& coding_to, c
std::string str_bk = str;

JDLIB::Iconv libiconv( coding_to, coding_from );
int byte_out;

std::string str_enc = libiconv.convert( &*str_bk.begin(), str_bk.size(), byte_out );
std::string str_enc = libiconv.convert( str_bk.data(), str_bk.size() );

return str_enc;
}
Expand Down
6 changes: 2 additions & 4 deletions src/message/messageviewbase.cpp
Expand Up @@ -913,8 +913,7 @@ void MessageViewBase::slot_switch_page( Gtk::Widget*, guint page )
// 対応していないUnicode文字を文字参照の形式(&#nnnn;)で表示する
if( DBTREE::get_unicode( get_url() ) == "change" ){
// MS932等に無い文字を数値文字参照にするために文字コードを変換する
int byte_out;
const std::string str_enc = m_iconv->convert( msg.data(), msg.size(), byte_out );
const std::string& str_enc = m_iconv->convert( msg.data(), msg.size() );
msg = MISC::Iconv( str_enc, "UTF-8", DBTREE::board_charset( get_url() ) );
}
else{
Expand Down Expand Up @@ -994,8 +993,7 @@ void MessageViewBase::show_status()
}
else if( m_text_changed )
{
int byte_out;
std::string str_enc = m_iconv->convert( message.data(), message.size(), byte_out );
const std::string& str_enc = m_iconv->convert( message.data(), message.size() );
m_lng_str_enc = str_enc.length();

// 特殊文字の文字数を計算
Expand Down
3 changes: 1 addition & 2 deletions src/message/post.cpp
Expand Up @@ -239,8 +239,7 @@ void Post::receive_finish()
{
const std::string charset = DBTREE::board_charset( m_url );
JDLIB::Iconv libiconv( "UTF-8", charset );
int byte_out;
m_return_html = libiconv.convert( &*m_rawdata.begin(), m_rawdata.size(), byte_out );
m_return_html = libiconv.convert( m_rawdata.data(), m_rawdata.size() );
}

#ifdef _DEBUG
Expand Down
3 changes: 1 addition & 2 deletions src/skeleton/textloader.cpp
Expand Up @@ -173,8 +173,7 @@ void TextLoader::receive_finish()

// UTF-8に変換しておく
JDLIB::Iconv libiconv( "UTF-8", get_charset() );
int byte_out;
m_data = libiconv.convert( &*m_rawdata.begin(), m_rawdata.size(), byte_out );
m_data = libiconv.convert( m_rawdata.data(), m_rawdata.size() );
clear();

receive_cookies();
Expand Down

0 comments on commit b0d746c

Please sign in to comment.