/*
* $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;
}
syntax highlighted by Code2HTML, v. 0.9.1