Module: dfmc-application Synopsis: Serving collection objects from the application Author: Paul Howard Copyright: Original Code is Copyright (c) 1995-2004 Functional Objects, Inc. All rights reserved. License: Functional Objects Library Public License Version 1.0 Dual-license: GNU Lesser General Public License Warranty: Distributed WITHOUT WARRANTY OF ANY KIND ///// COLLECTION-SIZE (Environment Protocol Method) // Returns the size of a collection. define method collection-size (application :: , collection :: ) => (size :: ) let target = application.application-target-app; with-debugger-transaction (target) let proxy = collection.application-object-proxy; let cl = runtime-proxy-to-remote-value(application, proxy); remote-collection-size(target, cl) end end method collection-size; ///// COLLECTION-KEYS (Environment Protocol Method) // Returns (possibly a subrange of) the sequence of keys in a runtime // collection object. (Emergency method for the implicit case). define method collection-keys (application :: , collection :: , #key range: collection-range = #f) => (key-seq :: false-or()) // The collection is implicit, which means that we are only required to // return a range, rather than an actual collection of keys. If the // range has been delimited by the caller, then we can just return it // back. collection-range | range(from: 0, below: collection-size(application, collection), by: 1) end method collection-keys; define method collection-keys (application :: , collection :: , #key range = #f) => (key-seq :: ) do-collection-contents(application, collection, #"keys", range: range) end method collection-keys; define method do-collection-keys (function :: , application :: , collection :: ) => () let collection-range = collection-size(application, collection); do(function, range(from: 0, below: collection-range, by: 1)) end method do-collection-keys; define method do-collection-keys (function :: , application :: , collection :: ) => () do-collection-contents(application, collection, #"keys", function: function) end method do-collection-keys; ///// COLLECTION-ELEMENTS (Environment Protocol Method) // Returns (possibly a subrange of) the sequence of elements in the // runtime collection objects. define method collection-elements (application :: , collection :: , #key range = #f) => (key-seq :: false-or()) do-collection-contents(application, collection, #"elements", range: range) end method collection-elements; define method do-collection-elements (function :: , application :: , collection :: ) => () do-collection-contents(application, collection, #"elements", function: function) end method do-collection-elements; /// Shared utility define method do-collection-contents (application :: ,collection :: , type :: one-of(#"keys", #"elements"), #key range :: false-or() = #f, function :: false-or() = #f) => (contents :: false-or()) local method get-index-subset () => (start :: , fin :: false-or()) case ~range => values(0, #f); range.empty? => values(0, 0); otherwise => let first = range.first; let last = range.last; assert(first <= last, "Attempting to query collection-keys with bogus range %=", range); values(first, last); end end method; let target = application.application-target-app; let proxy = collection.application-object-proxy; let (start, fin) = get-index-subset(); // Within a debugger transaction, use the DM to inspect the required // subset of the collection. That done, construct application environment // objects for each key. with-debugger-transaction (target) let proxy-value = runtime-proxy-to-remote-value(application, proxy); let (key-vals, el-vals) = remote-collection-inspect(target, proxy-value, first-index: start, last-index: fin); let values = if (type == #"keys") key-vals | #[] else el-vals end; if (function) for (value in values) let object = make-environment-object-for-runtime-value(application, value); function(object) end else map-as(, curry(make-environment-object-for-runtime-value, application), values) end end end method do-collection-contents;