]> git.cworth.org Git - vogl/blob - src/voglcore/vogl_data_stream.cpp
Initial vogl checkin
[vogl] / src / voglcore / vogl_data_stream.cpp
1 /**************************************************************************
2  *
3  * Copyright 2013-2014 RAD Game Tools and Valve Software
4  * Copyright 2010-2014 Rich Geldreich and Tenacious Software LLC
5  * All Rights Reserved.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to deal
9  * in the Software without restriction, including without limitation the rights
10  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11  * copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23  * THE SOFTWARE.
24  *
25  **************************************************************************/
26
27 // File: vogl_data_stream.cpp
28 #include "vogl_core.h"
29 #include "vogl_data_stream.h"
30 #include "vogl_file_utils.h"
31
32 namespace vogl
33 {
34     data_stream::data_stream()
35         : m_pUser_data(NULL),
36           m_attribs(0),
37           m_opened(false), m_error(false), m_got_cr(false)
38     {
39     }
40
41     data_stream::data_stream(const char *pName, uint attribs)
42         : m_name(pName),
43           m_pUser_data(NULL),
44           m_attribs(static_cast<uint16>(attribs)),
45           m_opened(false), m_error(false), m_got_cr(false)
46     {
47     }
48
49     uint64_t data_stream::read64(void *pBuf, uint64_t len)
50     {
51         uint64_t total_bytes_read = 0;
52
53         while (total_bytes_read < len)
54         {
55             uint bytes_to_read = static_cast<uint>(math::minimum<uint64_t>(0x7FFFFFFFU, len - total_bytes_read));
56
57             if (read(static_cast<uint8 *>(pBuf) + total_bytes_read, bytes_to_read) != bytes_to_read)
58                 break;
59
60             total_bytes_read += bytes_to_read;
61         }
62
63         return total_bytes_read;
64     }
65
66     uint64_t data_stream::skip(uint64_t len)
67     {
68         uint64_t total_bytes_read = 0;
69
70         const uint cBufSize = 1024;
71         uint8 buf[cBufSize];
72
73         while (len)
74         {
75             const uint64_t bytes_to_read = math::minimum<uint64_t>(sizeof(buf), len);
76             const uint64_t bytes_read = read(buf, static_cast<uint>(bytes_to_read));
77             total_bytes_read += bytes_read;
78
79             if (bytes_read != bytes_to_read)
80                 break;
81
82             len -= bytes_read;
83         }
84
85         return total_bytes_read;
86     }
87
88     bool data_stream::read_line(dynamic_string &str)
89     {
90         str.empty();
91
92         for (;;)
93         {
94             const int c = read_byte();
95
96             const bool prev_got_cr = m_got_cr;
97             m_got_cr = false;
98
99             if (c < 0)
100             {
101                 if (!str.is_empty())
102                     break;
103
104                 return false;
105             }
106             // ignores DOS EOF, assumes it's at the very end of the file
107             else if ((26 == c) || (!c))
108                 continue;
109             else if (13 == c)
110             {
111                 m_got_cr = true;
112                 break;
113             }
114             else if (10 == c)
115             {
116                 if (prev_got_cr)
117                     continue;
118
119                 break;
120             }
121
122             str.append_char(static_cast<char>(c));
123         }
124
125         return true;
126     }
127
128     bool data_stream::printf(const char *p, ...)
129     {
130         va_list args;
131
132         va_start(args, p);
133         dynamic_string buf;
134         buf.format_args(p, args);
135         va_end(args);
136
137         return write(buf.get_ptr(), buf.get_len() * sizeof(char)) == buf.get_len() * sizeof(char);
138     }
139
140     bool data_stream::puts(const char *p)
141     {
142         uint len = vogl_strlen(p);
143         return write(p, len * sizeof(char)) == len * sizeof(char);
144     }
145
146     bool data_stream::puts(const dynamic_string &str)
147     {
148         if (!str.is_empty())
149             return write(str.get_ptr(), str.get_len()) == str.get_len();
150
151         return true;
152     }
153
154     bool data_stream::read_array(vector<uint8> &buf)
155     {
156         if (buf.size() < get_remaining())
157         {
158             //if (get_remaining() > 1024U*1024U*1024U)
159             if (get_remaining() > static_cast<uint64_t>(cINT32_MAX))
160                 return false;
161
162             if (!buf.try_resize(static_cast<uint>(get_remaining())))
163                 return false;
164         }
165
166         if (!get_remaining())
167         {
168             buf.resize(0);
169             return true;
170         }
171
172         return read(&buf[0], buf.size()) == buf.size();
173     }
174
175     bool data_stream::write_array(const vector<uint8> &buf)
176     {
177         if (!buf.is_empty())
178             return write(&buf[0], buf.size()) == buf.size();
179         return true;
180     }
181
182     bool data_stream::write_file_data(const char *pFilename)
183     {
184         uint64_t file_size;
185         if (!file_utils::get_file_size(pFilename, file_size))
186             return false;
187
188         if (!file_size)
189             return true;
190
191         FILE *pFile = vogl_fopen(pFilename, "rb");
192         if (!pFile)
193             return false;
194
195         uint8_vec buf(64 * 1024);
196
197         uint64_t bytes_remaining = file_size;
198         while (bytes_remaining)
199         {
200             uint n = static_cast<uint>(math::minimum<uint64_t>(buf.size(), bytes_remaining));
201
202             if (vogl_fread(buf.get_ptr(), 1, n, pFile) != n)
203             {
204                 vogl_fclose(pFile);
205                 return false;
206             }
207
208             if (write(buf.get_ptr(), n) != n)
209             {
210                 vogl_fclose(pFile);
211                 return false;
212             }
213
214             bytes_remaining -= n;
215         }
216
217         vogl_fclose(pFile);
218         return true;
219     }
220
221 } // namespace vogl