/*------------------------------------------------------------------------ * object from tokens */ ogc_time_origin * ogc_time_origin :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int same; int end; int num; ogc_time_origin * obj = OGC_NULL; const char * origin; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !is_kwd(kwd) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 2 tokens: TIMEEXTENT[ start, end ... */ if ( same < 2 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 2 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ origin = arr[start++].str; /*--------------------------------------------------------- * Now process all sub-objects */ #if 0 /* who cares? */ int next = 0; for (int i = start; i < end; i = next) { /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } #endif /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(origin, err); } if ( obj == OGC_NULL ) { } return obj; }
/*------------------------------------------------------------------------ * object from tokens */ ogc_meridian * ogc_meridian :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int end; int same; int num; ogc_meridian * obj = OGC_NULL; ogc_angunit * angunit = OGC_NULL; double value; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !is_kwd(kwd) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 1 token: MERIDIAN[ value ... */ if ( same < 1 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 1 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ value = ogc_string::atod( arr[start++].str ); /*--------------------------------------------------------- * Now process all sub-objects */ int next = 0; for (int i = start; i < end; i = next) { if ( ogc_angunit::is_kwd(arr[i].str) ) { if ( angunit != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_UNIT, obj_kwd()); bad = true; } else { angunit = ogc_angunit::from_tokens(t, i, &next, err); if ( angunit == OGC_NULL ) bad = true; } continue; } /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(value, angunit, err); } if ( obj == OGC_NULL ) { ogc_angunit :: destroy( angunit ); } return obj; }
/*------------------------------------------------------------------------ * object from tokens */ ogc_parameter * ogc_parameter :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int end; int same; int num; ogc_parameter * obj = OGC_NULL; ogc_unit * unit = OGC_NULL; ogc_id * id = OGC_NULL; ogc_vector * ids = OGC_NULL; const char * name; double value; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !ogc_string::is_equal(kwd, obj_kwd()) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 2 tokens: PARAMETER[ "name", value ... */ if ( same < 2 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 2 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ name = arr[start++].str; value = ogc_string::atod( arr[start++].str ); /*--------------------------------------------------------- * Now process all sub-objects */ int next = 0; for (int i = start; i < end; i = next) { if ( ogc_string::is_equal(arr[0].str, ogc_unit ::obj_kwd()) || ogc_string::is_equal(arr[0].str, ogc_angunit ::obj_kwd()) || ogc_string::is_equal(arr[0].str, ogc_lenunit ::obj_kwd()) || ogc_string::is_equal(arr[0].str, ogc_paramunit::obj_kwd()) || ogc_string::is_equal(arr[0].str, ogc_scaleunit::obj_kwd()) || ogc_string::is_equal(arr[0].str, ogc_timeunit ::obj_kwd()) ) { if ( unit != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_UNIT, obj_kwd()); bad = true; } else { unit = ogc_unit::from_tokens(t, i, &next, err); if ( unit == OGC_NULL ) bad = true; } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_id::obj_kwd()) || ogc_string::is_equal(arr[i].str, ogc_id::alt_kwd()) ) { id = ogc_id::from_tokens(t, i, &next, err); if ( id == OGC_NULL ) { bad = true; } else { if ( ids == OGC_NULL ) { ids = ogc_vector::create(1, 1); if ( ids == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } if ( ids != OGC_NULL ) { void * p = ids->find( id, false, ogc_utils::compare_id); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_ID, obj_kwd(), id->name()); delete id; bad = true; } else { if ( ids->add( id ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } } } continue; } /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(name, value, unit, ids, err); } if ( obj == OGC_NULL ) { ogc_unit :: destroy( unit ); ogc_vector :: destroy( ids ); } return obj; }
/*------------------------------------------------------------------------ * object from tokens */ ogc_id * ogc_id :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int end; int same; int num; ogc_id * obj = OGC_NULL; ogc_citation * citation = OGC_NULL; ogc_uri * uri = OGC_NULL; const char * name; const char * identifier; const char * version; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !is_kwd(kwd) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 2 or 3 tokens: ID[ "name", "identity" ... * (version is optional) */ if ( same < 2 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 3 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ name = arr[start++].str; identifier = arr[start++].str; if ( same > 2 ) version = arr[start++].str; else version = ""; /*--------------------------------------------------------- * Now process all sub-objects */ int next = 0; for (int i = start; i < end; i = next) { if ( ogc_citation::is_kwd(arr[i].str) ) { if ( citation != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_CITATION, obj_kwd()); bad = true; } else { citation = ogc_citation::from_tokens(t, i, &next, err); if ( citation == OGC_NULL ) bad = true; } continue; } if ( ogc_uri::is_kwd(arr[i].str) ) { if ( uri != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_URI, obj_kwd()); bad = true; } else { uri = ogc_uri::from_tokens(t, i, &next, err); if ( uri == OGC_NULL ) bad = true; } continue; } /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(name, identifier, version, citation, uri, err); } if ( obj == OGC_NULL ) { ogc_citation :: destroy( citation ); ogc_uri :: destroy( uri ); } return obj; }
/*------------------------------------------------------------------------ * object from tokens */ ogc_geog3d_crs * ogc_geog3d_crs :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int end; int same; int num; ogc_geog3d_crs * obj = OGC_NULL; ogc_geodetic_datum * datum = OGC_NULL; ogc_primem * primem = OGC_NULL; ogc_cs * cs = OGC_NULL; ogc_axis * axis = OGC_NULL; ogc_axis * axis_1 = OGC_NULL; ogc_axis * axis_2 = OGC_NULL; ogc_axis * axis_3 = OGC_NULL; ogc_unit * unit = OGC_NULL; ogc_scope * scope = OGC_NULL; ogc_extent * extent = OGC_NULL; ogc_vector * extents = OGC_NULL; ogc_id * id = OGC_NULL; ogc_vector * ids = OGC_NULL; ogc_remark * remark = OGC_NULL; const char * name; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !ogc_string::is_equal(kwd, obj_kwd()) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 1 token: GEOG3DCRS[ "name" ... */ if ( same < 1 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 1 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ name = arr[start++].str; /*--------------------------------------------------------- * Now process all sub-objects */ int next = 0; for (int i = start; i < end; i = next) { if ( ogc_string::is_equal(arr[i].str, ogc_geodetic_datum::obj_kwd()) ) { if ( datum != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_DATUM, obj_kwd()); bad = true; } else { datum = ogc_geodetic_datum::from_tokens(t, i, &next, err); if ( datum == OGC_NULL ) bad = true; } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_primem::obj_kwd()) ) { if ( primem != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_PRIMEM, obj_kwd()); bad = true; } else { primem = ogc_primem::from_tokens(t, i, &next, err); if ( primem == OGC_NULL ) bad = true; } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_cs::obj_kwd()) ) { if ( cs != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_CS, obj_kwd()); bad = true; } else { cs = ogc_cs::from_tokens(t, i, &next, err); if ( cs == OGC_NULL ) bad = true; } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_axis::obj_kwd()) ) { axis = ogc_axis::from_tokens(t, i, &next, err); if ( axis == OGC_NULL ) { bad = true; } else { if ( !ogc_utils::place_axis(axis, &axis_1, &axis_2, &axis_3, obj_kwd(), err) ) { delete axis; bad = true; } } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_lenunit::obj_kwd()) || ogc_string::is_equal(arr[i].str, ogc_lenunit::alt_kwd()) ) { if ( unit != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_UNIT, obj_kwd()); bad = true; } else { unit = ogc_unit::from_tokens(t, i, &next, err); if ( unit == OGC_NULL ) bad = true; } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_scope::obj_kwd()) ) { if ( scope != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_SCOPE, obj_kwd()); bad = true; } else { scope = ogc_scope::from_tokens(t, i, &next, err); if ( scope == OGC_NULL ) bad = true; } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_area_extent::obj_kwd()) || ogc_string::is_equal(arr[i].str, ogc_bbox_extent::obj_kwd()) || ogc_string::is_equal(arr[i].str, ogc_time_extent::obj_kwd()) || ogc_string::is_equal(arr[i].str, ogc_vert_extent::obj_kwd()) ) { extent = ogc_extent::from_tokens(t, i, &next, err); if ( extent == OGC_NULL ) { bad = true; } else { if ( extents == OGC_NULL ) { extents = ogc_vector::create(1, 1); if ( extents == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete extent; bad = true; } } if ( extents != OGC_NULL ) { void * p = extents->find( extent, false, ogc_utils::compare_extent); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_EXTENT, obj_kwd(), ogc_utils::obj_type_to_kwd(extent->obj_type())); delete extent; bad = true; } else { if ( extents->add( extent ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete extent; bad = true; } } } } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_id::obj_kwd()) || ogc_string::is_equal(arr[i].str, ogc_id::alt_kwd()) ) { id = ogc_id::from_tokens(t, i, &next, err); if ( id == OGC_NULL ) { bad = true; } else { if ( ids == OGC_NULL ) { ids = ogc_vector::create(1, 1); if ( ids == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } if ( ids != OGC_NULL ) { void * p = ids->find( id, false, ogc_utils::compare_id); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_ID, obj_kwd(), id->name()); delete id; bad = true; } else { if ( ids->add( id ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } } } continue; } if ( ogc_string::is_equal(arr[i].str, ogc_remark::obj_kwd()) ) { if ( remark != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_REMARK, obj_kwd()); bad = true; } else { remark = ogc_remark::from_tokens(t, i, &next, err); if ( remark == OGC_NULL ) bad = true; } continue; } /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(name, datum, primem, cs, axis_1, axis_2, axis_3, unit, scope, extents, ids, remark, err); } if ( obj == OGC_NULL ) { ogc_geodetic_datum :: destroy( datum ); ogc_primem :: destroy( primem ); ogc_cs :: destroy( cs ); ogc_axis :: destroy( axis_1 ); ogc_axis :: destroy( axis_2 ); ogc_axis :: destroy( axis_3 ); ogc_unit :: destroy( unit ); ogc_scope :: destroy( scope ); ogc_vector :: destroy( extents ); ogc_vector :: destroy( ids ); ogc_remark :: destroy( remark ); } return obj; }
/*------------------------------------------------------------------------ * object from tokens */ ogc_image_datum * ogc_image_datum :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int end; int same; int num; ogc_image_datum * obj = OGC_NULL; ogc_anchor * anchor = OGC_NULL; ogc_id * id = OGC_NULL; ogc_vector * ids = OGC_NULL; ogc_pixel_type pixel_type; const char * name; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !is_kwd(kwd) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 1 token: <kwd>[ "name", pixel_type ... */ if ( same < 2 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 2 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ name = arr[start++].str; pixel_type = ogc_utils::pixel_kwd_to_type( arr[start++].str ); if ( !ogc_utils::pixel_type_valid(pixel_type) ) { ogc_error::set(err, OGC_ERR_INVALID_PIXEL_TYPE, obj_kwd(), arr[start-1].str); bad = true; } /*--------------------------------------------------------- * Now process all sub-objects */ int next = 0; for (int i = start; i < end; i = next) { if ( ogc_anchor::is_kwd(arr[i].str) ) { if ( anchor != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_ANCHOR, obj_kwd()); bad = true; } else { anchor = ogc_anchor::from_tokens(t, i, &next, err); if ( anchor == OGC_NULL ) bad = true; } continue; } if ( ogc_id::is_kwd(arr[i].str) ) { id = ogc_id::from_tokens(t, i, &next, err); if ( id == OGC_NULL ) { bad = true; } else { if ( ids == OGC_NULL ) { ids = ogc_vector::create(1, 1); if ( ids == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } if ( ids != OGC_NULL ) { void * p = ids->find( id, false, ogc_utils::compare_id); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_ID, obj_kwd(), id->name()); delete id; bad = true; } else { if ( ids->add( id ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } } } continue; } /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(name, pixel_type, anchor, ids, err); } if ( obj == OGC_NULL ) { ogc_anchor :: destroy( anchor ); ogc_vector :: destroy( ids ); } return obj; }
/*------------------------------------------------------------------------ * object from tokens */ ogc_deriving_conv * ogc_deriving_conv :: from_tokens( const ogc_token * t, int start, int * pend, ogc_error * err) { const ogc_token_entry * arr; const char * kwd; bool bad = false; int level; int end; int same; int num; ogc_deriving_conv * obj = OGC_NULL; ogc_id * id = OGC_NULL; ogc_method * method = OGC_NULL; ogc_vector * parameters = OGC_NULL; ogc_vector * param_files = OGC_NULL; ogc_parameter * param = OGC_NULL; ogc_param_file * param_file = OGC_NULL; ogc_vector * ids = OGC_NULL; const char * name; /*--------------------------------------------------------- * sanity checks */ if ( t == OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_EMPTY_STRING, obj_kwd()); return OGC_NULL; } arr = t->_arr; if ( start < 0 || start >= t->_num ) { ogc_error::set(err, OGC_ERR_WKT_INDEX_OUT_OF_RANGE, obj_kwd(), start); return OGC_NULL; } kwd = arr[start].str; if ( !is_kwd(kwd) ) { ogc_error::set(err, OGC_ERR_WKT_INVALID_KEYWORD, obj_kwd(), kwd); return OGC_NULL; } /*--------------------------------------------------------- * Get the level for this object, * the number of tokens at that level, * and the total number of tokens. */ level = arr[start].lvl; for (end = start+1; end < t->_num; end++) { if ( arr[end].lvl <= level ) break; } if ( pend != OGC_NULL ) *pend = end; num = (end - start); for (same = 0; same < num; same++) { if ( arr[start+same+1].lvl != level+1 || arr[start+same+1].idx == 0 ) break; } /*--------------------------------------------------------- * There must be 1 token: DERIVINGCONVERSION[ "name" ... */ if ( same < 1 ) { ogc_error::set(err, OGC_ERR_WKT_INSUFFICIENT_TOKENS, obj_kwd(), same); return OGC_NULL; } if ( same > 1 && get_strict_parsing() ) { ogc_error::set(err, OGC_ERR_WKT_TOO_MANY_TOKENS, obj_kwd(), same); return OGC_NULL; } start++; /*--------------------------------------------------------- * Process all non-object tokens. * They come first and are syntactically fixed. */ name = arr[start++].str; /*--------------------------------------------------------- * Now process all sub-objects */ int next = 0; for (int i = start; i < end; i = next) { if ( ogc_method::is_kwd(arr[i].str) ) { if ( method != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_METHOD, obj_kwd()); bad = true; } else { method = ogc_method::from_tokens(t, i, &next, err); if ( method == OGC_NULL ) bad = true; } continue; } if ( ogc_parameter::is_kwd(arr[i].str) ) { param = ogc_parameter::from_tokens(t, i, &next, err); if ( param == OGC_NULL ) { bad = true; } else { if ( parameters == OGC_NULL ) { parameters = ogc_vector::create(1, 1); if ( parameters == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete param; bad = true; } } if ( parameters != OGC_NULL ) { void * p = parameters->find( param, false, ogc_utils::compare_parameter); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_PARAMETER, obj_kwd(), param->name()); delete param; bad = true; } else { if ( parameters->add( param ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete param; bad = true; } } } } continue; } if ( ogc_param_file::is_kwd(arr[i].str) ) { param_file = ogc_param_file::from_tokens(t, i, &next, err); if ( param_file == OGC_NULL ) { bad = true; } else { if ( param_files == OGC_NULL ) { param_files = ogc_vector::create(1, 1); if ( param_files == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete param; bad = true; } } if ( param_files != OGC_NULL ) { void * p = param_files->find( param, false, ogc_utils::compare_param_file); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_PARAM_FILE, obj_kwd(), param->name()); delete param; bad = true; } else { if ( param_files->add( param ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete param; bad = true; } } } } continue; } if ( ogc_id::is_kwd(arr[i].str) ) { id = ogc_id::from_tokens(t, i, &next, err); if ( id == OGC_NULL ) { bad = true; } else { if ( ids == OGC_NULL ) { ids = ogc_vector::create(1, 1); if ( ids == OGC_NULL ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } if ( ids != OGC_NULL ) { void * p = ids->find( id, false, ogc_utils::compare_id); if ( p != OGC_NULL ) { ogc_error::set(err, OGC_ERR_WKT_DUPLICATE_ID, obj_kwd(), id->name()); delete id; bad = true; } else { if ( ids->add( id ) < 0 ) { ogc_error::set(err, OGC_ERR_NO_MEMORY, obj_kwd()); delete id; bad = true; } } } } continue; } /* unknown object, skip over it */ for (next = i+1; next < end; next++) { if ( (arr[next].lvl <= arr[i].lvl) ) break; } } /*--------------------------------------------------------- * Final checks */ /*--------------------------------------------------------- * Create the object */ if ( !bad ) { obj = create(name, method, parameters, param_files, ids, err); } if ( obj == OGC_NULL ) { ogc_method :: destroy( method ); ogc_vector :: destroy( parameters ); ogc_vector :: destroy( param_files ); ogc_vector :: destroy( ids ); } return obj; }