Browse Source

Added a parameter to File::appendText, File::replaceWithText and OutputStream::writeText to provide control over if/how line-feeds are replaced when writing text to a file

tags/2021-05-28
jules 7 years ago
parent
commit
efda09a512
4 changed files with 79 additions and 43 deletions
  1. +4
    -8
      modules/juce_core/files/juce_File.cpp
  2. +6
    -3
      modules/juce_core/files/juce_File.h
  3. +64
    -30
      modules/juce_core/streams/juce_OutputStream.cpp
  4. +5
    -2
      modules/juce_core/streams/juce_OutputStream.h

+ 4
- 8
modules/juce_core/files/juce_File.cpp View File

@@ -750,24 +750,20 @@ bool File::replaceWithData (const void* const dataToWrite,
return tempFile.overwriteTargetFileWithTemporary();
}
bool File::appendText (const String& text,
const bool asUnicode,
const bool writeUnicodeHeaderBytes) const
bool File::appendText (const String& text, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const
{
FileOutputStream out (*this);
if (out.failedToOpen())
return false;
return out.writeText (text, asUnicode, writeUnicodeHeaderBytes);
return out.writeText (text, asUnicode, writeHeaderBytes, lineFeed);
}
bool File::replaceWithText (const String& textToWrite,
const bool asUnicode,
const bool writeUnicodeHeaderBytes) const
bool File::replaceWithText (const String& textToWrite, bool asUnicode, bool writeHeaderBytes, const char* lineFeed) const
{
TemporaryFile tempFile (*this, TemporaryFile::useHiddenFile);
tempFile.getFile().appendText (textToWrite, asUnicode, writeUnicodeHeaderBytes);
tempFile.getFile().appendText (textToWrite, asUnicode, writeHeaderBytes, lineFeed);
return tempFile.overwriteTargetFileWithTemporary();
}


+ 6
- 3
modules/juce_core/files/juce_File.h View File

@@ -681,13 +681,15 @@ public:
It can also write the 'ff fe' unicode header bytes before the text to indicate
the endianness of the file.
Any single \\n characters in the string are replaced with \\r\\n before it is written.
If lineEndings is nullptr, then line endings in the text won't be modified. If you
pass "\\n" or "\\r\\n" then this function will replace any existing line feeds.
@see replaceWithText
*/
bool appendText (const String& textToAppend,
bool asUnicode = false,
bool writeUnicodeHeaderBytes = false) const;
bool writeUnicodeHeaderBytes = false,
const char* lineEndings = "\r\n") const;
/** Replaces this file's contents with a given text string.
@@ -707,7 +709,8 @@ public:
*/
bool replaceWithText (const String& textToWrite,
bool asUnicode = false,
bool writeUnicodeHeaderBytes = false) const;
bool writeUnicodeHeaderBytes = false,
const char* lineEndings = "\r\n") const;
/** Attempts to scan the contents of this file and compare it to another file, returning
true if this is possible and they match byte-for-byte.


+ 64
- 30
modules/juce_core/streams/juce_OutputStream.cpp View File

@@ -171,20 +171,27 @@ bool OutputStream::writeDoubleBigEndian (double value)
bool OutputStream::writeString (const String& text)
{
auto numBytes = text.getNumBytesAsUTF8() + 1;
#if (JUCE_STRING_UTF_TYPE == 8)
return write (text.toRawUTF8(), text.getNumBytesAsUTF8() + 1);
return write (text.toRawUTF8(), numBytes);
#else
// (This avoids using toUTF8() to prevent the memory bloat that it would leave behind
// if lots of large, persistent strings were to be written to streams).
const size_t numBytes = text.getNumBytesAsUTF8() + 1;
HeapBlock<char> temp (numBytes);
text.copyToUTF8 (temp, numBytes);
return write (temp, numBytes);
#endif
}
bool OutputStream::writeText (const String& text, bool asUTF16, bool writeUTF16ByteOrderMark)
bool OutputStream::writeText (const String& text, bool asUTF16, bool writeUTF16ByteOrderMark, const char* lf)
{
bool replaceLineFeedWithUnix = lf != nullptr && lf[0] == '\n' && lf[1] == 0;
bool replaceLineFeedWithWindows = lf != nullptr && lf[0] == '\r' && lf[1] == '\n' && lf[2] == 0;
// The line-feed passed in must be either nullptr, or "\n" or "\r\n"
jassert (lf == nullptr || replaceLineFeedWithWindows || replaceLineFeedWithUnix);
if (asUTF16)
{
if (writeUTF16ByteOrderMark)
@@ -200,10 +207,17 @@ bool OutputStream::writeText (const String& text, bool asUTF16, bool writeUTF16B
if (c == 0)
break;
if (c == '\n' && ! lastCharWasReturn)
writeShort ((short) '\r');
if (replaceLineFeedWithWindows)
{
if (c == '\n' && ! lastCharWasReturn)
writeShort ((short) '\r');
lastCharWasReturn = (c == L'\r');
lastCharWasReturn = (c == L'\r');
}
else if (replaceLineFeedWithUnix && c == '\r')
{
continue;
}
if (! writeShort ((short) c))
return false;
@@ -211,37 +225,57 @@ bool OutputStream::writeText (const String& text, bool asUTF16, bool writeUTF16B
}
else
{
const char* src = text.toUTF8();
auto* t = src;
const char* src = text.toRawUTF8();
for (;;)
if (replaceLineFeedWithWindows)
{
if (*t == '\n')
for (auto t = src;;)
{
if (t > src)
if (! write (src, (size_t) (t - src)))
return false;
if (*t == '\n')
{
if (t > src)
if (! write (src, (size_t) (t - src)))
return false;
if (! write ("\r\n", 2))
return false;
if (! write ("\r\n", 2))
return false;
src = t + 1;
src = t + 1;
}
else if (*t == '\r')
{
if (t[1] == '\n')
++t;
}
else if (*t == 0)
{
if (t > src)
if (! write (src, (size_t) (t - src)))
return false;
break;
}
++t;
}
else if (*t == '\r')
{
if (t[1] == '\n')
++t;
}
else if (*t == 0)
}
else if (replaceLineFeedWithUnix)
{
for (;;)
{
if (t > src)
if (! write (src, (size_t) (t - src)))
return false;
auto c = *src++;
break;
}
if (c == 0)
break;
++t;
if (c != '\r')
if (! writeByte (c))
return false;
}
}
else
{
return write (src, text.getNumBytesAsUTF8());
}
}
@@ -273,9 +307,9 @@ int64 OutputStream::writeFromInputStream (InputStream& source, int64 numBytesToW
}
//==============================================================================
void OutputStream::setNewLineString (const String& newLineString_)
void OutputStream::setNewLineString (const String& newLineStringToUse)
{
newLineString = newLineString_;
newLineString = newLineStringToUse;
}
//==============================================================================


+ 5
- 2
modules/juce_core/streams/juce_OutputStream.h View File

@@ -201,12 +201,15 @@ public:
bytes (0xff, 0xfe) to indicate the endianness (these should only be used at the start
of a file).
The method also replaces '\\n' characters in the text with '\\r\\n'.
If lineEndings is nullptr, then line endings in the text won't be modified. If you
pass "\\n" or "\\r\\n" then this function will replace any existing line feeds.
@returns false if the write operation fails for some reason
*/
virtual bool writeText (const String& text,
bool asUTF16,
bool writeUTF16ByteOrderMark);
bool writeUTF16ByteOrderMark,
const char* lineEndings);
/** Reads data from an input stream and writes it to this stream.


Loading…
Cancel
Save