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
9#include "mkvreader.hpp"
10
11#include <cassert>
12
13namespace mkvparser
14{
15
16MkvReader::MkvReader() :
17    m_file(NULL)
18{
19}
20
21MkvReader::~MkvReader()
22{
23    Close();
24}
25
26int MkvReader::Open(const char* fileName)
27{
28    if (fileName == NULL)
29        return -1;
30
31    if (m_file)
32        return -1;
33
34#ifdef _MSC_VER
35    const errno_t e = fopen_s(&m_file, fileName, "rb");
36
37    if (e)
38        return -1;  //error
39#else
40    m_file = fopen(fileName, "rb");
41
42    if (m_file == NULL)
43        return -1;
44#endif
45
46#ifdef _MSC_VER
47    int status = _fseeki64(m_file, 0L, SEEK_END);
48
49    if (status)
50        return -1;  //error
51
52    m_length = _ftelli64(m_file);
53#else
54    fseek(m_file, 0L, SEEK_END);
55    m_length = ftell(m_file);
56#endif
57    assert(m_length >= 0);
58
59#ifdef _MSC_VER
60    status = _fseeki64(m_file, 0L, SEEK_SET);
61
62    if (status)
63        return -1;  //error
64#else
65    fseek(m_file, 0L, SEEK_SET);
66#endif
67
68    return 0;
69}
70
71void MkvReader::Close()
72{
73    if (m_file != NULL)
74    {
75        fclose(m_file);
76        m_file = NULL;
77    }
78}
79
80int MkvReader::Length(long long* total, long long* available)
81{
82    if (m_file == NULL)
83        return -1;
84
85    if (total)
86        *total = m_length;
87
88    if (available)
89        *available = m_length;
90
91    return 0;
92}
93
94int MkvReader::Read(long long offset, long len, unsigned char* buffer)
95{
96    if (m_file == NULL)
97        return -1;
98
99    if (offset < 0)
100        return -1;
101
102    if (len < 0)
103        return -1;
104
105    if (len == 0)
106        return 0;
107
108    if (offset >= m_length)
109        return -1;
110
111#ifdef _MSC_VER
112    const int status = _fseeki64(m_file, offset, SEEK_SET);
113
114    if (status)
115        return -1;  //error
116#else
117    fseek(m_file, offset, SEEK_SET);
118#endif
119
120    const size_t size = fread(buffer, 1, len, m_file);
121
122    if (size < size_t(len))
123        return -1;  //error
124
125    return 0;  //success
126}
127
128}  //end namespace mkvparser
129