1 /**
2 * Reading files without the D runtime.
3 *
4 * Copyright: Copyright Auburn Sounds 2015-2016
5 * License:   $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
6 * Authors:   Guillaume Piolat
7 */
8 module dplug.core.file;
9 
10 import core.stdc.stdio;
11 
12 import dplug.core.nogc;
13 
14 nothrow:
15 @nogc:
16 
17 /// Replacement for `std.file.read`.
18 /// Returns: File contents, allocated with malloc. `null` on error.
19 ubyte[] readFile(const(char)[] fileNameZ)
20 {
21     // assuming that fileNameZ is zero-terminated, since it will in practice be
22     // a static string
23     FILE* file = fopen(fileNameZ.ptr, "rb".ptr);
24     if (file)
25     {
26         scope(exit) fclose(file);
27 
28         // finds the size of the file
29         fseek(file, 0, SEEK_END);
30         long size = ftell(file);
31         fseek(file, 0, SEEK_SET);
32 
33         // Is this too large to read? 
34         // Refuse to read more than 1gb file (if it happens, it's probably a bug).
35         if (size > 1024*1024*1024)
36             return null;
37 
38         // Read whole file in a mallocated slice
39         ubyte[] fileBytes = mallocSliceNoInit!ubyte(cast(int)size);
40         size_t remaining = cast(size_t)size;
41 
42         ubyte* p = fileBytes.ptr;
43 
44         while (remaining > 0)
45         {
46             size_t bytesRead = fread(p, 1, remaining, file);
47             if (bytesRead == 0)
48             {
49                 freeSlice(fileBytes);
50                 return null;
51             }
52             p += bytesRead;
53             remaining -= bytesRead;
54         }
55 
56         return fileBytes;
57     }
58     else
59         return null;
60 }