YAML: Add support for literal block scalar I/O.
This commit gives the users of the YAML Traits I/O library
the ability to serialize scalars using the YAML literal block
scalar notation by allowing them to implement a specialization
of the `BlockScalarTraits` struct for their custom types.
Reviewers: Duncan P. N. Exon Smith
Differential Revision: http://reviews.llvm.org/D9613
llvm-svn: 237404
diff --git a/llvm/lib/Support/YAMLTraits.cpp b/llvm/lib/Support/YAMLTraits.cpp
index 8ef36a3..90f34f6 100644
--- a/llvm/lib/Support/YAMLTraits.cpp
+++ b/llvm/lib/Support/YAMLTraits.cpp
@@ -14,6 +14,7 @@
#include "llvm/Support/Errc.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
+#include "llvm/Support/LineIterator.h"
#include "llvm/Support/YAMLParser.h"
#include "llvm/Support/raw_ostream.h"
#include <cctype>
@@ -309,6 +310,8 @@
}
}
+void Input::blockScalarString(StringRef &S) { scalarString(S, false); }
+
void Input::setError(HNode *hnode, const Twine &message) {
assert(hnode && "HNode must not be NULL");
this->setError(hnode->_node, message);
@@ -331,6 +334,11 @@
KeyStr = StringRef(Buf, Len);
}
return llvm::make_unique<ScalarHNode>(N, KeyStr);
+ } else if (BlockScalarNode *BSN = dyn_cast<BlockScalarNode>(N)) {
+ StringRef Value = BSN->getValue();
+ char *Buf = StringAllocator.Allocate<char>(Value.size());
+ memcpy(Buf, Value.data(), Value.size());
+ return llvm::make_unique<ScalarHNode>(N, StringRef(Buf, Value.size()));
} else if (SequenceNode *SQ = dyn_cast<SequenceNode>(N)) {
auto SQHNode = llvm::make_unique<SequenceHNode>(N);
for (Node &SN : *SQ) {
@@ -609,6 +617,24 @@
this->outputUpToEndOfLine("'"); // Ending single quote.
}
+void Output::blockScalarString(StringRef &S) {
+ if (!StateStack.empty())
+ newLineCheck();
+ output(" |");
+ outputNewLine();
+
+ unsigned Indent = StateStack.empty() ? 1 : StateStack.size();
+
+ auto Buffer = MemoryBuffer::getMemBuffer(S, "", false);
+ for (line_iterator Lines(*Buffer, false); !Lines.is_at_end(); ++Lines) {
+ for (unsigned I = 0; I < Indent; ++I) {
+ output(" ");
+ }
+ output(*Lines);
+ outputNewLine();
+ }
+}
+
void Output::setError(const Twine &message) {
}