Skip to content

Commit c5a1741

Browse files
committed
MWGIS-240; initial work on saving Shapefiles with UTF-8 code page
1 parent 2389fa9 commit c5a1741

4 files changed

Lines changed: 14 additions & 9 deletions

File tree

src/COM classes/TableClass.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -718,6 +718,9 @@ bool CTableClass::SaveToFile(const CStringW& dbfFilename, bool updateFileInPlace
718718
return false;
719719
}
720720

721+
// is the Shapefile UTF-8 (if unspecified or specified as UTF-8)
722+
bool isUTF8 = (DBFGetCodePage(_dbfHandle) == nullptr || strcmp(DBFGetCodePage(_dbfHandle), "UTF-8") == 0);
723+
721724
// joined fields must be removed; they will be restored in the process of reopening table
722725
// after saving operation
723726
this->RemoveJoinedFields();
@@ -799,7 +802,7 @@ bool CTableClass::SaveToFile(const CStringW& dbfFilename, bool updateFileInPlace
799802
continue;
800803
}
801804

802-
if (!WriteRecord(newdbfHandle, rowIndex, ++currentRowIndex))
805+
if (!WriteRecord(newdbfHandle, rowIndex, ++currentRowIndex, isUTF8))
803806
{
804807
ErrorMessage(tkDBF_CANT_WRITE_ROW);
805808
return false;
@@ -935,6 +938,8 @@ void CTableClass::LoadDefaultFields()
935938
field->put_Width(fwidth);
936939
field->put_Precision(fdecimals);
937940
field->put_Type((FieldType)type);
941+
//// field has not really been modified
942+
//((CField*)field)->SetIsUpdated(false);
938943

939944
FieldWrapper* fw = new FieldWrapper();
940945
fw->oldIndex = i;
@@ -1440,7 +1445,7 @@ bool CTableClass::ReadRecord(long RowIndex)
14401445
// WriteRecord()
14411446
// *******************************************************************
14421447
//Write a cached RecordWrapper into dbf file
1443-
bool CTableClass::WriteRecord(DBFInfo* dbfHandle, long fromRowIndex, long toRowIndex)
1448+
bool CTableClass::WriteRecord(DBFInfo* dbfHandle, long fromRowIndex, long toRowIndex, bool isUTF8)
14441449
{
14451450
AFX_MANAGE_STATE(AfxGetStaticModuleState())
14461451
USES_CONVERSION;
@@ -1454,7 +1459,7 @@ bool CTableClass::WriteRecord(DBFInfo* dbfHandle, long fromRowIndex, long toRowI
14541459
if (fromRowIndex < 0 || fromRowIndex >= RowCount())
14551460
return false;
14561461

1457-
char * nonstackString = NULL;
1462+
const char * nonstackString = NULL;
14581463

14591464
for (long i = 0; i < FieldCount(); i++)
14601465
{
@@ -1468,7 +1473,7 @@ bool CTableClass::WriteRecord(DBFInfo* dbfHandle, long fromRowIndex, long toRowI
14681473
{
14691474
if (val.vt == VT_BSTR)
14701475
{
1471-
nonstackString = Utility::SYS2A(val.bstrVal);
1476+
nonstackString = Utility::ConvertBSTRToLPSTR(val.bstrVal, (isUTF8 ? CP_UTF8 : CP_ACP)); // ((LPCSTR)Utility::ConvertToUtf8(val.bstrVal)); // Utility::SYS2A(val.bstrVal);
14721477
DBFWriteStringAttribute(dbfHandle, toRowIndex, i, nonstackString);
14731478
delete[] nonstackString;
14741479
nonstackString = NULL;

src/COM classes/TableClass.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,7 @@ class ATL_NO_VTABLE CTableClass :
206206
long RowCount() { return _rows.size(); }
207207
long FieldCount() { return _fields.size(); }
208208
bool ReadRecord(long RowIndex);
209-
bool WriteRecord(DBFInfo* dbfHandle, long fromRowIndex, long toRowIndex);
209+
bool WriteRecord(DBFInfo* dbfHandle, long fromRowIndex, long toRowIndex, bool isUTF8 = false);
210210
void ClearRow(long rowIndex);
211211
FieldType GetFieldType(long fieldIndex);
212212
long GetFieldPrecision(long fieldIndex);

src/Utilities/UtilityFunctions.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,21 +87,21 @@ namespace Utility
8787
// ConvertBSTRToLPSTR
8888
// ********************************************************
8989
//Rob Cairns 29-Aug-2009
90-
char* ConvertBSTRToLPSTR(BSTR bstrIn)
90+
char* ConvertBSTRToLPSTR(BSTR bstrIn, UINT codePage /* = CP_ACP */)
9191
{
9292
LPSTR pszOut = nullptr;
9393
if (bstrIn != nullptr)
9494
{
9595
int nInputStrLen = SysStringLen(bstrIn);
9696

9797
// Double NULL Termination
98-
int nOutputStrLen = WideCharToMultiByte(CP_ACP, 0, bstrIn, nInputStrLen, nullptr, 0, nullptr, nullptr) + 2;
98+
int nOutputStrLen = WideCharToMultiByte(codePage, 0, bstrIn, nInputStrLen, nullptr, 0, nullptr, nullptr) + 2;
9999
pszOut = new char[nOutputStrLen];
100100

101101
if (pszOut)
102102
{
103103
memset(pszOut, 0x00, sizeof(char)*nOutputStrLen);
104-
WideCharToMultiByte(CP_ACP, 0, bstrIn, nInputStrLen, pszOut, nOutputStrLen, nullptr, nullptr);
104+
WideCharToMultiByte(codePage, 0, bstrIn, nInputStrLen, pszOut, nOutputStrLen, nullptr, nullptr);
105105
}
106106
}
107107
return pszOut;

src/Utilities/UtilityFunctions.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ namespace Utility
1313
BSTR Variant2BSTR(VARIANT* val, CString floatFormat);
1414
char * SYS2A(BSTR str);
1515
WCHAR* StringToWideChar(CString s);
16-
char* ConvertBSTRToLPSTR (BSTR bstrIn);
16+
char* ConvertBSTRToLPSTR (BSTR bstrIn, UINT codePage = CP_ACP);
1717
CString ReplaceNoCase( LPCTSTR instr, LPCTSTR oldstr, LPCTSTR newstr );
1818

1919
CString UrlEncode(CString s);

0 commit comments

Comments
 (0)