public static string[] SplitCSV(string sLine, char cFieldDelimX, char cTextDelimX, bool bStripTextDelimiterNotation) { //formerly CSVLineToRow string[] sarrReturn=null; int iElements=CountCSVElements(sLine,cFieldDelimX,cTextDelimX); //Console.Error.WriteLine( String.Format("Elements found:{0} text delimiter:'{1}'",iElements,char.ToString(cTextDelimX))); //debug only try { if (iElements>0) { sarrReturn=new string[iElements]; int iFound=0; int iChar=0; bool bInQuotes=false; int iStartNow=0; int iEnderNow=-1; if (sLine!=null) { if (sLine!="") { while (iChar<=sLine.Length) {//intentionally <= if ( iChar!=sLine.Length&&sLine[iChar]==cTextDelimX) bInQuotes=!bInQuotes; if ( iChar==sLine.Length || (sLine[iChar]==cFieldDelimX&&!bInQuotes) ) {//TODO: make sure CountCSVFields has same logic, or combine the functions iEnderNow=iChar; sarrReturn[iFound]=sLine.Substring(iStartNow,iEnderNow-iStartNow); //Console.Error.WriteLine( String.Format("Found arg:\"{0}\" {{start:{1}; end:{2}; ender:{3}; next start:{4}}}", // sarrReturn[iFound],iStartNow,(iChar==sLine.Length?"yes":"no"),iEnderNow,iEnderNow+1 ) //); iFound++; iStartNow=++iEnderNow; } iChar++; } if (bStripTextDelimiterNotation) { for (int i=0; i<sarrReturn.Length; i++) { if (sarrReturn[i]!=null) { //Console.Error.Write("TextDelimiterNotation: "+sarrReturn[i]+" becomes "); sarrReturn[i]=RTable.CSVFieldToLiteralField(sarrReturn[i],cFieldDelimX,cTextDelimX); //Console.Error.WriteLine(sarrReturn[i]+"."); //if (sarrReturn[i].Length>=2&&sarrReturn[i][0]==cTextDelimX&&sarrReturn[i][sarrReturn[i].Length-1]==cTextDelimX) { // sarrReturn[i]=sarrReturn[i].Substring(1,sarrReturn[i].Length-2); //} } } } }//end if sLine!="" else { sarrReturn=new string[iElements]; for (int i=0; i<iElements; i++) sarrReturn[i]=""; //return new string[]{""}; } }//end if sLine!=null }//end if iElements>0 } catch (Exception exn) { Console.Error.WriteLine("Error in SplitCSV"); Console.Error.WriteLine(exn.ToString()); Console.Error.WriteLine(); } return sarrReturn; }//end SplitCSV
}//end RowToCSVLine public string RowToCSVLine(int AtInternalRowIndex, bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, int ColumnStart, int ColumnCount) { int iAbs=ColumnStart; string sReturn=""; try { for (int ColRel=0; ColRel<ColumnCount&&iAbs<this.Columns; ColRel++) { sReturn+=((ColRel!=0)?",":"")+RTable.LiteralFieldToCSVField(tearr[AtInternalRowIndex].Field(iAbs),this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty); iAbs++; } } catch (Exception exn) { RReporting.ShowExn(exn,"converting row to csv line","rtable RowToCSVLine(AtInternalRowIndex="+AtInternalRowIndex+",bTabsAsNewLines="+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"true":"false")+",ColumnStart="+ColumnStart+",ColumnCount="+ColumnCount+")"); } return sReturn; }
public RTable CopyTitlesOnly() { RTable tReturn=null; try { if (this.teTitles!=null&&this.teTitles.Columns>0) { tReturn=new RTable(this.teTitles.Copy(),true); } else tReturn=new RTable(); } catch (Exception exn) { tReturn=null; RReporting.ShowExn(exn,RReporting.sParticiple,"rtable CopyTitlesOnly()"); } return tReturn; }//end CopyTitlesTo
public string TitlesToCSVLine(bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, bool bExtendedTitleColumns, int ColumnStart, int ColumnCount) { string sReturn=""; RecheckIntegrity(); if (this.teTitles!=null) { if (bExtendedTitleColumns) { string sField=""; int ColAbs=ColumnStart; for (int ColRel=0; ColRel<ColumnCount; ColRel++) { sField=""; if (bExtendedTitleColumns) { sField=RString.SafeString(GetForcedType(ColAbs),false); if (sField!="") sField+=" "; }//end if bExtendedTitleColumns string FieldDataNow=teTitles.Field(ColAbs); if (FieldDataNow==null) { RReporting.ShowErr("Can't access field","generating csv line","TitlesToCSVLine {NewLineInField:"+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"TAB":"BR with marker")+"; Row:title; Column:"+ColAbs+"}"); } sField+=RString.SafeString(FieldDataNow,false); if (bExtendedTitleColumns) { string sMeta=GetForcedMeta(ColAbs); if (sMeta!=null) { sMeta=RString.SafeString(sMeta,false); sMeta=RString.RemoveEndsWhiteSpace(sMeta); if (!sMeta.StartsWith("{")) { sMeta=RString.Replace(sMeta,"{",""); sMeta="{"+sMeta; } if (!sMeta.EndsWith("}")) { sMeta=RString.Replace(sMeta,"}",""); sMeta+="}"; } sField+=sMeta; }//end if metadata }//end if bExtendedTitleColumns sReturn+=((ColRel!=0)?",":"")+RTable.LiteralFieldToCSVField(sField,this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty); ColAbs++; }//end for field (column header) } else sReturn=teTitles.ToCSVLine(cFieldDelimiter, cTextDelimiter, bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty,ColumnStart,ColumnCount); } else RReporting.ShowErr("Cannot read nonexistant title row.","Converting table titles to text line","TitlesToCSVLine"); return sReturn; }
}//end Save public bool SaveChunk(string sFile, bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, bool bExtendedTitleColumns, int RowStart, int RowCount, int ColStart, int ColCount) { StreamWriter fsDest=null; //sLastFile=sFile; do NOT set, since only saving a chunk and therefore says nothing about the source //if (sLastFile==null) sLastFile=""; bool bGood=false; //int iLines=0; RecheckIntegrity(); try { fsDest=new StreamWriter(sFile); if (TitleRowIsNonBlank) { //fsDest.WriteLine(teTitles.ToCSVLine(cFieldDelimiter,cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty)); string sTitles=""; string sField=""; int ColAbs=ColStart; for (int ColRel=0; ColRel<ColCount; ColRel++) { sField=""; if (bExtendedTitleColumns) { sField=RString.SafeString(GetForcedType(ColAbs),false); if (sField!="") sField+=" "; }//end if bExtendedTitleColumns string FieldDataNow=teTitles.Field(ColAbs); if (FieldDataNow==null) { RReporting.ShowErr("Can't access field","saving csv file","Save("+RReporting.StringMessage(sFile,true)+","+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"TAB as newline mode":"BR with marker as newline mode")+"){Row:title; Column:"+ColAbs+"}"); } sField+=RString.SafeString(FieldDataNow,false); if (bExtendedTitleColumns) { string sMeta=GetForcedMeta(ColAbs); if (sMeta!=null) { sMeta=RString.SafeString(sMeta,false); sMeta=RString.RemoveEndsWhiteSpace(sMeta); if (!sMeta.StartsWith("{")) { sMeta=RString.Replace(sMeta,"{",""); sMeta="{"+sMeta; } if (!sMeta.EndsWith("}")) { sMeta=RString.Replace(sMeta,"}",""); sMeta+="}"; } sField+=sMeta; }//end if metadata }//end if bExtendedTitleColumns sTitles+=((ColRel!=0)?",":"")+RTable.LiteralFieldToCSVField(sField,this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty); ColAbs++; }//end for field (column header) fsDest.WriteLine(sTitles); }//end if Title Row is not blank Console.Error.Write("Writing row range "+RowStart+" to "+(RowStart+RowCount-1)+" of "+iRows+" (total "+0+" to "+(iRows-1)+")..."); int RowAbs=RowStart; for (int RowRel=0; RowRel<RowCount&&RowAbs<iRows; RowRel++) { fsDest.WriteLine(RowToCSVLine(RowAbs,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty,ColStart,ColCount)); RowAbs++; } fsDest.Close(); Console.Error.WriteLine("done."); bGood=true; } catch (Exception exn) { Console.Error.WriteLine("Could not save table to \""+sFile+"\":"); Console.Error.WriteLine(exn.ToString()); bGood=false; try { fsDest.Close(); } catch (Exception exn2) { RReporting.ShowExn(exn2,"closing file after exception","rtable Load"); } } return bGood; }//end SaveChunk
}//end Delete_AllWithMarker public bool Save(string sFile, bool bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty, bool Set_bSaveMetaDataInTitleRow) { if (sLastFile==sFileUnknown) { sLastFile=sFile; if (sLastFile==null) sLastFile=""; } bSaveMetaDataInTitleRow=Set_bSaveMetaDataInTitleRow; StreamWriter fsDest=null; bool bGood=false; //int iLines=0; Delete_AllWithMarker(); RecheckIntegrity(); try { fsDest=new StreamWriter(sFile); if (TitleRowIsNonBlank) { //fsDest.WriteLine(teTitles.ToCSVLine(cFieldDelimiter,cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty)); string sTitles="";//cumulative string sField="";//cumulative for (int iCol=0; iCol<teTitles.Columns; iCol++) { sField="";//sField=RString.SafeString(GetForcedType(iCol),false);//old way if (bSaveMetaDataInTitleRow) sField=RString.SafeString(GetForcedType(iCol),false); if (sField!="") sField+=" "; string FieldDataNow=teTitles.Field(iCol); if (FieldDataNow==null) { RReporting.ShowErr("Can't access field","saving csv file","Save("+RReporting.StringMessage(sFile,true)+","+(bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty?"TAB as newline mode":"BR with marker as newline mode")+"){Row:title; Column:"+iCol+"}"); } sField+=RString.SafeString(FieldDataNow,false); if (bSaveMetaDataInTitleRow) { string sMeta=GetForcedMeta(iCol); if (sMeta!=null) { sMeta=RString.SafeString(sMeta,false); sMeta=RString.RemoveEndsWhiteSpace(sMeta); if (!sMeta.StartsWith("{")) { sMeta=RString.Replace(sMeta,"{",""); sMeta="{"+sMeta; } if (!sMeta.EndsWith("}")) { sMeta=RString.Replace(sMeta,"}",""); sMeta+="}"; } sField+=sMeta; }//end if metadata }//end if bSaveMetaDataInTitleRow sTitles+=((iCol!=0)?",":"")+RTable.LiteralFieldToCSVField(sField,this.cFieldDelimiter,this.cTextDelimiter,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty); }//end for column title iCol fsDest.WriteLine(sTitles); } Console.Error.Write("Writing "+iRows+" rows..."); for (int iNow=0; iNow<iRows; iNow++) { fsDest.WriteLine(RowToCSVLine(iNow,bReplaceNewLineWithTabInsteadOfHTMLBrWithMarkerProperty)); } fsDest.Close(); Console.Error.WriteLine("done."); bGood=true; } catch (Exception exn) { Console.Error.WriteLine("Could not save table to \""+sFile+"\":"); Console.Error.WriteLine(exn.ToString()); bGood=false; try { fsDest.Close(); } catch (Exception exn2) { RReporting.ShowExn(exn2,"closing file after exception","rtable Load"); } } return bGood; }//end Save
public bool Load(string sFile, bool FirstRowHasTitles) { sLastFile=sFile; if (sLastFile==null) sLastFile=""; bool bGood=false; bFirstRowLoadAndSaveAsTitles=FirstRowHasTitles; StreamReader fsSource=null; string sLine=null; try { fsSource=new StreamReader(sFile); if (bFirstRowLoadAndSaveAsTitles) { sLine=fsSource.ReadLine(); if ( bShowNewlineWarning && (RString.Contains(sLine,'\n')||RString.Contains(sLine,'\r')) ) { MessageBox.Show("Warning: newline character found in field. File may have been saved in a different operating system and need line breaks converted."); bShowNewlineWarning=false; } teTitles=new TableEntry(RTable.SplitCSV(sLine,cFieldDelimiter,cTextDelimiter)); //Parse TYPE NAME{METANAME:METAVALUE;...} title row notation: if (teTitles.Columns>0) { sarrFieldMetaData=new string[teTitles.Columns]; iarrFieldType=new int[teTitles.Columns]; for (int iColumn=0; iColumn<teTitles.Columns; iColumn++) { string FieldDataNow=teTitles.Field(iColumn); if (FieldDataNow==null) { RReporting.ShowErr("Field is not accessible","loading csv file","Load("+RReporting.StringMessage(sFile,true)+",...){Row 0:Titles; Column:"+iColumn+"}"); } int iType=StartsWithType(FieldDataNow); int iStartName=0; if (iType>-1) { iarrFieldType[iColumn]=iType; iStartName=sarrType[iType].Length+1; //teTitles.SetField(iColumn,RString.SafeSubstring(teTitles.Field(iColumn),sarrType[iType].Length+1)); } else { RReporting.Debug("Unknown type in column#"+iColumn.ToString()+"("+RReporting.StringMessage(FieldDataNow,true)+")"); } int iMetaData=-1; //if (FieldDataNow!=null) { iMetaData=FieldDataNow.IndexOf("{"); //} if (iMetaData>-1) { //string FieldDataNow=teTitles.Field(iColumn); if (FieldDataNow==null) { RReporting.ShowErr("Can't access field","loading csv file","rtable Load("+RReporting.StringMessage(sFile,true)+"){Row:titles; Column:"+iColumn+"}"); } this.sarrFieldMetaData[iColumn]=FieldDataNow.Substring(iMetaData); while (iMetaData>=0 && (FieldDataNow[iMetaData]=='{'||FieldDataNow[iMetaData]==' ')) iMetaData--; teTitles.SetField(iColumn,RString.SafeSubstringByInclusiveEnder(FieldDataNow,iStartName,iMetaData)); } else { teTitles.SetField(iColumn,RString.SafeSubstring(FieldDataNow,iStartName)); } }//end for iColumn in title row }//end if teTitles.Columns>0 }//if bFirstRowLoadAndSaveAsTitles tearr=new TableEntry[256]; for (int iNow=0; iNow<tearr.Length; iNow++) { tearr[iNow]=null; } iRows=0; //if (!bFirstRowLoadAndSaveAsTitles||sLine!=null) { if (bAllowNewLineInQuotes) { bool bInQuotes=false; string sLineCombined=""; while ( (sLine=fsSource.ReadLine()) != null ) { if (iRows>=Maximum) Maximum=iRows+iRows/2+1; for (int iChar=0; iChar<RString.SafeLength(sLine); iChar++) { if (sLine[iChar]==this.cTextDelimiter) bInQuotes=!bInQuotes; } sLineCombined+=sLine; if (!bInQuotes) { tearr[iRows]=new TableEntry(RTable.SplitCSV(sLineCombined,cFieldDelimiter,cTextDelimiter)); iRows++; sLineCombined=""; } }//end while not end of file if (sLineCombined!="") { //get bad data so it doesn't get lost tearr[iRows]=new TableEntry(RTable.SplitCSV(sLineCombined,cFieldDelimiter,cTextDelimiter)); iRows++; } } else { while ( (sLine=fsSource.ReadLine()) != null ) { if (iRows>=Maximum) Maximum=iRows+iRows/2+1; tearr[iRows]=new TableEntry(RTable.SplitCSV(sLine,cFieldDelimiter,cTextDelimiter)); iRows++; } } //}//if any data rows if (iRows<Maximum) { for (int i=iRows; i<Maximum; i++) { tearr[i]=new TableEntry(); } } bGood=true; fsSource.Close(); } catch (Exception exn) { RReporting.ShowExn(exn,"Loading table","rtable Load(\""+RReporting.StringMessage(sFile,true)+"\",FirstRowHasTitles="+(FirstRowHasTitles?"yes":"no")+")"); try { fsSource.Close(); } catch (Exception exn2) { RReporting.ShowExn(exn2,"closing file after exception","rtable Load"); } } return bGood; }//end Load