1// LAF Base Library
2// Copyright (C) 2018-2022 Igara Studio S.A.
3//
4// This file is released under the terms of the MIT license.
5// Read LICENSE.txt for more information.
6
7#ifdef HAVE_CONFIG_H
8#include "config.h"
9#endif
10
11#include "base/file_content.h"
12
13#include "base/file_handle.h"
14
15#include <algorithm>
16#include <cstdio>
17#include <stdexcept>
18
19#if LAF_WINDOWS
20 #include <fcntl.h>
21 #include <io.h>
22#endif
23
24namespace base {
25
26const size_t kChunkSize = 1024*64; // 64k
27
28buffer read_file_content(FILE* file)
29{
30 buffer buf;
31 size_t pos = 0;
32
33 while (!std::feof(file)) {
34 buf.resize(buf.size() + kChunkSize);
35 size_t read_bytes = std::fread(&buf[pos], 1, kChunkSize, file);
36 pos += read_bytes;
37 if (read_bytes < kChunkSize) {
38 buf.resize(pos);
39 break;
40 }
41 }
42
43 return buf;
44}
45
46buffer read_file_content(const std::string& filename)
47{
48 FileHandle f(open_file(filename, "rb"));
49 if (f)
50 return read_file_content(f.get());
51 else
52 return buffer();
53}
54
55void write_file_content(FILE* file, const uint8_t* buf, size_t size)
56{
57 for (size_t pos=0; pos < size; ) {
58 const int write_bytes = std::min(kChunkSize, size-pos);
59 const size_t written_bytes = std::fwrite(buf, 1, write_bytes, file);
60 if (written_bytes < write_bytes)
61 throw std::runtime_error("Cannot write all bytes");
62 pos += written_bytes;
63 buf += written_bytes;
64 }
65}
66
67void write_file_content(const std::string& filename, const uint8_t* buf, size_t size)
68{
69 FileHandle f(open_file(filename, "wb"));
70 if (f)
71 write_file_content(f.get(), buf, size);
72}
73
74void set_write_binary_file_content(FILE* file)
75{
76#if LAF_WINDOWS
77 _setmode(_fileno(file), O_BINARY);
78#endif
79}
80
81} // namespace base
82