Esempio n. 1
0
        /// <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);
        }