Преглед на файлове

New Str.Translate() function to map characters

Maps characters found in the search string to characters in the second.

Signed-off-by: Gavin Halliday <gavin.halliday@lexisnexis.com>
Gavin Halliday преди 13 години
родител
ревизия
6d3a18fc15
променени са 4 файла, в които са добавени 60 реда и са изтрити 1 реда
  1. 15 1
      ecllibrary/std/Str.ecl
  2. 18 0
      ecllibrary/teststd/str/TestTranslate.ecl
  3. 26 0
      plugins/stringlib/stringlib.cpp
  4. 1 0
      plugins/stringlib/stringlib.hpp

+ 15 - 1
ecllibrary/std/Str.ecl

@@ -107,7 +107,7 @@ EXPORT STRING Filter(STRING src, STRING filter) := lib_stringlib.StringLib.Strin
  * @param src           The string that is being tested.
  * @param filter        The string containing the set of characters to be included.
  * @param replace_char  The character to be substituted into the result.
- * @see                 Std.Str.SubstituteExcluded
+ * @see                 Std.Str.Translate, Std.Str.SubstituteExcluded
  */
 
 EXPORT STRING SubstituteIncluded(STRING src, STRING filter, STRING replace_char) :=
@@ -128,6 +128,20 @@ EXPORT STRING SubstituteExcluded(STRING src, STRING filter, STRING replace_char)
   lib_stringlib.StringLib.StringSubstitute(src, filter, replace_char);
 
 /**
+ * Returns the source string with the all characters that match characters in the search string replaced
+ * with the character at the corresponding position in the replacement string.
+ *
+ * @param src           The string that is being tested.
+ * @param search        The string containing the set of characters to be included.
+ * @param replacement   The string containing the characters to act as replacements.
+ * @see                 Std.Str.SubstituteIncluded
+ */
+
+//MORE: Would be more efficient to create a mapping object, and pass that to the replacement function.
+EXPORT STRING Translate(STRING src, STRING search, STRING replacement) :=
+  lib_stringlib.StringLib.StringTranslate(src, search, replacement);
+
+/**
  * Returns the argument string with all upper case characters converted to lower case.
  * 
  * @param src           The string that is being converted.

+ 18 - 0
ecllibrary/teststd/str/TestTranslate.ecl

@@ -0,0 +1,18 @@
+/*##############################################################################
+## Copyright (c) 2011 HPCC Systems.  All rights reserved.
+############################################################################## */
+
+IMPORT Std.Str;
+
+EXPORT TestTranslate := MODULE
+
+  EXPORT TestConstant := MODULE
+    EXPORT Test01 := ASSERT(Str.Translate(' ABCDEF FEDCBA ', 'A', 'Z')+'X' = ' ZBCDEF FEDCBZ X', CONST);
+    EXPORT Test02 := ASSERT(Str.Translate(' ABCDEF FEDCBA ', 'A', '')+'X' = ' ABCDEF FEDCBA X', CONST);
+    EXPORT Test03 := ASSERT(Str.Translate(' ABCDEF FEDCBA ', 'A', 'ZZ')+'X' = ' ABCDEF FEDCBA X', CONST);
+    EXPORT Test04 := ASSERT(Str.Translate(' ABCDEF FEDCBA ', 'AB', '$!')+'X' = ' $!CDEF FEDC!$ X', CONST);
+    EXPORT Test05 := ASSERT(Str.Translate(' \377ABCDEF FEDCBA ', 'AB', '$!')+'X' = ' \377$!CDEF FEDC!$ X', CONST);
+    EXPORT Test06 := ASSERT(Str.Translate(' ABCDEF FEDCBA ', 'AAA', '!%$')+'X' = ' $BCDEF FEDCB$ X', CONST);
+  END;
+
+END;

+ 26 - 0
plugins/stringlib/stringlib.cpp

@@ -46,6 +46,7 @@ const char * EclDefinition =
 "  string StringSubstituteOut(const string src, const string _within, const string _newchar) : c, pure,entrypoint='slStringSubsOut'; \n"
 "  string StringSubstitute(const string src, const string _within, const string _newchar) : c, pure,entrypoint='slStringSubs'; \n"
 "  string StringRepad(const string src, unsigned4 size) : c, pure,entrypoint='slStringRepad'; \n"
+"  string StringTranslate(const string src, const string _within, const string _mapping) : c, pure,entrypoint='slStringTranslate'; \n"
 "  unsigned integer4 StringFind(const string src, const string tofind, unsigned4 instance ) : c, pure,entrypoint='slStringFind'; \n"
 "  unsigned integer4 StringUnboundedUnsafeFind(const string src, const string tofind ) : c, pure,entrypoint='slStringFind2'; \n"
 "  unsigned integer4 StringFindCount(const string src, const string tofind) : c, pure,entrypoint='slStringFindCount'; \n"
@@ -648,6 +649,31 @@ STRINGLIB_API void STRINGLIB_CALL slStringSubs(unsigned & tgtLen, char * & tgt,
     tgtLen = srcLen;
 }
 
+STRINGLIB_API void STRINGLIB_CALL slStringTranslate(unsigned & tgtLen, char * & tgt, unsigned srcLen, const char * src, unsigned hitLen, const char * hit, unsigned mappingLen, const char * mapping)
+{
+    char mapped[256];
+    for (unsigned i=0; i < sizeof(mapped); i++)
+        mapped[i] = i;
+    if (hitLen == mappingLen)
+    {
+        for (unsigned j = 0; j < hitLen; j++ )
+        {
+            unsigned char c = ((unsigned char *)hit)[j];
+            mapped[c] = mapping[j];
+        }
+    }
+
+    char * ret = (char *)CTXMALLOC(parentCtx, srcLen);
+    for ( unsigned i = 0; i < srcLen; i++ )
+    {
+        unsigned char c = ((unsigned char *)src)[i];
+        ret[i] = mapped[c];
+    }
+
+    tgt = ret;
+    tgtLen = srcLen;
+}
+
 STRINGLIB_API void STRINGLIB_CALL slStringRepad(unsigned & tgtLen, char * & tgt, unsigned srcLen, const char * src, unsigned tLen)
 {
     char *base = (char *)src;

+ 1 - 0
plugins/stringlib/stringlib.hpp

@@ -42,6 +42,7 @@ STRINGLIB_API void STRINGLIB_CALL slStringFilter(unsigned & tgtLen, char * & tgt
 STRINGLIB_API void STRINGLIB_CALL slStringSubsOut(unsigned & tgtLen, char * & tgt, unsigned srcLen, const char * src, unsigned hitLen, const char * hit, unsigned newCharLen, const char * newChar);
 STRINGLIB_API void STRINGLIB_CALL slStringSubs(unsigned & tgtLen, char * & tgt, unsigned srcLen, const char * src, unsigned hitLen, const char * hit, unsigned newCharLen, const char * newChar);
 STRINGLIB_API void STRINGLIB_CALL slStringRepad(unsigned & tgtLen, char * & tgt, unsigned srcLen, const char * src, unsigned tLen);
+STRINGLIB_API void STRINGLIB_CALL slStringTranslate(unsigned & tgtLen, char * & tgt, unsigned srcLen, const char * src, unsigned hitLen, const char * hit, unsigned mappingLen, const char * mapping);
 STRINGLIB_API unsigned STRINGLIB_CALL slStringFind(unsigned srcLen, const char * src, unsigned hitLen, const char * hit, unsigned instance);
 STRINGLIB_API unsigned STRINGLIB_CALL slStringFind2(unsigned srcLen, const char * src, unsigned hitLen, const char * hit);
 STRINGLIB_API unsigned STRINGLIB_CALL slStringFindCount(unsigned srcLen, const char * src, unsigned hitLen, const char * hit);