--- a/src/StreamletAttributeFinder.h Sun Jan 19 15:44:30 2020 +0100
+++ b/src/StreamletAttributeFinder.h Sun Jan 19 17:05:46 2020 +0100
@@ -45,24 +45,36 @@
std::map<int, std::shared_ptr<SubProcess>> subProcesses;
std::map<int, std::vector<AttributeMetadata>> cachedMetadata;
+ std::vector<string_t> splitBySeparator(const string_t& originalString, const wchar_t separator = L':', const wchar_t escape = L'\\') {
+ std::vector<string_t> result;
+ std::wstringstream current;
+ for (int i = 0, size = originalString.size(); i < size; i++) {
+ wchar_t ch = originalString[i];
+ if (ch == escape) {
+ if (i + 1 < size) {
+ ch = originalString[++i];
+ if (ch == separator || ch == escape) current.put(ch);
+ else RelpipeWriterException(L"Invalid escape sequence at position " + std::to_wstring(i) + L" of: " + originalString);
+ } else {
+ throw RelpipeWriterException(L"Invalid use of escape character at the end of: " + originalString);
+ }
+ } else if (ch == separator || i + 1 == size) {
+ if (current.str().size()) result.push_back(current.str());
+ current.str(L"");
+ current.clear();
+ } else {
+ current.put(ch);
+ }
+ }
+ return result;
+ }
+
string_t getStreamletCommand(const RequestedField& field) {
const char* streamletPathChars = getenv("RELPIPE_IN_FILESYSTEM_STREAMLET_PATH");
if (streamletPathChars) {
- std::wstringstream current;
- string_t streamletPath = convertor.from_bytes(streamletPathChars);
- for (int i = 0, streamletPathSize = streamletPath.size(); i < streamletPathSize; i++) {
- if (streamletPath[i] == ':' || i == streamletPathSize - 1) { // FIXME: support \: and \\ escaping
- current << L"/" << field.name;
- fs::path streamletFile(current.str());
- if (fs::exists(streamletFile) && ::access(streamletFile.c_str(), X_OK) == 0) { // n.b. must be set executable using e.g. chmod – files executable through only ACL, are actually not executable
- return current.str();
- } else {
- current.str(L"");
- current.clear();
- }
- } else {
- current.put(streamletPath[i]);
- }
+ for (string_t path : splitBySeparator(convertor.from_bytes(streamletPathChars))) {
+ fs::path file = fs::path(path) / fs::path(field.name);
+ if (fs::exists(file) && ::access(file.c_str(), X_OK) == 0) return file.wstring();
}
throw RelpipeWriterException(L"Streamlet „" + field.name + L"“ was not found at $RELPIPE_IN_FILESYSTEM_STREAMLET_PATH");
} else {
@@ -99,9 +111,7 @@
public:
- static const string_t SCRIPT_PREFIX;
-
- virtual vector<AttributeMetadata> toMetadata(RelationalWriter* writer, const string_t& relationName, const RequestedField& field) override {
+ virtual vector<AttributeMetadata> toMetadata(RelationalWriter* writer, const string_t& relationName, const RequestedField & field) override {
if (field.group == RequestedField::GROUP_STREAMLET) {
if (cachedMetadata.count(field.id)) {
@@ -160,8 +170,6 @@
}
};
-const relpipe::writer::string_t StreamletAttributeFinder::SCRIPT_PREFIX = L"__relpipe_in_filesystem_script_";
-
}
}
}