Codebase list readosm / d0ca1bb src / readosm.c
d0ca1bb

Tree @d0ca1bb (Download .tar.gz)

readosm.c @d0ca1bbraw · history · blame

/* 
/ readosm.c
/
/ ReadOSM main implementation (externally visible API)
/
/ version  1.1.0, 2017 September 25
/
/ Author: Sandro Furieri a.furieri@lqt.it
/
/ ------------------------------------------------------------------------------
/ 
/ Version: MPL 1.1/GPL 2.0/LGPL 2.1
/ 
/ The contents of this file are subject to the Mozilla Public License Version
/ 1.1 (the "License"); you may not use this file except in compliance with
/ the License. You may obtain a copy of the License at
/ http://www.mozilla.org/MPL/
/ 
/ Software distributed under the License is distributed on an "AS IS" basis,
/ WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
/ for the specific language governing rights and limitations under the
/ License.
/
/ The Original Code is the ReadOSM library
/
/ The Initial Developer of the Original Code is Alessandro Furieri
/ 
/ Portions created by the Initial Developer are Copyright (C) 2012-2017
/ the Initial Developer. All Rights Reserved.
/ 
/ Contributor(s):
/ 
/ Alternatively, the contents of this file may be used under the terms of
/ either the GNU General Public License Version 2 or later (the "GPL"), or
/ the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
/ in which case the provisions of the GPL or the LGPL are applicable instead
/ of those above. If you wish to allow use of your version of this file only
/ under the terms of either the GPL or the LGPL, and not to allow others to
/ use your version of this file under the terms of the MPL, indicate your
/ decision by deleting the provisions above and replace them with the notice
/ and other provisions required by the GPL or the LGPL. If you do not delete
/ the provisions above, a recipient may use your version of this file under
/ the terms of any one of the MPL, the GPL or the LGPL.
/ 
*/

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#if defined(_WIN32) && !defined(__MINGW32__)
/* MSVC: avoiding to include at all config.h */
#define VERSION	1.1.0
#else
#include "config.h"
#endif

#include "readosm.h"
#include "readosm_internals.h"

#ifdef _WIN32
#define strcasecmp	_stricmp
#endif /* not WIN32 */

static int
test_endianness ()
{
/* checks the current CPU endianness */
    readosm_endian4 endian4;
    endian4.bytes[0] = 0x01;
    endian4.bytes[1] = 0x00;
    endian4.bytes[2] = 0x00;
    endian4.bytes[3] = 0x00;
    if (endian4.uint32_value == 1)
	return READOSM_LITTLE_ENDIAN;
    return READOSM_BIG_ENDIAN;
}

static readosm_file *
alloc_osm_file (int little_endian_cpu, int format)
{
/* allocating and initializing the OSM input file struct */
    readosm_file *input = malloc (sizeof (readosm_file));
    if (!input)
	return NULL;
    input->magic1 = READOSM_MAGIC_START;
    input->file_format = format;
    input->little_endian_cpu = little_endian_cpu;
    input->magic2 = READOSM_MAGIC_END;
    input->in = NULL;
    return input;
}

static void
destroy_osm_file (readosm_file * input)
{
/* destroying the OSM input file struct */
    if (input)
      {
	  if (input->in)
	      fclose (input->in);
	  free (input);
      }
}

READOSM_DECLARE int
readosm_open (const char *path, const void **osm_handle)
{
/* opening and initializing the OSM input file */
    readosm_file *input;
    int len;
    int format;
    int little_endian_cpu = test_endianness ();

    *osm_handle = NULL;
    if (path == NULL || osm_handle == NULL)
	return READOSM_NULL_HANDLE;

    len = strlen (path);
    if (len > 4 && strcasecmp (path + len - 4, ".osm") == 0)
	format = READOSM_OSM_FORMAT;
    else if (len > 4 && strcasecmp (path + len - 4, ".pbf") == 0)
	format = READOSM_PBF_FORMAT;
    else
	return READOSM_INVALID_SUFFIX;

/* allocating the OSM input file struct */
    input = alloc_osm_file (little_endian_cpu, format);
    if (!input)
	return READOSM_INSUFFICIENT_MEMORY;
    *osm_handle = input;

    input->in = fopen (path, "rb");
    if (input->in == NULL)
	return READOSM_FILE_NOT_FOUND;

    return READOSM_OK;
}

READOSM_DECLARE int
readosm_close (const void *osm_handle)
{
/* attempting to destroy the OSM input file */
    readosm_file *input = (readosm_file *) osm_handle;
    if (!input)
	return READOSM_NULL_HANDLE;
    if ((input->magic1 == READOSM_MAGIC_START)
	&& input->magic2 == READOSM_MAGIC_END)
	;
    else
	return READOSM_INVALID_HANDLE;

/* destroying the workbook */
    destroy_osm_file (input);

    return READOSM_OK;
}

READOSM_DECLARE int
readosm_parse (const void *osm_handle, const void *user_data,
	       readosm_node_callback node_fnct, readosm_way_callback way_fnct,
	       readosm_relation_callback relation_fnct)
{
/* attempting to parse the OSM input file */
    int ret;
    readosm_file *input = (readosm_file *) osm_handle;
    if (!input)
	return READOSM_NULL_HANDLE;
    if ((input->magic1 == READOSM_MAGIC_START)
	&& input->magic2 == READOSM_MAGIC_END)
	;
    else
	return READOSM_INVALID_HANDLE;

    if (input->file_format == READOSM_OSM_FORMAT)
	ret =
	    parse_osm_xml (input, user_data, node_fnct, way_fnct,
			   relation_fnct);
    else if (input->file_format == READOSM_PBF_FORMAT)
	ret =
	    parse_osm_pbf (input, user_data, node_fnct, way_fnct,
			   relation_fnct);
    else
	return READOSM_INVALID_HANDLE;

    return ret;
}

READOSM_DECLARE const char *
readosm_version (void)
{
/* returning the current ReadOSM version string */
    return VERSION;
}