/[svn]/linuxsampler/trunk/src/network/lscpserver.cpp
ViewVC logotype

Diff of /linuxsampler/trunk/src/network/lscpserver.cpp

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2516 by schoenebeck, Thu Feb 6 21:11:23 2014 UTC revision 3054 by schoenebeck, Thu Dec 15 12:47:45 2016 UTC
# Line 3  Line 3 
3   *   LinuxSampler - modular, streaming capable sampler                     *   *   LinuxSampler - modular, streaming capable sampler                     *
4   *                                                                         *   *                                                                         *
5   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *   *   Copyright (C) 2003, 2004 by Benno Senoner and Christian Schoenebeck   *
6   *   Copyright (C) 2005 - 2014 Christian Schoenebeck                       *   *   Copyright (C) 2005 - 2016 Christian Schoenebeck                       *
7   *                                                                         *   *                                                                         *
8   *   This library is free software; you can redistribute it and/or modify  *   *   This library is free software; you can redistribute it and/or modify  *
9   *   it under the terms of the GNU General Public License as published by  *   *   it under the terms of the GNU General Public License as published by  *
# Line 47  Line 47 
47    
48  namespace LinuxSampler {  namespace LinuxSampler {
49    
50  String lscpParserProcessShellInteraction(String& line, yyparse_param_t* param);  String lscpParserProcessShellInteraction(String& line, yyparse_param_t* param, bool possibilities);
51    
52  /**  /**
53   * Returns a copy of the given string where all special characters are   * Returns a copy of the given string where all special characters are
# Line 111  Mutex LSCPServer::RTNotifyMutex; Line 111  Mutex LSCPServer::RTNotifyMutex;
111    
112  LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4), eventHandler(this) {  LSCPServer::LSCPServer(Sampler* pSampler, long int addr, short int port) : Thread(true, false, 0, -4), eventHandler(this) {
113      SocketAddress.sin_family      = AF_INET;      SocketAddress.sin_family      = AF_INET;
114      SocketAddress.sin_addr.s_addr = addr;      SocketAddress.sin_addr.s_addr = (in_addr_t)addr;
115      SocketAddress.sin_port        = port;      SocketAddress.sin_port        = (in_port_t)port;
116      this->pSampler = pSampler;      this->pSampler = pSampler;
117      LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");      LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_count, "AUDIO_OUTPUT_DEVICE_COUNT");
118      LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");      LSCPEvent::RegisterEvent(LSCPEvent::event_audio_device_info, "AUDIO_OUTPUT_DEVICE_INFO");
# Line 708  extern int GetLSCPCommand( void *buf, in Line 708  extern int GetLSCPCommand( void *buf, in
708    
709          strcpy((char*) buf, command.c_str());          strcpy((char*) buf, command.c_str());
710          LSCPServer::bufferedCommands.erase(LSCPServer::currentSocket);          LSCPServer::bufferedCommands.erase(LSCPServer::currentSocket);
711          return command.size();          return (int) command.size();
712  }  }
713    
714  extern yyparse_param_t* GetCurrentYaccSession() {  extern yyparse_param_t* GetCurrentYaccSession() {
# Line 716  extern yyparse_param_t* GetCurrentYaccSe Line 716  extern yyparse_param_t* GetCurrentYaccSe
716  }  }
717    
718  /**  /**
719     * Generate the relevant LSCP documentation reference section if necessary.
720     * The documentation section for the currently active command on the LSCP
721     * shell's command line will be encoded in a special format, specifically for
722     * the LSCP shell application.
723     *
724     * @param line - current LSCP command line
725     * @param param - reentrant Bison parser parameters
726     *
727     * @return encoded reference string or empty string if nothing shall be sent
728     *         to LSCP shell (client) at this point
729     */
730    String LSCPServer::generateLSCPDocReply(const String& line, yyparse_param_t* param) {
731        String result;
732        lscp_ref_entry_t* ref = lscp_reference_for_command(line.c_str());
733        // Pointer comparison works here, since the function above always
734        // returns the same constant pointer for the respective LSCP
735        // command ... Only send the LSCP reference section to the client if
736        // another LSCP reference section became relevant now:
737        if (ref != param->pLSCPDocRef) {
738            param->pLSCPDocRef = ref;
739            if (ref) { // send a new LSCP doc section to client ...
740                result += "SHD:" + ToString(LSCP_SHD_MATCH) + ":" + String(ref->name) + "\n";
741                result += String(ref->section) + "\n";
742                result += "."; // dot line marks the end of the text for client
743            } else { // inform client that no LSCP doc section matches right now ...
744                result = "SHD:" + ToString(LSCP_SHD_NO_MATCH);
745            }
746        }
747        dmsg(4,("LSCP doc reply -> '%s'\n", result.c_str()));
748        return result;
749    }
750    
751    /**
752   * Will be called to try to read the command from the socket   * Will be called to try to read the command from the socket
753   * If command is read, it will return true. Otherwise false is returned.   * If command is read, it will return true. Otherwise false is returned.
754   * In any case the received portion (complete or incomplete) is saved into bufferedCommand map.   * In any case the received portion (complete or incomplete) is saved into bufferedCommand map.
755   */   */
756  bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {  bool LSCPServer::GetLSCPCommand( std::vector<yyparse_param_t>::iterator iter ) {
757          int socket = (*iter).hSession;          int socket = (*iter).hSession;
758            int result;
759          char c;          char c;
760          int i = 0;          std::vector<char> input;
761    
762            // first get as many character as possible and add it to the 'input' buffer
763          while (true) {          while (true) {
764                  #if defined(WIN32)                  #if defined(WIN32)
765                  int result = recv(socket, (char *)&c, 1, 0); //Read one character at a time for now                  result = (int)recv(socket, (char*)&c, 1, 0); //Read one character at a time for now
766                  #else                  #else
767                  int result = recv(socket, (void *)&c, 1, 0); //Read one character at a time for now                  result = (int)recv(socket, (void*)&c, 1, 0); //Read one character at a time for now
768                  #endif                  #endif
769                  if (result == 0) { //socket was selected, so 0 here means client has closed the connection                  if (result == 1) input.push_back(c);
770                          CloseConnection(iter);                  else break; // end of input or some error
771                          break;                  if (c == '\n') break; // process line by line
772                  }          }
773                  if (result == 1) {  
774                          if (c == '\r')          // process input buffer
775                                  continue; //Ignore CR          for (int i = 0; i < input.size(); ++i) {
776                          if (c == '\n') {                  c = input[i];
777                                  LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));                  if (c == '\r') continue; //Ignore CR
778                                  bufferedCommands[socket] += "\r\n";                  if (c == '\n') {
779                                  return true; //Complete command was read                          // only if the other side is the LSCP shell application:
780                            // check the current (incomplete) command line for syntax errors,
781                            // possible completions and report everything back to the shell
782                            if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
783                                    String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), false);
784                                    if (!s.empty() && (*iter).bShellInteract) AnswerClient(s + "\n");
785                            }
786                            // if other side is LSCP shell application, send the relevant LSCP
787                            // documentation section of the current command line (if necessary)
788                            if ((*iter).bShellSendLSCPDoc && (*iter).bShellInteract) {
789                                    String s = generateLSCPDocReply(bufferedCommands[socket], &(*iter));
790                                    if (!s.empty()) AnswerClient(s + "\n");
791                          }                          }
792                            LSCPServer::SendLSCPNotify(LSCPEvent(LSCPEvent::event_misc, "Received \'" + bufferedCommands[socket] + "\' on socket", socket));
793                            bufferedCommands[socket] += "\r\n";
794                            return true; //Complete command was read
795                    } else if (c == 2) { // custom ASCII code usage for moving cursor left (LSCP shell)
796                            if (iter->iCursorOffset + bufferedCommands[socket].size() > 0)
797                                    iter->iCursorOffset--;
798                    } else if (c == 3) { // custom ASCII code usage for moving cursor right (LSCP shell)
799                            if (iter->iCursorOffset < 0) iter->iCursorOffset++;
800                    } else {
801                            ssize_t cursorPos = bufferedCommands[socket].size() + iter->iCursorOffset;
802                          // backspace character - should only happen with shell                          // backspace character - should only happen with shell
803                          if (c == '\b') {                          if (c == '\b') {
804                                  if (!bufferedCommands[socket].empty()) {                                  if (!bufferedCommands[socket].empty() && cursorPos > 0)
805                                          bufferedCommands[socket] = bufferedCommands[socket].substr(                                          bufferedCommands[socket].erase(cursorPos - 1, 1);
806                                                  0, bufferedCommands[socket].length() - 1                          } else { // append (or insert) new character (at current cursor position) ...
807                                          );                                  if (cursorPos >= 0)
808                                  }                                          bufferedCommands[socket].insert(cursorPos, String(1,c)); // insert
809                          } else bufferedCommands[socket] += c;                                  else
810                          // only if the other side is the LSCP shell application:                                          bufferedCommands[socket] += c; // append
811                            }
812                    }
813                    // Only if the other side (client) is the LSCP shell application:
814                    // The following block takes care about automatic correction, auto
815                    // completion (and suggestions), LSCP reference documentation, etc.
816                    // The "if" statement here is for optimization reasons, so that the
817                    // heavy LSCP grammar evaluation algorithm is only executed once for an
818                    // entire command line received.
819                    if (i == input.size() - 1) {
820                          // check the current (incomplete) command line for syntax errors,                          // check the current (incomplete) command line for syntax errors,
821                          // possible completions and report everything back to the shell                          // possible completions and report everything back to the shell
822                          if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {                          if ((*iter).bShellInteract || (*iter).bShellAutoCorrect) {
823                                  String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter));                                  String s = lscpParserProcessShellInteraction(bufferedCommands[socket], &(*iter), true);
824                                  if (!s.empty() && (*iter).bShellInteract) AnswerClient(s + "\n");                                  if (!s.empty() && (*iter).bShellInteract && i == input.size() - 1)
825                                            AnswerClient(s + "\n");
826                            }
827                            // if other side is LSCP shell application, send the relevant LSCP
828                            // documentation section of the current command line (if necessary)
829                            if ((*iter).bShellSendLSCPDoc && (*iter).bShellInteract) {
830                                    String s = generateLSCPDocReply(bufferedCommands[socket], &(*iter));
831                                    if (!s.empty()) AnswerClient(s + "\n");
832                          }                          }
833                  }                  }
834                  #if defined(WIN32)          }
835                  if (result == SOCKET_ERROR) {  
836                      int wsa_lasterror = WSAGetLastError();          // handle network errors ...
837                          if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.          if (result == 0) { //socket was selected, so 0 here means client has closed the connection
838                    CloseConnection(iter);
839                    return false;
840            }
841            #if defined(WIN32)
842            if (result == SOCKET_ERROR) {
843                    int wsa_lasterror = WSAGetLastError();
844                    if (wsa_lasterror == WSAEWOULDBLOCK) //Would block, try again later.
845                            return false;
846                    dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));
847                    CloseConnection(iter);
848                    return false;
849            }
850            #else
851            if (result == -1) {
852                    if (errno == EAGAIN) //Would block, try again later.
853                            return false;
854                    switch(errno) {
855                            case EBADF:
856                                    dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));
857                                  return false;                                  return false;
858                          dmsg(2,("LSCPScanner: Socket error after recv() Error %d.\n", wsa_lasterror));                          case ECONNREFUSED:
859                          CloseConnection(iter);                                  dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));
860                          break;                                  return false;
861                  }                          case ENOTCONN:
862                  #else                                  dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));
863                  if (result == -1) {                                  return false;
864                          if (errno == EAGAIN) //Would block, try again later.                          case ENOTSOCK:
865                                    dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));
866                                    return false;
867                            case EAGAIN:
868                                    dmsg(2,("LSCPScanner: The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.\n"));
869                                    return false;
870                            case EINTR:
871                                    dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));
872                                    return false;
873                            case EFAULT:
874                                    dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));
875                                    return false;
876                            case EINVAL:
877                                    dmsg(2,("LSCPScanner: Invalid argument passed.\n"));
878                                    return false;
879                            case ENOMEM:
880                                    dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));
881                                    return false;
882                            default:
883                                    dmsg(2,("LSCPScanner: Unknown recv() error.\n"));
884                                  return false;                                  return false;
                         switch(errno) {  
                                 case EBADF:  
                                         dmsg(2,("LSCPScanner: The argument s is an invalid descriptor.\n"));  
                                         break;  
                                 case ECONNREFUSED:  
                                         dmsg(2,("LSCPScanner: A remote host refused to allow the network connection (typically because it is not running the requested service).\n"));  
                                         break;  
                                 case ENOTCONN:  
                                         dmsg(2,("LSCPScanner: The socket is associated with a connection-oriented protocol and has not been connected (see connect(2) and accept(2)).\n"));  
                                         break;  
                                 case ENOTSOCK:  
                                         dmsg(2,("LSCPScanner: The argument s does not refer to a socket.\n"));  
                                         break;  
                                 case EAGAIN:  
                                         dmsg(2,("LSCPScanner: The socket is marked non-blocking and the receive operation would block, or a receive timeout had been set and the timeout expired before data was received.\n"));  
                                         break;  
                                 case EINTR:  
                                         dmsg(2,("LSCPScanner: The receive was interrupted by delivery of a signal before any data were available.\n"));  
                                         break;  
                                 case EFAULT:  
                                         dmsg(2,("LSCPScanner: The receive buffer pointer(s) point outside the process's address space.\n"));  
                                         break;  
                                 case EINVAL:  
                                         dmsg(2,("LSCPScanner: Invalid argument passed.\n"));  
                                         break;  
                                 case ENOMEM:  
                                         dmsg(2,("LSCPScanner: Could not allocate memory for recvmsg.\n"));  
                                         break;  
                                 default:  
                                         dmsg(2,("LSCPScanner: Unknown recv() error.\n"));  
                                         break;  
                         }  
                         CloseConnection(iter);  
                         break;  
885                  }                  }
886                  #endif                  CloseConnection(iter);
887                    return false;
888          }          }
889            #endif
890    
891          return false;          return false;
892  }  }
893    
# Line 1066  String LSCPServer::GetAvailableEngines() Line 1146  String LSCPServer::GetAvailableEngines()
1146      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));      dmsg(2,("LSCPServer: GetAvailableEngines()\n"));
1147      LSCPResultSet result;      LSCPResultSet result;
1148      try {      try {
1149          int n = EngineFactory::AvailableEngineTypes().size();          int n = (int)EngineFactory::AvailableEngineTypes().size();
1150          result.Add(n);          result.Add(n);
1151      }      }
1152      catch (Exception e) {      catch (Exception e) {
# Line 1270  String LSCPServer::GetAvailableAudioOutp Line 1350  String LSCPServer::GetAvailableAudioOutp
1350      dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));      dmsg(2,("LSCPServer: GetAvailableAudioOutputDrivers()\n"));
1351      LSCPResultSet result;      LSCPResultSet result;
1352      try {      try {
1353          int n = AudioOutputDeviceFactory::AvailableDrivers().size();          int n = (int) AudioOutputDeviceFactory::AvailableDrivers().size();
1354          result.Add(n);          result.Add(n);
1355      }      }
1356      catch (Exception e) {      catch (Exception e) {
# Line 1296  String LSCPServer::GetAvailableMidiInput Line 1376  String LSCPServer::GetAvailableMidiInput
1376      dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));      dmsg(2,("LSCPServer: GetAvailableMidiInputDrivers()\n"));
1377      LSCPResultSet result;      LSCPResultSet result;
1378      try {      try {
1379          int n = MidiInputDeviceFactory::AvailableDrivers().size();          int n = (int)MidiInputDeviceFactory::AvailableDrivers().size();
1380          result.Add(n);          result.Add(n);
1381      }      }
1382      catch (Exception e) {      catch (Exception e) {
# Line 1369  String LSCPServer::GetAudioOutputDriverI Line 1449  String LSCPServer::GetAudioOutputDriverI
1449  }  }
1450    
1451  String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {  String LSCPServer::GetMidiInputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
1452      dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));      dmsg(2,("LSCPServer: GetMidiInputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),int(DependencyList.size())));
1453      LSCPResultSet result;      LSCPResultSet result;
1454      try {      try {
1455          DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);          DeviceCreationParameter* pParameter = MidiInputDeviceFactory::GetDriverParameter(Driver, Parameter);
# Line 1397  String LSCPServer::GetMidiInputDriverPar Line 1477  String LSCPServer::GetMidiInputDriverPar
1477  }  }
1478    
1479  String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {  String LSCPServer::GetAudioOutputDriverParameterInfo(String Driver, String Parameter, std::map<String,String> DependencyList) {
1480      dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),DependencyList.size()));      dmsg(2,("LSCPServer: GetAudioOutputDriverParameterInfo(Driver=%s,Parameter=%s,DependencyListSize=%d)\n",Driver.c_str(),Parameter.c_str(),int(DependencyList.size())));
1481      LSCPResultSet result;      LSCPResultSet result;
1482      try {      try {
1483          DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);          DeviceCreationParameter* pParameter = AudioOutputDeviceFactory::GetDriverParameter(Driver, Parameter);
# Line 1554  String LSCPServer::GetMidiInputPortInfo( Line 1634  String LSCPServer::GetMidiInputPortInfo(
1634  }  }
1635    
1636  String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {  String LSCPServer::GetAudioOutputChannelInfo(uint DeviceId, uint ChannelId) {
1637      dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%d,ChannelId)\n",DeviceId,ChannelId));      dmsg(2,("LSCPServer: GetAudioOutputChannelInfo(DeviceId=%u,ChannelId=%u)\n",DeviceId,ChannelId));
1638      LSCPResultSet result;      LSCPResultSet result;
1639      try {      try {
1640          // get audio output device          // get audio output device
# Line 2354  String LSCPServer::GetMidiInstrumentMaps Line 2434  String LSCPServer::GetMidiInstrumentMaps
2434      dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));      dmsg(2,("LSCPServer: GetMidiInstrumentMaps()\n"));
2435      LSCPResultSet result;      LSCPResultSet result;
2436      try {      try {
2437          result.Add(MidiInstrumentMapper::Maps().size());          result.Add(int(MidiInstrumentMapper::Maps().size()));
2438      } catch (Exception e) {      } catch (Exception e) {
2439          result.Error(e);          result.Error(e);
2440      }      }
# Line 3073  String LSCPServer::EditSamplerChannelIns Line 3153  String LSCPServer::EditSamplerChannelIns
3153          InstrumentManager::instrument_id_t instrumentID;          InstrumentManager::instrument_id_t instrumentID;
3154          instrumentID.FileName = pEngineChannel->InstrumentFileName();          instrumentID.FileName = pEngineChannel->InstrumentFileName();
3155          instrumentID.Index    = pEngineChannel->InstrumentIndex();          instrumentID.Index    = pEngineChannel->InstrumentIndex();
3156          pInstrumentManager->LaunchInstrumentEditor(instrumentID);          pInstrumentManager->LaunchInstrumentEditor(pEngineChannel, instrumentID);
3157      } catch (Exception e) {      } catch (Exception e) {
3158          result.Error(e);          result.Error(e);
3159      }      }
# Line 3195  String LSCPServer::GetTotalVoiceCount() Line 3275  String LSCPServer::GetTotalVoiceCount()
3275  String LSCPServer::GetTotalVoiceCountMax() {  String LSCPServer::GetTotalVoiceCountMax() {
3276      dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));      dmsg(2,("LSCPServer: GetTotalVoiceCountMax()\n"));
3277      LSCPResultSet result;      LSCPResultSet result;
3278      result.Add(EngineFactory::EngineInstances().size() * pSampler->GetGlobalMaxVoices());      result.Add(int(EngineFactory::EngineInstances().size() * pSampler->GetGlobalMaxVoices()));
3279      return result.Produce();      return result.Produce();
3280  }  }
3281    
# Line 3297  String LSCPServer::GetFileInstruments(St Line 3377  String LSCPServer::GetFileInstruments(St
3377                  std::vector<InstrumentManager::instrument_id_t> IDs =                  std::vector<InstrumentManager::instrument_id_t> IDs =
3378                      pManager->GetInstrumentFileContent(Filename);                      pManager->GetInstrumentFileContent(Filename);
3379                  // return the amount of instruments in the file                  // return the amount of instruments in the file
3380                  result.Add(IDs.size());                  result.Add((int)IDs.size());
3381                  // no more need to ask other engine types                  // no more need to ask other engine types
3382                  bFound = true;                  bFound = true;
3383              } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));              } else dmsg(1,("Warning: engine '%s' does not provide an instrument manager\n", engineTypes[i].c_str()));
# Line 4019  String LSCPServer::SetShellAutoCorrect(y Line 4099  String LSCPServer::SetShellAutoCorrect(y
4099          else throw Exception("Not a boolean value, must either be 0 or 1");          else throw Exception("Not a boolean value, must either be 0 or 1");
4100      } catch (Exception e) {      } catch (Exception e) {
4101          result.Error(e);          result.Error(e);
4102        }
4103        return result.Produce();
4104    }
4105    
4106    String LSCPServer::SetShellDoc(yyparse_param_t* pSession, double boolean_value) {
4107        dmsg(2,("LSCPServer: SetShellDoc(val=%f)\n", boolean_value));
4108        LSCPResultSet result;
4109        try {
4110            if      (boolean_value == 0) pSession->bShellSendLSCPDoc = false;
4111            else if (boolean_value == 1) pSession->bShellSendLSCPDoc = true;
4112            else throw Exception("Not a boolean value, must either be 0 or 1");
4113        } catch (Exception e) {
4114            result.Error(e);
4115      }      }
4116      return result.Produce();      return result.Produce();
4117  }  }

Legend:
Removed from v.2516  
changed lines
  Added in v.3054

  ViewVC Help
Powered by ViewVC