~ubuntu-branches/ubuntu/saucy/octave-miscellaneous/saucy-proposed

« back to all changes in this revision

Viewing changes to src/csv2cell.cc

  • Committer: Package Import Robot
  • Author(s): Sébastien Villemot, Sébastien Villemot, Rafael Laboissiere
  • Date: 2012-04-02 13:20:23 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120402132023-t41xaso7sl5cex90
Tags: 1.1.0-1
[ Sébastien Villemot ]
* Imported Upstream version 1.1.0
* debian/patches/match-cell-array.patch: remove patch (applied upstream)
* debian/patches/waitbar-rename.patch: remove patch (applied upstream)
* debian/patches/no-flexml.patch: remove obsolete patch, flex no longer used
  (Closes: #666294)
* debian/copyright: reflect upstream changes
* debian/octave-miscellaneous.docs: remove, no more docs in the package
* debian/clean: remove obsolete file
* debian/rules: remove hack for wrong permissions in upstream tarball

[ Rafael Laboissiere ]
* debian/watch: Use the SourceForge redirector

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright (C) 2004 Laurent Mazet
3
 
 *
4
 
 * This program is free software; you can redistribute it and/or modify
5
 
 * it under the terms of the GNU General Public License as published by
6
 
 * the Free Software Foundation; either version 2 of the License, or
7
 
 * (at your option) any later version.
8
 
 *
9
 
 * This program is distributed in the hope that it will be useful,
10
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 
 * GNU General Public License for more details.
13
 
 *
14
 
 * You should have received a copy of the GNU General Public License
15
 
 * along with this program; If not, see <http://www.gnu.org/licenses/>.
16
 
 */
17
 
 
18
 
/* 2004-04-08
19
 
 *   initial release
20
 
 */
21
 
 
22
 
#include <fstream>
23
 
 
24
 
#include <octave/oct.h>
25
 
#include <octave/Cell.h>
26
 
 
27
 
#define MAXSTRINGLENGTH 4096
28
 
 
29
 
DEFUN_DLD (csv2cell, args, nargout, 
30
 
       "-*- texinfo -*-\n"
31
 
       "@deftypefn {Function File} {@var{c} = } csv2cell (@var{file})\n"
32
 
       "@deftypefnx {Function File} {@var{c} = } csv2cell (@var{file}, @var{sep})\n"
33
 
       "@deftypefnx {Function File} {@var{c} = } csv2cell (@var{file}, @var{sep}, @var{prot})\n"
34
 
       "\n"
35
 
       "Read a CSV (Comma Separated Values) file and convert it into a "
36
 
       "cell. "
37
 
       "@var{sep} changes the character used to separate two fields. By "
38
 
       "default, two fields are expected to be separated by a coma "
39
 
       "(@code{,}). @var{prot} changes the character used to protect a string. "
40
 
       "By default it's a double quote (@code{\"}).\n"
41
 
       "@end deftypefn") {
42
 
 
43
 
  /* Get arguments */
44
 
  const int nargin = args.length ();
45
 
  octave_value_list retval;
46
 
  if (nargin == 0)
47
 
    {
48
 
      error ("csv2cell: not enough input arguments");
49
 
      return retval;
50
 
    }
51
 
    
52
 
  const std::string file = args (0).string_value ();
53
 
 
54
 
  const std::string _sep = (nargin > 1) ? args (1).string_value () : ",";
55
 
  if (_sep.length() != 1)
56
 
    {
57
 
      error ("csv2cell: only on charactere need as separator");
58
 
      return retval;
59
 
    }
60
 
  char sep = _sep[0];
61
 
 
62
 
  const std::string _prot = (nargin > 2) ? args (2).string_value () : "\"";
63
 
  if (_prot.length() != 1)
64
 
    {
65
 
      error ("csv2cell: only on charactere need as protector");
66
 
      return retval;
67
 
    }
68
 
  char prot = _prot[0];
69
 
 
70
 
  /* Open file */
71
 
  std::ifstream fd (file.c_str ());
72
 
  if (!fd.is_open ())
73
 
    {
74
 
      error ("csv2cell: cannot read %s", file.c_str());
75
 
      return retval;
76
 
    }
77
 
  fd.seekg (0, std::ios::end);
78
 
  long fdend = fd.tellg ();
79
 
  fd.seekg (0, std::ios::beg);
80
 
 
81
 
  /* Buffers */
82
 
  char line [MAXSTRINGLENGTH];
83
 
  std::string str, word;
84
 
  bool inside = false;
85
 
 
86
 
  /* Read a line */
87
 
  str = "";
88
 
  fd.getline (line, MAXSTRINGLENGTH);
89
 
  while (fd.fail ())
90
 
    {
91
 
      fd.clear ();
92
 
      str += line;
93
 
      fd.getline (line, MAXSTRINGLENGTH);
94
 
    }
95
 
  str += line;
96
 
 
97
 
  /* Parse first to get number of columns */
98
 
  int nbcolumns = 0;
99
 
  for (int i = 0, len = str.length (); i <= len; i++)
100
 
    if (((i==len) || (str [i] == sep)) && (!inside))
101
 
      nbcolumns++;
102
 
    else if ((inside) && (str [i] == prot) && ((i < len) && (str [i+1] == prot)))
103
 
      ++i;
104
 
    else if (str [i] == prot)
105
 
      inside = !inside;
106
 
  
107
 
  /* Read all the file to get number of rows */
108
 
  int nbrows = 1;
109
 
  while (fd.tellg () < fdend)
110
 
    {
111
 
      fd.getline (line, MAXSTRINGLENGTH);
112
 
      while (fd.fail ())
113
 
        {
114
 
          fd.clear ();
115
 
          fd.getline (line, MAXSTRINGLENGTH);
116
 
        }
117
 
      nbrows++;
118
 
    }
119
 
 
120
 
  /* Rewind */
121
 
  fd.seekg (0, std::ios::beg);
122
 
  if (!fd.good ())
123
 
    {
124
 
      error ("csv2cell: cannot reread %s", file.c_str ());
125
 
      return retval;
126
 
    }
127
 
 
128
 
  /* Read all the file until the end */
129
 
  Cell c (nbrows, nbcolumns);
130
 
  for (int i = 0; i < nbrows; i++)
131
 
    {
132
 
      /* Read a line */
133
 
      str = "";
134
 
      fd.getline (line, MAXSTRINGLENGTH);
135
 
      while (fd.fail ())
136
 
        {
137
 
          fd.clear ();
138
 
          str += line;
139
 
          fd.getline (line, MAXSTRINGLENGTH);
140
 
        }
141
 
      str += line;
142
 
 
143
 
      /* Explode a line into a sub cell */
144
 
      word = "";
145
 
      inside = false;
146
 
      int j = 0;
147
 
      for (int k = 0, len = str.length (); k <= len; k++)
148
 
        {
149
 
          if (((k == len) || (str [k] == sep)) && (!inside))
150
 
            {
151
 
              /* Check number of columns */
152
 
              if (j == nbcolumns)
153
 
                {
154
 
                  fd.close ();
155
 
                  error ("csv2cell: incorrect CSV file, line %d too long", i+1);
156
 
                  return retval;
157
 
                }
158
 
 
159
 
              /* Check if scalar */
160
 
              const char *word_str = word.c_str ();
161
 
              char *err;
162
 
              double val = strtod (word_str, &err);
163
 
 
164
 
              /* Store into the cell */
165
 
              c (i, j++) = ((word == "") || (err != word_str+word.length())) ?
166
 
                           octave_value (word) : octave_value (val);
167
 
              word = "";
168
 
            }
169
 
          else if ((inside) && (str[k]==prot) && ((k<len) && (str[k+1]==prot)))
170
 
            {
171
 
              /* Insisde a string */
172
 
              word += prot;
173
 
              ++k;
174
 
            }
175
 
          else if (str[k] == prot)
176
 
            /* Changing */
177
 
            inside = !inside;
178
 
          else
179
 
            word += str[k];
180
 
        }
181
 
 
182
 
      /* Check number of columns */
183
 
      if (j != nbcolumns)
184
 
        {
185
 
          fd.close ();
186
 
          error ("csv2cell: incorrect CSV file, line %d too short", i+1);
187
 
          return retval;
188
 
        }
189
 
    }
190
 
 
191
 
  /* Close file */
192
 
  fd.close ();
193
 
 
194
 
  retval (0) = c;
195
 
  return retval;
196
 
}