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