PageRenderTime 24ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/src/jvm/clojure/lang/Stream.java

https://github.com/jabley/clojure
Java | 88 lines | 62 code | 16 blank | 10 comment | 11 complexity | f34782e5c6b35b3acb7df108634c9d96 MD5 | raw file
  1. /**
  2. * Copyright (c) Rich Hickey. All rights reserved.
  3. * The use and distribution terms for this software are covered by the
  4. * Eclipse Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
  5. * which can be found in the file epl-v10.html at the root of this distribution.
  6. * By using this software in any fashion, you are agreeing to be bound by
  7. * the terms of this license.
  8. * You must not remove this notice, or any other, from this software.
  9. **/
  10. /* rich Mar 5, 2009 */
  11. package clojure.lang;
  12. final public class Stream implements Seqable, Streamable, Sequential {
  13. static final ISeq NO_SEQ = new Cons(null, null);
  14. ISeq sequence = NO_SEQ;
  15. final IFn src;
  16. final IFn xform;
  17. IFn tap = null;
  18. public Stream(IFn src){
  19. this.src = src;
  20. this.xform = null;
  21. }
  22. public Stream(IFn xform, Stream src) {
  23. this.src = src.tap();
  24. this.xform = xform;
  25. }
  26. final public ISeq seq(){
  27. return sequence().seq();
  28. }
  29. final synchronized public ISeq sequence(){
  30. if(sequence == NO_SEQ)
  31. {
  32. tap();
  33. sequence = makeSequence(tap);
  34. }
  35. return sequence;
  36. }
  37. static ISeq makeSequence(final IFn tap){
  38. return new LazySeq(new AFn(){
  39. public Object invoke() throws Exception{
  40. Object v = tap.invoke();
  41. if(v == RT.EOS)
  42. return null;
  43. return new Cons(v, new LazySeq(this));
  44. }
  45. });
  46. }
  47. final synchronized public Stream stream() throws Exception {
  48. return this;
  49. }
  50. final synchronized public IFn tap() {
  51. if (tap != null)
  52. throw new IllegalStateException("Stream already tapped");
  53. return tap = makeTap(xform, src);
  54. }
  55. static IFn makeTap(final IFn xform, final IFn src){
  56. return new AFn(){
  57. final synchronized public Object invoke() throws Exception{
  58. if(xform == null)
  59. return src.invoke();
  60. Object v;
  61. Object xv;
  62. do {
  63. v = src.invoke();
  64. if(v == RT.EOS)
  65. return v;
  66. xv = xform.invoke(v);
  67. } while(xv == RT.SKIP);
  68. return xv;
  69. }
  70. };
  71. }
  72. }