⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 promptmanager.cpp

📁 sloedgy open sip stack source code
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 
   // (3) audio
   case NODE_AUDIO:
   {
     // (3.1) Process the 'expr' if provided.  NOTE: Exactly one of 'src' and 
     //       'expr' MUST be specified.
 
     vxistring expr;
 
     if (elem.GetAttribute(ATTRIBUTE_EXPR, expr)) {
       // (3.1.1) Handle the expr case.
       VXIValue * value = translator.EvaluateExpression(expr);
       if (value == NULL) return;  // Ignore this element
   
       // (3.1.2) Handle audio content from <record> elements.
       if (VXIValueGetType(value) == VALUE_CONTENT) {
         AddContent(props, sofar, value);
         return;
       }
 
       // (3.1.3) Otherwise, try to convert the type into a string.
       bool conversionFailed = !ConvertValueToString(value, expr);
       VXIValueDestroy(&value);
   
       if (conversionFailed) {
         log->LogDiagnostic(0, L"PromptManager::ProcessSegments - "
                            L"audio src evaluation failed");
         throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC,
                                              L"audio src evaluation failed");
       }
 
       if (expr.empty()) return;  // Ignore this element
     }
 
     // (3.2) Add an <audio> element to the current request.
     sofar += L"<audio";
 
     AddSSMLAttribute(elem, ATTRIBUTE_SRC, expr.c_str(), L"src", sofar);
 
     AddSSMLAttribute(elem, ATTRIBUTE_FETCHTIMEOUT,
                      propertyList.GetProperty(L"fetchtimeout"),
                      L"fetchtimeout", sofar);
 
     AddSSMLAttribute(elem, ATTRIBUTE_FETCHHINT,
                      propertyList.GetProperty(L"audiofetchhint"),
                      L"fetchhint", sofar);
 
     AddSSMLAttribute(elem, ATTRIBUTE_MAXAGE,
                      propertyList.GetProperty(L"audiomaxage"),
                      L"maxage", sofar);
 
     AddSSMLAttribute(elem, ATTRIBUTE_MAXSTALE,
                      propertyList.GetProperty(L"audiomaxstale"),
                      L"maxstale", sofar);
 
     // Add in the alternate text (if any).
     if (elem.hasChildren()) {
       sofar += L">";
       for (VXMLNodeIterator it(elem); it; ++it)
         ProcessSegments(*it, item, propertyList, translator,
                         bargein, props, sofar);
       sofar += L"</audio>";
     }
     else
       sofar += L"/>";
 
     return;
   }
 
   // (4) <value>
   case NODE_VALUE:
   {
     // (4.1) Evaluate the expression.  Can we handle this type?
     vxistring expr;
     if (!elem.GetAttribute(ATTRIBUTE_EXPR, expr) || expr.empty()) return;
     VXIValue * value = translator.EvaluateExpression(expr);
     if (value == NULL) return;
 
     // (4.2) Convert to a string a play as TTS.
     bool conversionFailed = !ConvertValueToString(value, expr);
     VXIValueDestroy(&value);
 
     if (conversionFailed) {
       log->LogDiagnostic(0, L"PromptManager::ProcessSegments - "
                          L"value expr was not a simple type");
       throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC,
                                            L"value expr gave invalid type");
     }
 
     if (expr.empty()) return;
     AppendTextSegment(sofar, expr);
     return;
   }
   break;
 
   // (5) <enumerate>
   case NODE_ENUMERATE:
   {
     // (5.1) Is enumerate valid in this location?
     if (item == 0)
       throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC, L"invalid use "
                                            L"of enumerate element");
 
     bool foundMatch = false;
 
     for (VXMLNodeIterator it(item); it; ++it) {
       // (5.2) Ignore anything which isn't an <option> or <choice> grammar.
       if ((*it).GetType() != VXMLNode::Type_VXMLElement) continue;
       const VXMLNode & tmp = *it;
       const VXMLElement & itemElem = reinterpret_cast<const VXMLElement&>(tmp);
       switch (itemElem.GetName()) {
       case NODE_CHOICE:
       case NODE_OPTION:
         foundMatch = true;
         break;
       default:
         continue;
       }
 
       // (5.3) Convert item into text.
       vxistring promptText;
       for (VXMLNodeIterator choiceNode(itemElem); choiceNode; ++choiceNode) {
         if ((*choiceNode).GetType() == VXMLNode::Type_VXMLContent) {
 
           if (!promptText.empty()) promptText += SPACE;
           const VXMLNode temp = *choiceNode;
   
           promptText += reinterpret_cast<const VXMLContent &>(temp).GetValue();
           /*
           // Get text from this node.
           vxistring text = reinterpret_cast<const VXMLContent &>
                              (*choiceNode).GetValue();
 
           if (!promptText.empty()) promptText += SPACE;
 
           // Strip the leading whitespace.
           while (text.length() > 0) {
             VXIchar c = text[0];
             if (c == ' ' || c == '\r' || c == '\n' || c == '\t')
               text.erase(0, 1);
             else {
               promptText += text;
               break;
             }
           }
 
           // Strip off any trailing whitespace
           while (promptText.length() > 0) {
             unsigned int len = promptText.length();
             VXIchar c = promptText[len - 1];
             if (c == ' ' || c == '\r' || c == '\n' || c == '\t')
               promptText.erase(len - 1, 1);
             else break;
           }
           */
         }
       }
 
       // (5.4) Handle the simple case where enumerate does not specify a
       // format string.
       if (!elem.hasChildren()) {
         AppendTextSegment(sofar, promptText);
         sofar += L"<break time='small'/>";
       }
       else {
         // (5.5) Get the associated dtmf value.
         vxistring dtmfText;
         itemElem.GetAttribute(ATTRIBUTE_DTMF, dtmfText);
 
         translator.SetVariable(L"_prompt", promptText);
         translator.SetVariable(L"_dtmf",   dtmfText);
 
         for (VXMLNodeIterator subNode(elem); subNode; ++subNode)
           ProcessSegments(*subNode, item, propertyList, translator,
                           bargein, props, sofar);
       }
     }
 
     // (5.6) Final check - was there an <option> or <choice>?
     if (!foundMatch)
       throw VXIException::InterpreterEvent(EV_ERROR_SEMANTIC, L"invalid use "
                                            L"of enumerate element");
     break;
   }
   default:
     log->LogError(999, SimpleLogger::MESSAGE,
                   L"logic error PromptManager::ProcessSegments");
     throw VXIException::Fatal();
   }
 }
 
 void PromptManager::AddContent(VXIMapHolder & props,
                                vxistring & sofar,
                                VXIValue * value)
 {
   VXIMapHolder allRefs(NULL);
 
   // (1) Get existing map (if it exists) or create a new one.
   const VXIValue * temp = VXIMapGetProperty(props.GetValue(),
                                             PROMPT_AUDIO_REFS);
   if (temp != NULL && VXIValueGetType(temp) == VALUE_MAP)
     allRefs.Acquire(VXIMapClone(reinterpret_cast<const VXIMap *>(temp)));
   else
     allRefs.Acquire(VXIMapCreate());
   if (allRefs.GetValue() == NULL) throw VXIException::OutOfMemory();
 
   // (2) Generate a hidden name.
   vxistring hiddenName;
   VXMLDocumentModel::CreateHiddenVariable(hiddenName);
   hiddenName.erase(0, 1);
   hiddenName = vxistring(PROMPT_AUDIO_REFS_SCHEME) + hiddenName;
 
   // (3) Place hidden name and content into the map.
   VXIMapSetProperty(allRefs.GetValue(), hiddenName.c_str(), value);
 
   // (4) Replace the references map with the updated one.
   VXIMapSetProperty(props.GetValue(), PROMPT_AUDIO_REFS,
                     reinterpret_cast<VXIValue *>(allRefs.Release()));
   
   // (5) Handle the SSML case
   sofar += L"<mark name=\"";
   sofar += hiddenName;
   sofar += L"\"/>";
 }
 
 bool PromptManager::ProcessPrefetchPrompts(const VXMLNode & node, const VXMLElement& item,
                       const PropertyList & propertyList, 
                       PromptTranslator & translator, 
                       vxistring & sofar)
 {
   bool rc = false;
    
   switch (node.GetType()) {
     case VXMLNode::Type_VXMLContent:
     {
       const VXMLContent & content = reinterpret_cast<const VXMLContent &>(node);
       sofar += content.GetValue();
       return true;
     }
     case VXMLNode::Type_VXMLElement:
       break;
     default:
       return false;
   }
         
   // Look at other type
   const VXMLElement & elem = reinterpret_cast<const VXMLElement &>(node);
 
   switch (elem.GetName()) 
   {
     // audio
     case NODE_AUDIO:
     {
       // ignore this entire prompt if expr is found
       vxistring expr;
       if (elem.GetAttribute(ATTRIBUTE_EXPR, expr) == true)
         return false;
       else {
         rc = true;
         sofar += L"<audio";
         AddSSMLAttribute(elem, ATTRIBUTE_SRC, expr.c_str(), L"src", sofar);
         
         AddSSMLAttribute(elem, ATTRIBUTE_FETCHTIMEOUT,
                      propertyList.GetProperty(L"fetchtimeout"),
                      L"fetchtimeout", sofar);
 
         AddSSMLAttribute(elem, ATTRIBUTE_FETCHHINT,
                      propertyList.GetProperty(L"audiofetchhint"),
                      L"fetchhint", sofar);
 
         AddSSMLAttribute(elem, ATTRIBUTE_MAXAGE,
                      propertyList.GetProperty(L"audiomaxage"),
                      L"maxage", sofar);
 
         AddSSMLAttribute(elem, ATTRIBUTE_MAXSTALE,
                      propertyList.GetProperty(L"audiomaxstale"),
                      L"maxstale", sofar);
                          
         // Add in the alternate text (if any).
         if (elem.hasChildren()) {
           sofar += L">";
           for (VXMLNodeIterator it(elem); rc && it; ++it)
             rc = ProcessPrefetchPrompts(*it, item, propertyList, translator, sofar);         
           sofar += L"</audio>";
         }
         else
           sofar += L"/>";      
         
         if( rc ) sofar += L"</speak>";
       }
     
     } break;    
     
     // value tag and other tags found inside a prompt, do not fetch this entire prompt
     // case NODE_VALUE: case NODE_ENUMERATE:
     default:
       return false;
   }
   return rc;
 }
 
 void PromptManager::PreloadPrompts(const VXMLElement& doc,
                                    PropertyList & properties, 
                                    PromptTranslator & translator)
 {
   VXIMapHolder temp(NULL);
   DoPreloadPrompts(doc, properties, temp, translator);
 }
 
 void PromptManager::DoPreloadPrompts(const VXMLElement& doc,
                                      PropertyList & properties,
                                      VXIMapHolder & levelProperties,
                                      PromptTranslator & translator)
 {
   // (1) Look for prompts in current nodes.
 
   for (VXMLNodeIterator it(doc); it; ++it) {
     VXMLNode child = *it;
     if (child.GetType() != VXMLNode::Type_VXMLElement) continue;
     const VXMLElement & element = reinterpret_cast<const VXMLElement &>(child);
     VXMLElementType elementName = element.GetName();
 
     // (2) Handle anything which is not a prompt.
 
     if (elementName != NODE_PROMPT) { 
       bool doPop = properties.PushProperties(element);
 
       if (doPop) {
         VXIMapHolder temp(NULL);
         DoPreloadPrompts(element, properties, temp, translator);
       }
       else
         DoPreloadPrompts(element, properties, levelProperties, translator);
 
       if (doPop) properties.PopProperties();
 
       continue;
     }
 
     // (3) Handle <prompt>.  
 
     // (3.1) Ignore anything other than simple content.
 
     if (!element.hasChildren()) continue;
 
     // (3.2) Find the fetchhint setting.
     if (levelProperties.GetValue() == NULL) {
       levelProperties.Acquire(VXIMapCreate());
       properties.GetProperties(levelProperties);
     }
 
     vxistring attr = L"";
     if (element.GetAttribute(ATTRIBUTE_FETCHHINT, attr) != true) {
       const VXIValue * v = VXIMapGetProperty(levelProperties.GetValue(),
                                              L"audiofetchhint");
       if (VXIValueGetType(v) == VALUE_STRING)
         attr = VXIStringCStr(reinterpret_cast<const VXIString *>(v));
     }
 
     // (3.3) Get the level properties if necessary & add the prefetch setting.
     if (attr == L"prefetch")
       AddParamValue(levelProperties, PROMPT_PREFETCH_REQUEST, 1);
     else
       AddParamValue(levelProperties, PROMPT_PREFETCH_REQUEST, 0);
 
     // (3.4) Create full ssml document
     vxistring ssmldoc;    
     bool shouldPrefetch = true;
     
     for (VXMLNodeIterator it2(element); shouldPrefetch && it2; ++it2)
        shouldPrefetch = ProcessPrefetchPrompts(*it2, element, properties, translator, ssmldoc);     
 
      // (3.5) Call prefetch for prompt.
     if( shouldPrefetch ) {
       prompt->Prefetch(prompt, VXI_MIME_SSML, NULL,
                      ssmldoc.c_str(),
                      levelProperties.GetValue());
     }
     
     // (3.6) We might undo the addition of PROMPT_PREFETCH_REQUEST, but this
     //       parameter is always set and will be overwritten on the next pass.
   }
 }
 
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -