383 lines
9.2 KiB
C++
383 lines
9.2 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
----
|
|
|
|
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
|
|
|
|
[1] FText Algebra
|
|
|
|
March - April 2003 Lothar Sowada
|
|
|
|
The algebra ~FText~ provides the type constructor ~text~ and two operators:
|
|
|
|
(i) ~contains~, which search text or string in a text.
|
|
|
|
(ii) ~length~ which give back the length of a text.
|
|
|
|
*/
|
|
|
|
#ifndef __F_TEXT_ALGEBRA__
|
|
#define __F_TEXT_ALGEBRA__
|
|
|
|
#include <iostream>
|
|
|
|
#undef TRACE_ON
|
|
#include "Trace.h"
|
|
|
|
#include "IndexableAttribute.h"
|
|
#include "../../Tools/Flob/Flob.h"
|
|
#include "ListUtils.h"
|
|
#include "StringUtils.h"
|
|
#include <algorithm>
|
|
|
|
// switch off log messages
|
|
#undef LOGMSG
|
|
#define LOGMSG(a, b)
|
|
|
|
class FText: public IndexableAttribute
|
|
{
|
|
public:
|
|
|
|
inline FText();
|
|
inline FText( bool newDefined, const char *newText = NULL) ;
|
|
inline FText( bool newDefined, const std::string& newText );
|
|
inline FText(const FText&);
|
|
inline ~FText();
|
|
inline void Destroy();
|
|
|
|
inline bool SearchString( const std::string subString );
|
|
inline void Set( const char *newString );
|
|
inline void Set( bool newDefined, const char *newString );
|
|
inline void Set( bool newDefined, const std::string& newString );
|
|
inline int TextLength() const;
|
|
inline size_t Length() const;
|
|
inline char *Get() const;
|
|
inline const std::string GetValue() const;
|
|
|
|
/*************************************************************************
|
|
|
|
The following virtual functions:
|
|
IsDefined, SetDefined, HashValue, CopyFrom, Compare, Sizeof, Clone,
|
|
Print, Adjacent need to be defined if we want to use ~text~ as an
|
|
attribute type in tuple definitions.
|
|
|
|
*************************************************************************/
|
|
|
|
inline size_t Sizeof() const;
|
|
size_t HashValue() const;
|
|
void CopyFrom(const Attribute* right);
|
|
int Compare(const Attribute * arg) const;
|
|
inline FText* Clone() const;
|
|
std::ostream& Print(std::ostream &os) const;
|
|
bool Adjacent(const Attribute * arg) const;
|
|
|
|
inline int NumOfFLOBs() const;
|
|
inline Flob* GetFLOB( const int );
|
|
|
|
/*************************************************************************
|
|
|
|
For use with Btree-Indices, we need text to be in kind INDEXABLE.
|
|
therefore, we need to inherit from IndexableAttribute
|
|
|
|
*************************************************************************/
|
|
|
|
virtual void WriteTo( char *dest ) const;
|
|
virtual void ReadFrom( const char *src );
|
|
virtual SmiSize SizeOfChars() const;
|
|
|
|
virtual bool hasDB3Representation() const {return true;}
|
|
virtual unsigned char getDB3Type() const { return 'M'; }
|
|
virtual unsigned char getDB3Length() const { return 0; }
|
|
virtual unsigned char getDB3DecimalCount(){ return 0; }
|
|
virtual std::string getDB3String() const { return GetValue(); }
|
|
|
|
virtual void ReadFromString(std::string value){
|
|
Set(true,value);
|
|
}
|
|
|
|
static const std::string BasicType(){
|
|
return "text";
|
|
}
|
|
|
|
static bool checkType(const ListExpr type){
|
|
return listutils::isSymbol(type, BasicType());
|
|
}
|
|
|
|
void trim() {
|
|
if(!IsDefined()){
|
|
return;
|
|
}
|
|
std::string s = GetValue();
|
|
stringutils::trim(s);
|
|
Set(true,s);
|
|
}
|
|
|
|
virtual bool hasTextRepresentation() const{
|
|
return true;
|
|
}
|
|
|
|
virtual std::string toText() const{
|
|
return GetValue();
|
|
}
|
|
|
|
virtual bool fromText(const std::string& value) {
|
|
Set(true,value);
|
|
return true;
|
|
}
|
|
|
|
virtual std::string getCsvStr() const {
|
|
if(!IsDefined()) return "";
|
|
return GetValue();
|
|
}
|
|
/*
|
|
Set FText to be csvexportable.
|
|
Note that the text may contain line break mark, in this case the text can be
|
|
exported into the csv file, but cannot be imported.
|
|
|
|
*/
|
|
|
|
private:
|
|
Flob theText;
|
|
};
|
|
|
|
/*
|
|
2 Inline Functions
|
|
|
|
*/
|
|
const std::string typeName="text";
|
|
const bool traces=false;
|
|
|
|
inline FText::FText()
|
|
{
|
|
LOGMSG( "FText:Trace", std::cout << '\n' <<"Start FText()"<<'\n'; )
|
|
LOGMSG( "FText:Trace", std::cout <<"End FText()"<<'\n'; )
|
|
}
|
|
|
|
inline FText::FText( bool newDefined, const char *newText /* =0*/ ) :
|
|
IndexableAttribute(newDefined),
|
|
theText( 0 )
|
|
{
|
|
LOGMSG( "FText:Trace",
|
|
std::cout << '\n'
|
|
<<"Start FText(bool newDefined, textType newText)"
|
|
<<'\n'; )
|
|
if(newDefined && newText){
|
|
Set( newDefined, newText );
|
|
}
|
|
LOGMSG( "FText:Trace",
|
|
std::cout <<"End FText(bool newDefined, textType newText)"
|
|
<<'\n'; )
|
|
}
|
|
|
|
inline FText::FText( bool newDefined, const std::string& newText ) :
|
|
IndexableAttribute(newDefined),
|
|
theText( 0 )
|
|
{
|
|
LOGMSG( "FText:Trace",
|
|
std::cout << '\n'
|
|
<<"Start FText( bool newDefined, const string newText )"
|
|
<<'\n'; )
|
|
if(newDefined){
|
|
Set( newDefined, newText );
|
|
}
|
|
LOGMSG( "FText:Trace",
|
|
std::cout <<"End FText( bool newDefined, const string newText )"
|
|
<<'\n'; )
|
|
}
|
|
|
|
|
|
inline FText::FText( const FText& f ) :
|
|
IndexableAttribute(f.IsDefined()),
|
|
theText( f.theText.getSize() )
|
|
{
|
|
LOGMSG( "FText:Trace", std::cout << '\n' <<"Start FText(FText& f)"<<'\n'; )
|
|
//SPM? Assuming Flob fits into memory
|
|
//const char* s = new char(f.theText.getSize());
|
|
theText.copyFrom( f.theText );
|
|
SetDefined( f.IsDefined() );
|
|
LOGMSG( "FText:Trace", std::cout <<"End FText(FText& f)"<<'\n'; )
|
|
|
|
}
|
|
|
|
inline FText::~FText()
|
|
{
|
|
LOGMSG( "FText:Trace", std::cout << '\n' <<"Start ~FText()"<<'\n'; )
|
|
LOGMSG( "FText:Trace", std::cout <<"End ~FText()"<<'\n'; )
|
|
}
|
|
|
|
inline void FText::Destroy()
|
|
{
|
|
theText.destroy();
|
|
SetDefined(false);
|
|
}
|
|
|
|
inline bool FText::SearchString( std::string subString )
|
|
{
|
|
std::string s = GetValue();
|
|
return s.find(subString) != std::string::npos;
|
|
}
|
|
|
|
inline void FText::Set( const char *newString )
|
|
{
|
|
LOGMSG( "FText:Trace",
|
|
std::cout << '\n'
|
|
<< "Start Set with *newString='"<< newString << std::endl; )
|
|
|
|
Set( true, newString );
|
|
|
|
LOGMSG( "FText:Trace", std::cout <<"End Set"<<'\n'; )
|
|
}
|
|
|
|
inline void FText::Set( bool newDefined, const char *newString )
|
|
{
|
|
LOGMSG( "FText:Trace",
|
|
std::cout << '\n' << "Start Set with *newString='"
|
|
<< newString << std::endl; )
|
|
|
|
theText.clean();
|
|
if( newString != NULL )
|
|
{
|
|
SHOW(theText)
|
|
SmiSize sz = strlen( newString ) + 1;
|
|
if(sz>0){
|
|
assert(newString[sz-1]==0);
|
|
theText.write( newString, sz);
|
|
} else {
|
|
char d=0;
|
|
theText.write(&d,1);
|
|
}
|
|
}
|
|
SetDefined( newDefined );
|
|
|
|
LOGMSG( "FText:Trace", std::cout <<"End Set"<<'\n'; )
|
|
}
|
|
|
|
inline void FText::Set( bool newDefined, const std::string& newString )
|
|
{
|
|
LOGMSG( "FText:Trace",
|
|
std::cout << '\n' << "Start Set with newString='"
|
|
<< newString << std::endl; )
|
|
Set(newDefined,newString.c_str());
|
|
}
|
|
|
|
|
|
inline int FText::TextLength() const
|
|
{
|
|
return theText.getSize() - 1;
|
|
}
|
|
|
|
|
|
inline size_t FText::Length() const
|
|
{
|
|
if(!IsDefined()){
|
|
return 0;
|
|
}
|
|
return std::max(0,(int)theText.getSize() - 1);
|
|
}
|
|
|
|
// SPM: caller is responsible for delete
|
|
inline char *FText::Get() const
|
|
{
|
|
assert(IsDefined());
|
|
SmiSize sz = theText.getSize();
|
|
if(sz==0){
|
|
char* s = new char[1];
|
|
s[0] = 0;
|
|
return s;
|
|
}
|
|
|
|
char* s = new char[sz];
|
|
bool ok = theText.read(s, sz);
|
|
assert(ok);
|
|
if(s[sz-1] !=0) {
|
|
std::cerr << "Warning: last char of a text flob is not 0." << std::endl;
|
|
size_t sl = strlen(s);
|
|
std::cerr << " sz = " << sz << ", strlen = " << sl << std::endl;
|
|
assert(sl <= sz);
|
|
}
|
|
return s;
|
|
}
|
|
|
|
inline const std::string FText::GetValue() const
|
|
{
|
|
char* s = Get();
|
|
std::string res(s);
|
|
delete [] s;
|
|
return res;
|
|
}
|
|
|
|
inline size_t FText::Sizeof() const
|
|
{
|
|
if(traces)
|
|
std::cout << '\n' << "Start Sizeof" << '\n';
|
|
return sizeof( *this );
|
|
}
|
|
|
|
inline FText* FText::Clone() const
|
|
{
|
|
return new FText( *this );
|
|
}
|
|
|
|
inline int FText::NumOfFLOBs() const
|
|
{
|
|
return 1;
|
|
}
|
|
|
|
inline Flob* FText::GetFLOB( const int i )
|
|
{
|
|
assert( i == 0 );
|
|
return &theText;
|
|
}
|
|
|
|
|
|
namespace ftext{
|
|
|
|
Word CreateFText( const ListExpr typeInfo );
|
|
|
|
void DeleteFText( const ListExpr typeInfo, Word& w );
|
|
|
|
void CloseFText( const ListExpr typeInfo, Word& w );
|
|
|
|
Word CloneFText( const ListExpr typeInfo, const Word& w );
|
|
|
|
int SizeOfFText();
|
|
|
|
void* CastFText( void* addr );
|
|
|
|
ListExpr OutFText( ListExpr typeInfo, Word value );
|
|
|
|
Word InFText( const ListExpr typeInfo, const ListExpr instance,
|
|
const int errorPos, ListExpr& errorInfo, bool& correct );
|
|
|
|
bool OpenFText( SmiRecord& valueRecord, size_t& offset,
|
|
const ListExpr typeInfo, Word& value );
|
|
|
|
bool SaveFText( SmiRecord& valueRecord, size_t& offset,
|
|
const ListExpr typeInfo, Word& value );
|
|
|
|
} // end namespace ftext
|
|
|
|
namespace SVG {
|
|
const std::string BasicType();
|
|
}
|
|
#endif
|
|
|