12ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
22ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian//
32ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// Use of this source code is governed by a BSD-style license
42ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// that can be found in the LICENSE file in the root of the source
52ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// tree. An additional intellectual property rights grant can be found
62ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// in the file PATENTS.  All contributing project authors may
72ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian// be found in the AUTHORS file in the root of the source tree.
82ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
92ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include "mkvreader.hpp"
102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cassert>
122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
13ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace mkvparser {
142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
15ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
17ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
184fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  GetFileSize();
194fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
204fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
214fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangMkvReader::~MkvReader() {
224fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  if (reader_owns_file_)
232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    Close();
244fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  m_file = NULL;
252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Open(const char* fileName) {
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (fileName == NULL)
29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file)
32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
35ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const errno_t e = fopen_s(&m_file, fileName, "rb");
362ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (e)
38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
392ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
40ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_file = fopen(fileName, "rb");
412ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
442ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
45ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return !GetFileSize();
464fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
472ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
484fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangbool MkvReader::GetFileSize() {
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;
512ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
52ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int status = _fseeki64(m_file, 0L, SEEK_END);
532ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;  // error
562ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
57ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_length = _ftelli64(m_file);
582ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, 0L, SEEK_END);
60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_length = ftell(m_file);
612ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
62ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(m_length >= 0);
632ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_length < 0)
65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;
664fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
672ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
68ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  status = _fseeki64(m_file, 0L, SEEK_SET);
692ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;  // error
722ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
73ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, 0L, SEEK_SET);
742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
76ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return true;
772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MkvReader::Close() {
80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file != NULL) {
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    fclose(m_file);
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    m_file = NULL;
83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Length(long long* total, long long* available) {
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
892ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (total)
91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *total = m_length;
922ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (available)
94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *available = m_length;
952ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
96ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;
972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Read(long long offset, long len, unsigned char* buffer) {
100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1022ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (offset < 0)
104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1052ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (len < 0)
107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1082ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (len == 0)
110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
1112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (offset >= m_length)
113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
116ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const int status = _fseeki64(m_file, offset, SEEK_SET);
1172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
1202ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
121ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, offset, SEEK_SET);
1222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
1232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
124ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const size_t size = fread(buffer, 1, len, m_file);
1252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (size < size_t(len))
127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
1282ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
129ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;  // success
1302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
132ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian}  // end namespace mkvparser
133