Parcourir la source

[3400] Element::preprocess() is now thread safe.

Tomek Mrugalski il y a 11 ans
Parent
commit
e03b3b7f15
3 fichiers modifiés avec 29 ajouts et 19 suppressions
  1. 21 12
      src/lib/cc/data.cc
  2. 6 5
      src/lib/cc/data.h
  3. 2 2
      src/lib/cc/tests/data_unittests.cc

+ 21 - 12
src/lib/cc/data.cc

@@ -614,7 +614,14 @@ ElementPtr
 Element::fromJSON(std::istream& in, bool preproc) throw(JSONError) {
 
     int line = 1, pos = 1;
-    return (fromJSON(preproc?preprocess(in):in, "<istream>", line, pos));
+    stringstream filtered;
+    if (preproc) {
+        preprocess(in, filtered);
+    }
+
+    ElementPtr value = fromJSON(preproc?filtered:in, "<istream>", line, pos);
+
+    return (value);
 }
 
 ElementPtr
@@ -622,7 +629,11 @@ Element::fromJSON(std::istream& in, const std::string& file_name, bool preproc)
     throw(JSONError)
 {
     int line = 1, pos = 1;
-    return (fromJSON(preproc?preprocess(in):in, file_name, line, pos));
+    stringstream filtered;
+    if (preproc) {
+        preprocess(in, filtered);
+    }
+    return (fromJSON(preproc?filtered:in, file_name, line, pos));
 }
 
 ElementPtr
@@ -705,8 +716,11 @@ Element::fromJSON(const std::string& in, bool preproc) {
     ss << in;
 
     int line = 1, pos = 1;
-    ElementPtr result(fromJSON(preproc?preprocess(ss):ss, "<string>",
-                               line, pos));
+    stringstream filtered;
+    if (preproc) {
+        preprocess(ss, filtered);
+    }
+    ElementPtr result(fromJSON(preproc?filtered:ss, "<string>", line, pos));
     skipChars(ss, WHITESPACE, line, pos);
     // ss must now be at end
     if (ss.peek() != EOF) {
@@ -1046,7 +1060,7 @@ merge(ElementPtr element, ConstElementPtr other) {
     }
 }
 
-std::istream& Element::preprocess(std::istream& in) {
+void Element::preprocess(std::istream& in, std::stringstream& out) {
 
     // There is no assignment operator defined for streams, so we can't return
     // stream as an object. If we return a pointer, someone would have to free
@@ -1054,11 +1068,8 @@ std::istream& Element::preprocess(std::istream& in) {
     // it's not allowed to return references to automatic variables, we must
     // make sure that the reference is valid after this method returns. So
     // returning a value to static object seems the only feasible way to go.
-    static stringstream filtered;
     std::string line;
 
-    filtered.clear();
-    filtered.str("");
     while (std::getline(in, line)) {
         // If this is a comments line, replace it with empty line
         // (so the line numbers will still match
@@ -1069,11 +1080,9 @@ std::istream& Element::preprocess(std::istream& in) {
         // getline() removes end line charaters. Unfortunately, we need
         // it for getting the line numbers right (in case we report an
         // error.
-        filtered << line;
-        filtered << "\n";
+        out << line;
+        out << "\n";
     }
-
-    return filtered;
 }
 
 }

+ 6 - 5
src/lib/cc/data.h

@@ -481,14 +481,15 @@ public:
     /// expected to contain a text version of to be parsed JSON). For now the
     /// sole supported operation is bash-style (line starting with #) comment
     /// removal, but it will be extended later to cover more cases (C, C++ style
-    /// comments, file inclusions, maybe macro replacements?)
+    /// comments, file inclusions, maybe macro replacements?).
     ///
-    /// It reads all contents of the input stream, filters the content and
-    /// returns the result in a different stream.
+    /// This method processes the whole input stream. It reads all contents of
+    /// the input stream, filters the content and returns the result in a
+    /// different stream.
     ///
     /// @param in input stream to be preprocessed
-    /// @return a new stream that has the content filtered.
-    static std::istream& preprocess(std::istream& in);
+    /// @param out output stream (filtered content will be written here)
+    static void preprocess(std::istream& in, std::stringstream& out);
 
     /// \name Wire format factory functions
 

+ 2 - 2
src/lib/cc/tests/data_unittests.cc

@@ -1011,7 +1011,7 @@ TEST(Element, getPosition) {
     // Create a JSON string holding different type of values. Some of the
     // values in the config string are not aligned, so as we can check that
     // the position is set correctly for the elements.
-    ElementPtr top = Element::fromJSON(ss, "kea.conf");
+    ElementPtr top = Element::fromJSON(ss, string("kea.conf"));
     ASSERT_TRUE(top);
 
     // Element "a"
@@ -1103,7 +1103,7 @@ TEST(Element, getPositionCommented) {
     // Create a JSON string holding different type of values. Some of the
     // values in the config string are not aligned, so as we can check that
     // the position is set correctly for the elements.
-    ElementPtr top = Element::fromJSON(ss, "kea.conf");
+    ElementPtr top = Element::fromJSON(ss, string("kea.conf"), true);
     ASSERT_TRUE(top);
 
     // Element "a"