1 module served.filereader;
2 
3 import core.thread;
4 import core.sync.mutex;
5 
6 import std.algorithm;
7 import std.stdio;
8 
9 class FileReader : Thread
10 {
11 	this(File file)
12 	{
13 		super(&run);
14 		mutex = new Mutex();
15 		this.file = file;
16 	}
17 
18 	string yieldLine()
19 	{
20 		ptrdiff_t index;
21 		string ret;
22 		while (true)
23 		{
24 			synchronized (mutex)
25 			{
26 				index = data.countUntil([cast(ubyte) '\r', cast(ubyte) '\n']);
27 				if (index != -1)
28 				{
29 					ret = cast(string) data[0 .. index].dup;
30 					data = data[index + 2 .. $];
31 					break;
32 				}
33 			}
34 			Fiber.yield();
35 		}
36 		return ret;
37 	}
38 
39 	ubyte[] yieldData(size_t length)
40 	{
41 		while (true)
42 		{
43 			synchronized (mutex)
44 			{
45 				if (data.length >= length)
46 				{
47 					auto ret = data[0 .. length].dup;
48 					data = data[length .. $];
49 					return ret;
50 				}
51 			}
52 			Fiber.yield();
53 		}
54 	}
55 
56 	void stop()
57 	{
58 		file.close();
59 	}
60 
61 private:
62 	void run()
63 	{
64 		foreach (b; file.byChunk(1))
65 			synchronized (mutex)
66 				data ~= b[0];
67 	}
68 
69 	ubyte[] data;
70 	File file;
71 	Mutex mutex;
72 	bool running;
73 }