1 /******************************************************************************* 2 3 copyright: Copyright (c) 2004 Kris Bell. All rights reserved 4 5 license: BSD style: $(LICENSE) 6 7 version: Initial release: January 2006 8 9 author: Kris 10 11 *******************************************************************************/ 12 13 module tango.io.stream.Delimiters; 14 15 private import tango.io.model.IConduit; 16 private import tango.io.stream.Iterator; 17 18 /******************************************************************************* 19 20 Iterate across a set of text patterns. 21 22 Each pattern is exposed to the client as a slice of the original 23 content, where the slice is transient. If you need to retain the 24 exposed content, then you should .dup it appropriately. 25 26 The content exposed via an iterator is supposed to be entirely 27 read-only. All current iterators abide by this rule, but it is 28 possible a user could mutate the content through a get() slice. 29 To enforce the desired read-only aspect, the code would have to 30 introduce redundant copying or the compiler would have to support 31 read-only arrays. 32 33 See Lines, Patterns, Quotes. 34 35 *******************************************************************************/ 36 37 class Delimiters(T) : Iterator!(T) 38 { 39 private const(T)[] delim; 40 41 /*********************************************************************** 42 43 Construct an uninitialized iterator. For example: 44 --- 45 auto lines = new Lines!(char); 46 47 void somefunc (InputStream stream) 48 { 49 foreach (line; lines.set(stream)) 50 Cout (line).newline; 51 } 52 --- 53 54 Construct a streaming iterator upon a stream: 55 --- 56 void somefunc (InputStream stream) 57 { 58 foreach (line; new Lines!(char) (stream)) 59 Cout (line).newline; 60 } 61 --- 62 63 Construct a streaming iterator upon a conduit: 64 --- 65 foreach (line; new Lines!(char) (new File ("myfile"))) 66 Cout (line).newline; 67 --- 68 69 ***********************************************************************/ 70 71 this (const(T)[] delim, InputStream stream = null) 72 { 73 this.delim = delim; 74 super (stream); 75 } 76 77 /*********************************************************************** 78 79 ***********************************************************************/ 80 81 protected override size_t scan (const(void)[] data) 82 { 83 auto content = (cast(const(T)*) data.ptr) [0 .. data.length / T.sizeof]; 84 85 if (delim.length is 1) 86 { 87 foreach (i, T c; content) 88 if (c is delim[0]) 89 return found (set (content.ptr, 0, i, i)); 90 } 91 else 92 foreach (i, T c; content) 93 if (has (delim, c)) 94 return found (set (content.ptr, 0, i, i)); 95 96 return notFound(); 97 } 98 } 99 100 101 102 /******************************************************************************* 103 104 *******************************************************************************/ 105 106 debug(UnitTest) 107 { 108 private import tango.io.device.Array; 109 110 unittest 111 { 112 auto p = new Delimiters!(char) (", ", new Array("blah".dup)); 113 } 114 }