Example #1
0
void  GlobalsClass::checkSerialMsg()
{

	String msgStr = qCon.readStringUntil('\n');
	DebugPrintln("received :" + msgStr);		

	if ((getValue(msgStr, 0) == "$HMSU")) //msg is good updatemsg
	{
		if (validatechksum(msgStr) == false) return;
		hmSetPoint = getValue(msgStr, 1); if (hmSetPoint == "U") hmSetPoint = "0";
		hmPitTemp = getValue(msgStr, 2);  if (hmPitTemp == "U") hmPitTemp = "0";
		hmFood1 = getValue(msgStr, 3);   // if (hmFood1 == "U") hmFood1 = "0";
		hmFood2 = getValue(msgStr, 4);   // if (hmFood2 == "U") hmFood2 = "0";
		hmAmbient = getValue(msgStr, 5); // if (hmAmbient == "U") hmAmbient = "0";
		hmFan = getValue(msgStr, 6);     // if (hmFan == "U") hmFan = "0";
		hmFanMovAvg = getValue(msgStr, 7); //if (hmFanMovAvg == "U") hmFanMovAvg = "0";
		hmLidOpenCountdown = getValue(msgStr, 8);//	if (hmLidOpenCountdown == "U") hmLidOpenCountdown = "0";
	}
	else if ((getValue(msgStr, 0) == "$HMAL")) //Alarm is firing....
	{
		if (validatechksum(msgStr) == false) return;
		String AlarmInfo;
		bool HasAlarm;

		AlarmInfo = "Pit Alarm! : ";
		HasAlarm = false;
		int msgpos = 1;
		for (int i = 0; i < 4; i++) {
			String AlarmLo;
			String AlarmHi;
			AlarmLo = getValue(msgStr, msgpos);
			if (AlarmLo.charAt(AlarmLo.length() - 1) == 'L')
			{
				AlarmLo.remove(AlarmLo.length() - 1, 1);
				AlarmInfo += "Probe " + String(i + 1) + " Low:  " + AlarmLo + " ! ";
				HasAlarm = true;
			}
			msgpos += 1;
			AlarmHi = getValue(msgStr, msgpos);
			if (AlarmHi.charAt(AlarmHi.length() - 1) == 'H')
			{
				AlarmHi.remove(AlarmHi.length() - 1, 1);
				AlarmInfo += "Probe " + String(i + 1) + " Hi:  " + AlarmHi + " ! ";
				HasAlarm = true;
			}
			msgpos += 1;
		}  //for each probe, check alarms
		//reset alarms
		if (ResetTimeCheck > 0) { HasAlarm = false; }  //if we're already in alarm countdown, ignore alarm....
		if (HasAlarm)	{
			if (ResetAlarmSeconds > 0) { ResetTimeCheck = millis(); }
			else { ResetTimeCheck = 0; }   //reset alarm in x Seconds.
		MQTTLink.SendAlarm(AlarmInfo);
		ThingSpeak.SendAlarm(AlarmInfo);		
		}		
	}

	
}
Example #2
0
/**
 * phasing the url for all needed informations
 * @param url String
 * @param httpsFingerprint String
 */
void HTTPClient::begin(String url, String httpsFingerprint) {

    DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str());

    _httpsFingerprint = httpsFingerprint;
    _returnCode = 0;
    _size = -1;

    _Headers = "";

    String protocol;
    // check for : (http: or https:
    int index = url.indexOf(':');
    int index2;
    bool hasPort = false;
    if(index) {
        protocol = url.substring(0, index);
        url.remove(0, (index + 3)); // remove http:// or https://

        index = url.indexOf(':');
        index2 = url.indexOf('/');

        if(index >= 0 && ((index2 >= 0 && index < index2) || index2 == 0)) { // do we have a port?
            _host = url.substring(0, index); // hostname
            url.remove(0, (index + 1)); // remove hostname + :

            index = url.indexOf('/');
            _port = url.substring(0, index).toInt(); // get port
            url.remove(0, index); // remove port
            hasPort = true;
        } else {
            index = index2;
            _host = url.substring(0, index);
            url.remove(0, index); // remove hostname
        }

        _url = url;

        if(protocol.equalsIgnoreCase("http")) {
            _https = false;
            if(!hasPort) {
                _port = 80;
            }
        } else if(protocol.equalsIgnoreCase("https")) {
            _https = true;
            if(!hasPort) {
                _port = 443;
            }
        } else {
            DEBUG_HTTPCLIENT("[HTTP-Client][begin] protocol: %s unknown?!\n", protocol.c_str());
            return;
        }
    }

    DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s https: %d httpsFingerprint: %s\n", _host.c_str(), _port, _url.c_str(), _https, _httpsFingerprint.c_str());

}
bool NerveTool::extract_fibers( FILE *sout , StringList& fibersinfo , String& s ) {
	// format: 
	// <type>:<item>[,item...] -> <item>[,item...] ... -> <item>[,item...]; <type>:...

	String type;
	s.trim();
	while( !s.isEmpty() ) {
		int idx = s.find( ":" );
		if( idx < 0 )
			return( false );

		// parse type and its value
		type = s.getMid( 0 , idx );

		int l_typeid = 0;
		if( type.equals( "GSE" ) )
			l_typeid = 1;
		else if( type.equals( "GSA" ) )
			l_typeid = 2;
		else if( type.equals( "GVE" ) )
			l_typeid = 3;
		else if( type.equals( "GVA" ) )
			l_typeid = 4;
		else if( type.equals( "SSA" ) )
			l_typeid = 5;
		else if( type.equals( "SVA" ) )
			l_typeid = 6;
		else if( type.equals( "SVE" ) )
			l_typeid = 7;
		else
			return( false );

		s.remove( 0 , idx + 1 );
		s.trim();

		String value;
		idx = s.find( ";" );
		if( idx < 0 ) {
			value = s;
			s.clear();
		}
		else {
			value = s.getMid( 0 , idx );
			s.remove( 0 , idx + 1 );
			s.trim();
			value.trim();
		}

		if( !extract_fiberitems( sout , fibersinfo , type , value ) ) {
			fprintf( sout , "wrong fibers typeinfo=%s\n" , ( const char * )value );
			return( false );
		}
	}

	return( true );
}
const String getEventPayload(const String msg) {
	String result = msg.substring(msg.indexOf("\"",4)+2,msg.length()-1);
	if(result.startsWith("\"")) {
		result.remove(0,1);
	}
	if(result.endsWith("\"")) {
		result.remove(result.length()-1);
	}
	return result;
}
Example #5
0
String TextDecoder::decode(const char* start,
                           size_t length,
                           const TextDecodeOptions& options,
                           ExceptionState& exceptionState) {
    WTF::FlushBehavior flush = options.stream() ? WTF::DoNotFlush : WTF::DataEOF;

    bool sawError = false;
    String s = m_codec->decode(start, length, flush, m_fatal, sawError);

    if (m_fatal && sawError) {
        exceptionState.throwTypeError("The encoded data was not valid.");
        return String();
    }

    if (!m_ignoreBOM && !m_bomSeen && !s.isEmpty()) {
        m_bomSeen = true;
        String name(m_encoding.name());
        if ((name == "UTF-8" || name == "UTF-16LE" || name == "UTF-16BE") &&
                s[0] == 0xFEFF)
            s.remove(0);
    }

    if (flush)
        m_bomSeen = false;

    return s;
}
Example #6
0
static void removeMarkupPrefix(String& markup)
{
    // The markup prefix is not harmful, but we remove it from the string anyway, so that
    // we can have consistent results with other ports during the layout tests.
    if (markup.startsWith(gMarkupPrefix))
        markup.remove(0, gMarkupPrefix.length());
}
Example #7
0
TparameterResult ApplicationMQTTClient::dissectParameter(String Parameter){

	TparameterResult par;
	par.count = 0;
    for (int i = 0; i < 11; i++) {
    	par.item[i] = "";
    }

    String str = Parameter;

    int index = -1;
    int i = 0;

    do{
     index = str.indexOf(",");
     if (index != -1){
    	 par.item[i] = str.substring(0, index);
         //Serial.println("Parameter[" + String(i) + "] = " + par.item[i]);
         str.remove(0, index +1);
         i++;
         if (str.indexOf(",") == -1 and str.length() > 0){    //best of the rest
        	 index = -1;
        	 par.item[i] = str;
        	 //Serial.println("Parameter[" + String(i) + "] = " + par.item[i]);
        	 i++;
         }
  	  }else{
  	  }
    } while (index != -1);

    par.count = i;
    return par;

}
Example #8
0
/*
Open connection dialog with TreeItem data to CREATE a brand-new connection.
*/
void ConnectionsDock::_open_connection_dialog(TreeItem &item) {

	String signal = item.get_metadata(0).operator Dictionary()["name"];
	String signalname = signal;
	String midname = selectedNode->get_name();
	for (int i = 0; i < midname.length(); i++) { //TODO: Regex filter may be cleaner.
		CharType c = midname[i];
		if (!((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_')) {
			if (c == ' ') {
				//Replace spaces with underlines.
				c = '_';
			} else {
				//Remove any other characters.
				midname.remove(i);
				i--;
				continue;
			}
		}
		midname[i] = c;
	}

	Node *dst_node = selectedNode->get_owner() ? selectedNode->get_owner() : selectedNode;
	StringName dst_method = "_on_" + midname + "_" + signal;

	Connection c;
	c.source = selectedNode;
	c.signal = StringName(signalname);
	c.target = dst_node;
	c.method = dst_method;

	connect_dialog->init(c);
	connect_dialog->set_title(TTR("Connect Signal: ") + signalname);
	connect_dialog->popup_centered_ratio();
}
Example #9
0
String CIMScope::toString () const
{
    String tmp;

    if (this->hasScope (CIMScope::CLASS))
	tmp.append("CLASS ");

    if (this->hasScope (CIMScope::ASSOCIATION))
	tmp.append("ASSOCIATION ");

    if (this->hasScope (CIMScope::INDICATION))
	tmp.append("INDICATION ");

    if (this->hasScope (CIMScope::PROPERTY))
	tmp.append("PROPERTY ");

    if (this->hasScope (CIMScope::REFERENCE))
	tmp.append("REFERENCE ");

    if (this->hasScope (CIMScope::METHOD))
	tmp.append("METHOD ");

    if (this->hasScope (CIMScope::PARAMETER))
	tmp.append("PARAMETER ");

    if (tmp.size())
	tmp.remove(tmp.size() - 1);

    return tmp;
}
void Interpreter::parse(String line)
{
  //_stream->println(line);
  int space = line.indexOf(" ");
  String command;
  if(space != 0){
    command = line.substring(0, space);
  } else {
    command = line;
  }

  // remove command from line
  line.remove(0, command.length());
  line.trim();
  
  // extract arguments
  const char *args = line.c_str();
  _argc = 0;
  int start = 0;
  space = 0;
  while( (start < line.length()) && _argc < MAX_ARG_COUNT ){
    space = line.indexOf(" ", space);
    _argv[_argc] = &args[start];
    _argc++;
    if(space != -1){ // more arguments later
      ((char *)args)[space] = '\0'; // add null terminator here
      start = space = space+1;
    } else { // we've reached the end
      break;
    }
  }

  this->execute(command, _argv, _argc);
}
static bool verifyCustomHandlerURL(const KURL& baseURL, const String& url, ExceptionState& exceptionState)
{
    // The specification requires that it is a SyntaxError if the "%s" token is
    // not present.
    static const char token[] = "%s";
    int index = url.find(token);
    if (-1 == index) {
        exceptionState.throwDOMException(SyntaxError, "The url provided ('" + url + "') does not contain '%s'.");
        return false;
    }

    // It is also a SyntaxError if the custom handler URL, as created by removing
    // the "%s" token and prepending the base url, does not resolve.
    String newURL = url;
    newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);

    KURL kurl(baseURL, newURL);

    if (kurl.isEmpty() || !kurl.isValid()) {
        exceptionState.throwDOMException(SyntaxError, "The custom handler URL created by removing '%s' and prepending '" + baseURL.string() + "' is invalid.");
        return false;
    }

    return true;
}
Example #12
0
String CIMFlavor::toString () const
{
    String tmp;

    if (this->hasFlavor (CIMFlavor::OVERRIDABLE))
        tmp.append("OVERRIDABLE ");

    if (this->hasFlavor (CIMFlavor::TOSUBCLASS))
        tmp.append("TOSUBCLASS ");

    if (this->hasFlavor (CIMFlavor::TOINSTANCE))
        tmp.append("TOINSTANCE ");

    if (this->hasFlavor (CIMFlavor::TRANSLATABLE))
        tmp.append("TRANSLATABLE ");

    if (this->hasFlavor (CIMFlavor::DISABLEOVERRIDE))
        tmp.append("DISABLEOVERRIDE ");

    if (this->hasFlavor (CIMFlavor::RESTRICTED))
        tmp.append("RESTRICTED ");

    if (tmp.size ())
        tmp.remove (tmp.size () - 1);

    return tmp;
}
Example #13
0
bool cutBefore(String &str, const String& pat)
{
    int pos = str.indexOf(pat);
    if(pos < 0) return false;
    str.remove(0, pos);
    return true;
}
String cookies(const Document* /*document*/, const KURL& url)
{
    String rawCookie = cookieJar.get(url.host());
    String urlPath = url.path();
    String resCookie;
    Vector<String> field;
    const int fieldNum = 7;
    int i, len;

    if (rawCookie.length() == 0)
        return resCookie;

    // --- Parse raw cookie ---
    rawCookie.split('\t', true, field);
    len = field.size();

    for (i = 0; i < len; i += fieldNum)
        if (urlPath.startsWith(field[i + 2], false))
            resCookie += "; " + field[i + 5] + "=" + field[i + 6];

    // --- Trim leading separator ---
    if (!resCookie.isEmpty())
        resCookie.remove(0, 2);

    // printf("%s: %s\n%s\n\n", __func__, url.string().utf8().data(), resCookie.utf8().data());
    return resCookie;
}
Example #15
0
void CharacterData::deleteData(unsigned offset, unsigned count, ExceptionCode& ec)
{
    checkCharDataOperation(offset, ec);
    if (ec)
        return;

    unsigned realCount;
    if (offset + count > length())
        realCount = length() - offset;
    else
        realCount = count;

    String newStr = m_data;
    newStr.remove(offset, realCount);

    RefPtr<StringImpl> oldStr = m_data;
    m_data = newStr.impl();
    
    if ((!renderer() || !rendererIsNeeded(renderer()->style())) && attached()) {
        detach();
        attach();
    } else if (renderer())
        static_cast<RenderText*>(renderer())->setTextWithOffset(m_data, offset, count);

    dispatchModifiedEvent(oldStr.get());

    document()->textRemoved(this, offset, realCount);
}
Example #16
0
String TextDecoder::decode(ArrayBufferView* input, const Dictionary& options, ExceptionState& exceptionState)
{
    bool stream = false;
    options.get("stream", stream);

    const char* start = input ? static_cast<const char*>(input->baseAddress()) : 0;
    size_t length = input ? input->byteLength() : 0;

    WTF::FlushBehavior flush = stream ? WTF::DoNotFlush : WTF::DataEOF;

    bool sawError = false;
    String s = m_codec->decode(start, length, flush, m_fatal, sawError);

    if (m_fatal && sawError) {
        exceptionState.throwDOMException(EncodingError, "The encoded data was not valid.");
        return String();
    }

    if (!m_ignoreBOM && !m_bomSeen && !s.isEmpty()) {
        m_bomSeen = true;
        String name(m_encoding.name());
        if ((name == "UTF-8" || name == "UTF-16LE" || name == "UTF-16BE") && s[0] == 0xFEFF)
            s.remove(0);
    }

    if (flush)
        m_bomSeen = false;

    return s;
}
static bool verifyCustomHandlerURL(const String& baseURL, const String& url, ExceptionCode& ec)
{
    // The specification requires that it is a SYNTAX_ERR if the "%s" token is
    // not present.
    static const char token[] = "%s";
    int index = url.find(token);
    if (-1 == index) {
        ec = SYNTAX_ERR;
        return false;
    }

    // It is also a SYNTAX_ERR if the custom handler URL, as created by removing
    // the "%s" token and prepending the base url, does not resolve.
    String newURL = url;
    newURL.remove(index, WTF_ARRAY_LENGTH(token) - 1);

    URL base(ParsedURLString, baseURL);
    URL kurl(base, newURL);

    if (kurl.isEmpty() || !kurl.isValid()) {
        ec = SYNTAX_ERR;
        return false;
    }

    return true;
}
Example #18
0
void CharacterData::replaceData(unsigned offset, unsigned count, const String& arg, ExceptionCode& ec)
{
    checkCharDataOperation(offset, ec);
    if (ec)
        return;

    unsigned realCount;
    if (offset + count > length())
        realCount = length() - offset;
    else
        realCount = count;

    String newStr = m_data;
    newStr.remove(offset, realCount);
    newStr.insert(arg, offset);

    RefPtr<StringImpl> oldStr = m_data;
    m_data = newStr.impl();

    if ((!renderer() || !rendererIsNeeded(renderer()->style())) && attached()) {
        detach();
        attach();
    } else if (renderer())
        static_cast<RenderText*>(renderer())->setTextWithOffset(m_data, offset, count);
    
    dispatchModifiedEvent(oldStr.get());
    
    // update the markers for spell checking and grammar checking
    document()->textRemoved(this, offset, realCount);
    document()->textInserted(this, offset, arg.length());
}
String sendData(String tcpHeader, String data){
  int x;
  SerialUSB.println("Wi-Fi Sending data...");
  Serial1.setTimeout(5000);
  Serial1.println(tcpHeader);
  Serial1.flush();
  Serial1.println(data);
  Serial1.flush();
  String response = Serial1.readStringUntil(Serial1.available());
  if(response.length() > 2){
    x = findString("OK", response);
  } 
  else{
    SerialUSB.println("Wi-Fi Sending data Timeout!");
    return "";
  }

  if(x != -1){
    SerialUSB.println("Wi-Fi data sent");
    response.remove(0, findString("alive",response) + 9);
    Serial1.setTimeout(1000);
    return response;
  }
  else{
    SerialUSB.println("Wi-Fi couldn't send the data!");
    Serial1.setTimeout(1000);
    return "";
  }

}
bool HTTPClient::beginInternal(String url, const char* expectedProtocol)
{
    DEBUG_HTTPCLIENT("[HTTP-Client][begin] url: %s\n", url.c_str());
    bool hasPort = false;
    clear();

    // check for : (http: or https:
    int index = url.indexOf(':');
    if(index < 0) {
        DEBUG_HTTPCLIENT("[HTTP-Client][begin] failed to parse protocol\n");
        return false;
    }

    _protocol = url.substring(0, index);
    url.remove(0, (index + 3)); // remove http:// or https://

    index = url.indexOf('/');
    String host = url.substring(0, index);
    url.remove(0, index); // remove host part

    // get Authorization
    index = host.indexOf('@');
    if(index >= 0) {
        // auth info
        String auth = host.substring(0, index);
        host.remove(0, index + 1); // remove auth part including @
        _base64Authorization = base64::encode(auth);
    }

    // get port
    index = host.indexOf(':');
    if(index >= 0) {
        _host = host.substring(0, index); // hostname
        host.remove(0, (index + 1)); // remove hostname + :
        _port = host.toInt(); // get port
    } else {
        _host = host;
    }
    _uri = url;
    if (_protocol != expectedProtocol) {
        DEBUG_HTTPCLIENT("[HTTP-Client][begin] unexpected protocol: %s, expected %s\n", _protocol.c_str(), expectedProtocol);
        return false;
    }
    DEBUG_HTTPCLIENT("[HTTP-Client][begin] host: %s port: %d url: %s\n", _host.c_str(), _port, _uri.c_str());
    return true;
}
Example #21
0
bool cutAfter(String &str, const String& pat)
{
    int pos = str.indexOf(pat);
    if(pos < 0) return false;
    pos += pat.size();
    str.remove(pos, str.size() - pos);
    return true;
}
String HTMLTextAreaElement::defaultValue() const
{
    String value = "";

    // Since there may be comments, ignore nodes other than text nodes.
    for (Node* n = firstChild(); n; n = n->nextSibling()) {
        if (n->isTextNode())
            value += static_cast<Text*>(n)->data();
    }

    UChar firstCharacter = value[0];
    if (firstCharacter == '\r' && value[1] == '\n')
        value.remove(0, 2);
    else if (firstCharacter == '\r' || firstCharacter == '\n')
        value.remove(0, 1);

    return value;
}
int ShellClass::findCmd(String& line, ShellCommand* cmd){
	//Binary search channel's index by canID
	int s = 0, d = CMDS_NUM - 1;
	int p, cmp;

	int index = line.indexOf(' ');
	String cmdLine;

	//Remove \n and \r
	line.remove(line.indexOf('\n'), 1);
	line.remove(line.indexOf('\r'), 1);

	//Get the cmd
	cmdLine = line.substring(0, index == -1 ? line.length() : index);

	//Remove cmd string and leave only the params
	line.remove(0, index + 1);


	while (s <= d){
		p = (s + d) / 2;

		//Load cmd from flash
		mempcpy(cmd, &cmdsList[p], sizeof(ShellCommand));
		//Compare loaded cmd string and searched cmd line
		cmp = strcmp(cmd->cmdString, cmdLine.c_str());

		if (cmp == 0){
			//Log << Hex << Log.array<byte>((byte*)line.c_str(), line.length()) << Endl;

			return p;
		}
		else if (cmp < 0){
			s = p + 1;
		}
		else{
			d = p - 1;
		}
	}
	
	cmd = NULL;
	return -1;
}
bool NerveTool::extract_item( FILE *sout , String& item , String& s , String p ) {
	s.trimStarting( ' ' );
	if( !s.startsFrom( p + "={" ) ) {
		item.clear();
		return( true );
	}

	s.remove( 0 , p.length() + 2 );
	int idx = s.find( "}" );
	if( idx < 0 )
		return( false );

	item = s.getMid( 0 , idx );
	s.remove( 0 , idx + 1 );
	if( s.startsFrom( "; " ) )
		s.remove( 0 , 2 );

	return( true );
}
String HTMLTextAreaElement::defaultValue() const
{
    String val = "";

    // Since there may be comments, ignore nodes other than text nodes.
    for (Node* n = firstChild(); n; n = n->nextSibling())
        if (n->isTextNode())
            val += static_cast<Text*>(n)->data();

    // FIXME: We should only drop the first carriage return for the default
    // value in the original source, not defaultValues set from JS. This code
    // will do both.
    if (val.length() >= 2 && val[0] == '\r' && val[1] == '\n')
        val.remove(0, 2);
    else if (val.length() >= 1 && (val[0] == '\r' || val[0] == '\n'))
        val.remove(0, 1);

    return val;
}
Example #26
0
String SocketClient::readAll()
{
    String buf;
    std::swap(buf, mReadBuffer);
    if (mReadBufferPos) {
        buf.remove(0, mReadBufferPos);
        mReadBufferPos = 0;
    }
    return buf;
}
Example #27
0
String getStringFromJsonDirty(String &JSON, String key){
  String value = "";
  int end;
  end = JSON.indexOf("\""+key+"\":");
  if(end != -1){
    JSON.remove(0,end+key.length() + 3);
    value = JSON.substring(0,JSON.indexOf(","));
  }

  return value;
}
Example #28
0
const VirtualFunctionTableEntry* VirtualClass::getDefaultConstructor() const
{
   String name = mName;
   std::size_t pos = mName.lastIndexOf('.');
   if ( pos != String::npos )
   {
      name.remove(0, pos + 1);
   }

   return mVTable.findByName(name);
}
bool NerveTool::extract_codes( String& s , StringList *z ) {
	String so;

	// [zzz,code],[zzz,code]
	s.trim();
	while( !s.isEmpty() ) {
		if( !s.startsFrom( "[" ) )
			return( false );

		int idx = s.find( "]" );
		if( idx < 0 )
			return( false );

		String a = s.getMid( 1 , idx - 1 );
		s.remove( 0 , idx + 1 );
		s.trim();

		idx = a.find( "," );
		if( idx < 0 )
			return( false );

		a = a.getMid( idx + 1 );
		a.trim();
		if( a.isEmpty() )
			return( false );

		idx = s.find( "," );
		if( idx >= 0 ) {
			s.remove( 0 , idx + 1 );
			s.trim();

			if( s.isEmpty() )
				return( false );
		}

		// add to list
		z -> add( a );
	}

	return( true );
}
Example #30
0
String StyledMarkupAccumulator::stringValueForRange(const Text& node)
{
    if (m_start.isNull())
        return node.data();

    String str = node.data();
    if (m_start.text() == node)
        str.truncate(m_end.offset());
    if (m_end.text() == node)
        str.remove(0, m_start.offset());
    return str;
}