采用ISO8211封装的S57数据,中文读取时乱码及丢字原因分析与解决方法,终极解决方案.

来源:互联网 发布:四环医学网络学员登录 编辑:程序博客网 时间:2024/06/02 16:16

// 该程序自动判断输入数据的类型,正确返回数据长度,首先判断字段定长或变长,然后根据数据的定界符判断数据是双字节还是字节字串。

// 最后正确返加字串的长度和字段占用内存的长度

// 依据:

// 字段和子字段终止
// 可变长度子字段必须由“单元定界符”(UT)终止。 可变长度子字段是在数据结构中通过没有范围的格式指示器指定(见第7.2.2.1节)。 

// 所有S-57(ISO / IEC 8211数据字段)必须由“字段定界符”(FT)终止。当S-57字段使用不同字符集时时,UT和FT必须编码为该字段指定的级别。

// 下表定义了每个级别的定界符。
// 词汇级 UT FT
// 0级 (1/15)(1/14)
// 1级 (1/15)(1/14)
// 2级    (0/0)(1/15)(0/0)(1/14)

// 当词汇级为2级时,s57允许NATF(国家属性字段)使用本国语言,并用双字节UNICODE编码,单元结束符和字段结束符为两个字节

// 由于编码采用大尾序,因此实际定界符编码为UT(1F00),FT(1E00)

int DDFSubfieldDefn::GetDataLength( const char * pachSourceData,

int nMaxBytes, int * pnConsumedBytes )


{
if( !bIsVariable )
{ // 定长字段
if( nFormatWidth > nMaxBytes )
{
CPLError( CE_Warning, CPLE_AppDefined, 
"Only %d bytes available for subfield %s with\n"
"format string %s ... returning shortened data.",
nMaxBytes, pszName, pszFormatString );


if( pnConsumedBytes != NULL )
*pnConsumedBytes = nMaxBytes;


return nMaxBytes;
}
else
{
if( pnConsumedBytes != NULL )
*pnConsumedBytes = nFormatWidth;


return nFormatWidth;
}
}
else
{ // 变长字段
int     nLength = 0;
int nConsumedBytes = 0;
bool bDoubleBytes = FALSE;// 双字节标志


while(nLength + 1 < nMaxBytes)// 循环测试,判断是否为双字节字段
{
if(pachSourceData[nLength] == DDF_UNIT_TERMINATOR && pachSourceData[nLength+1] == 0 ||
pachSourceData[nLength] ==  DDF_FIELD_TERMINATOR && pachSourceData[nLength] == 0)
{
bDoubleBytes = TRUE;
break;
}
nLength++;
}


nLength = 0; // 字节长度清零


if (bDoubleBytes)
{ // 双字节
while(nLength < nMaxBytes)
{  
//双字节单元结束符和字段结束符
if( pachSourceData[nLength] == DDF_UNIT_TERMINATOR && pachSourceData[nLength+1] == 0 &&
pachSourceData[nLength + 2] ==  DDF_FIELD_TERMINATOR && pachSourceData[nLength+3] == 0)
{
nConsumedBytes = nLength + 4;
break;
}
//双字节单元结束符或字段结束符
if( pachSourceData[nLength] == DDF_UNIT_TERMINATOR && pachSourceData[nLength+1] == 0 ||
pachSourceData[nLength] ==  DDF_FIELD_TERMINATOR && pachSourceData[nLength+1] == 0)
{
nConsumedBytes = nLength + 2;
break;
}
nLength ++;
}
}
else
{ //单字节
while(nLength < nMaxBytes)
{
//单字节单元结束符和字段结束符
if( pachSourceData[nLength] == DDF_UNIT_TERMINATOR &&
pachSourceData[nLength+1] == DDF_FIELD_TERMINATOR) 
{
nConsumedBytes = nLength + 2;
break;
}
//单字节单元结束符或字段结束符
if( pachSourceData[nLength] == DDF_UNIT_TERMINATOR||
pachSourceData[nLength] == DDF_FIELD_TERMINATOR) 
{
nConsumedBytes = nLength + 1;
break;
}
nLength++;
}
}


if( pnConsumedBytes != NULL )
{
if( nMaxBytes < nConsumedBytes )
*pnConsumedBytes = nLength;
else
*pnConsumedBytes = nConsumedBytes;
}


return nLength;
}
}
阅读全文
0 0
原创粉丝点击