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 }