您的位置:首页 > 其它

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

2017-10-08 18:10 751 查看
// 该程序自动判断输入数据的类型,正确返回数据长度,首先判断字段定长或变长,然后根据数据的定界符判断数据是双字节还是字节字串。最后正确返加字串的长度和字段占用内存的长度。
// 依据:
// 字段和子字段终止
// 可变长度子字段必须由“单元定界符”(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;
        }
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐