/** **************************************************************************************** * Cuts the given number of characters from the end of the Substring and optionally * places the portion that was cut in parameter \p target (if provided).<br> * Parameter \p regionLength is checked to be between 0 and length. If negative, nothing * is cut and \p target is set empty. If \p regionLength is greater than this * objects' length, all contents is 'moved' to \p target. * * @param regionLength The length of the region at the start to delete. * @param target An optional target \b %Substring that receives the portion that * is cut from this object. Defaults to null. * * @return The new length of the substring. ******************************************************************************************/ public int ConsumeFromEnd( int regionLength, Substring target= null ) { if ( regionLength < 0 ) { if ( target != null ) target.Clear(); return Length(); } if ( regionLength > Length() ) regionLength= Length(); if ( target != null ) target.Set( this, Length() - regionLength, regionLength ); End-= regionLength; hash= 0; return Length(); }
// ############################################################################################# // file IO // ############################################################################################# /** **************************************************************************************** * Clears all configuration data and reads the file. It might happen that lines are * ignored or otherwise marked as faulty. All numbers of such lines get collected in * field LinesWithReadErrors. * @return Returns the #Status of the operation. ******************************************************************************************/ public IniFile.Status ReadFile() { Reset(); LastStatus= Status.OK; // read all variables StreamReader file; try { file= new StreamReader( FileName.ToString() ); } catch( Exception ) { return LastStatus= Status.ERROR_OPENING_FILE; } String lineS; AString name= new AString(); AString value= new AString(); AString comments= new AString(); Section actSection= (IniFile.Section) Sections[0]; Substring line= new Substring(); int lineNo= 0; bool fileHeaderRead= false; char[] separatorCharacters= value._( "=" )._( CString.DefaultWhitespaces ) .ToString().ToCharArray(); LinesWithReadErrors.Clear(); while ( (lineS= file.ReadLine()) != null ) { lineNo++; bool isEmpty= line.Set( lineS ).Trim().IsEmpty(); bool isCommentLine= startsWithCommentSymbol( line ); if ( isCommentLine ) { if ( comments.IsNotEmpty() ) comments.NewLine(); comments._(line); continue; } // still processing file header? if ( !fileHeaderRead ) { fileHeaderRead= true; FileComments._()._( comments ); comments.Clear(); } // empty line? if ( isEmpty ) { if ( comments.IsNotEmpty() ) comments.NewLine(); continue; } // section line if ( line.Consume( '[' ) ) { fileHeaderRead= true; // we do not care if there is no closing bracket. But if there is one, we remove it. if( !line.ConsumeFromEnd(']') ) LinesWithReadErrors.Add( lineNo ); // search the section in our section list (if section existed already, new comments // are dropped) actSection= (IniFile.Section) SearchOrCreateSection( line, comments); comments.Clear(); continue; } // variable line? value.Clear(); int idx= line.IndexOfAny( separatorCharacters, Inclusion.Include ); if( idx < 0 ) { name._()._( line ); line.Clear(); } else { name._()._( line.Buf, line.Start, idx ); line.Consume( idx ); value._(line); } // read continues as long as lines end with '\' (must not be '\\') while ( line.CharAtEnd() == '\\' && line.CharAtEnd(1) != '\\' ) { value.NewLine(); if ( (lineS= file.ReadLine()) == null ) { // last line of the file ended with '\' ! line.Clear(); break; } line.Set( lineS ).TrimEnd(); value._( line ); } // insert entry with raw value { IniFile.Entry entry= (IniFile.Entry) actSection.GetEntry( name, true ); entry.Values .Clear(); entry.Comments._()._( comments ); entry.RawValue._()._( value ); // if there is just no raw value, we add an empty string to the entries' values if ( value.IsEmpty() ) entry.Values.Add( new AString() ); } comments.Clear(); } file.Close(); return LastStatus; }
/** **************************************************************************************** * Cuts the given number of characters from the beginning of the Substring and optionally * places the portion that was cut in parameter \p target (if provided).<br> * Parameter \p regionLength is checked to be between 0 and length. If negative, nothing * is cut and \p target is set empty. If \p regionLength is greater than this * objects' length, all contents is 'moved' to \p target. * * @param regionLength The length of the region at the start to delete. * @param target An optional target \b %Substring that receives the portion that * is cut from this object. Defaults to null. * * @return The new length of the substring. ******************************************************************************************/ public int Consume( int regionLength, Substring target= null ) { if ( regionLength < 0 ) { if ( target != null ) target.Clear(); return Length(); } if ( regionLength > Length() ) regionLength= Length(); if ( target != null ) target.Set( this, 0, regionLength ); Start+= regionLength; hash= 0; return Length(); }