~ubuntu-branches/debian/sid/pgadmin3/sid

« back to all changes in this revision

Viewing changes to pgadmin/utils/csvfiles.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Gerfried Fuchs
  • Date: 2009-07-30 12:27:16 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20090730122716-fddbh42on721bbs2
Tags: 1.10.0-1
* New upstream release.
* Adjusted watch file to match release candidates.
* Updated to Standards-Version 3.8.2:
  - Moved to Section: database.
  - Add DEB_BUILD_OPTIONS support for parallel building.
  - Move from findstring to filter suggestion for DEB_BUILD_OPTIONS parsing.
* pgagent got split into its own separate source package by upstream.
* Exclude Docs.vcproj from installation.
* Move doc-base.enus from pgadmin3 to pgadmin3-data package, the files are
  in there too.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//////////////////////////////////////////////////////////////////////////
 
2
//
 
3
// pgAdmin III - PostgreSQL Tools
 
4
// RCS-ID:      $Id:  $
 
5
// Copyright (C) 2002 - 2009, The pgAdmin Development Team
 
6
// This software is released under the BSD Licence
 
7
//
 
8
// csvfiles.cpp - CSV file parsing
 
9
//
 
10
//////////////////////////////////////////////////////////////////////////
 
11
 
 
12
#include "pgAdmin3.h"
 
13
#include "utils/sysLogger.h"
 
14
#include "utils/csvfiles.h"
 
15
 
 
16
// PostgreSQL and GPDB now support CSV format logs.
 
17
// So, we need a way to parse the CSV files into lines, and lines into tokens (fields).
 
18
 
 
19
bool CSVTokenizer::HasMoreTokens() const
 
20
{
 
21
    if ( m_string.length() > 0)
 
22
    {
 
23
        if ( m_pos >= m_string.length())
 
24
            return false;
 
25
 
 
26
        if ( m_string.find_first_not_of(wxT(','), m_pos) != wxString::npos )
 
27
            // there are non delimiter characters left, so we do have more tokens
 
28
            return true;
 
29
 
 
30
        if (m_string[m_pos] == wxT('\n'))
 
31
            return false;
 
32
    }
 
33
    return m_pos == 0 && !m_string.empty();
 
34
}
 
35
 
 
36
wxString CSVTokenizer::GetNextToken()
 
37
{
 
38
    wxString token;
 
39
 
 
40
    if ( !HasMoreTokens() )
 
41
        return token;
 
42
 
 
43
    // skip leading blanks if not quoted.
 
44
    while (m_pos < m_string.length() && m_string[m_pos] == wxT(' '))
 
45
        m_pos ++;
 
46
 
 
47
    // Are we a quoted field?  Must handle this special.
 
48
    bool quoted_string = (m_string[m_pos] == wxT('\"'));
 
49
    bool inquote = false;
 
50
 
 
51
    size_t pos = m_pos;
 
52
 
 
53
    // find the end of this token.
 
54
    for (; pos < m_string.length(); pos++)
 
55
    {
 
56
        if (quoted_string && m_string[pos] == wxT('\"'))
 
57
            inquote = !inquote;
 
58
 
 
59
        if (!inquote)
 
60
        {
 
61
            // Check to see if we have found the end of this token.
 
62
            // Tokens normally end with a ',' delimiter.
 
63
            if (m_string[pos] == wxT(','))
 
64
                break;
 
65
 
 
66
            // Last token is delimited by '\n' or by end of string.
 
67
            if (m_string[pos] == wxT('\n') && pos == m_string.length()-1)
 
68
                break;
 
69
        }
 
70
    }
 
71
 
 
72
    if (quoted_string && !inquote)
 
73
    {
 
74
        token.assign(m_string, m_pos + 1, pos - m_pos - 2);  // Remove leading and trailing quotes
 
75
 
 
76
        // Remove double doublequote chars, replace with single doublequote chars
 
77
        token.Replace(wxT("\"\""),wxT("\""),true);
 
78
    }
 
79
    else
 
80
        token.assign(m_string, m_pos, pos - m_pos);
 
81
 
 
82
    if (quoted_string && inquote)
 
83
            wxLogNotice(wxT("unterminated double quoted string: %s\n"), token.c_str());
 
84
 
 
85
    m_pos = pos + 1;    // Skip token and delimiter
 
86
 
 
87
    if (m_pos > m_string.length())  // Perhaps no delimiter if at end of string if orig string didn't have '\n'.
 
88
        m_pos = m_string.length();
 
89
 
 
90
    return token;
 
91
}
 
92
 
 
93
bool CSVLineTokenizer::HasMoreLines() const
 
94
{
 
95
    if ( m_string.find_first_not_of(wxT('\n'), m_pos) != wxString::npos )
 
96
        // there are non line-end characters left, so we do have more lines
 
97
        return true;
 
98
    return false;
 
99
}
 
100
 
 
101
wxString CSVLineTokenizer::GetNextLine(bool & partial)
 
102
{
 
103
    wxString token;
 
104
    partial = true;
 
105
 
 
106
    if ( !HasMoreLines() )
 
107
        return token;
 
108
 
 
109
    // find the end of this line.  CSV lines end in "\n", but 
 
110
    // CSV lines may have "\n" chars inside double-quoted strings, so we need to find that out.
 
111
 
 
112
    bool inquote = false;
 
113
    for (size_t pos = m_pos; pos < m_string.length(); pos++)
 
114
    {
 
115
        if (m_string[pos] == wxT('\"'))
 
116
            inquote = !inquote;
 
117
 
 
118
        if (m_string[pos] == wxT('\n') && !inquote)
 
119
        {
 
120
            // Good, we found a complete log line terminated 
 
121
            // by "\n", and the "\n" wasn't in a quoted string.
 
122
 
 
123
            size_t len = pos - m_pos + 1;   // return the line, including the trailing "\n"
 
124
            token.assign(m_string, m_pos, len);
 
125
            m_pos = pos + 1;                // point to next line.
 
126
            partial = false;
 
127
            return token;
 
128
        }
 
129
    }
 
130
 
 
131
    // no more delimiters, so the line is everything till the end of
 
132
    // string, but we don't have all of the CSV the line... Some must still be coming.
 
133
     
 
134
    token.assign(m_string, m_pos, wxString::npos);
 
135
    partial = true;
 
136
 
 
137
    m_pos = m_string.length();
 
138
  
 
139
    return token;
 
140
}