blob: de1300efbc67625730b2f17b1a4078e47207f42b [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 2008 PacketVideo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied.
* See the License for the specific language governing permissions
* and limitations under the License.
* -------------------------------------------------------------------
*/
#include "oscl_string_utils.h"
#include "common_info.h"
#include "rtsp_range_utils.h"
#include "oscl_str_ptr_len.h"
#include "oscl_stdstring.h"
bool get_next_line(const char *start_ptr, const char * end_ptr,
const char *& line_start,
const char *& line_end)
{
// Finds the boundaries of the next non-empty line within start
// and end ptrs
// This initializes line_start to the first non-whitespace character
line_start = skip_whitespace_and_line_term(start_ptr, end_ptr);
line_end = skip_to_line_term(line_start, end_ptr);
return (line_start < end_ptr);
}
bool parseQoEMetrics(const char *start_ptr, const char *end_ptr, QoEMetricsType &qoeMetrics)
{
const char *sptr = start_ptr;
const char *eptr = end_ptr;
sptr = skip_whitespace_and_line_term(sptr, end_ptr);
StrPtrLen rate("rate=");
StrPtrLen range("range:");
if (!oscl_strncmp(sptr, "{", 1))
sptr = sptr + 1;
else
return false;
sptr = skip_whitespace_and_line_term(sptr, end_ptr);
if (sptr > eptr)
return false;
while (sptr < end_ptr)
{
if (!oscl_strncmp(sptr, "Initial_Buffering_Duration",
oscl_strlen("Initial_Buffering_Duration")))
{
qoeMetrics.name[QoEMetricsType::INITIAL_BUFFERING_DURATION] = true;
sptr = sptr + oscl_strlen("Initial_Buffering_Duration");
}
else if (!oscl_strncmp(sptr, "Rebuffering_Duration",
oscl_strlen("Rebuffering_Duration")))
{
qoeMetrics.name[QoEMetricsType::REBUFFERING_DURATION] = true;
sptr = sptr + oscl_strlen("Rebuffering_Duration");
}
else if (!oscl_strncmp(sptr, "Corruption_Duration",
oscl_strlen("Corruption_Duration")))
{
qoeMetrics.name[QoEMetricsType::CORRUPTION_DURATION] = true;
sptr = sptr + oscl_strlen("Corruption_Duration");
}
else if (!oscl_strncmp(sptr, "Succssive_Loss",
oscl_strlen("Succssive_Loss")))
{
qoeMetrics.name[QoEMetricsType::SUCESSIVE_LOSS] = true;
sptr = sptr + oscl_strlen("Succssive_Loss");
}
else if (!oscl_strncmp(sptr, "Framerate_Deviation",
oscl_strlen("Framerate_Deviation")))
{
qoeMetrics.name[QoEMetricsType::FRAMERATE_DEVIATION] = true;
sptr = sptr + oscl_strlen("Framerate_Deviation");
}
else if (!oscl_strncmp(sptr, "Jitter_Duration",
oscl_strlen("Jitter_Duration")))
{
qoeMetrics.name[QoEMetricsType::JITTER_DURATION] = true;
sptr = sptr + oscl_strlen("Jitter_Duration");
}
else if (!oscl_strncmp(sptr, "Decoded_Bytes",
oscl_strlen("Decoded_Bytes")))
{
qoeMetrics.name[QoEMetricsType::DECODED_BYTES] = true;
sptr = sptr + oscl_strlen("Decoded_Bytes");
}
else
return false;
sptr = skip_whitespace_and_line_term(sptr, end_ptr);
if (sptr > end_ptr)
return false;
if (!oscl_strncmp(sptr, ",", 1))
sptr = sptr + 1;
else if (!oscl_strncmp(sptr, "}", 1))
{
sptr = sptr + 1;
break;
}
}
if (sptr > end_ptr)
return false;
if (!oscl_strncmp(sptr, ";", 1))
sptr = sptr + 1;
else
return false;
if (!oscl_strncmp(sptr, rate.c_str(), rate.length()))
{
sptr = sptr + rate.length();
if (!oscl_strncmp(sptr, "End", oscl_strlen("End")))
{
qoeMetrics.rateFmt = QoEMetricsType::END;
qoeMetrics.rateEnd = 'E';
sptr = sptr + oscl_strlen("End");
}
else
{
uint32 temp;
eptr = sptr; //get length of range digit
for (; (*eptr != ';' && eptr < end_ptr); ++eptr);
qoeMetrics.rateFmt = QoEMetricsType::VAL;
if (PV_atoi(sptr, 'd', (int)(eptr - sptr), temp))
{
qoeMetrics.rateVal = temp;
sptr = eptr ;
}
else
return false;
}
}
else
return false;
if (sptr == end_ptr) //end of line reached.
return true;
if (sptr > end_ptr)
return false;
if (!oscl_strncmp(sptr, ";", 1))
sptr = sptr + 1;
else
return false;
if (!oscl_strncmp(sptr, range.c_str(), range.length()))
{
eptr = sptr + range.length();
for (; *eptr != ';' && eptr != end_ptr ; eptr++); // get length of range.
if (!parseRtspRange((sptr + range.length()), (eptr - sptr - range.length()),
qoeMetrics.range))
return false;
}
sptr = eptr;
if (sptr == end_ptr)
return true; // end of line reached.
else //Parameter_Ext
{
sptr = eptr + 1;
if (!oscl_strncmp(sptr, "On", oscl_strlen("On")))
{
qoeMetrics.paramExtStat = true;
qoeMetrics.paramFmt = QoEMetricsType::STATUS;
}
else if (!oscl_strncmp(sptr, "Off", oscl_strlen("Off")))
{
qoeMetrics.paramExtStat = false;
qoeMetrics.paramFmt = QoEMetricsType::STATUS;
}
else
{
if (NULL != oscl_strstr(sptr, ".")) //if floating point number
{
if (!PV_atof(sptr, (int)(eptr - sptr), qoeMetrics.paramExtFdigit))
return false;
qoeMetrics.paramFmt = QoEMetricsType::FDIGIT;
}
else // hex digit
{
uint32 temp;
if (PV_atoi(sptr, 'x', (int)(eptr - sptr), temp))
{
qoeMetrics.paramExtIdigit = temp;
qoeMetrics.paramFmt = QoEMetricsType::IDIGIT;
}
else
return false;
}
}
}
return true;
}
bool parseAssetInfo(const char *sptr, const char *line_end_ptr, AssetInfoType &ainfo)
{
const char *eptr = sptr;
int assetbox;
while (eptr < line_end_ptr)
{
sptr = skip_whitespace(sptr, line_end_ptr);
if (oscl_strncmp(sptr, "{", 1))
return false;
sptr = sptr + 1;
sptr = skip_whitespace(sptr, line_end_ptr);
if (sptr > line_end_ptr)
return false;
if (!oscl_strncmp(sptr, "url=", oscl_strlen("url=")))
{
sptr = sptr + oscl_strlen("url=");
sptr = skip_whitespace(sptr, line_end_ptr);
if (sptr > line_end_ptr)
return false;
if (oscl_strncmp(sptr, "\"", 1))
return false;
sptr = sptr + 1;
sptr = skip_whitespace(sptr, line_end_ptr);
if (sptr > line_end_ptr)
return false;
eptr = sptr;
for (; *eptr != '"'; ++eptr);
ainfo.URL.set((const char *)sptr, (eptr - sptr));
return true;
}
if (!oscl_strncmp(sptr, "Title=", oscl_strlen("Title=")))
{
sptr = sptr + oscl_strlen("Title=");
assetbox = (int) AssetInfoType::TITLE;
ainfo.oTitlePresent = true;
}
else if (!oscl_strncmp(sptr, "Description=", oscl_strlen("Description=")))
{
sptr = sptr + oscl_strlen("Description=");
assetbox = (int) AssetInfoType::DESCRIPTION;
ainfo.oDescriptionPresent = true;
}
else if (!oscl_strncmp(sptr, "Copyright=", oscl_strlen("Copyright=")))
{
sptr = sptr + oscl_strlen("Copyright=");
assetbox = (int) AssetInfoType::COPYRIGHT;
ainfo.oCopyRightPresent = true;
}
else if (!oscl_strncmp(sptr, "Performer=", oscl_strlen("Performer=")))
{
sptr = sptr + oscl_strlen("Performer=");
assetbox = (int) AssetInfoType::PERFORMER;
ainfo.oPerformerPresent = true;
}
else if (!oscl_strncmp(sptr, "Author=", oscl_strlen("Author=")))
{
sptr = sptr + oscl_strlen("Author=");
assetbox = (int) AssetInfoType::AUTHOR;
ainfo.oAuthorPresent = true;
}
else if (!oscl_strncmp(sptr, "Genre=", oscl_strlen("Genre=")))
{
sptr = sptr + oscl_strlen("Genre=");
assetbox = (int) AssetInfoType::GENRE;
ainfo.oGenrePresent = true;
}
else if (!oscl_strncmp(sptr, "Rating=", oscl_strlen("Rating=")))
{
sptr = sptr + oscl_strlen("Rating=");
assetbox = (int) AssetInfoType::RATING;
ainfo.oRatingPresent = true;
}
else if (!oscl_strncmp(sptr, "Classification=", oscl_strlen("Classification=")))
{
sptr = sptr + oscl_strlen("Classification=");
assetbox = (int) AssetInfoType::CLASSIFICATION;
ainfo.oClassificationPresent = true;
}
else if (!oscl_strncmp(sptr, "Keywords=", oscl_strlen("Keywords=")))
{
sptr = sptr + oscl_strlen("Keywords=");
assetbox = (int) AssetInfoType::KEYWORDS;
ainfo.oKeyWordsPresent = true;
}
else if (!oscl_strncmp(sptr, "Location=", oscl_strlen("Location=")))
{
sptr = sptr + oscl_strlen("Location=");
assetbox = (int) AssetInfoType::LOCATION;
ainfo.oLocationPresent = true;
}
else// if(!oscl_strncmp(sptr, "asset-extention=", oscl_strlen("asset-extention=")))
{//asset-extension ignore for now
//sptr = sptr + oscl_strlen("asset-extention=");
assetbox = (int) AssetInfoType::ASSET_EXTENTION;
ainfo.oAssetExtensionPresent = true;
}
sptr = skip_whitespace(sptr, line_end_ptr);
if (sptr > line_end_ptr)
return false;
for (eptr = sptr; *eptr != '}'; ++eptr)
{
if (eptr > line_end_ptr)
return false;
}
ainfo.Box[assetbox].set((const char *)sptr, (eptr - sptr));
eptr = eptr + 1;
sptr = eptr + 1;
}
return true;
}
bool sdp_decodebase64(uint8* aInBuf, uint32 aInBufLen,
uint8* aOutBuf, uint32& aOutBufLen, uint32 aMaxOutBufLen)
{
oscl_memset(aOutBuf, 0, aMaxOutBufLen);
aOutBufLen = 0;
int i;
uint8 dtable[256];
for (i = 0;i < 255;i++)
{
dtable[i] = 0x80;
}
for (i = 'A';i <= 'I';i++)
{
dtable[i] = 0 + (i - 'A');
}
for (i = 'J';i <= 'R';i++)
{
dtable[i] = 9 + (i - 'J');
}
for (i = 'S';i <= 'Z';i++)
{
dtable[i] = 18 + (i - 'S');
}
for (i = 'a';i <= 'i';i++)
{
dtable[i] = 26 + (i - 'a');
}
for (i = 'j';i <= 'r';i++)
{
dtable[i] = 35 + (i - 'j');
}
for (i = 's';i <= 'z';i++)
{
dtable[i] = 44 + (i - 's');
}
for (i = '0';i <= '9';i++)
{
dtable[i] = 52 + (i - '0');
}
dtable[(int)'+'] = 62;
dtable[(int)'/'] = 63;
dtable[(int)'='] = 0;
uint32 read_count = 0;
uint32 write_count = 0;
while (read_count < aInBufLen)
{
uint8 a[4], b[4], o[3];
for (i = 0;i < 4;i++)
{
uint8 c = *(aInBuf++);
read_count++;
if (read_count > aInBufLen)
{
//Input incomplete
return false;
}
if (dtable[(int)c]&0x80)
{
//Illegal character in
//return false;
i--;
continue;
}
a[i] = (uint8)c;
b[i] = (uint8)dtable[(int)c];
}
o[0] = (b[0] << 2) | (b[1] >> 4);
o[1] = (b[1] << 4) | (b[2] >> 2);
o[2] = (b[2] << 6) | b[3];
i = a[2] == '=' ? 1 : (a[3] == '=' ? 2 : 3);
oscl_memcpy(aOutBuf, o, i);
aOutBuf += i;
write_count += i;
if (write_count > aMaxOutBufLen)
{
return false;
}
if (i < 3)
{
break;
}
}
aOutBufLen = write_count;
return true;
}