1 | /* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */ |
---|---|
2 | /* If you are missing that file, acquire a complete release at teeworlds.com. */ |
3 | #include "linereader.h" |
4 | |
5 | #include <base/system.h> |
6 | |
7 | void CLineReader::Init(IOHANDLE File) |
8 | { |
9 | m_BufferMaxSize = sizeof(m_aBuffer) - 1; |
10 | m_BufferSize = 0; |
11 | m_BufferPos = 0; |
12 | m_File = File; |
13 | } |
14 | |
15 | char *CLineReader::Get() |
16 | { |
17 | unsigned LineStart = m_BufferPos; |
18 | bool CRLFBreak = false; |
19 | |
20 | while(true) |
21 | { |
22 | if(m_BufferPos >= m_BufferSize) |
23 | { |
24 | // fetch more |
25 | |
26 | // move the remaining part to the front |
27 | unsigned Left = m_BufferSize - LineStart; |
28 | |
29 | if(LineStart > m_BufferSize) |
30 | Left = 0; |
31 | if(Left) |
32 | mem_move(dest: m_aBuffer, source: &m_aBuffer[LineStart], size: Left); |
33 | m_BufferPos = Left; |
34 | |
35 | // fill the buffer |
36 | unsigned Read = io_read(io: m_File, buffer: &m_aBuffer[m_BufferPos], size: m_BufferMaxSize - m_BufferPos); |
37 | m_BufferSize = Left + Read; |
38 | LineStart = 0; |
39 | |
40 | if(!Read) |
41 | { |
42 | if(Left) |
43 | { |
44 | m_aBuffer[Left] = '\0'; // return the last line |
45 | m_BufferPos = Left; |
46 | m_BufferSize = Left; |
47 | if(!str_utf8_check(str: m_aBuffer)) |
48 | { |
49 | LineStart = m_BufferPos; |
50 | CRLFBreak = false; |
51 | continue; // skip lines containing invalid UTF-8 |
52 | } |
53 | return m_aBuffer; |
54 | } |
55 | return nullptr; // we are done! |
56 | } |
57 | } |
58 | else |
59 | { |
60 | if(m_aBuffer[m_BufferPos] == '\n' || m_aBuffer[m_BufferPos] == '\r') |
61 | { |
62 | // line found |
63 | if(m_aBuffer[m_BufferPos] == '\r') |
64 | { |
65 | if(m_BufferPos + 1 >= m_BufferSize) |
66 | { |
67 | // read more to get the connected '\n' |
68 | CRLFBreak = true; |
69 | ++m_BufferPos; |
70 | continue; |
71 | } |
72 | else if(m_aBuffer[m_BufferPos + 1] == '\n') |
73 | m_aBuffer[m_BufferPos++] = '\0'; |
74 | } |
75 | m_aBuffer[m_BufferPos++] = '\0'; |
76 | if(!str_utf8_check(str: &m_aBuffer[LineStart])) |
77 | { |
78 | LineStart = m_BufferPos; |
79 | CRLFBreak = false; |
80 | continue; // skip lines containing invalid UTF-8 |
81 | } |
82 | return &m_aBuffer[LineStart]; |
83 | } |
84 | else if(CRLFBreak) |
85 | { |
86 | if(m_aBuffer[m_BufferPos] == '\n') |
87 | m_aBuffer[m_BufferPos++] = '\0'; |
88 | if(!str_utf8_check(str: &m_aBuffer[LineStart])) |
89 | { |
90 | LineStart = m_BufferPos; |
91 | CRLFBreak = false; |
92 | continue; // skip lines containing invalid UTF-8 |
93 | } |
94 | return &m_aBuffer[LineStart]; |
95 | } |
96 | else |
97 | m_BufferPos++; |
98 | } |
99 | } |
100 | } |
101 |