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