Exemplo n.º 1
0
void TestQgsField::convertCompatible()
{
  //test string field
  QgsField stringField( QStringLiteral( "string" ), QVariant::String, QStringLiteral( "string" ) );

  QVariant stringVar( "test string" );
  QVERIFY( stringField.convertCompatible( stringVar ) );
  QCOMPARE( stringVar.toString(), QString( "test string" ) );
  QVariant nullString = QVariant( QVariant::String );
  QVERIFY( stringField.convertCompatible( nullString ) );
  QCOMPARE( nullString.type(), QVariant::String );
  QVERIFY( nullString.isNull() );
  QVariant intVar( 5 );
  QVERIFY( stringField.convertCompatible( intVar ) );
  QCOMPARE( intVar.type(), QVariant::String );
  QCOMPARE( intVar, QVariant( "5" ) );
  QVariant nullInt = QVariant( QVariant::Int );
  QVERIFY( stringField.convertCompatible( nullInt ) );
  QCOMPARE( nullInt.type(), QVariant::String );
  QVERIFY( nullInt.isNull() );
  QVariant doubleVar( 1.25 );
  QVERIFY( stringField.convertCompatible( doubleVar ) );
  QCOMPARE( doubleVar.type(), QVariant::String );
  QCOMPARE( doubleVar, QVariant( "1.25" ) );
  QVariant nullDouble = QVariant( QVariant::Double );
  QVERIFY( stringField.convertCompatible( nullDouble ) );
  QCOMPARE( nullDouble.type(), QVariant::String );
  QVERIFY( nullDouble.isNull() );

  //test double
  QgsField doubleField( QStringLiteral( "double" ), QVariant::Double, QStringLiteral( "double" ) );

  stringVar = QVariant( "test string" );
  QVERIFY( !doubleField.convertCompatible( stringVar ) );
  QCOMPARE( stringVar.type(), QVariant::Double );
  QVERIFY( stringVar.isNull() );
  nullString = QVariant( QVariant::String );
  QVERIFY( doubleField.convertCompatible( nullString ) );
  QCOMPARE( nullString.type(), QVariant::Double );
  QVERIFY( nullString.isNull() );
  intVar = QVariant( 5 );
  QVERIFY( doubleField.convertCompatible( intVar ) );
  QCOMPARE( intVar.type(), QVariant::Double );
  QCOMPARE( intVar, QVariant( 5.0 ) );
  nullInt = QVariant( QVariant::Int );
  QVERIFY( doubleField.convertCompatible( nullInt ) );
  QCOMPARE( nullInt.type(), QVariant::Double );
  QVERIFY( nullInt.isNull() );
  doubleVar = QVariant( 1.25 );
  QVERIFY( doubleField.convertCompatible( doubleVar ) );
  QCOMPARE( doubleVar.type(), QVariant::Double );
  QCOMPARE( doubleVar, QVariant( 1.25 ) );
  nullDouble = QVariant( QVariant::Double );
  QVERIFY( doubleField.convertCompatible( nullDouble ) );
  QCOMPARE( nullDouble.type(), QVariant::Double );
  QVERIFY( nullDouble.isNull() );

  //test special rules

  //conversion of double to int
  QgsField intField( QStringLiteral( "int" ), QVariant::Int, QStringLiteral( "int" ) );
  //small double, should be rounded
  QVariant smallDouble( 45.7 );
  QVERIFY( intField.convertCompatible( smallDouble ) );
  QCOMPARE( smallDouble.type(), QVariant::Int );
  QCOMPARE( smallDouble, QVariant( 46 ) );
  QVariant negativeSmallDouble( -9345.754534525235235 );
  QVERIFY( intField.convertCompatible( negativeSmallDouble ) );
  QCOMPARE( negativeSmallDouble.type(), QVariant::Int );
  QCOMPARE( negativeSmallDouble, QVariant( -9346 ) );
  //large double, cannot be converted
  QVariant largeDouble( 9999999999.99 );
  QVERIFY( !intField.convertCompatible( largeDouble ) );
  QCOMPARE( largeDouble.type(), QVariant::Int );
  QVERIFY( largeDouble.isNull() );

  //conversion of string double value to int
  QVariant notNumberString( "notanumber" );
  QVERIFY( !intField.convertCompatible( notNumberString ) );
  QCOMPARE( notNumberString.type(), QVariant::Int );
  QVERIFY( notNumberString.isNull() );
  //small double, should be rounded
  QVariant smallDoubleString( "45.7" );
  QVERIFY( intField.convertCompatible( smallDoubleString ) );
  QCOMPARE( smallDoubleString.type(), QVariant::Int );
  QCOMPARE( smallDoubleString, QVariant( 46 ) );
  QVariant negativeSmallDoubleString( "-9345.754534525235235" );
  QVERIFY( intField.convertCompatible( negativeSmallDoubleString ) );
  QCOMPARE( negativeSmallDoubleString.type(), QVariant::Int );
  QCOMPARE( negativeSmallDoubleString, QVariant( -9346 ) );
  //large double, cannot be converted
  QVariant largeDoubleString( "9999999999.99" );
  QVERIFY( !intField.convertCompatible( largeDoubleString ) );
  QCOMPARE( largeDoubleString.type(), QVariant::Int );
  QVERIFY( largeDoubleString.isNull() );

  //conversion of longlong to int
  QVariant longlong( 99999999999999999LL );
  QVERIFY( !intField.convertCompatible( longlong ) );
  QCOMPARE( longlong.type(), QVariant::Int );
  QVERIFY( longlong.isNull() );
  QVariant smallLonglong( 99LL );
  QVERIFY( intField.convertCompatible( smallLonglong ) );
  QCOMPARE( smallLonglong.type(), QVariant::Int );
  QCOMPARE( smallLonglong, QVariant( 99 ) );
  //conversion of longlong to longlong field
  QgsField longlongField( QStringLiteral( "long" ), QVariant::LongLong, QStringLiteral( "longlong" ) );
  longlong = QVariant( 99999999999999999LL );
  QVERIFY( longlongField.convertCompatible( longlong ) );
  QCOMPARE( longlong.type(), QVariant::LongLong );
  QCOMPARE( longlong, QVariant( 99999999999999999LL ) );

  //string representation of an int
  QVariant stringInt( "123456" );
  QVERIFY( intField.convertCompatible( stringInt ) );
  QCOMPARE( stringInt.type(), QVariant::Int );
  QCOMPARE( stringInt, QVariant( 123456 ) );
  // now with group separator for english locale
  stringInt = QVariant( "123,456" );
  QVERIFY( intField.convertCompatible( stringInt ) );
  QCOMPARE( stringInt.type(), QVariant::Int );
  QCOMPARE( stringInt, QVariant( "123456" ) );

  //string representation of a longlong
  QVariant stringLong( "99999999999999999" );
  QVERIFY( longlongField.convertCompatible( stringLong ) );
  QCOMPARE( stringLong.type(), QVariant::LongLong );
  QCOMPARE( stringLong, QVariant( 99999999999999999LL ) );
  // now with group separator for english locale
  stringLong = QVariant( "99,999,999,999,999,999" );
  QVERIFY( longlongField.convertCompatible( stringLong ) );
  QCOMPARE( stringLong.type(), QVariant::LongLong );
  QCOMPARE( stringLong, QVariant( 99999999999999999LL ) );


  //string representation of a double
  QVariant stringDouble( "123456.012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 123456.012345 ) );
  // now with group separator for english locale
  stringDouble = QVariant( "1,223,456.012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 1223456.012345 ) );
  // This should not convert
  stringDouble = QVariant( "1.223.456,012345" );
  QVERIFY( ! doubleField.convertCompatible( stringDouble ) );


  //double with precision
  QgsField doubleWithPrecField( QStringLiteral( "double" ), QVariant::Double, QStringLiteral( "double" ), 10, 3 );
  doubleVar = QVariant( 10.12345678 );
  //note - this returns true!
  QVERIFY( doubleWithPrecField.convertCompatible( doubleVar ) );
  QCOMPARE( doubleVar.type(), QVariant::Double );
  QCOMPARE( doubleVar.toDouble(), 10.123 );

  //truncating string length
  QgsField stringWithLen( QStringLiteral( "string" ), QVariant::String, QStringLiteral( "string" ), 3 );
  stringVar = QVariant( "longstring" );
  QVERIFY( !stringWithLen.convertCompatible( stringVar ) );
  QCOMPARE( stringVar.type(), QVariant::String );
  QCOMPARE( stringVar.toString(), QString( "lon" ) );


  /////////////////////////////////////////////////////////
  // German locale tests

  //double with ',' as decimal separator for German locale
  QLocale::setDefault( QLocale::German );
  QVariant doubleCommaVar( "1,2345" );
  QVERIFY( doubleField.convertCompatible( doubleCommaVar ) );
  QCOMPARE( doubleCommaVar.type(), QVariant::Double );
  QCOMPARE( doubleCommaVar.toString(), QString( "1.2345" ) );

  //string representation of an int
  stringInt = QVariant( "123456" );
  QVERIFY( intField.convertCompatible( stringInt ) );
  QCOMPARE( stringInt.type(), QVariant::Int );
  QCOMPARE( stringInt, QVariant( 123456 ) );
  // now with group separator for german locale
  stringInt = QVariant( "123.456" );
  QVERIFY( intField.convertCompatible( stringInt ) );
  QCOMPARE( stringInt.type(), QVariant::Int );
  QCOMPARE( stringInt, QVariant( "123456" ) );

  //string representation of a longlong
  stringLong = QVariant( "99999999999999999" );
  QVERIFY( longlongField.convertCompatible( stringLong ) );
  QCOMPARE( stringLong.type(), QVariant::LongLong );
  QCOMPARE( stringLong, QVariant( 99999999999999999LL ) );
  // now with group separator for german locale
  stringLong = QVariant( "99.999.999.999.999.999" );
  QVERIFY( longlongField.convertCompatible( stringLong ) );
  QCOMPARE( stringLong.type(), QVariant::LongLong );
  QCOMPARE( stringLong, QVariant( 99999999999999999LL ) );

  //string representation of a double
  stringDouble = QVariant( "123456,012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 123456.012345 ) );
  // For doubles we also want to accept dot as a decimal point
  stringDouble = QVariant( "123456.012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 123456.012345 ) );
  // now with group separator for german locale
  stringDouble = QVariant( "1.223.456,012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 1223456.012345 ) );
  // Be are good citizens and we also accept english locale
  stringDouble = QVariant( "1,223,456.012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 1223456.012345 ) );

  // Test that wrongly formatted decimal separator are also accepted
  QLocale::setDefault( QLocale::German );
  stringDouble = QVariant( "12.23.456,012345" );
  QVERIFY( doubleField.convertCompatible( stringDouble ) );
  QCOMPARE( stringDouble.type(), QVariant::Double );
  QCOMPARE( stringDouble, QVariant( 1223456.012345 ) );

}
Exemplo n.º 2
0
// преобразование словаря групп времени в удобный для поиска вид
bool CSemanticsHolder::InitTimeUnits()
{
 // инициализация констант 
 BYTE GramFunctDomNo = GetRoss(TimeRoss)->GetDomenNoByDomStr("D_GRAM_FUNCT");
 int AbbrFunctName = GetRoss(TimeRoss)->GetItemNoByItemStr("СОКР", GramFunctDomNo);
 int AbbrFunctPluralName = GetRoss(TimeRoss)->GetItemNoByItemStr("СОКР_мн", GramFunctDomNo);
 m_TimeAbbrPairs.clear();
 m_TimeUnits.clear();
 
 // идем по всем статьям словаря групп времени 
 for (size_t UnitNo =0; UnitNo < GetRoss(TimeRoss)->GetUnitsSize(); UnitNo++)
 {
   try {
    
    CTimeUnit U;
    U.m_UnitNo = UnitNo;
	
	if (!GetRoss(TimeRoss)->IsEmptyArticle(UnitNo))
		// по словарной статье 
	for (size_t i = GetRoss(TimeRoss)->GetUnitStartPos(UnitNo); i<= GetRoss(TimeRoss)->GetUnitEndPos(UnitNo); i++)
	{
	  TCortege C = GetCortege(GetRoss(TimeRoss), i);
	  //незаполненное поле?
	  if (C.m_DomItemNos[0] == -1) continue;
	  // строю массив U.m_Places по полю CONTENT
	  string FieldStr = (const char*)GetRoss(TimeRoss)->Fields[C.m_FieldNo].FieldStr;
      if (    (FieldStr == "CONTENT") 
	       && (C.m_LeafId == 0) 
		   && (C.m_BracketLeafId == 0) 
		 )
	  {
		 string Lemma;
		 string Contents = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]);
 	     for (BYTE PlaceNo =0; GetLemmaFromTitle(Contents, PlaceNo, Lemma);  PlaceNo++)
	       U.m_Places.push_back(Lemma);
	  };
	 
      if (    (FieldStr == "RESTR") 
	       && (C.m_LeafId == 0) 
		   && (C.m_BracketLeafId == 0) 
		 )
	  {
		 string Contents = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]);
		 if (Contents == "свобод")
			 U.m_bCanFillNotTimeValency = true;
	  };

	  // инициализирую перечень всех необходимых синтаксических отношений их поля SYNREP
	  if (    (FieldStr == "SYNREP") 
	       && (C.m_LeafId == 0) 
		   && (C.m_BracketLeafId == 0) 
		 )
	  {
		  long PlaceNo1 = atoi(GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[1]));
		  long PlaceNo2 = atoi(GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[2]));
		  if (!PlaceNo1 || !PlaceNo2) continue;
		  string SynGrp = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]);
		  rml_TRACE  (SynGrp.c_str());
	      U.m_Rels.push_back(CSynRelation(PlaceNo1-1, PlaceNo2-1, SynGrp));
	  };

	  // инициализирую глобальный перечень наборов (полное временное слово, аббревиатура, аббревиатурная функция),
	  // который называется m_TimeAbbrPairs
	  // аббревиатурная функция = АББР_мн, АББР, АББР_ед
	  // например:(год, гг.,АББР_мн)
	  //          (год, г., АББР_ед)
  	  if (    (FieldStr == "DERIV") 
	       && (C.m_LeafId == 0) 
		   && (C.m_BracketLeafId == 0) 
		 )
	  {
		  if (    (C.m_DomItemNos[0] != AbbrFunctPluralName)
			   && (C.m_DomItemNos[0] != AbbrFunctName)
			 ) 
		  continue;
		  string FullForm = GetRoss(TimeRoss)->GetEntryStr(UnitNo);
		  EngRusMakeUpper(FullForm);
		  string AbbrForm = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[1]);
		  EngRusMakeUpper(AbbrForm);
		  m_TimeAbbrPairs.push_back(CAbbrFunct(AbbrForm, FullForm, GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0])));
	  };

	   // инициализирую перечень лексического заполнения дырок, который берется из 
	   // полей LEX и PREP

	   if   (FieldStr == "LEX")
		 {
		    string S =   GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]);
			EngRusMakeUpper(S);
			long LexFillingNoNo = U.GetLexicalFillingNo(CTimeLexicalFilling(C.m_LeafId, C.m_BracketLeafId));
			U.m_LexicalFillings[LexFillingNoNo].m_LexFets.push_back(stringLong(S,C.m_LevelId));
		 }
		 else
		 if (FieldStr == "PREP")
		 {
             string Prep = GetRossHolder(TimeRoss)->GetDomItemStrInner(C.m_DomItemNos[0]);
		     WORD PrepNo = GetRossHolder(OborRoss)->LocateUnit(Prep.c_str(),1);
             if (PrepNo == ErrUnitNo) 
			 {
				 string Q =Format ("Предлог %s в статье %s не найден в словаре оборотов", Prep.c_str(), GetRoss(TimeRoss)->GetEntryStr(UnitNo).c_str());
				 ErrorMessage (Q);
				 continue;
			 };
			 long LexFillingNoNo = U.GetLexicalFillingNo(CTimeLexicalFilling(C.m_LeafId, C.m_BracketLeafId));
			 U.m_LexicalFillings[LexFillingNoNo].m_Preps.push_back(LongLong(PrepNo,C.m_LevelId));
		 };

	};

	
	m_TimeUnits.push_back(U);
   }
	catch (...) 
	{
		ErrorMessage (Format("Cannot index article \"%s\"", GetRoss(TimeRoss)->GetEntryStr(UnitNo).c_str()));
		return false;
	};
   };
 
	return true;
};