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