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