/// <remarks> /// Affected by run-time quoting (data are unqouted before written) /// (<see cref="LocalConfiguration.VariablesSection.QuoteRuntimeVariables"/>). /// </remarks> public static int fputcsv(Context ctx, PhpResource handle, PhpArray fields, char delimiter = DefaultCsvDelimiter, char enclosure = DefaultCsvEnclosure) { PhpStream stream = PhpStream.GetValid(handle, FileAccess.Write); if (stream == null || !stream.CanWrite) { return(-1); } char[] special_chars = { delimiter, ' ', '\\', '\t', '\r', '\n' }; string str_enclosure = enclosure.ToString(); string str_delimiter = delimiter.ToString(); int initial_position = stream.WritePosition; var enumerator = fields.GetFastEnumerator(); while (enumerator.MoveNext()) { var str_field = StringUtils.StripCSlashes(enumerator.CurrentValue.ToString(ctx)); if (stream.WritePosition > initial_position) { stream.WriteString(str_delimiter); } int special_char_index = str_field.IndexOfAny(special_chars); int enclosure_index = str_field.IndexOf(enclosure); if (special_char_index >= 0 || enclosure_index >= 0) { stream.WriteString(str_enclosure); if (enclosure_index >= 0) { // escapes enclosure characters: int start = 0; for (; ;) { // writes string starting after the last enclosure and ending by the next one: stream.WriteString(str_field.Substring(start, enclosure_index - start + 1)); stream.WriteString(str_enclosure); start = enclosure_index + 1; if (start >= str_field.Length) { break; } enclosure_index = str_field.IndexOf(enclosure, start); if (enclosure_index < 0) { // remaining substring: stream.WriteString(str_field.Substring(start)); break; } } } else { stream.WriteString(str_field); } stream.WriteString(str_enclosure); } else { stream.WriteString(str_field); } } stream.WriteString("\n"); return((initial_position == -1) ? stream.WritePosition : stream.WritePosition - initial_position); }