summaryrefslogtreecommitdiff
path: root/ebus-racket/ebus
diff options
context:
space:
mode:
Diffstat (limited to 'ebus-racket/ebus')
-rw-r--r--ebus-racket/ebus/layer7.rkt6
-rw-r--r--ebus-racket/ebus/xexpr-path/info.rkt5
-rw-r--r--ebus-racket/ebus/xexpr-path/main.rkt99
3 files changed, 107 insertions, 3 deletions
diff --git a/ebus-racket/ebus/layer7.rkt b/ebus-racket/ebus/layer7.rkt
index 9393ec8..c7fb228 100644
--- a/ebus-racket/ebus/layer7.rkt
+++ b/ebus-racket/ebus/layer7.rkt
@@ -3,7 +3,7 @@
racket/bool
racket/function
xml
- xexpr-path
+ "xexpr-path/main.rkt"
"layer2.rkt")
(define logger (make-logger 'ebus-layer7 (current-logger)))
@@ -44,7 +44,7 @@
(define payload (layer2-ebus-paket-payload ebus-paket))
(for/list ([decoder decoders])
(decoder payload)))
- (else (void (log-message logger 'warning
+ (else (void (log-message logger 'warning
(format "Unknown Paket from source ~s: ~s" (layer2-ebus-paket-source ebus-paket) ebus-paket) #t)))))
@@ -53,7 +53,7 @@
(define name (string-append paket-id "." (xexpr-path-first '((name)) field)))
(define offset (string->number (xexpr-path-first '((offset)) field)))
(define decoder (hash-ref decoder-table type #f))
- (cond ((false? decoder) (void (log-message logger 'warning (format "No decoder for type ~s" type))))
+ (cond ((false? decoder) (void (log-message logger 'warning (format "No decoder for type ~s" type) #t)))
(else (curry (car decoder) name field offset))))
(define decoder-table
diff --git a/ebus-racket/ebus/xexpr-path/info.rkt b/ebus-racket/ebus/xexpr-path/info.rkt
new file mode 100644
index 0000000..9fd7188
--- /dev/null
+++ b/ebus-racket/ebus/xexpr-path/info.rkt
@@ -0,0 +1,5 @@
+#lang setup/infotab
+
+(define scribblings '(("xexpr-path.scrbl" ())))
+
+; vim:set ts=2 sw=2 et:
diff --git a/ebus-racket/ebus/xexpr-path/main.rkt b/ebus-racket/ebus/xexpr-path/main.rkt
new file mode 100644
index 0000000..97e7f81
--- /dev/null
+++ b/ebus-racket/ebus/xexpr-path/main.rkt
@@ -0,0 +1,99 @@
+#lang racket/base
+;
+; XML-Expression Path Lookup
+;
+
+(require racket/contract
+ racket/string
+ racket/match
+ racket/dict
+ racket/list
+ xml)
+
+(provide xexpr-path-first
+ xexpr-path-list
+ xexpr-path-text
+ xexpr-path/c)
+
+
+(define xexpr-path/c
+ (listof (or/c symbol?
+ (list/c symbol? string?)
+ (list/c symbol?))))
+
+
+(define (children element)
+ (match element
+ ((list tag (list (list name value) ...) children ...)
+ children)
+
+ ((list tag children ...)
+ children)
+
+ (else
+ null)))
+
+
+(define (attr-value?? name value)
+ (lambda (v)
+ (equal? (dict-ref (attributes v) name #f) value)))
+
+
+(define (tag-name?? name)
+ (lambda (v)
+ (or (eq? name '*)
+ (and (pair? v)
+ (eq? (car v) name)))))
+
+
+(define (attributes element)
+ (match element
+ ((list tag (list (list name value) ...) children ...)
+ (for/list ((n (in-list name))
+ (v (in-list value)))
+ (cons n v)))
+
+ (else
+ null)))
+
+
+(define (path-item-procedure item)
+ (match item
+ ((list attr-name attr-value)
+ (lambda (tags)
+ (list (filter (attr-value?? attr-name attr-value) tags))))
+
+ ((list attr-name)
+ (lambda (tags)
+ (list
+ (filter values
+ (for/list ((tag (in-list tags)))
+ (dict-ref (attributes tag) attr-name #f))))))
+
+ (tag-name
+ (lambda (tags)
+ (for/list ((tag (in-list tags)))
+ (filter (tag-name?? tag-name) (children tag)))))))
+
+
+(define/contract (xexpr-path-list path xexpr)
+ (-> xexpr-path/c xexpr/c (listof (or/c xexpr/c string?)))
+ (let ((pipeline (append* (for/list ((item (in-list path)))
+ (list (path-item-procedure item) append*)))))
+ ((apply compose (reverse pipeline)) (list xexpr))))
+
+
+(define/contract (xexpr-path-first path xexpr)
+ (-> xexpr-path/c xexpr/c (or/c xexpr/c string? #f))
+ (let ((results (xexpr-path-list path xexpr)))
+ (and (not (null? results))
+ (first results))))
+
+
+(define/contract (xexpr-path-text path xexpr)
+ (-> xexpr-path/c xexpr/c (or/c #f string?))
+ (let ((results (xexpr-path-list path xexpr)))
+ (string-append* (map xexpr->string results))))
+
+
+; vim:set ts=2 sw=2 et: