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.
868e1c830ade592be74773e249bf94e2bbfb50de7Johann#include "mkvparser/mkvreader.h"
92ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cassert>
112ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
12ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace mkvparser {
132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
174fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  GetFileSize();
184fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
194fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
204fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangMkvReader::~MkvReader() {
214fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  if (reader_owns_file_)
222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    Close();
234fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  m_file = NULL;
242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
252ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
26ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Open(const char* fileName) {
27ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (fileName == NULL)
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file)
31ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
332ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
34ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const errno_t e = fopen_s(&m_file, fileName, "rb");
352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (e)
37ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
382ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_file = fopen(fileName, "rb");
402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
42ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
432ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return !GetFileSize();
454fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
462ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
474fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangbool MkvReader::GetFileSize() {
48ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
49ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;
502ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int status = _fseeki64(m_file, 0L, SEEK_END);
522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
54ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;  // error
552ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_length = _ftelli64(m_file);
572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, 0L, SEEK_END);
59ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_length = ftell(m_file);
602ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(m_length >= 0);
622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_length < 0)
64ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;
654fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
662ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
67ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  status = _fseeki64(m_file, 0L, SEEK_SET);
682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
70ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;  // error
712ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, 0L, SEEK_SET);
732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
742ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
75ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return true;
762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
772ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
78ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MkvReader::Close() {
79ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file != NULL) {
80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    fclose(m_file);
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    m_file = NULL;
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
832ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
842ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
85ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Length(long long* total, long long* available) {
86ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
882ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (total)
90ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *total = m_length;
912ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (available)
93ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *available = m_length;
942ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;
962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
972ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
98ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Read(long long offset, long len, unsigned char* buffer) {
99ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1012ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (offset < 0)
103ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1042ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (len < 0)
106ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1072ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (len == 0)
109ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
1102ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (offset >= m_length)
112ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1142ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
115ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const int status = _fseeki64(m_file, offset, SEEK_SET);
1162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
118ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
1192ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
1207bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fseeko(m_file, static_cast<off_t>(offset), SEEK_SET);
1212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
1222ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
123ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const size_t size = fread(buffer, 1, len, m_file);
1242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (size < size_t(len))
126ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
1272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;  // success
1292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1302ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1317bc9febe8749e98a3812a0dc4380ceae75c29450Johann}  // namespace mkvparser
132