Skip to content

Instantly share code, notes, and snippets.

@hiredman
Created May 9, 2012 22:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hiredman/2649231 to your computer and use it in GitHub Desktop.
Save hiredman/2649231 to your computer and use it in GitHub Desktop.
+(defn decorate! [proxy-instance method fun]
+ (update-proxy
+ proxy-instance
+ (update-in (proxy-mappings proxy-instance)
+ [(name method)]
+ fun))
+ proxy-instance)
+
+;; should use reflection to generate method bodies
+(defmacro dummy-up [classes constructor-args methods]
+ `(proxy [~@classes] [~@constructor-args]
+ ~@(for [[name arities] methods]
+ `(~name
+ ~@(for [arity arities
+ :let [args (map gensym (range arity))]]
+ `(~(vec args)
+ (proxy-super ~name ~@args)))))))
+
+(defn ensured-inputstream [stream byte-count]
+ (doto (dummy-up [CountingInputStream] [stream]
+ {read #{0 1 3}})
+ (decorate!
+ :read
+ (fn [read-fn]
+ (fn [this & args]
+ (let [r (apply read-fn this args)]
+ (when (and (= -1 r)
+ (> byte-count (.getCount this)))
+ (throw (IllegalStateException.
+ (format "inputstream expected length %s actual %s"
+ byte-count
+ (.getCount this)))))
+ r))))))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment