TestGrammar/src/ParseObjects.cpp
// choose one from provided links to validate further
// we select a link with all required values and with matching possible values 
// sometimes required values are missing, are inherited etc. 
// we use scoring mechanism
// +1 = if required key is missing
// +1 = if required key is different type
// +1 = if required key value doesn't correspond with possible value
// +5 = if possible value doesn't match and key is Type or Subtype
// grammar file with the lowest score is our selected link
choose one from provided links to validate further
we select a link with all required values and with matching possible values
sometimes required values are missing, are inherited etc.
we use scoring mechanism
+1 = if required key is missing
+1 = if required key is different type
+1 = if required key value doesn't correspond with possible value
+5 = if possible value doesn't match and key is Type or Subtype
grammar file with the lowest score is our selected link
choose one from provided links to validate further we select a link with all required values and with matching possible values sometimes required values are missing are inherited etc . we use scoring mechanism + 1 = if required key is missing + 1 = if required key is different type + 1 = if required key value doesn ' t correspond with possible value + 5 = if possible value doesn ' t match and key is Type or Subtype grammar file with the lowest score is our selected link
std::string CParsePDF::select_one(PdsObject* obj, const std::string &links_string, std::string &obj_name) {
  if (links_string == "[]" || links_string == "")
    return "";
  std::vector<std::string> links = split(links_string.substr(1, links_string.size() - 2), ',');
  if (links.size() == 1)
    return links[0];
  int to_ret = -1;
  int min_score = 1000;
  for (auto i = 0; i < (int)links.size(); i++) {
    std::string function;
    auto lnk = extract_function(links[i], function);
    const std::vector<std::vector<std::string>>* data_list = get_grammar(lnk);
    auto j = 0;
    auto link_score = 0;
    if (obj->GetObjectType() == kPdsDictionary || obj->GetObjectType() == kPdsStream || obj->GetObjectType() == kPdsArray) {
      for (auto& vec : *data_list) {
        j++;
        if (vec[TSV_REQUIRED] != "TRUE")
          continue;
        PdsObject* inner_object = nullptr;
        if (obj->GetObjectType() == kPdsArray) {
          if (j-1 < ((PdsArray*)obj)->GetNumObjects())
            inner_object = ((PdsArray*)obj)->Get(j - 1);
        }
        else {
          PdsDictionary* dictObj = (PdsDictionary*)obj;
          if (obj->GetObjectType() == kPdsStream)
            dictObj = ((PdsStream*)obj)->GetStreamDict();
          if (dictObj->Known(utf8ToUtf16(vec[TSV_KEYNAME]).c_str()))
            inner_object = dictObj->Get(utf8ToUtf16(vec[TSV_KEYNAME]).c_str());
        }
        if (inner_object != nullptr) {
          int index = get_type_index(inner_object, vec[TSV_TYPE]);
          if (index != -1 ) {
            std::wstring str_value;
            if (vec[TSV_POSSIBLEVALUES] != "" && !check_possible_values(inner_object, vec[TSV_POSSIBLEVALUES], index, str_value))
              if (vec[TSV_KEYNAME] == "Type" || vec[TSV_KEYNAME] == "Subtype")
                link_score += 5;
              else link_score++;
          } else link_score++;
        } else link_score++;
      } 
    }
    if (min_score > link_score) {
      to_ret = i;
      min_score = link_score;
    }
  }
  if (to_ret != -1) {
    std::string function;
    auto lnk = extract_function(links[to_ret], function);
    obj_name += " (as " + lnk + ")";
    return links[to_ret];
  }
  output << "Error: Can't select any link from " << links_string <<" to validate provided object: " << obj_name; 
  if (obj->GetId() != 0)
    output << " for object " << obj->GetId();
  output << std::endl;
  return "";
}
std :: string CParsePDF :: select_one ( PdsObject * obj , const std :: string & links_string , std :: string & obj_name ) { if ( links_string == " " || links_string == " " ) return " " ; std :: vector < std :: string > links = split ( links_string . substr ( 1 , links_string . size ( ) - 2 ) , ' ' ) ; if ( links . size ( ) == 1 ) return links [ 0 ] ; int to_ret = -1 ; int min_score = 1000 ; for ( auto i = 0 ; i < ( int ) links . size ( ) ; i ++ ) { std :: string function ; auto lnk = extract_function ( links [ i ] , function ) ; const std :: vector < std :: vector < std :: string > > * data_list = get_grammar ( lnk ) ; auto j = 0 ; auto link_score = 0 ; if ( obj -> GetObjectType ( ) == kPdsDictionary || obj -> GetObjectType ( ) == kPdsStream || obj -> GetObjectType ( ) == kPdsArray ) { for ( auto & vec : * data_list ) { j ++ ; if ( vec [ TSV_REQUIRED ] != " " ) continue ; PdsObject * inner_object = nullptr ; if ( obj -> GetObjectType ( ) == kPdsArray ) { if ( j - 1 < ( ( PdsArray * ) obj ) -> GetNumObjects ( ) ) inner_object = ( ( PdsArray * ) obj ) -> Get ( j - 1 ) ; } else { PdsDictionary * dictObj = ( PdsDictionary * ) obj ; if ( obj -> GetObjectType ( ) == kPdsStream ) dictObj = ( ( PdsStream * ) obj ) -> GetStreamDict ( ) ; if ( dictObj -> Known ( utf8ToUtf16 ( vec [ TSV_KEYNAME ] ) . c_str ( ) ) ) inner_object = dictObj -> Get ( utf8ToUtf16 ( vec [ TSV_KEYNAME ] ) . c_str ( ) ) ; } if ( inner_object != nullptr ) { int index = get_type_index ( inner_object , vec [ TSV_TYPE ] ) ; if ( index != -1 ) { std :: wstring str_value ; if ( vec [ TSV_POSSIBLEVALUES ] != " " && ! check_possible_values ( inner_object , vec [ TSV_POSSIBLEVALUES ] , index , str_value ) ) if ( vec [ TSV_KEYNAME ] == " " || vec [ TSV_KEYNAME ] == " " ) link_score += 5 ; else link_score ++ ; } else link_score ++ ; } else link_score ++ ; } } if ( min_score > link_score ) { to_ret = i ; min_score = link_score ; } } if ( to_ret != -1 ) { std :: string function ; auto lnk = extract_function ( links [ to_ret ] , function ) ; obj_name += " " + lnk + " " ; return links [ to_ret ] ; } output << " " << links_string << " " << obj_name ; if ( obj -> GetId ( ) != 0 ) output << " " << obj -> GetId ( ) ; output << std :: endl ; return " " ; }
choose one from provided links to validate further
we select a link with all required values and with matching possible values
sometimes required values are missing, are inherited etc.
choose one from provided links to validate further we select a link with all required values and with matching possible values sometimes required values are missing are inherited etc .
// checking all links to see which one is suitable for provided object  // are all "required" fields has to be present // and if required value is defined then has to match with possible value // only checking required keys //required value exists? //have required object, let's check possible values and compute score // for each key in grammar file // remembering the lowest score // if all required are there - return this position in list of links