/* * $Id: CSVAnalyzer.cpp,v 1.5 2005/10/19 14:05:44 ozawa Exp $ * * Copyright 2005- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.5 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "xdtp.h" #include "CSVAnalyzer.h" #include "Utilities.h" using namespace XDTP; CSVAnalyzer::CSVAnalyzer() { } CSVAnalyzer::~CSVAnalyzer() { } /** * CSV データを解析し、List データ構造に格納します。 * * @param aLine * 解析元のCSVデータ1行 * @return List データ構造に格納した CSV データ */ bool CSVAnalyzer::analyzeLine(const Glib::ustring& aLine, StringList& aList) { // 切出の最初の位置 Glib::ustring::size_type startPoint = 0; // 切出の終りの位置 Glib::ustring::size_type nextPoint = 0; // 解析文字列の長さ Glib::ustring::size_type csvLenght = aLine.length(); Glib::ustring token; aList.clear(); nextPoint = nextCommaPoint(startPoint, aLine); while (nextPoint != Glib::ustring::npos && nextPoint >= startPoint && nextPoint <= csvLenght) { token = aLine.substr(startPoint, nextPoint - startPoint); // 囲っているダブルクォーテーションを取り除く if (1 < token.length() && '"' == token.at(0)) { token = token.substr(1, token.length() -2); } // エスケープされたダブルクォーテーションを元に戻す token = Utilities::strReplaceAll(token, "\"\"", "\""); aList.push_back(token); startPoint = nextPoint + 1; nextPoint = nextCommaPoint(startPoint, aLine); } // ダブルクォーテーションの囲いを抜けていない場合は false を返す if (nextPoint == Glib::ustring::npos) { aList.clear(); return false; } return true; } /** * 指定された場所以降で, 次に区切りのカンマが現れる場所を返します。 * 次にカンマが見当たらない場合, 解析対象の文字列の長さが還ります。 * ただし、データが妥当でない(たとえばダブルクォーテーションの囲いが * 終了していないのに行が終わっている場合)は -1 を返します。 * * @param aStartPoint * 解析開始位置 * @param aLine * 解析元CSVデータ1行 * @return 次に区切りのカンマが来る位置か, データの長さ。データが 妥当でない場合は -1 が返ります。 */ Glib::ustring::size_type CSVAnalyzer::nextCommaPoint (Glib::ustring::size_type aStartPoint, const Glib::ustring& aLine) { // 次のカンマが現れるまでインクリメントされる位置ポイント Glib::ustring::size_type targetPoint = aStartPoint; // 解析文字列の長さ Glib::ustring::size_type csvLength = aLine.length(); // 解析対象の文字 Glib::ustring::value_type value; // ダブルクォーテーションの内部にあるかないかを表します。CSV データ // は, データ内にカンマがある場合, そのデータをダブルクォーテーショ // ンで囲むことで区切りのカンマと区別します。本真偽値はその判定に利用 // されます。 bool isQuoted = false; // 次の区切りカンマが来るか, または for (; targetPoint < csvLength; targetPoint++) { value = aLine.at(targetPoint); if (',' == value && !isQuoted) { // ダブルクォーテーション内部ではないカンマの場合に次のカンマ // が来たと判断し処理を抜けます。 break; } else if ('"' == value) { // CSV データは, データ内にダブルクォーテーションがある場合, // そのデータを二つのダブルクォーテーションに変換します。 // 次の処理は, 連続した二つのダブルクォーテーションには影響 // を与えずに囲みのダブルクォーテーションを調べることができ // ます。 isQuoted = !isQuoted; } } // ダブルクォーテーションの囲いを抜けていない場合は -1 を返します。 if (isQuoted) { targetPoint = Glib::ustring::npos; } return targetPoint; }