summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2018-12-12 15:17:54 -0500
committerGitHub <noreply@github.com>2018-12-12 15:17:54 -0500
commit76280cfc114e489f4b596dc2b0e2a560b7f13a55 (patch)
tree6a43de1aee40fd1ed88777e659640b17643dea66
parent24c34cbeaa9d6a44caf7abba4a1a8e196002df1b (diff)
Remove the valist from the ISlangWriter interface. Replace with begin/endAppendBuffer. (#751)
-rw-r--r--slang.h20
-rw-r--r--source/core/slang-writer.cpp60
-rw-r--r--source/core/slang-writer.h39
3 files changed, 78 insertions, 41 deletions
diff --git a/slang.h b/slang.h
index 5ea1d13f8..23bc830e7 100644
--- a/slang.h
+++ b/slang.h
@@ -352,8 +352,6 @@ convention for interface methods.
#include <stddef.h>
#endif // ! SLANG_NO_STDDEF
-#include <stdarg.h>
-
#ifdef __cplusplus
extern "C"
{
@@ -851,17 +849,23 @@ extern "C"
struct ISlangWriter : public ISlangUnknown
{
public:
- /** Write the formatted string with the used args. If returns SLANG_E_NOT_IMPLEMENTED, will use a default internal implementation, and call write with result
- @param format Format string
- @param args The arguments
- @return SLANG_E_NOT_IMPLEMENTED if not implemented, SLANG_OK on success */
- virtual SLANG_NO_THROW SlangResult SLANG_MCALL writeVaList(const char* format, va_list args) = 0;
+ /** Begin an append buffer.
+ NOTE! Only one append buffer can be active at any time.
+ @param maxNumChars The maximum of chars that will be appended
+ @returns The start of the buffer for appending to. */
+ virtual SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) = 0;
+ /** Ends the append buffer, and is equivalent to a write of the append buffer.
+ NOTE! That an endAppendBuffer is not necessary if there are no characters to write.
+ @param buffer is the start of the data to append and must be identical to last value returned from beginAppendBuffer
+ @param numChars must be a value less than or equal to what was returned from last call to beginAppendBuffer
+ @returns Result, will be SLANG_OK on success */
+ virtual SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars) = 0;
/** Write text to the writer
@param chars The characters to write out
@param numChars The amount of characters
@returns SLANG_OK on success */
virtual SLANG_NO_THROW SlangResult SLANG_MCALL write(const char* chars, size_t numChars) = 0;
- /** Flushes any content to the ouput */
+ /** Flushes any content to the output */
virtual SLANG_NO_THROW void SLANG_MCALL flush() = 0;
/** Determines if the writer stream is to the console, and can be used to alter the output
@returns Returns true if is a console writer */
diff --git a/source/core/slang-writer.cpp b/source/core/slang-writer.cpp
index 4c5df0c8a..21c8c6209 100644
--- a/source/core/slang-writer.cpp
+++ b/source/core/slang-writer.cpp
@@ -25,15 +25,23 @@ SlangResult WriterHelper::print(const char* format, ...)
{
va_list args;
va_start(args, format);
- SlangResult res = m_writer->writeVaList(format, args);
- if (res == SLANG_E_NOT_IMPLEMENTED)
+ SlangResult res = SLANG_OK;
+
+ size_t numChars;
{
- StringBuilder builder;
- StringUtil::append(format, args, builder);
+ // Create a copy of args, as will be consumed by calcFormattedSize
+ va_list argsCopy;
+ va_copy(argsCopy, args);
+ numChars = StringUtil::calcFormattedSize(format, argsCopy);
+ va_end(argsCopy);
+ }
- // Write if there is anything to write
- res = (builder.Length()) ? m_writer->write(builder.Buffer(), builder.Length()) : SLANG_OK;
+ if (numChars > 0)
+ {
+ char* appendBuffer = m_writer->beginAppendBuffer(numChars);
+ StringUtil::calcFormatted(format, args, numChars, appendBuffer);
+ res = m_writer->endAppendBuffer(appendBuffer, numChars);
}
va_end(args);
@@ -52,6 +60,24 @@ ISlangUnknown* BaseWriter::getInterface(const Guid& guid)
return (guid == IID_ISlangUnknown || guid == IID_ISlangWriter) ? static_cast<ISlangWriter*>(this) : nullptr;
}
+/* !!!!!!!!!!!!!!!!!!!!!!!!! AppendBufferWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
+
+SLANG_NO_THROW char* SLANG_MCALL AppendBufferWriter::beginAppendBuffer(size_t maxNumChars)
+{
+ m_appendBuffer.SetSize(maxNumChars);
+ return m_appendBuffer.Buffer();
+}
+
+SLANG_NO_THROW SlangResult SLANG_MCALL AppendBufferWriter::endAppendBuffer(char* buffer, size_t numChars)
+{
+ SLANG_ASSERT(m_appendBuffer.Buffer() == buffer && buffer + numChars <= m_appendBuffer.end());
+ // Do the actual write
+ SlangResult res = write(buffer, numChars);
+ // Clear so that buffer can't be written from again without assert
+ m_appendBuffer.Clear();
+ return res;
+}
+
/* !!!!!!!!!!!!!!!!!!!!!!!!! CallbackWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
SlangResult CallbackWriter::write(const char* chars, size_t numChars)
@@ -78,19 +104,6 @@ FileWriter::~FileWriter()
}
}
-SlangResult FileWriter::writeVaList(const char* format, va_list args)
-{
- // http://www.cplusplus.com/reference/cstdio/vfprintf/
- ::vfprintf(m_file, format, args);
-
- if (m_flags & WriterFlag::AutoFlush)
- {
- ::fflush(m_file);
- }
-
- return SLANG_OK;
-}
-
SlangResult FileWriter::write(const char* text, size_t numChars)
{
const size_t numWritten = ::fwrite(text, sizeof(char), numChars, m_file);
@@ -133,9 +146,14 @@ SlangResult FileWriter::setMode(SlangWriterMode mode)
/* !!!!!!!!!!!!!!!!!!!!!!!!! StringWriter !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
-SlangResult StringWriter::writeVaList(const char* format, va_list args)
+SLANG_NO_THROW char* SLANG_MCALL StringWriter::beginAppendBuffer(size_t maxNumChars)
+{
+ return m_builder->prepareForAppend(maxNumChars);
+}
+
+SLANG_NO_THROW SlangResult SLANG_MCALL StringWriter::endAppendBuffer(char* buffer, size_t numChars)
{
- StringUtil::append(format, args, *m_builder);
+ m_builder->appendInPlace(buffer, numChars);
return SLANG_OK;
}
diff --git a/source/core/slang-writer.h b/source/core/slang-writer.h
index 0fa336d6e..4c30ddb96 100644
--- a/source/core/slang-writer.h
+++ b/source/core/slang-writer.h
@@ -4,11 +4,11 @@
#include "slang-string.h"
#include "../../slang-com-helper.h"
+#include "../../source/core/list.h"
namespace Slang
{
-
class WriterHelper
{
public:
@@ -48,7 +48,6 @@ public:
SLANG_NO_THROW uint32_t SLANG_MCALL release() { return (m_flags & WriterFlag::IsStatic) ? 1 : (uint32_t)releaseReference(); }
// ISlangWriter - default impl
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL writeVaList(const char* format, va_list args) { SLANG_UNUSED(args); SLANG_UNUSED(format); return SLANG_E_NOT_IMPLEMENTED; }
SLANG_NO_THROW virtual void SLANG_MCALL flush() SLANG_OVERRIDE {}
SLANG_NO_THROW virtual bool SLANG_MCALL isConsole() SLANG_OVERRIDE { return (m_flags & WriterFlag::IsConsole) != 0; }
SLANG_NO_THROW virtual SlangResult SLANG_MCALL setMode(SlangWriterMode mode) SLANG_OVERRIDE { SLANG_UNUSED(mode); return SLANG_FAIL; }
@@ -63,10 +62,28 @@ protected:
WriterFlags m_flags;
};
-class CallbackWriter : public BaseWriter
+/* Implemented the append buffer part of the writer, such that calls to begin/endAppendBuffer are transformed into appropriate calls to write method */
+class AppendBufferWriter : public BaseWriter
{
public:
- typedef BaseWriter Parent;
+ typedef BaseWriter Parent;
+
+ // ISlangWriter default impl for appendBuffer
+ SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars) SLANG_OVERRIDE;
+
+ AppendBufferWriter(WriterFlags flags) :
+ Parent(flags)
+ {}
+
+protected:
+ List<char> m_appendBuffer;
+};
+
+class CallbackWriter : public AppendBufferWriter
+{
+public:
+ typedef AppendBufferWriter Parent;
// ISlangWriter
SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE;
@@ -82,12 +99,11 @@ protected:
const void* m_data;
};
-class FileWriter : public BaseWriter
+class FileWriter : public AppendBufferWriter
{
public:
- typedef BaseWriter Parent;
+ typedef AppendBufferWriter Parent;
// ISlangWriter
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL writeVaList(const char* format, va_list args) SLANG_OVERRIDE;
SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE;
SLANG_NO_THROW virtual void SLANG_MCALL flush() SLANG_OVERRIDE;
SLANG_NO_THROW virtual SlangResult SLANG_MCALL setMode(SlangWriterMode mode) SLANG_OVERRIDE;
@@ -113,7 +129,8 @@ class StringWriter : public BaseWriter
public:
typedef BaseWriter Parent;
// ISlangWriter
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL writeVaList(const char* format, va_list args) SLANG_OVERRIDE;
+ SLANG_NO_THROW char* SLANG_MCALL beginAppendBuffer(size_t maxNumChars) SLANG_OVERRIDE;
+ SLANG_NO_THROW SlangResult SLANG_MCALL endAppendBuffer(char* buffer, size_t numChars) SLANG_OVERRIDE;
SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE;
/// Ctor
@@ -126,14 +143,12 @@ protected:
StringBuilder* m_builder;
};
-class NullWriter : public BaseWriter
+class NullWriter : public AppendBufferWriter
{
public:
- typedef BaseWriter Parent;
+ typedef AppendBufferWriter Parent;
// ISlangWriter
- SLANG_NO_THROW virtual SlangResult SLANG_MCALL writeVaList(const char* format, va_list args) SLANG_OVERRIDE { SLANG_UNUSED(format); SLANG_UNUSED(args); return SLANG_OK; }
SLANG_NO_THROW virtual SlangResult SLANG_MCALL write(const char* chars, size_t numChars) SLANG_OVERRIDE { SLANG_UNUSED(chars); SLANG_UNUSED(numChars); return SLANG_OK; }
-
/// Ctor
NullWriter(WriterFlags flags) :
Parent(flags)