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 }