132
|
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.text.stream.QuoteIterator;
|
|
14
|
|
15 private import tango.text.stream.StreamIterator;
|
|
16
|
|
17 /*******************************************************************************
|
|
18
|
|
19 Iterate across a set of text patterns.
|
|
20
|
|
21 Each pattern is exposed to the client as a slice of the original
|
|
22 content, where the slice is transient. If you need to retain the
|
|
23 exposed content, then you should .dup it appropriately.
|
|
24
|
|
25 These iterators are based upon the IBuffer construct, and can
|
|
26 thus be used in conjunction with other Iterators and/or Reader
|
|
27 instances upon a common buffer ~ each will stay in lockstep via
|
|
28 state maintained within the IBuffer.
|
|
29
|
|
30 The content exposed via an iterator is supposed to be entirely
|
|
31 read-only. All current iterators abide by this rule, but it is
|
|
32 possible a user could mutate the content through a get() slice.
|
|
33 To enforce the desired read-only aspect, the code would have to
|
|
34 introduce redundant copying or the compiler would have to support
|
|
35 read-only arrays.
|
|
36
|
|
37 See LineIterator, SimpleIterator, RegexIterator, QuotedIterator.
|
|
38
|
|
39
|
|
40 *******************************************************************************/
|
|
41
|
|
42 class QuoteIterator(T) : StreamIterator!(T)
|
|
43 {
|
|
44 private T[] delim;
|
|
45
|
|
46 /***********************************************************************
|
|
47
|
|
48 Construct an uninitialized iterator. For example:
|
|
49 ---
|
|
50 auto lines = new LineIterator!(char);
|
|
51
|
|
52 void somefunc (IBuffer buffer)
|
|
53 {
|
|
54 foreach (line; lines.set(buffer))
|
|
55 Cout (line).newline;
|
|
56 }
|
|
57 ---
|
|
58
|
|
59 Construct a streaming iterator upon a buffer:
|
|
60 ---
|
|
61 void somefunc (IBuffer buffer)
|
|
62 {
|
|
63 foreach (line; new LineIterator!(char) (buffer))
|
|
64 Cout (line).newline;
|
|
65 }
|
|
66 ---
|
|
67
|
|
68 Construct a streaming iterator upon a conduit:
|
|
69 ---
|
|
70 foreach (line; new LineIterator!(char) (new FileConduit ("myfile")))
|
|
71 Cout (line).newline;
|
|
72 ---
|
|
73
|
|
74 ***********************************************************************/
|
|
75
|
|
76 this (T[] delim, InputStream stream = null)
|
|
77 {
|
|
78 super (stream);
|
|
79 this.delim = delim;
|
|
80 }
|
|
81
|
|
82 /***********************************************************************
|
|
83
|
|
84 ***********************************************************************/
|
|
85
|
|
86 private uint pair (T[] content, T quote)
|
|
87 {
|
|
88 foreach (int i, T c; content)
|
|
89 if (c is quote)
|
|
90 return found (set (content.ptr, 0, i) + 1);
|
|
91
|
|
92 return notFound;
|
|
93 }
|
|
94
|
|
95 /***********************************************************************
|
|
96
|
|
97 ***********************************************************************/
|
|
98
|
|
99 protected uint scan (void[] data)
|
|
100 {
|
|
101 auto content = (cast(T*) data.ptr) [0 .. data.length / T.sizeof];
|
|
102
|
|
103 foreach (int i, T c; content)
|
|
104 if (has (delim, c))
|
|
105 return found (set (content.ptr, 0, i));
|
|
106 else
|
|
107 if (c is '"' || c is '\'')
|
|
108 if (i)
|
|
109 return found (set (content.ptr, 0, i));
|
|
110 else
|
|
111 return pair (content[1 .. content.length], c);
|
|
112
|
|
113 return notFound;
|
|
114 }
|
|
115 }
|