📄 time_attrs.cpp
字号:
// This file is part of Ambulant Player, www.ambulantplayer.org.//// Copyright (C) 2003-2007 Stichting CWI, // Kruislaan 413, 1098 SJ Amsterdam, The Netherlands.//// Ambulant Player 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.//// Ambulant Player 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 Ambulant Player; if not, write to the Free Software// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA/* * @$Id: time_attrs.cpp,v 1.21 2007/02/12 14:15:21 jackjansen Exp $ */#include "ambulant/smil2/time_attrs.h"#include "ambulant/lib/node.h"#include "ambulant/lib/document.h"#include "ambulant/lib/parselets.h"#include "ambulant/lib/string_util.h"#include "ambulant/smil2/time_node.h"#include <list>#include "ambulant/lib/logger.h"//#define AM_DBG if(1)#ifndef AM_DBG#define AM_DBG if(0)#endifusing namespace ambulant;using namespace smil2;// create an instance of this type// force all compilers to create code for this.static smil_time<double> dummy;time_attrs::time_attrs(const node *n) : m_node(n), m_spflags(0) { m_logger = logger::get_logger(); const char *pid = m_node->get_attribute("id"); m_id = (pid?pid:"no-id"); m_tag = m_node->get_local_name(); parse_time_attrs();}void time_attrs::parse_time_attrs() { parse_dur(); parse_rcount(); parse_rdur(); parse_begin(); parse_end(); parse_min(); parse_max(); parse_endsync(); parse_fill(); parse_restart(); parse_actuate(); parse_transitions(); parse_time_manipulations();}bool time_attrs::end_is_indefinite() const { return m_elist.size() == 1 && m_elist.front().type == sv_indefinite;}bool time_attrs::end_has_event_conditions() const { sync_list::const_iterator it; for(it=m_elist.begin();it!=m_elist.end();it++) { sync_value_type t = (*it).type; if(t != sv_offset && t != sv_wallclock && t != sv_indefinite) return true; } return false;}bool time_attrs::has_dur_specifier() const { return specified_dur() || specified_rdur() || specified_rcount();}// dur ::= Clock-value | "media" | "indefinite"// struct dur_t { dur_type type; time_type value;} m_dur;// enum dur_type {dt_unspecified, dt_definite, dt_indefinite, dt_media};void time_attrs::parse_dur() { m_dur.type = dt_unspecified; m_dur.value = time_type::unspecified; const char *p = m_node->get_attribute("dur"); if(!p) return; set_specified(SP_DUR); std::string sdur = trim(p); if(sdur == "indefinite") { m_dur.type = dt_indefinite; m_dur.value = time_type::indefinite; AM_DBG m_logger->debug("%s[%s].dur=indefinite", m_tag.c_str(), m_id.c_str()); return; } if(sdur == "media") { m_dur.type = dt_media; AM_DBG m_logger->debug("%s[%s].dur=media", m_tag.c_str(), m_id.c_str()); return; } clock_value_p pl; std::string::const_iterator b = sdur.begin(); std::string::const_iterator e = sdur.end(); std::ptrdiff_t d = pl.parse(b, e); if(d == -1) { m_logger->trace("<%s id=\"%s\" dur=\"%s\">: invalid dur attr", m_tag.c_str(), m_id.c_str(), sdur.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } m_dur.type = dt_definite; m_dur.value = time_type(pl.m_result); AM_DBG m_logger->debug("%s[%s].dur=%ld", m_tag.c_str(), m_id.c_str(), m_dur.value()); }// repeatCount ::= floating_point | "indefinite"void time_attrs::parse_rcount() { const char *p = m_node->get_attribute("repeatCount"); if(!p) return; set_specified(SP_RCOUNT); std::string rcount_str = trim(p); if(rcount_str == "indefinite") { m_rcount = std::numeric_limits<double>::max(); //smil_time<double>::indefinite(); AM_DBG m_logger->debug("%s[%s].repeatCount=indefinite", m_tag.c_str(), m_id.c_str()); return; } number_p parser; std::string::const_iterator b = rcount_str.begin(); std::string::const_iterator e = rcount_str.end(); std::ptrdiff_t d = parser.parse(b, e); if(d == -1) { m_logger->trace("<%s id=\"%s\" repeatCount=\"%s\">: invalid repeatCount attr", m_tag.c_str(), m_id.c_str(), rcount_str.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } m_rcount = parser.m_result; AM_DBG m_logger->debug("%s[%s].repeatCount=%.3f", m_tag.c_str(), m_id.c_str(), m_rcount); }// repeatDur ::= Clock-value | "indefinite"void time_attrs::parse_rdur() { const char *p = m_node->get_attribute("repeatDur"); if(!p) return; set_specified(SP_RDUR); std::string rdur_str = trim(p); if(rdur_str == "indefinite") { m_rdur = time_type::indefinite; AM_DBG m_logger->debug("%s[%s].repeatDur=indefinite", m_tag.c_str(), m_id.c_str()); return; } clock_value_p parser; std::string::const_iterator b = rdur_str.begin(); std::string::const_iterator e = rdur_str.end(); std::ptrdiff_t d = parser.parse(b, e); if(d == -1) { m_logger->trace("<%s id=\"%s\" repeatDur=\"%s\">: invalid repeatDur attr", m_tag.c_str(), m_id.c_str(), rdur_str.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } m_rdur = parser.m_result; AM_DBG m_logger->debug("%s[%s].repeatDur=%ld", m_tag.c_str(), m_id.c_str(), m_rdur()); }// min ::= Clock-value | "media" void time_attrs::parse_min() { const char *p = m_node->get_attribute("min"); if(!p) return; set_specified(SP_MIN); std::string min_str = trim(p); if(min_str == "media") { m_min.media = true; m_min.value = time_type::unspecified; return; } m_min.media = false; clock_value_p parser; std::string::const_iterator b = min_str.begin(); std::string::const_iterator e = min_str.end(); std::ptrdiff_t d = parser.parse(b, e); if(d == -1) { m_logger->trace("<%s id=\"%s\" min=\"%s\">: invalid min attr", m_tag.c_str(), m_id.c_str(), min_str.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } m_min.value = parser.m_result;}// max ::= Clock-value | "media" | "indefinite" void time_attrs::parse_max() { const char *p = m_node->get_attribute("max"); if(!p) return; set_specified(SP_MAX); std::string max_str = trim(p); if(max_str == "media") { m_max.media = true; m_max.value = time_type::unspecified; return; } else if(max_str == "indefinite") { m_max.media = false; m_max.value = time_type::indefinite; return; } m_max.media = false; clock_value_p parser; std::string::const_iterator b = max_str.begin(); std::string::const_iterator e = max_str.end(); std::ptrdiff_t d = parser.parse(b, e); if(d == -1) { m_logger->trace("<%s id=\"%s\" max=\"%s\">: invalid max attr", m_tag.c_str(), m_id.c_str(), max_str.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } m_max.value = parser.m_result;}void time_attrs::parse_begin() { const char *p = m_node->get_attribute("begin"); if(!p) return; set_specified(SP_BEGIN); std::string sbegin = trim(p); std::list<std::string> strlist; split_trim_list(sbegin, strlist); parse_sync_list(strlist, m_blist);}void time_attrs::parse_end() { const char *p = m_node->get_attribute("end"); if(!p) return; set_specified(SP_END); std::string send = trim(p); std::list<std::string> strlist; split_trim_list(send, strlist); parse_sync_list(strlist, m_elist);}void time_attrs::parse_sync_list( const std::list<std::string>& strlist, sync_list& svslist) { std::list<std::string>::const_iterator it; for(it = strlist.begin(); it!=strlist.end();it++) { char ch = (*it)[0]; sync_value_struct svs; svs.offset = 0; svs.iparam = -1; if(isdigit(ch) || ch == '-' || ch == '+') { parse_plain_offset(*it, svs, svslist); } else if(starts_with((*it), "wallclock")) { parse_wallclock(*it, svs, svslist); } else if(starts_with((*it), "accesskey")) { parse_accesskey(*it, svs, svslist); } else if((*it) == "indefinite") { svs.type = sv_indefinite; svs.offset = time_type::indefinite(); svslist.push_back(svs); } else { parse_nmtoken_offset(*it, svs, svslist); } }}void time_attrs::parse_plain_offset(const std::string& s, sync_value_struct& svs, sync_list& sl) { svs.type = sv_offset; offset_value_p parser; if(!parser.matches(s)) { m_logger->trace("<%s id=\"%s\">.%s invalid offset [%s]", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), s.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } svs.offset = parser.m_result; sl.push_back(svs); AM_DBG m_logger->debug("%s[%s].%s += [%s]", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), repr(svs).c_str());}void time_attrs::parse_wallclock(const std::string& s, sync_value_struct& svs, sync_list& sl) { svs.type = sv_wallclock; m_logger->warn(gettext("Ignoring wallclock in document")); //sl.push_back(svs); }// Accesskey-value ::= "accesskey(" character ")" ( S? ("+"|"-") S? Clock-value )? void time_attrs::parse_accesskey(const std::string& s, sync_value_struct& svs, sync_list& sl) { svs.type = sv_accesskey; size_type open_par_ix = s.find('('); if(open_par_ix == std::string::npos) { m_logger->trace("Invalid accesskey spec [%s] for <%s id=\"%s\">", s.c_str(), m_tag.c_str(), m_id.c_str()); m_logger->warn(gettext("Error in SMIL interaction info in document")); return; } svs.iparam = int(s[open_par_ix+1]); size_type close_par_ix = s.find(')', open_par_ix); if(close_par_ix == std::string::npos) { m_logger->trace("%s[%s].%s invalid accesskey spec [%s]", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), s.c_str()); m_logger->warn(gettext("Error in SMIL interaction info in document")); return; } std::string rest = trim(s.substr(close_par_ix+1)); if(rest.empty()) { sl.push_back(svs); AM_DBG m_logger->debug("%s[%s].%s += [%s] (as int %d)", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), repr(svs).c_str(), svs.iparam); return; } offset_value_p parser; if(!parser.matches(s)) { m_logger->trace("%s[%s].%s invalid accesskey offset [%s]", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), s.c_str()); m_logger->warn(gettext("Error in SMIL interaction info in document")); return; } svs.offset = parser.m_result; sl.push_back(svs); AM_DBG m_logger->debug("%s[%s].%s += [%s] (as int %d)", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), repr(svs).c_str(), svs.iparam);}void time_attrs::parse_nmtoken_offset(const std::string& s, sync_value_struct& svs, sync_list& sl) { std::string::const_iterator b; std::string::const_iterator e; std::ptrdiff_t d; std::string s1 = s; std::string offset_str; size_type last_pm_ix = s.find_last_of("+-"); if(last_pm_ix != std::string::npos) { // Parse offset, limit raw nmtoken offset_str = s.substr(last_pm_ix); offset_value_p parser; if(parser.matches(offset_str)) { svs.offset = parser.m_result; s1 = trim(s.substr(0, last_pm_ix)); } } // s1 holds the nmtoken + optional event specifier // extract nmtokek from s1 xml_nmtoken_p parser; b = s1.begin(); e = s1.end(); d = parser.parse(b, e); if(d == -1) { m_logger->trace("%s[%s].%s invalid attr [%s]", m_tag.c_str(), m_id.c_str(), time_spec_id(sl), s.c_str()); m_logger->warn(gettext("Error in SMIL timing info in document")); return; } std::string nmtoken = parser.m_result;#ifdef CHECK_EVENT_NAMES // Careful re-reading of the SMIL standard by Sjoerd and Jack // seems to indicate that the set of event names is open-ended. // Therefore, don't check the names. // the nmtoken suffix static std::set<std::string> events; if(events.empty()) { events.insert("begin"); events.insert("end"); events.insert("beginEvent"); events.insert("endEvent"); events.insert("repeat"); events.insert("activateEvent"); events.insert("focusInEvent"); events.insert("focusOutEvent"); events.insert("inBoundsEvent"); events.insert("outOfBoundsEvent"); events.insert("click"); events.insert("marker"); }#endif // CHECK_EVENT_NAMES std::string event; size_type last_dot_ix = nmtoken.find_last_of("."); if(last_dot_ix == std::string::npos) { // an event-value with default eventbase-element svs.type = sv_event; svs.base = ""; // default event = nmtoken; // check repeat(d+)? } else if(ends_with(nmtoken, ".begin") || ends_with(nmtoken, ".end")) { // syncbase-value svs.type = sv_syncbase; svs.base = nmtoken.substr(0, last_dot_ix); event = nmtoken.substr(last_dot_ix+1); } else if(ends_with(nmtoken, ".marker")) { // media-marker-value svs.type = sv_media_marker; svs.base = nmtoken.substr(0, last_dot_ix);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -