📄 smlprstime.cpp
字号:
/* ***** BEGIN LICENSE BLOCK ***** * Source last modified: $Id: smlprstime.cpp,v 1.2.12.1 2004/07/09 01:58:02 hubbe Exp $ * * Portions Copyright (c) 1995-2004 RealNetworks, Inc. All Rights Reserved. * * The contents of this file, and the files included with this file, * are subject to the current version of the RealNetworks Public * Source License (the "RPSL") available at * http://www.helixcommunity.org/content/rpsl unless you have licensed * the file under the current version of the RealNetworks Community * Source License (the "RCSL") available at * http://www.helixcommunity.org/content/rcsl, in which case the RCSL * will apply. You may also obtain the license terms directly from * RealNetworks. You may not use this file except in compliance with * the RPSL or, if you have a valid RCSL with RealNetworks applicable * to this file, the RCSL. Please see the applicable RPSL or RCSL for * the rights, obligations and limitations governing use of the * contents of the file. * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL") in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your version of * this file only under the terms of the GPL, and not to allow others * to use your version of this file under the terms of either the RPSL * or RCSL, indicate your decision by deleting the provisions above * and replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient may * use your version of this file under the terms of any one of the * RPSL, the RCSL or the GPL. * * This file is part of the Helix DNA Technology. RealNetworks is the * developer of the Original Code and owns the copyrights in the * portions it created. * * This file, and the files included with this file, is distributed * and made available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY * KIND, EITHER EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS * ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET * ENJOYMENT OR NON-INFRINGEMENT. * * Technology Compatibility Kit Test Suite(s) Location: * http://www.helixcommunity.org/content/tck * * Contributor(s): * * ***** END LICENSE BLOCK ***** */// system#include <time.h>#ifdef _UNIX#include <ctype.h>#endif// include#include "hxtypes.h"#include "hxwintyp.h"#include "hxcom.h"#include "hxxml.h"#include "smiltype.h"// pncont#include "hxstring.h"#include "hxslist.h"// pnmisc#include "nptime.h"#include "smpte.h"#include "hxwinver.h"// rnxmllib#include "hxxmlprs.h"// rmasmil#include "smlerror.h"#include "smlparse.h"#include "smlelem.h"#include "smlprstime.h"// pndebug#include "hxheap.h"#ifdef _DEBUG#undef HX_THIS_FILE static const char HX_THIS_FILE[] = __FILE__;#endifSmilTimeValue::SmilTimeValue(IUnknown* pContext, UINT32 ulStartLine, CSmilElement* pElement): m_pContext(pContext), m_pElement(pElement), m_ulStartLine(ulStartLine), m_type(SmilTimeNone), m_position(SMILEventSourceEnd), m_uRepeatIteration(0), m_bTreatSyncArcAsEvent(FALSE), m_lOffset(0), m_lOriginalOffset(0), m_year(-1), m_month(-1), m_day(-1), m_hour(0), m_min(0), m_sec(0), m_ms(0), m_UTCOffsetMin(0), m_bRelativeToUTC(FALSE), m_pszMarkerName(NULL), m_bIsExternalMarker(FALSE), m_pszExternalMarkerFileName(NULL), m_pszExternalMarkerName(NULL), m_ulMarkerTime(0), m_bUsedToBeMediaMarker(FALSE), m_pEventName(NULL), m_bTimeIsResolved(FALSE), m_lResolvedToTime(SMILTIME_INFINITY), m_lWhenTimeWasResolved(SMILTIME_INFINITY), m_lTimeOfPause(SMILTIME_INFINITY){ m_pContext->AddRef();}SmilTimeValue::~SmilTimeValue(){ HX_RELEASE(m_pContext); // /fixes mem leak. HX_VECTOR_DELETE(m_pszMarkerName); HX_VECTOR_DELETE(m_pszExternalMarkerFileName); HX_VECTOR_DELETE(m_pszExternalMarkerName); HX_VECTOR_DELETE(m_pEventName);}// /This returns the resolved time, including any positive offset,// and includes only the part of a negative offset that is after// the resolved-AT time (which is m_lWhenTimeWasResolved). In other// words, this returns the time at which the element will actually// begin or end based on this SmilTimeValue://// Returns HXR_OK if resolved time is returned in lEffectiveResolveTime,// else returns HXR_FAILED.HX_RESULTSmilTimeValue::getEffectiveResolvedTime(REF(INT32) lEffectiveResolvedTime){ HX_RESULT retval = HXR_OK; lEffectiveResolvedTime = SMILTIME_NEGATIVE_INFINITY; switch (m_type) { case SmilTimeSyncBase:#if defined(ENABLE_SYNC_TO_PREV) case SmilTimeSyncToPrev:#endif case SmilTimeMediaMarker: case SmilTimeEvent: { if (isTimeResolved()) { // /EH- the following should *always* be true: HX_ASSERT(m_lResolvedToTime >= m_lWhenTimeWasResolved); // /Note: resolvedToTime doesn't include offset: lEffectiveResolvedTime = m_lResolvedToTime;#define XXXEH_OFFSET_NOT_ALREADY_ACCOUNTED_FOR#if defined(XXXEH_OFFSET_NOT_ALREADY_ACCOUNTED_FOR) if (SmilTimeEvent == m_type // /XXXEH- TODO: handle SmilTimeMediaMarker here, too, // if and when we get internal markers (event-like // ones) working: || (isSyncBaseTimeVal() && m_bTreatSyncArcAsEvent)) { INT32 lEffectiveOffset = m_lOffset; if (lEffectiveOffset < 0) { lEffectiveOffset = m_lWhenTimeWasResolved - m_lResolvedToTime; if (lEffectiveOffset < m_lOffset) { // /Resolved-at time was well before resolved-to // time minus |offset|, so the entire offset is // used: lEffectiveOffset = m_lOffset; } } lEffectiveResolvedTime += lEffectiveOffset; }#endif } else { retval = HXR_FAILED; } } break; // /XXXEH- TODO: figure out how to handle wallclock; I think // it should just work the same as clock values: case SmilTimeWallclock: case SmilTimeClockValue: case SmilTimeOffset: { if (isTimeResolved()) { lEffectiveResolvedTime = m_lOffset; } else { retval = HXR_FAILED; // /All wallclock, clock, and offset values should have // been set as resolved at parse time: HX_ASSERT(isTimeResolved()); } } break; default: { retval = HXR_FAILED; } break; } return retval;}HX_RESULTSmilTimeValue::parseValue(const char* pPos, SMILSyncAttributeTag nTag, // /Needed for self-references: const char* pThisElementID){ HX_RESULT ret = HXR_OK; if (pPos == (const char*)NULL) { ret = HXR_FAIL; } else if (*pPos == '+' || *pPos == '-') { HX_ASSERT(nTag == SMILSyncAttrBegin); if (nTag == SMILSyncAttrBegin) { ret = parseOffset(pPos); m_type = SmilTimeOffset; if (SUCCEEDED(ret)) { m_bTimeIsResolved = TRUE; } } else { CSmilSMILSyntaxErrorHandler errHandler(m_pContext); errHandler.ReportError(SMILErrorBadTimeValue, pPos, m_ulStartLine); return ret; } } else if (isdigit(*pPos) // /Fixes PR 42592: // "0.5s" was OK but ".5s" was being treated as unresolved: || '.' == *pPos) { ret = parseOffset(pPos); if (SUCCEEDED(ret)) { m_bTimeIsResolved = TRUE; } // this is actually a Clock Value if it is an end // time. if (nTag == SMILSyncAttrBegin) { m_type = SmilTimeOffset; } else // nTag == SMILSyncAttrEnd { m_type = SmilTimeClockValue; } }#if defined(ENABLE_SYNC_TO_PREV) else if (strncmp(pPos, "prev", 4) == 0) { // syncToPrev-value ret = parseSyncToPrev(pPos); }#endif else if (strncmp(pPos, "wallclock", 9) == 0) { // wallclock-sync-value ret = parseWallClockValue(pPos); } else { const char* pDotPos = NULL; BOOL bEscape = FALSE; UINT32 len = strlen(pPos); char* idref = new char [len+1]; char* idrefPos = idref; *idrefPos = '\0'; char* command = new char [len+1]; char* commandPos = command; *commandPos = '\0'; const char* pOffset = NULL; enum { IDREF, ESCAPE, COMMAND, END, OFFSET } state = IDREF; const char* pBegin = pPos; while (*pPos) { switch (state) { case ESCAPE: *idrefPos++ = *pPos; state = IDREF; break; case IDREF: if (*pPos == '\\') { // /Don't include escape char in idref; go to next char: state = ESCAPE; } else if (*pPos == '.') { *idrefPos = '\0'; state = COMMAND; } else if (isspace(*pPos)) { *idrefPos = '\0'; state = END; } else if (*pPos == '+' || *pPos == '-') { *idrefPos++ = '\0'; pOffset = pPos; state = OFFSET; } else { *idrefPos++ = *pPos; } break; case COMMAND: if (isspace(*pPos)) { *commandPos = '\0'; state = END; } else if (*pPos == '+' || *pPos == '-') { pOffset = pPos; *commandPos = '\0'; state = OFFSET; } else { *commandPos++ = *pPos; } break; case END: if (*pPos == '+' || *pPos == '-') { pOffset = pPos; state = OFFSET; } break; case OFFSET: break; } ++pPos; } if (state == COMMAND) { *commandPos = '\0'; } else if (state == IDREF || state == ESCAPE) { *idrefPos = '\0'; } // XXXMEH - if this is an animation element, then we // will handle the ".repeat(x)" syntax differently than // we treat sources. We will treat ".repeat(x)" as an // event rather than a sync-arc. BOOL bIsAnimate = FALSE; if (m_pElement && m_pElement->m_pNode && (m_pElement->m_pNode->m_tag == SMILAnimate || m_pElement->m_pNode->m_tag == SMILSet || m_pElement->m_pNode->m_tag == SMILAnimateMotion || m_pElement->m_pNode->m_tag == SMILAnimateColor)) { bIsAnimate = TRUE; } if (*command == '\0') { // /The SMIL Boston draft supports the fact that the name of the // event ("Event-symbol") is required and is what is used when // no "Eventbase-element." precedes it. Thus, we need to // treat the idref as the command string and use this // element's id for the idref: // /HOWEVER, for PR 69849 (needed for PR 58290) fix, if event is // "accesskey(...)", then the event is not self-generated and is // not raised for another element, so give it a fake id here so // special-case code isn't needed in multiple places, elsewhere: if (!strncmp(idref, "accesskey(", 10)) { ret = parseEvent( // /Use this string (an invalid XML id) as the fake ID: ACCESSKEY_EVENT_FAKE_ID_STRING, // /fake ID. idref, // /<==actually the command (i.e., Event-symbol) pOffset); } else { ret = parseEvent(pThisElementID, idref, // /<==actually the command (i.e., Event-symbol) pOffset); } } else if (strcmp(command, "begin") == 0 ||#if defined(XXXEH_REPEAT_VALUE_TIMING_SHOULD_BE_EVENT_BASED)#else ((0 == strncmp(command, "repeat(", 7)) && !bIsAnimate) ||#endif strcmp(command, "end") == 0) { // base, memeber, offset ret = parseSyncBase(idref, command, pOffset); } else if (strncmp(command, "marker(", 7) == 0) { ret = parseMarker(idref, command, pOffset); } else // /everything else is an event (i.e., "Event-symbol") name: { ret = parseEvent(idref, command, pOffset); } HX_VECTOR_DELETE(command); HX_VECTOR_DELETE(idref); } // /We need to make sure we set scheduled time values' resolved-to times // in case these times are used AFTER the element has already begun // playing or finished playing: if (SmilTimeOffset == m_type || SmilTimeClockValue == m_type || SmilTimeWallclock == m_type) { setResolvedToTime(0); setWhenTimeWasResolved(0); } return ret;}HX_RESULTSmilTimeValue::setTimeOffset(time_t tRefTime){ HX_RESULT ret = HXR_OK; if (m_type == SmilTimeWallclock) { struct tm ourtime; ourtime.tm_sec = m_sec; ourtime.tm_min = m_min; ourtime.tm_hour = m_hour; if (m_day != -1 && m_year != -1 && m_month != -1) { ourtime.tm_mday = m_day; // /tm::tm_mon is 0-based, while m_month is 1-based, so we need // to subtract 1 (and our parser already made sure m_month is // greater than 0 and less than 13): ourtime.tm_mon = m_month - 1; ourtime.tm_year = m_year - 1900; } else { time_t thetime; time(&thetime); struct tm* cur; cur = localtime(&thetime); ourtime.tm_mday = cur->tm_mday; ourtime.tm_mon = cur->tm_mon; ourtime.tm_year = cur->tm_year; ourtime.tm_isdst = cur->tm_isdst;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -