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