|
28 | 28 | // Includes.
|
29 | 29 | //---------------------------------------------------------------------------------
|
30 | 30 | // Source.Python
|
| 31 | +#include "modules/memory/memory_alloc.h" |
31 | 32 | #include "utilities/wrap_macros.h"
|
32 | 33 | #include "filesystem.h"
|
33 | 34 |
|
|
37 | 38 | //---------------------------------------------------------------------------------
|
38 | 39 | extern IFileSystem* filesystem;
|
39 | 40 |
|
| 41 | +// Chunk size for InternalReadline() |
| 42 | +#define CHUNK_SIZE 128 |
| 43 | + |
40 | 44 |
|
41 | 45 | //---------------------------------------------------------------------------------
|
42 | 46 | // Functions
|
@@ -96,41 +100,99 @@ PyObject* SourceFile::Read(int size)
|
96 | 100 | size = filesystem->Size(m_handle);
|
97 | 101 | }
|
98 | 102 |
|
99 |
| - void* pOutput = new char[size+1]; |
| 103 | + char* pOutput = new char[size+1]; |
100 | 104 | int bytesRead = filesystem->Read(pOutput, size, m_handle);
|
101 | 105 | return ConsumeBuffer(pOutput, bytesRead);
|
102 | 106 | }
|
103 | 107 |
|
104 |
| -object SourceFile::Readline(int size) |
| 108 | +PyObject* SourceFile::Readline(int size) |
105 | 109 | {
|
106 | 110 | CheckClosed();
|
107 | 111 | CheckReadable();
|
108 |
| - // TODO |
109 |
| - BOOST_RAISE_EXCEPTION(PyExc_NotImplementedError, "Not implemented yet.") |
110 |
| - return object(); |
| 112 | + |
| 113 | + int bytesRead = 0; |
| 114 | + return InternalReadline(IsBinaryMode(), size, bytesRead); |
| 115 | +} |
| 116 | + |
| 117 | +PyObject* SourceFile::InternalReadline(bool binaryMode, int size, int& outBytesRead) |
| 118 | +{ |
| 119 | + int bytesPut = 0; |
| 120 | + char* buffer = (char*) UTIL_Alloc(CHUNK_SIZE); |
| 121 | + |
| 122 | + while (size < 0 || bytesPut < size) { |
| 123 | + char temp[1]; |
| 124 | + |
| 125 | + // EOF? |
| 126 | + if (filesystem->Read(temp, 1, m_handle) != 1) { |
| 127 | + break; |
| 128 | + } |
| 129 | + |
| 130 | + // Ignore \r in text mode |
| 131 | + if (!binaryMode && temp[0] == '\r') { |
| 132 | + continue; |
| 133 | + } |
| 134 | + |
| 135 | + if (temp[0] == '\0') { |
| 136 | + buffer[bytesPut] = '\n'; |
| 137 | + } |
| 138 | + else { |
| 139 | + buffer[bytesPut] = temp[0]; |
| 140 | + } |
| 141 | + ++bytesPut; |
| 142 | + ++outBytesRead; |
| 143 | + |
| 144 | + if (temp[0] == '\n') { |
| 145 | + break; |
| 146 | + } |
| 147 | + |
| 148 | + if (bytesPut >= CHUNK_SIZE) { |
| 149 | + buffer = (char*) UTIL_Realloc(buffer, bytesPut + CHUNK_SIZE); |
| 150 | + if (buffer == NULL) |
| 151 | + BOOST_RAISE_EXCEPTION(PyExc_MemoryError, "Failed to reallocate the buffer.") |
| 152 | + } |
| 153 | + } |
| 154 | + |
| 155 | + PyObject* result = NULL; |
| 156 | + if (IsBinaryMode()) { |
| 157 | + result = PyBytes_FromStringAndSize(buffer, bytesPut); |
| 158 | + } |
| 159 | + else { |
| 160 | + result = PyUnicode_FromStringAndSize(buffer, bytesPut); |
| 161 | + } |
| 162 | + |
| 163 | + return result; |
111 | 164 | }
|
112 | 165 |
|
113 | 166 | list SourceFile::Readlines(int hint)
|
114 | 167 | {
|
115 | 168 | CheckClosed();
|
116 | 169 | CheckReadable();
|
117 | 170 |
|
| 171 | + bool binaryMode = IsBinaryMode(); |
| 172 | + |
118 | 173 | list result;
|
119 | 174 |
|
120 |
| - // TODO |
| 175 | + int bytesRead = 0; |
| 176 | + while (true) { |
| 177 | + PyObject* line = InternalReadline(binaryMode, -1, bytesRead); |
| 178 | + result.append(handle<>(borrowed(line))); |
| 179 | + if (EndOfFile() || (hint > 0 && bytesRead > hint)) { |
| 180 | + break; |
| 181 | + } |
| 182 | + } |
121 | 183 |
|
122 | 184 | return result;
|
123 | 185 | }
|
124 | 186 |
|
125 | 187 | // internal
|
126 |
| -PyObject* SourceFile::ConsumeBuffer(void* buffer, int bytesRead) |
127 |
| -{ |
| 188 | +PyObject* SourceFile::ConsumeBuffer(char* buffer, int bytesRead) |
| 189 | +{ |
128 | 190 | PyObject* result = NULL;
|
129 | 191 | if (IsBinaryMode()) {
|
130 |
| - result = PyBytes_FromStringAndSize((char*) buffer, bytesRead); |
| 192 | + result = PyBytes_FromStringAndSize(buffer, bytesRead); |
131 | 193 | }
|
132 | 194 | else {
|
133 |
| - result = PyUnicode_FromStringAndSize((char*) buffer, bytesRead); |
| 195 | + result = PyUnicode_FromStringAndSize(buffer, bytesRead); |
134 | 196 | }
|
135 | 197 |
|
136 | 198 | delete buffer;
|
@@ -278,6 +340,11 @@ bool SourceFile::Closed()
|
278 | 340 | return m_handle == NULL;
|
279 | 341 | }
|
280 | 342 |
|
| 343 | +bool SourceFile::EndOfFile() |
| 344 | +{ |
| 345 | + return filesystem->EndOfFile(m_handle); |
| 346 | +} |
| 347 | + |
281 | 348 |
|
282 | 349 | //---------------------------------------------------------------------------------
|
283 | 350 | // SourceFile - internal
|
|
0 commit comments