[WASAPI] fix stream types and frequencies enumeration
[xbmc.git] / xbmc / guilib / XBTFReader.cpp
blobb4f561f6151c61711b3ac200474f38408e6d4a06
1 /*
2 * Copyright (C) 2005-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
9 #include <inttypes.h>
10 #include <stdio.h>
11 #include <string.h>
12 #include <sys/stat.h>
14 #include "XBTFReader.h"
15 #include "guilib/XBTF.h"
16 #include "utils/EndianSwap.h"
18 #ifdef TARGET_WINDOWS
19 #include "filesystem/SpecialProtocol.h"
20 #include "utils/CharsetConverter.h"
21 #include "platform/win32/PlatformDefs.h"
22 #endif
24 static bool ReadString(FILE* file, char* str, size_t max_length)
26 if (file == nullptr || str == nullptr || max_length <= 0)
27 return false;
29 return (fread(str, max_length, 1, file) == 1);
32 static bool ReadChar(FILE* file, char& value)
34 if (file == nullptr)
35 return false;
37 if (fread(&value, sizeof(char), 1, file) != 1)
38 return false;
40 return true;
43 static bool ReadUInt32(FILE* file, uint32_t& value)
45 if (file == nullptr)
46 return false;
48 if (fread(&value, sizeof(uint32_t), 1, file) != 1)
49 return false;
51 value = Endian_SwapLE32(value);
52 return true;
55 static bool ReadUInt64(FILE* file, uint64_t& value)
57 if (file == nullptr)
58 return false;
60 if (fread(&value, sizeof(uint64_t), 1, file) != 1)
61 return false;
63 value = Endian_SwapLE64(value);
64 return true;
67 CXBTFReader::CXBTFReader()
68 : CXBTFBase(),
69 m_path()
70 { }
72 CXBTFReader::~CXBTFReader()
74 Close();
77 bool CXBTFReader::Open(const std::string& path)
79 if (path.empty())
80 return false;
82 m_path = path;
84 #ifdef TARGET_WINDOWS
85 std::wstring strPathW;
86 g_charsetConverter.utf8ToW(CSpecialProtocol::TranslatePath(m_path), strPathW, false);
87 m_file = _wfopen(strPathW.c_str(), L"rb");
88 #else
89 m_file = fopen(m_path.c_str(), "rb");
90 #endif
91 if (m_file == nullptr)
92 return false;
94 // read the magic word
95 char magic[4];
96 if (!ReadString(m_file, magic, sizeof(magic)))
97 return false;
99 if (strncmp(XBTF_MAGIC.c_str(), magic, sizeof(magic)) != 0)
100 return false;
102 // read the version
103 char version;
104 if (!ReadChar(m_file, version))
105 return false;
107 if (version < XBTF_VERSION_MIN)
108 return false;
110 unsigned int nofFiles;
111 if (!ReadUInt32(m_file, nofFiles))
112 return false;
114 for (uint32_t i = 0; i < nofFiles; i++)
116 CXBTFFile xbtfFile;
117 uint32_t u32;
118 uint64_t u64;
120 // one extra char to null terminate the string
121 char path[CXBTFFile::MaximumPathLength + 1] = {};
122 if (!ReadString(m_file, path, sizeof(path) - 1))
123 return false;
124 xbtfFile.SetPath(path);
126 if (!ReadUInt32(m_file, u32))
127 return false;
128 xbtfFile.SetLoop(u32);
130 unsigned int nofFrames;
131 if (!ReadUInt32(m_file, nofFrames))
132 return false;
134 for (uint32_t j = 0; j < nofFrames; j++)
136 CXBTFFrame frame;
138 if (!ReadUInt32(m_file, u32))
139 return false;
140 frame.SetWidth(u32);
142 if (!ReadUInt32(m_file, u32))
143 return false;
144 frame.SetHeight(u32);
146 if (!ReadUInt32(m_file, u32))
147 return false;
148 frame.SetFormat(static_cast<XB_FMT>(u32));
150 if (!ReadUInt64(m_file, u64))
151 return false;
152 frame.SetPackedSize(u64);
154 if (!ReadUInt64(m_file, u64))
155 return false;
156 frame.SetUnpackedSize(u64);
158 if (!ReadUInt32(m_file, u32))
159 return false;
160 frame.SetDuration(u32);
162 if (!ReadUInt64(m_file, u64))
163 return false;
164 frame.SetOffset(u64);
166 xbtfFile.GetFrames().push_back(frame);
169 AddFile(xbtfFile);
172 // Sanity check
173 uint64_t pos = static_cast<uint64_t>(ftell(m_file));
174 if (pos != GetHeaderSize())
175 return false;
177 return true;
180 bool CXBTFReader::IsOpen() const
182 return m_file != nullptr;
185 void CXBTFReader::Close()
187 if (m_file != nullptr)
189 fclose(m_file);
190 m_file = nullptr;
193 m_path.clear();
194 m_files.clear();
197 time_t CXBTFReader::GetLastModificationTimestamp() const
199 if (m_file == nullptr)
200 return 0;
202 struct stat fileStat;
203 if (fstat(fileno(m_file), &fileStat) == -1)
204 return 0;
206 return fileStat.st_mtime;
209 bool CXBTFReader::Load(const CXBTFFrame& frame, unsigned char* buffer) const
211 if (m_file == nullptr)
212 return false;
214 #if defined(TARGET_DARWIN) || defined(TARGET_FREEBSD)
215 if (fseeko(m_file, static_cast<off_t>(frame.GetOffset()), SEEK_SET) == -1)
216 #elif defined(TARGET_ANDROID)
217 if (fseek(m_file, static_cast<long>(frame.GetOffset()), SEEK_SET) == -1) // No fseeko64 before N
218 #else
219 if (fseeko64(m_file, static_cast<off_t>(frame.GetOffset()), SEEK_SET) == -1)
220 #endif
221 return false;
223 if (fread(buffer, 1, static_cast<size_t>(frame.GetPackedSize()), m_file) != frame.GetPackedSize())
224 return false;
226 return true;