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
10df37111358d02836cb29bbcb9c6e4c95dff90a16Johann#include <sys/types.h>
11df37111358d02836cb29bbcb9c6e4c95dff90a16Johann
122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#include <cassert>
132ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
14ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramaniannamespace mkvparser {
152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
16ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMkvReader::MkvReader() : m_file(NULL), reader_owns_file_(true) {}
172ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
18ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh VenkatasubramanianMkvReader::MkvReader(FILE* fp) : m_file(fp), reader_owns_file_(false) {
194fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  GetFileSize();
204fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
214fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
224fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangMkvReader::~MkvReader() {
234fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  if (reader_owns_file_)
242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian    Close();
254fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang  m_file = NULL;
262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
272ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
28ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Open(const char* fileName) {
29ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (fileName == NULL)
30ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
32ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file)
33ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
342ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
352ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
36ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const errno_t e = fopen_s(&m_file, fileName, "rb");
372ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
38ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (e)
39ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
402ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
41ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_file = fopen(fileName, "rb");
422ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
43ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
44ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
452ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
46ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return !GetFileSize();
474fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang}
482ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
494fb68e5dd4e93c7599dc905d861de11ac39c5585hkuangbool MkvReader::GetFileSize() {
50ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
51ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;
522ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
53ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  int status = _fseeki64(m_file, 0L, SEEK_END);
542ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
55ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
56ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;  // error
572ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
58ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_length = _ftelli64(m_file);
592ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
60ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, 0L, SEEK_END);
61ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  m_length = ftell(m_file);
622ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
63ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  assert(m_length >= 0);
642ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
65ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_length < 0)
66ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;
674fb68e5dd4e93c7599dc905d861de11ac39c5585hkuang
682ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
69ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  status = _fseeki64(m_file, 0L, SEEK_SET);
702ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
71ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
72ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return false;  // error
732ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
74ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  fseek(m_file, 0L, SEEK_SET);
752ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
762ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
77ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return true;
782ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
792ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
80ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianvoid MkvReader::Close() {
81ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file != NULL) {
82ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    fclose(m_file);
83ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    m_file = NULL;
84ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  }
852ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
862ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
87ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Length(long long* total, long long* available) {
88ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
89ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
902ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
91ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (total)
92ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *total = m_length;
932ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
94ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (available)
95ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    *available = m_length;
962ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
97ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;
982ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
992ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
100ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanianint MkvReader::Read(long long offset, long len, unsigned char* buffer) {
101ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (m_file == NULL)
102ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1032ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
104ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (offset < 0)
105ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1062ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
107ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (len < 0)
108ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1092ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
110ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (len == 0)
111ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return 0;
1122ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
113ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (offset >= m_length)
114ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;
1152ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1162ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#ifdef _MSC_VER
117ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const int status = _fseeki64(m_file, offset, SEEK_SET);
1182ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
119ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (status)
120ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
1212ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#else
1227bc9febe8749e98a3812a0dc4380ceae75c29450Johann  fseeko(m_file, static_cast<off_t>(offset), SEEK_SET);
1232ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian#endif
1242ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
125ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  const size_t size = fread(buffer, 1, len, m_file);
1262ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
127ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  if (size < size_t(len))
128ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian    return -1;  // error
1292ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
130ba6c59e9d7d7013b3906b6f4230b663422681848Vignesh Venkatasubramanian  return 0;  // success
1312ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian}
1322ec72e65689c948e92b826ae1e867bf369e72f13Vignesh Venkatasubramanian
1337bc9febe8749e98a3812a0dc4380ceae75c29450Johann}  // namespace mkvparser
134