faster STRING and UNSTRING functions
authorPaul Hänsch <paul@plutz.net>
Wed, 29 Jan 2020 17:22:44 +0000 (18:22 +0100)
committerPaul Hänsch <paul@plutz.net>
Wed, 29 Jan 2020 17:22:44 +0000 (18:22 +0100)
storage.sh

index 10a8029..d84f0c2 100755 (executable)
 [ -n "$include_storage" ] && return 0
 include_storage="$0"
 
+CR="\r"
+BR='
+'
+
 LOCK(){
   local lock timeout block
   lock="${1}.lock"
@@ -72,11 +76,27 @@ STRING='
   s; ;+;g;
 '
 
-STRING(){
+STRING_OLD(){
   { [ $# -eq 0 ] && cat || printf %s "$*"; } \
   | sed -E ':X; $!{N;bX;}'"$STRING"
 }
 
+STRING(){
+  local in out=''
+  [ $# -gt 0 ] && in="$*" || in="$(cat)"
+  while [ "$in" ]; do case $in in
+    \\*) out="${out}\\\\"; in="${in#\\}" ;;
+    "$BR"*) out="${out}\\n"; in="${in#${BR}}" ;;
+    "$CR"*) out="${out}\\r"; in="${in#${CR}}" ;;
+    "  "*) out="${out}\\t"; in="${in#  }" ;;
+    +*) out="${out}\\+"; in="${in#+}" ;;
+    " "*) out="${out}+"; in="${in# }" ;;
+    *) out="${out}${in%%[\\${CR}${BR}  + ]*}"; in="${in#${in%%[\\${BR}${CR}    + ]*}}" ;;
+  esac; done
+  printf '%s' "$out"
+}
+
+
 UNSTRING='
   :UNSTRING_X
   s;((^|[^\\])(\\\\)*)\\n;\1\n;g;
@@ -87,7 +107,23 @@ UNSTRING='
   s;((^|[^\\])(\\\\)*)\\\+;\1+;g;
   s;\\\\;\\;g;
 '
-UNSTRING(){
+UNSTRING_OLD(){
   { [ $# -eq 0 ] && cat || printf %s "$*"; } \
   | sed -E "$UNSTRING"
 }
+UNSTRING(){
+  local in out=''
+  [ $# -gt 0 ] && in="$*" || in="$(cat)"
+  while [ "$in" ]; do case $in in
+    \\\\*) out="${out}\\"; in="${in#\\\\}" ;;
+    \\n*) out="${out}${BR}"; in="${in#\\n}" ;;
+    \\r*) out="${out}${CR}"; in="${in#\\r}" ;;
+    \\t*) out="${out}  "; in="${in#\\t}" ;;
+    \\+) out="${out}+"; in="${in#\\+}" ;;
+    +*) out="${out} "; in="${in#+}" ;;
+    \\*) in="${in#\\}" ;;
+    *) out="${out}${in%%[\\+]*}"; in="${in#${in%%[\\+]*}}" ;;
+  esac; done
+  printf '%s' "$out"
+}
+