1 // Copyright (c) 2010 The WebM project authors. All Rights Reserved.
2 //
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the LICENSE file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 #include "mkvparser/mkvreader.h"
9
10 #include <sys/types.h>
11
12 #include <cassert>
13
14 namespace mkvparser {
15
MkvReader()16 MkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
17
MkvReader(FILE * fp)18 MkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
19 GetFileSize();
20 }
21
~MkvReader()22 MkvReader::~MkvReader() {
23 if (reader_owns_file_)
24 Close();
25 m_file = NULL;
26 }
27
Open(const char * fileName)28 int MkvReader::Open(const char* fileName) {
29 if (fileName == NULL)
30 return -1;
31
32 if (m_file)
33 return -1;
34
35 #ifdef _MSC_VER
36 const errno_t e = fopen_s(&m_file, fileName, "rb");
37
38 if (e)
39 return -1; // error
40 #else
41 m_file = fopen(fileName, "rb");
42
43 if (m_file == NULL)
44 return -1;
45 #endif
46 return !GetFileSize();
47 }
48
GetFileSize()49 bool MkvReader::GetFileSize() {
50 if (m_file == NULL)
51 return false;
52 #ifdef _MSC_VER
53 int status = _fseeki64(m_file, 0L, SEEK_END);
54
55 if (status)
56 return false; // error
57
58 m_length = _ftelli64(m_file);
59 #else
60 fseek(m_file, 0L, SEEK_END);
61 m_length = ftell(m_file);
62 #endif
63 assert(m_length >= 0);
64
65 if (m_length < 0)
66 return false;
67
68 #ifdef _MSC_VER
69 status = _fseeki64(m_file, 0L, SEEK_SET);
70
71 if (status)
72 return false; // error
73 #else
74 fseek(m_file, 0L, SEEK_SET);
75 #endif
76
77 return true;
78 }
79
Close()80 void MkvReader::Close() {
81 if (m_file != NULL) {
82 fclose(m_file);
83 m_file = NULL;
84 }
85 }
86
Length(long long * total,long long * available)87 int MkvReader::Length(long long* total, long long* available) {
88 if (m_file == NULL)
89 return -1;
90
91 if (total)
92 *total = m_length;
93
94 if (available)
95 *available = m_length;
96
97 return 0;
98 }
99
Read(long long offset,long len,unsigned char * buffer)100 int MkvReader::Read(long long offset, long len, unsigned char* buffer) {
101 if (m_file == NULL)
102 return -1;
103
104 if (offset < 0)
105 return -1;
106
107 if (len < 0)
108 return -1;
109
110 if (len == 0)
111 return 0;
112
113 if (offset >= m_length)
114 return -1;
115
116 #ifdef _MSC_VER
117 const int status = _fseeki64(m_file, offset, SEEK_SET);
118
119 if (status)
120 return -1; // error
121 #elif defined(_WIN32)
122 fseeko64(m_file, static_cast<off_t>(offset), SEEK_SET);
123 #else
124 fseeko(m_file, static_cast<off_t>(offset), SEEK_SET);
125 #endif
126
127 const size_t size = fread(buffer, 1, len, m_file);
128
129 if (size < size_t(len))
130 return -1; // error
131
132 return 0; // success
133 }
134
135 } // namespace mkvparser
136