Write correct number of bytes in wxFile::Write(wxString).

This function was broken for conversions using more than one byte per
character (e.g. UTF-16 or UTF-32) and also even for UTF-8 for strings
containing NUL bytes as it used strlen() to determine the number of bytes to
write out instead of using the really needed number.

Fix this by using the wxCharBuffer::length() method which always returns the
correct value.

Also add a wxFile unit test verifying that it can correctly read back a string
written using any of UTF-8, UTF-16 or UTF-32.

Closes #11192.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61898 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2009-09-12 22:40:42 +00:00
parent caa96da739
commit 227989f3e9
12 changed files with 132 additions and 1 deletions

View File

@@ -312,7 +312,7 @@ bool wxFile::Write(const wxString& s, const wxMBConv& conv)
if ( !buf ) if ( !buf )
return false; return false;
const size_t size = strlen(buf); // FIXME: use buf.length() when available const size_t size = buf.length();
return Write(buf, size) == size; return Write(buf, size) == size;
} }

View File

@@ -65,6 +65,7 @@ TEST_OBJECTS = \
test_evthandler.o \ test_evthandler.o \
test_timertest.o \ test_timertest.o \
test_exec.o \ test_exec.o \
test_filetest.o \
test_filekind.o \ test_filekind.o \
test_filenametest.o \ test_filenametest.o \
test_filesystest.o \ test_filesystest.o \
@@ -378,6 +379,9 @@ test_timertest.o: $(srcdir)/events/timertest.cpp $(TEST_ODEP)
test_exec.o: $(srcdir)/exec/exec.cpp $(TEST_ODEP) test_exec.o: $(srcdir)/exec/exec.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/exec/exec.cpp $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/exec/exec.cpp
test_filetest.o: $(srcdir)/file/filetest.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/file/filetest.cpp
test_filekind.o: $(srcdir)/filekind/filekind.cpp $(TEST_ODEP) test_filekind.o: $(srcdir)/filekind/filekind.cpp $(TEST_ODEP)
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/filekind/filekind.cpp $(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/filekind/filekind.cpp

95
tests/file/filetest.cpp Normal file
View File

@@ -0,0 +1,95 @@
///////////////////////////////////////////////////////////////////////////////
// Name: tests/file/filetest.cpp
// Purpose: wxFile unit test
// Author: Vadim Zeitlin
// Created: 2009-09-12
// RCS-ID: $Id$
// Copyright: (c) 2009 Vadim Zeitlin <vadim@wxwidgets.org>
///////////////////////////////////////////////////////////////////////////////
// ----------------------------------------------------------------------------
// headers
// ----------------------------------------------------------------------------
#include "testprec.h"
#ifdef __BORLANDC__
#pragma hdrstop
#endif
#if wxUSE_FILE
#include "wx/file.h"
#include "testfile.h"
// ----------------------------------------------------------------------------
// test class
// ----------------------------------------------------------------------------
class FileTestCase : public CppUnit::TestCase
{
public:
FileTestCase() { }
private:
CPPUNIT_TEST_SUITE( FileTestCase );
CPPUNIT_TEST( RoundTripUTF8 );
CPPUNIT_TEST( RoundTripUTF16 );
CPPUNIT_TEST( RoundTripUTF32 );
CPPUNIT_TEST_SUITE_END();
void RoundTripUTF8() { DoRoundTripTest(wxConvUTF8); }
void RoundTripUTF16() { DoRoundTripTest(wxMBConvUTF16()); }
void RoundTripUTF32() { DoRoundTripTest(wxMBConvUTF32()); }
void DoRoundTripTest(const wxMBConv& conv);
wxDECLARE_NO_COPY_CLASS(FileTestCase);
};
// ----------------------------------------------------------------------------
// CppUnit macros
// ----------------------------------------------------------------------------
CPPUNIT_TEST_SUITE_REGISTRATION( FileTestCase );
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION( FileTestCase, "FileTestCase" );
// ----------------------------------------------------------------------------
// tests implementation
// ----------------------------------------------------------------------------
void FileTestCase::DoRoundTripTest(const wxMBConv& conv)
{
TestFile tf;
const wxString data = "Hello\0UTF";
{
wxFile fout(tf.GetName(), wxFile::write);
CPPUNIT_ASSERT( fout.IsOpened() );
CPPUNIT_ASSERT( fout.Write(data, conv) );
}
{
wxFile fin(tf.GetName(), wxFile::read);
CPPUNIT_ASSERT( fin.IsOpened() );
const wxFileOffset len = fin.Length();
wxCharBuffer buf(len);
CPPUNIT_ASSERT_EQUAL( len, fin.Read(buf.data(), len) );
wxWCharBuffer wbuf(conv.cMB2WC(buf));
#if wxUSE_UNICODE
CPPUNIT_ASSERT_EQUAL( data, wbuf );
#else // !wxUSE_UNICODE
CPPUNIT_ASSERT
(
memcmp(wbuf, L"Hello\0UTF", data.length()*sizeof(wchar_t)) == 0
);
#endif // wxUSE_UNICODE/!wxUSE_UNICODE
}
}
#endif // wxUSE_FILE

View File

@@ -49,6 +49,7 @@ TEST_OBJECTS = \
$(OBJS)\test_evthandler.obj \ $(OBJS)\test_evthandler.obj \
$(OBJS)\test_timertest.obj \ $(OBJS)\test_timertest.obj \
$(OBJS)\test_exec.obj \ $(OBJS)\test_exec.obj \
$(OBJS)\test_filetest.obj \
$(OBJS)\test_filekind.obj \ $(OBJS)\test_filekind.obj \
$(OBJS)\test_filenametest.obj \ $(OBJS)\test_filenametest.obj \
$(OBJS)\test_filesystest.obj \ $(OBJS)\test_filesystest.obj \
@@ -410,6 +411,9 @@ $(OBJS)\test_timertest.obj: .\events\timertest.cpp
$(OBJS)\test_exec.obj: .\exec\exec.cpp $(OBJS)\test_exec.obj: .\exec\exec.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\exec\exec.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\exec\exec.cpp
$(OBJS)\test_filetest.obj: .\file\filetest.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\file\filetest.cpp
$(OBJS)\test_filekind.obj: .\filekind\filekind.cpp $(OBJS)\test_filekind.obj: .\filekind\filekind.cpp
$(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\filekind\filekind.cpp $(CXX) -q -c -P -o$@ $(TEST_CXXFLAGS) .\filekind\filekind.cpp

View File

@@ -41,6 +41,7 @@ TEST_OBJECTS = \
$(OBJS)\test_evthandler.o \ $(OBJS)\test_evthandler.o \
$(OBJS)\test_timertest.o \ $(OBJS)\test_timertest.o \
$(OBJS)\test_exec.o \ $(OBJS)\test_exec.o \
$(OBJS)\test_filetest.o \
$(OBJS)\test_filekind.o \ $(OBJS)\test_filekind.o \
$(OBJS)\test_filenametest.o \ $(OBJS)\test_filenametest.o \
$(OBJS)\test_filesystest.o \ $(OBJS)\test_filesystest.o \
@@ -391,6 +392,9 @@ $(OBJS)\test_timertest.o: ./events/timertest.cpp
$(OBJS)\test_exec.o: ./exec/exec.cpp $(OBJS)\test_exec.o: ./exec/exec.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_filetest.o: ./file/filetest.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
$(OBJS)\test_filekind.o: ./filekind/filekind.cpp $(OBJS)\test_filekind.o: ./filekind/filekind.cpp
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $< $(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<

View File

@@ -42,6 +42,7 @@ TEST_OBJECTS = \
$(OBJS)\test_evthandler.obj \ $(OBJS)\test_evthandler.obj \
$(OBJS)\test_timertest.obj \ $(OBJS)\test_timertest.obj \
$(OBJS)\test_exec.obj \ $(OBJS)\test_exec.obj \
$(OBJS)\test_filetest.obj \
$(OBJS)\test_filekind.obj \ $(OBJS)\test_filekind.obj \
$(OBJS)\test_filenametest.obj \ $(OBJS)\test_filenametest.obj \
$(OBJS)\test_filesystest.obj \ $(OBJS)\test_filesystest.obj \
@@ -493,6 +494,9 @@ $(OBJS)\test_timertest.obj: .\events\timertest.cpp
$(OBJS)\test_exec.obj: .\exec\exec.cpp $(OBJS)\test_exec.obj: .\exec\exec.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\exec\exec.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\exec\exec.cpp
$(OBJS)\test_filetest.obj: .\file\filetest.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\file\filetest.cpp
$(OBJS)\test_filekind.obj: .\filekind\filekind.cpp $(OBJS)\test_filekind.obj: .\filekind\filekind.cpp
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\filekind\filekind.cpp $(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\filekind\filekind.cpp

View File

@@ -270,6 +270,7 @@ TEST_OBJECTS = &
$(OBJS)\test_evthandler.obj & $(OBJS)\test_evthandler.obj &
$(OBJS)\test_timertest.obj & $(OBJS)\test_timertest.obj &
$(OBJS)\test_exec.obj & $(OBJS)\test_exec.obj &
$(OBJS)\test_filetest.obj &
$(OBJS)\test_filekind.obj & $(OBJS)\test_filekind.obj &
$(OBJS)\test_filenametest.obj & $(OBJS)\test_filenametest.obj &
$(OBJS)\test_filesystest.obj & $(OBJS)\test_filesystest.obj &
@@ -448,6 +449,9 @@ $(OBJS)\test_timertest.obj : .AUTODEPEND .\events\timertest.cpp
$(OBJS)\test_exec.obj : .AUTODEPEND .\exec\exec.cpp $(OBJS)\test_exec.obj : .AUTODEPEND .\exec\exec.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_filetest.obj : .AUTODEPEND .\file\filetest.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<
$(OBJS)\test_filekind.obj : .AUTODEPEND .\filekind\filekind.cpp $(OBJS)\test_filekind.obj : .AUTODEPEND .\filekind\filekind.cpp
$(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $< $(CXX) -bt=nt -zq -fo=$^@ $(TEST_CXXFLAGS) $<

View File

@@ -40,6 +40,7 @@
events/evthandler.cpp events/evthandler.cpp
events/timertest.cpp events/timertest.cpp
exec/exec.cpp exec/exec.cpp
file/filetest.cpp
filekind/filekind.cpp filekind/filekind.cpp
filename/filenametest.cpp filename/filenametest.cpp
filesys/filesystest.cpp filesys/filesystest.cpp

View File

@@ -321,6 +321,10 @@ SOURCE=.\filesys\filesystest.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File
SOURCE=.\file\filetest.cpp
# End Source File
# Begin Source File
SOURCE=.\fontmap\fontmaptest.cpp SOURCE=.\fontmap\fontmaptest.cpp
# End Source File # End Source File
# Begin Source File # Begin Source File

View File

@@ -668,6 +668,9 @@
<File <File
RelativePath=".\filesys\filesystest.cpp"> RelativePath=".\filesys\filesystest.cpp">
</File> </File>
<File
RelativePath=".\file\filetest.cpp">
</File>
<File <File
RelativePath=".\fontmap\fontmaptest.cpp"> RelativePath=".\fontmap\fontmaptest.cpp">
</File> </File>

View File

@@ -967,6 +967,10 @@
RelativePath=".\filesys\filesystest.cpp" RelativePath=".\filesys\filesystest.cpp"
> >
</File> </File>
<File
RelativePath=".\file\filetest.cpp"
>
</File>
<File <File
RelativePath=".\fontmap\fontmaptest.cpp" RelativePath=".\fontmap\fontmaptest.cpp"
> >

View File

@@ -939,6 +939,10 @@
RelativePath=".\filesys\filesystest.cpp" RelativePath=".\filesys\filesystest.cpp"
> >
</File> </File>
<File
RelativePath=".\file\filetest.cpp"
>
</File>
<File <File
RelativePath=".\fontmap\fontmaptest.cpp" RelativePath=".\fontmap\fontmaptest.cpp"
> >