/*
 * MMS protocol common definitions.
 * Copyright (c) 2006,2007 Ryan Martell
 * Copyright (c) 2007 Björn Axelsson
 * Copyright (c) 2010 Zhentan Feng <spyfeng at gmail dot com>
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */
#include "mms.h"
#include "asf.h"
#include "libavutil/intreadwrite.h"

#define MMS_MAX_STREAMS 256    /**< arbitrary sanity check value */

int ff_mms_read_header(MMSContext *mms, uint8_t *buf, const int size)
{
    char *pos;
    int size_to_copy;
    int remaining_size = mms->asf_header_size - mms->asf_header_read_size;
    size_to_copy = FFMIN(size, remaining_size);
    pos = mms->asf_header + mms->asf_header_read_size;
    memcpy(buf, pos, size_to_copy);
    if (mms->asf_header_read_size == mms->asf_header_size) {
        av_freep(&mms->asf_header); // which contains asf header
    }
    mms->asf_header_read_size += size_to_copy;
    return size_to_copy;
}

int ff_mms_read_data(MMSContext *mms, uint8_t *buf, const int size)
{
    int read_size;
    read_size = FFMIN(size, mms->remaining_in_len);
    memcpy(buf, mms->read_in_ptr, read_size);
    mms->remaining_in_len -= read_size;
    mms->read_in_ptr      += read_size;
    return read_size;
}

int ff_mms_asf_header_parser(MMSContext *mms)
{
    uint8_t *p = mms->asf_header;
    uint8_t *end;
    int flags, stream_id;
    mms->stream_num = 0;

    if (mms->asf_header_size < sizeof(ff_asf_guid) * 2 + 22 ||
        memcmp(p, ff_asf_header, sizeof(ff_asf_guid))) {
        av_log(NULL, AV_LOG_ERROR,
               "Corrupt stream (invalid ASF header, size=%d)\n",
               mms->asf_header_size);
        return AVERROR_INVALIDDATA;
    }

    end = mms->asf_header + mms->asf_header_size;

    p += sizeof(ff_asf_guid) + 14;
    while(end - p >= sizeof(ff_asf_guid) + 8) {
        uint64_t chunksize;
        if (!memcmp(p, ff_asf_data_header, sizeof(ff_asf_guid))) {
            chunksize = 50; // see Reference [2] section 5.1
        } else {
            chunksize = AV_RL64(p + sizeof(ff_asf_guid));
        }
        if (!chunksize || chunksize > end - p) {
            av_log(NULL, AV_LOG_ERROR,
                   "Corrupt stream (header chunksize %"PRId64" is invalid)\n",
                   chunksize);
            return AVERROR_INVALIDDATA;
        }
        if (!memcmp(p, ff_asf_file_header, sizeof(ff_asf_guid))) {
            /* read packet size */
            if (end - p > sizeof(ff_asf_guid) * 2 + 68) {
                mms->asf_packet_len = AV_RL32(p + sizeof(ff_asf_guid) * 2 + 64);
                if (mms->asf_packet_len <= 0 || mms->asf_packet_len > sizeof(mms->in_buffer)) {
                    av_log(NULL, AV_LOG_ERROR,
                           "Corrupt stream (too large pkt_len %d)\n",
                           mms->asf_packet_len);
                    return AVERROR_INVALIDDATA;
                }
            }
        } else if (!memcmp(p, ff_asf_stream_header, sizeof(ff_asf_guid))) {
            if (end - p >= (sizeof(ff_asf_guid) * 3 + 26)) {
                flags     = AV_RL16(p + sizeof(ff_asf_guid)*3 + 24);
                stream_id = flags & 0x7F;
                //The second condition is for checking CS_PKT_STREAM_ID_REQUEST packet size,
                //we can calculate the packet size by stream_num.
                //Please see function send_stream_selection_request().
                if (mms->stream_num < MMS_MAX_STREAMS &&
                        46 + mms->stream_num * 6 < sizeof(mms->out_buffer)) {
                    mms->streams = av_fast_realloc(mms->streams,
                                       &mms->nb_streams_allocated,
                                       (mms->stream_num + 1) * sizeof(MMSStream));
                    if (!mms->streams)
                        return AVERROR(ENOMEM);
                    mms->streams[mms->stream_num].id = stream_id;
                    mms->stream_num++;
                } else {
                    av_log(NULL, AV_LOG_ERROR,
                           "Corrupt stream (too many A/V streams)\n");
                    return AVERROR_INVALIDDATA;
                }
            }
        } else if (!memcmp(p, ff_asf_ext_stream_header, sizeof(ff_asf_guid))) {
            if (end - p >= 88) {
                int stream_count = AV_RL16(p + 84), ext_len_count = AV_RL16(p + 86);
                uint64_t skip_bytes = 88;
                while (stream_count--) {
                    if (end - p < skip_bytes + 4) {
                        av_log(NULL, AV_LOG_ERROR,
                               "Corrupt stream (next stream name length is not in the buffer)\n");
                        return AVERROR_INVALIDDATA;
                    }
                    skip_bytes += 4 + AV_RL16(p + skip_bytes + 2);
                }
                while (ext_len_count--) {
                    if (end - p < skip_bytes + 22) {
                        av_log(NULL, AV_LOG_ERROR,
                               "Corrupt stream (next extension system info length is not in the buffer)\n");
                        return AVERROR_INVALIDDATA;
                    }
                    skip_bytes += 22 + AV_RL32(p + skip_bytes + 18);
                }
                if (end - p < skip_bytes) {
                    av_log(NULL, AV_LOG_ERROR,
                           "Corrupt stream (the last extension system info length is invalid)\n");
                    return AVERROR_INVALIDDATA;
                }
                if (chunksize - skip_bytes > 24)
                    chunksize = skip_bytes;
            }
        } else if (!memcmp(p, ff_asf_head1_guid, sizeof(ff_asf_guid))) {
            chunksize = 46; // see references [2] section 3.4. This should be set 46.
            if (chunksize > end - p) {
                av_log(NULL, AV_LOG_ERROR,
                    "Corrupt stream (header chunksize %"PRId64" is invalid)\n",
                    chunksize);
                return AVERROR_INVALIDDATA;
            }
        }
        p += chunksize;
    }

    return 0;
}
