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 moduleocean.io.stream.Lines;
19 20 importocean.meta.types.Qualifiers;
21 22 importocean.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 Delimiters, Patterns, Quotes.
40 41 *******************************************************************************/42 43 classLines : Iterator44 {
45 /***********************************************************************
46 47 Construct an uninitialized iterator. For example:
48 ---
49 auto lines = new Lines!(char);
50 51 void somefunc (InputStream stream)
52 {
53 foreach (line; lines.set(stream))
54 Cout (line).newline;
55 }
56 ---
57 58 Construct a streaming iterator upon a stream:
59 ---
60 void somefunc (InputStream stream)
61 {
62 foreach (line; new Lines!(char) (stream))
63 Cout (line).newline;
64 }
65 ---
66 67 Construct a streaming iterator upon a conduit:
68 ---
69 foreach (line; new Lines!(char) (new File ("myfile")))
70 Cout (line).newline;
71 ---
72 73 ***********************************************************************/74 75 this (InputStreamstream = null)
76 {
77 super (stream);
78 }
79 80 /***********************************************************************
81 82 Read a line of text, and return false when there's no
83 further content available.
84 85 ***********************************************************************/86 87 finalboolreadln (refcstringcontent)
88 {
89 content = super.next;
90 returncontent.ptr !isnull;
91 }
92 93 /***********************************************************************
94 95 Scanner implementation for this iterator. Find a '\n',
96 and eat any immediately preceeding '\r'.
97 98 ***********************************************************************/99 100 protectedoverridesize_tscan (const(void)[] data)
101 {
102 autocontent = (cast(const(char)*) data.ptr) [0 .. data.length];
103 104 foreach (i, c; content)
105 if (cis'\n')
106 {
107 size_tslice = i;
108 if (i && content[i-1] is'\r')
109 --slice;
110 set (content.ptr, 0, slice, i);
111 returnfound (i);
112 }
113 114 returnnotFound;
115 }
116 }
117 118 119 120 /*******************************************************************************
121 122 *******************************************************************************/123 124 version (unittest)
125 {
126 importocean.io.device.Array;
127 }
128 129 unittest130 {
131 autop = newLines(newArray("blah".dup));
132 }