You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
806 lines
18 KiB
806 lines
18 KiB
/*
|
|
* $Id: location.c,v 1.1 2009/02/22 08:09:01 nicholas Exp $
|
|
*
|
|
* location.c: Translate Pilot location data formats
|
|
* (c) 2008, Jon Schewe
|
|
*
|
|
* This library is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU Library General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or (at
|
|
* your option) any later version.
|
|
*
|
|
* This library 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 Library
|
|
* General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Library General Public License
|
|
* along with this library; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
|
|
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
|
|
#include "pi-macros.h"
|
|
#include "pi-location.h"
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: new_Timezone
|
|
*
|
|
* Summary: Create empty timzone
|
|
*
|
|
* Parameters: Timezone_t*
|
|
*
|
|
* Returns: void
|
|
*
|
|
***********************************************************************/
|
|
void
|
|
new_Timezone(Timezone_t *a)
|
|
{
|
|
a->offset = 0;
|
|
a->t2 = 0;
|
|
a->dstStart.dayOfWeek = 0;
|
|
a->dstStart.weekOfMonth = 0;
|
|
a->dstStart.month = 0;
|
|
a->dstStart.unknown = 0;
|
|
a->dstEnd.dayOfWeek = 0;
|
|
a->dstEnd.weekOfMonth = 0;
|
|
a->dstEnd.month = 0;
|
|
a->dstEnd.unknown = 0;
|
|
a->dstObserved = 0;
|
|
a->t4 = 0;
|
|
a->unknown = 0;
|
|
a->name = NULL;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: new_Locatio
|
|
*
|
|
* Summary: Create empty location
|
|
*
|
|
* Parameters: Location_t*
|
|
*
|
|
* Returns: void
|
|
*
|
|
***********************************************************************/
|
|
void
|
|
new_Location(Location_t *a)
|
|
{
|
|
new_Timezone(&(a->tz));
|
|
a->unknownExists = 0;
|
|
a->unknown = 0;
|
|
a->latitude.degrees = 0;
|
|
a->latitude.minutes = 0;
|
|
a->latitude.direction = 0;
|
|
a->longitude.degrees = 0;
|
|
a->longitude.minutes = 0;
|
|
a->longitude.direction = 0;
|
|
a->note = NULL;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: copy_Timezone
|
|
*
|
|
* Summary: Copy the data from one timezone to another. The destination
|
|
* timezone event must already be cleared, either by creating new or by
|
|
* calling free_Timezone on it first.
|
|
*
|
|
* Parameters: Timezone_t*, Timezone_t*
|
|
*
|
|
* Returns: int -1 on failure (errno will be set), 0 on success
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
copy_Timezone(const Timezone_t *source, Timezone_t *dest)
|
|
{
|
|
|
|
dest->offset = source->offset;
|
|
dest->t2 = source->t2;
|
|
dest->dstStart.dayOfWeek = source->dstStart.dayOfWeek;
|
|
dest->dstStart.weekOfMonth = source->dstStart.weekOfMonth;
|
|
dest->dstStart.month = source->dstStart.month;
|
|
dest->dstStart.unknown = source->dstStart.unknown;
|
|
dest->dstEnd.dayOfWeek = source->dstEnd.dayOfWeek;
|
|
dest->dstEnd.weekOfMonth = source->dstEnd.weekOfMonth;
|
|
dest->dstEnd.month = source->dstEnd.month;
|
|
dest->dstEnd.unknown = source->dstEnd.unknown;
|
|
dest->dstObserved = source->dstObserved;
|
|
dest->t4 = source->t4;
|
|
dest->unknown = source->unknown;
|
|
if(NULL != source->name) {
|
|
dest->name = strdup(source->name);
|
|
} else {
|
|
dest->name = NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: copy_Location
|
|
*
|
|
* Summary: Copy the data from one location to another. The destination
|
|
* location event must already be cleared, either by creating new or by
|
|
* calling free_Location on it first.
|
|
*
|
|
* Parameters: Location_t*, Location_t*
|
|
*
|
|
* Returns: int -1 on failure (errno will be set), 0 on success
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
copy_Location(const Location_t *source, Location_t *dest)
|
|
{
|
|
int retval;
|
|
retval = copy_Timezone(&(source->tz), &(dest->tz));
|
|
if(0 != retval) {
|
|
return retval;
|
|
}
|
|
dest->unknownExists = source->unknownExists;
|
|
dest->unknown = source->unknown;
|
|
dest->latitude.degrees = source->latitude.degrees;
|
|
dest->latitude.minutes = source->latitude.minutes;
|
|
dest->latitude.direction = source->latitude.direction;
|
|
dest->longitude.degrees = source->longitude.degrees;
|
|
dest->longitude.minutes = source->longitude.minutes;
|
|
dest->longitude.direction = source->longitude.direction;
|
|
if(NULL != source->note) {
|
|
dest->note = strdup(source->note);
|
|
} else {
|
|
dest->note = NULL;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: free_Location
|
|
*
|
|
* Summary: Free the members of a location structure
|
|
*
|
|
* Parameters: Location_t*
|
|
*
|
|
* Returns: void
|
|
*
|
|
***********************************************************************/
|
|
void
|
|
free_Location(Location_t *loc)
|
|
{
|
|
free_Timezone(&(loc->tz));
|
|
|
|
if(loc->note != NULL) {
|
|
free(loc->note);
|
|
loc->note = NULL;
|
|
}
|
|
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: dup_Timezone
|
|
*
|
|
* Summary: Allocate memory for a new timezone that is a duplicate of this one and copy the data into it
|
|
*
|
|
* Parameters: Timezone_t*
|
|
*
|
|
* Returns: Timezone_t* or NULL if there isn't enough memory and errno is set to ENOMEM
|
|
*
|
|
***********************************************************************/
|
|
Timezone_t*
|
|
dup_Timezone(const Timezone_t *tz)
|
|
{
|
|
Timezone_t *retval = (Timezone_t*)malloc(sizeof(Timezone_t));
|
|
if(NULL == retval) {
|
|
errno = ENOMEM;
|
|
return NULL;
|
|
}
|
|
retval->offset = tz->offset;
|
|
retval->t2 = tz->t2;
|
|
memcpy(&(retval->dstStart), &(tz->dstStart), sizeof(DST_t));
|
|
memcpy(&(retval->dstEnd), &(tz->dstEnd), sizeof(DST_t));
|
|
retval->dstObserved = tz->dstObserved;
|
|
retval->t4 = tz->t4;
|
|
retval->unknown = tz->unknown;
|
|
if(NULL != tz->name) {
|
|
retval->name = strdup(tz->name);
|
|
} else {
|
|
retval->name = NULL;
|
|
}
|
|
|
|
return retval;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: free_Timezone
|
|
*
|
|
* Summary: Free the members of a timezone structure
|
|
*
|
|
* Parameters: Timezone_t*
|
|
*
|
|
* Returns: void
|
|
*
|
|
***********************************************************************/
|
|
void
|
|
free_Timezone(Timezone_t *tz) {
|
|
if(tz->name != NULL) {
|
|
free(tz->name);
|
|
tz->name = NULL;
|
|
}
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: unpack_DST
|
|
*
|
|
* Summary: Fill in the daylight savings time structure based on the raw record
|
|
* data
|
|
*
|
|
* Parameters: DST_t*, pi_buffer_t *buf
|
|
*
|
|
* Returns: -1 on error, 0 on success
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
unpack_DST(DST_t *dst, const pi_buffer_t *buf) {
|
|
return unpack_DST_p(dst, buf->data, 0);
|
|
}
|
|
/**
|
|
Does the work for unpack_DST given a position in buf
|
|
*/
|
|
int
|
|
unpack_DST_p(DST_t *dst, const unsigned char *data, const size_t position) {
|
|
uint8_t byte;
|
|
|
|
byte = get_byte(data+position);
|
|
switch(byte) {
|
|
case 0x00:
|
|
dst->dayOfWeek = sunday;
|
|
break;
|
|
case 0x01:
|
|
dst->dayOfWeek = monday;
|
|
break;
|
|
case 0x02:
|
|
dst->dayOfWeek = tuesday;
|
|
break;
|
|
case 0x03:
|
|
dst->dayOfWeek = wednesday;
|
|
break;
|
|
case 0x04:
|
|
dst->dayOfWeek = thursday;
|
|
break;
|
|
case 0x05:
|
|
dst->dayOfWeek = friday;
|
|
break;
|
|
case 0x06:
|
|
dst->dayOfWeek = saturday;
|
|
break;
|
|
default:
|
|
printf("Illegal value found in day of week: 0x%02X\n", byte);
|
|
return -1;
|
|
}
|
|
|
|
byte = get_byte(data+position+1);
|
|
switch(byte) {
|
|
case 0x00:
|
|
dst->weekOfMonth = first;
|
|
break;
|
|
case 0x01:
|
|
dst->weekOfMonth = second;
|
|
break;
|
|
case 0x02:
|
|
dst->weekOfMonth = third;
|
|
break;
|
|
case 0x03:
|
|
dst->weekOfMonth = fourth;
|
|
break;
|
|
case 0x04:
|
|
dst->weekOfMonth = last;
|
|
break;
|
|
default:
|
|
printf("Illegal value found in week: 0x%02Xd\n", byte);
|
|
return -1;
|
|
}
|
|
|
|
byte = get_byte(data+position+2);
|
|
switch(byte) {
|
|
case 0x00:
|
|
dst->month = none;
|
|
break;
|
|
case 0x01:
|
|
dst->month = january;
|
|
break;
|
|
case 0x02:
|
|
dst->month = february;
|
|
break;
|
|
case 0x03:
|
|
dst->month = march;
|
|
break;
|
|
case 0x04:
|
|
dst->month = april;
|
|
break;
|
|
case 0x05:
|
|
dst->month = may;
|
|
break;
|
|
case 0x06:
|
|
dst->month = june;
|
|
break;
|
|
case 0x07:
|
|
dst->month = july;
|
|
break;
|
|
case 0x08:
|
|
dst->month = august;
|
|
break;
|
|
case 0x09:
|
|
dst->month = september;
|
|
break;
|
|
case 0x0a:
|
|
dst->month = october;
|
|
break;
|
|
case 0x0b:
|
|
dst->month = november;
|
|
break;
|
|
case 0x0c:
|
|
dst->month = december;
|
|
break;
|
|
default:
|
|
printf("Illegal value found in month: 0x%02Xd\n", byte);
|
|
return -1;
|
|
}
|
|
|
|
dst->unknown = get_byte(data+position+3);
|
|
switch(dst->unknown) {
|
|
case 0x00:
|
|
case 0x01:
|
|
case 0x02:
|
|
case 0x03:
|
|
/*case 0x04:*/
|
|
break;
|
|
default:
|
|
printf("Bad value for DST.unknown: 0x%02x\n", dst->unknown);
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: unpack_timezone
|
|
*
|
|
* Summary: Fill in the timezone structure based on the raw record
|
|
* data
|
|
*
|
|
* Parameters: Timezone_t*, pi_buffer_t *buf, optional position in buf
|
|
*
|
|
* Returns: -1 on error, number of bytes read on success
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
unpack_Timezone(Timezone_t *tz, const pi_buffer_t *buf) {
|
|
return unpack_Timezone_p(tz, buf->data, 0);
|
|
}
|
|
/**
|
|
* Does the work of unpack_Timezone given a position in buf.
|
|
*
|
|
* Returns: -1 on error, number of bytes read on success
|
|
*/
|
|
int
|
|
unpack_Timezone_p(Timezone_t *tz, const unsigned char *data, const size_t position) {
|
|
uint8_t byte;
|
|
size_t localPosition = position;
|
|
|
|
tz->offset = get_short(data+localPosition);
|
|
localPosition += 2;
|
|
/*printf("Offset is %d\n", tz->offset);*/
|
|
|
|
tz->t2 = get_byte(data + localPosition);
|
|
++localPosition;
|
|
switch(tz->t2) {
|
|
case 0x00:
|
|
break;
|
|
case 0x01:
|
|
break;
|
|
case 0x02:
|
|
break;
|
|
case 0x03:
|
|
break;
|
|
default:
|
|
/*printf("Bad value for t2 0x%02X\n", tz->t2);*/
|
|
return -1;
|
|
}
|
|
|
|
if(unpack_DST_p(&(tz->dstStart), data, localPosition) != 0) {
|
|
return -1;
|
|
}
|
|
localPosition += 4;
|
|
|
|
if(unpack_DST_p(&(tz->dstEnd), data, localPosition) != 0) {
|
|
return -1;
|
|
}
|
|
localPosition += 4;
|
|
|
|
byte = get_byte(data+localPosition);
|
|
++localPosition;
|
|
switch(byte) {
|
|
case 0x3c:
|
|
/* dst observed */
|
|
tz->dstObserved = 1;
|
|
break;
|
|
case 0x00:
|
|
/* dst not observed */
|
|
tz->dstObserved = 0;
|
|
break;
|
|
default:
|
|
printf("Illegal value in dst_observed 0x%02X\n", byte);
|
|
return -1;
|
|
}
|
|
|
|
tz->t4 = get_byte(data+localPosition);
|
|
++localPosition;
|
|
|
|
tz->unknown = get_byte(data+localPosition);
|
|
++localPosition;
|
|
switch(tz->unknown) {
|
|
case 0x80:
|
|
case 0x00:
|
|
break;
|
|
default:
|
|
printf("Bad value for unknown 0x%02X\n", tz->unknown);
|
|
return -1;
|
|
}
|
|
|
|
if(0x00 == data+localPosition) {
|
|
tz->name = NULL;
|
|
++localPosition;
|
|
} else {
|
|
tz->name = strdup((char *)(data+localPosition));
|
|
localPosition += strlen(tz->name) + 1;
|
|
}
|
|
|
|
return localPosition;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: unpack_Location
|
|
*
|
|
* Summary: Fill in the location structure based on the raw record
|
|
* data
|
|
*
|
|
* Parameters: Location_t*, pi_buffer_t *buf
|
|
*
|
|
* Returns: -1 on error, 0 on success
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
unpack_Location(Location_t *loc, const pi_buffer_t *buf)
|
|
{
|
|
size_t localPosition = 0;
|
|
|
|
localPosition = unpack_Timezone_p(&(loc->tz), buf->data, localPosition);
|
|
if(localPosition < 0) {
|
|
return -1;
|
|
}
|
|
|
|
loc->unknownExists = 0;
|
|
|
|
/* unpack latitude */
|
|
loc->latitude.degrees = get_short(buf->data+localPosition);
|
|
loc->latitude.minutes = get_short(buf->data+localPosition+2);
|
|
if(loc->latitude.degrees > 90 || loc->latitude.degrees < -90
|
|
|| loc->latitude.minutes > 60 || loc->latitude.minutes < -60) {
|
|
/*
|
|
printf("latitude degrees out of range: %d or\n", loc->latitude.degrees);
|
|
printf("latitude minutes out of range: %d\n", loc->latitude.minutes);
|
|
*/
|
|
|
|
loc->unknownExists = 1;
|
|
loc->unknown = get_byte(buf->data+localPosition);
|
|
++localPosition;
|
|
|
|
/*printf("Found unknown: 0x%02X\n", loc->unknown); */
|
|
|
|
loc->latitude.degrees = get_short(buf->data+localPosition);
|
|
localPosition += 2;
|
|
loc->latitude.minutes = get_short(buf->data+localPosition);
|
|
localPosition += 2;
|
|
} else {
|
|
localPosition += 4;
|
|
}
|
|
|
|
loc->longitude.degrees = get_short(buf->data+localPosition);
|
|
localPosition += 2;
|
|
loc->longitude.minutes = get_short(buf->data+localPosition);
|
|
localPosition += 2;
|
|
|
|
/* now make latitude and longitude easy to read */
|
|
loc->latitude.direction = south;
|
|
loc->longitude.direction = west;
|
|
if(loc->latitude.minutes < 0) {
|
|
loc->latitude.direction = north;
|
|
loc->latitude.minutes = -1 * loc->latitude.minutes;
|
|
}
|
|
if(loc->latitude.degrees < 0) {
|
|
loc->latitude.direction = north;
|
|
loc->latitude.degrees = -1 * loc->latitude.degrees;
|
|
}
|
|
if(loc->longitude.minutes < 0) {
|
|
loc->longitude.direction = east;
|
|
loc->longitude.minutes = -1 * loc->longitude.minutes;
|
|
}
|
|
if(loc->longitude.degrees < 0) {
|
|
loc->longitude.direction = east;
|
|
loc->longitude.degrees = -1 * loc->longitude.degrees;
|
|
}
|
|
|
|
|
|
if(0x00 == buf->data[localPosition]) {
|
|
loc->note = NULL;
|
|
++localPosition;
|
|
} else {
|
|
loc->note = strdup((char *)(buf->data+localPosition));
|
|
localPosition += strlen(loc->note) + 1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: pack_DST
|
|
*
|
|
* Summary: append raw DST record data to buf based on the
|
|
* DST structure
|
|
*
|
|
* Parameters: DST_t*, pi_buffer_t *buf of record, record type
|
|
*
|
|
* Returns: -1 on error, 0 on success.
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
pack_DST(const DST_t *dst, pi_buffer_t *buf)
|
|
{
|
|
size_t offset;
|
|
|
|
if (dst == NULL || buf == NULL)
|
|
return -1;
|
|
|
|
offset = buf->used;
|
|
|
|
pi_buffer_expect(buf, buf->used + 4);
|
|
buf->used = buf->used + 4;
|
|
|
|
switch(dst->dayOfWeek) {
|
|
case sunday:
|
|
set_byte(buf->data+offset, 0x00);
|
|
break;
|
|
case monday:
|
|
set_byte(buf->data+offset, 0x01);
|
|
break;
|
|
case tuesday:
|
|
set_byte(buf->data+offset, 0x02);
|
|
break;
|
|
case wednesday:
|
|
set_byte(buf->data+offset, 0x03);
|
|
break;
|
|
case thursday:
|
|
set_byte(buf->data+offset, 0x04);
|
|
break;
|
|
case friday:
|
|
set_byte(buf->data+offset, 0x05);
|
|
break;
|
|
case saturday:
|
|
set_byte(buf->data+offset, 0x06);
|
|
break;
|
|
default:
|
|
return -1;
|
|
|
|
}
|
|
|
|
switch(dst->weekOfMonth) {
|
|
case first:
|
|
set_byte(buf->data+offset+1, 0x00);
|
|
break;
|
|
case second:
|
|
set_byte(buf->data+offset+1, 0x01);
|
|
break;
|
|
case third:
|
|
set_byte(buf->data+offset+1, 0x02);
|
|
break;
|
|
case fourth:
|
|
set_byte(buf->data+offset+1, 0x03);
|
|
break;
|
|
case last:
|
|
set_byte(buf->data+offset+1, 0x04);
|
|
break;
|
|
default:
|
|
return -1;
|
|
|
|
}
|
|
|
|
switch(dst->month) {
|
|
case none:
|
|
set_byte(buf->data+offset+2, 0x00);
|
|
break;
|
|
case january:
|
|
set_byte(buf->data+offset+2, 0x01);
|
|
break;
|
|
case february:
|
|
set_byte(buf->data+offset+2, 0x02);
|
|
break;
|
|
case march:
|
|
set_byte(buf->data+offset+2, 0x03);
|
|
break;
|
|
case april:
|
|
set_byte(buf->data+offset+2, 0x04);
|
|
break;
|
|
case may:
|
|
set_byte(buf->data+offset+2, 0x05);
|
|
break;
|
|
case june:
|
|
set_byte(buf->data+offset+2, 0x06);
|
|
break;
|
|
case july:
|
|
set_byte(buf->data+offset+2, 0x07);
|
|
break;
|
|
case august:
|
|
set_byte(buf->data+offset+2, 0x08);
|
|
break;
|
|
case september:
|
|
set_byte(buf->data+offset+2, 0x09);
|
|
break;
|
|
case october:
|
|
set_byte(buf->data+offset+2, 0x0a);
|
|
break;
|
|
case november:
|
|
set_byte(buf->data+offset+2, 0x0b);
|
|
break;
|
|
case december:
|
|
set_byte(buf->data+offset+2, 0x0c);
|
|
break;
|
|
default:
|
|
return -1;
|
|
}
|
|
|
|
set_byte(buf->data+offset+3, dst->unknown);
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: pack_Timezone
|
|
*
|
|
* Summary: Append the raw Timezone record to buf based on the
|
|
* Timezone structure
|
|
*
|
|
* Parameters: Timezone_t*, pi_buffer_t *buf of record, record type
|
|
*
|
|
* Returns: -1 on error, 0 on success.
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
pack_Timezone(const Timezone_t *tz, pi_buffer_t *buf)
|
|
{
|
|
|
|
size_t offset;
|
|
|
|
if (tz == NULL || buf == NULL)
|
|
return -1;
|
|
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used + 3);
|
|
buf->used = buf->used + 3;
|
|
|
|
set_short(buf->data+offset, tz->offset);
|
|
set_byte(buf->data+offset+2, tz->t2);
|
|
|
|
pack_DST(&(tz->dstStart), buf);
|
|
pack_DST(&(tz->dstEnd), buf);
|
|
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used + 3);
|
|
buf->used = buf->used + 3;
|
|
|
|
if(tz->dstObserved) {
|
|
set_byte(buf->data+offset, 0x3c);
|
|
} else {
|
|
set_byte(buf->data+offset, 0x00);
|
|
}
|
|
set_byte(buf->data+offset, tz->t4);
|
|
|
|
if(NULL != tz->name) {
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used + strlen(tz->name)+1);
|
|
buf->used = buf->used + strlen(tz->name)+1;
|
|
|
|
strcpy((char *)(buf->data+offset), tz->name);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/***********************************************************************
|
|
*
|
|
* Function: pack_Location
|
|
*
|
|
* Summary: Append the raw Location record to buf based on the
|
|
* Location structure
|
|
*
|
|
* Parameters: Location_t*, pi_buffer_t *buf of record, record type
|
|
*
|
|
* Returns: -1 on error, 0 on success.
|
|
*
|
|
***********************************************************************/
|
|
int
|
|
pack_Location(const Location_t *loc, pi_buffer_t *buf)
|
|
{
|
|
size_t offset;
|
|
|
|
if (loc == NULL || buf == NULL)
|
|
return -1;
|
|
|
|
pack_Timezone(&(loc->tz), buf);
|
|
|
|
if(loc->unknownExists) {
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used + 1);
|
|
buf->used = buf->used+1;
|
|
set_byte(buf->data+offset, loc->unknown);
|
|
}
|
|
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used+8);
|
|
buf->used = buf->used+8;
|
|
|
|
if(loc->latitude.direction == north) {
|
|
set_short(buf->data+offset, -1 * loc->latitude.degrees);
|
|
set_short(buf->data+offset+2, -1 * loc->latitude.minutes);
|
|
} else {
|
|
set_short(buf->data+offset, loc->latitude.degrees);
|
|
set_short(buf->data+offset+2, loc->latitude.minutes);
|
|
}
|
|
if(loc->longitude.direction == east) {
|
|
set_short(buf->data+offset+4, -1 * loc->longitude.degrees);
|
|
set_short(buf->data+offset+6, -1 * loc->longitude.minutes);
|
|
} else {
|
|
set_short(buf->data+offset+4, loc->longitude.degrees);
|
|
set_short(buf->data+offset+6, loc->longitude.minutes);
|
|
}
|
|
|
|
if(NULL != loc->note) {
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used + strlen(loc->note)+1);
|
|
buf->used = buf->used + strlen(loc->note)+1;
|
|
|
|
strcpy((char *)(buf->data+offset), loc->note);
|
|
} else {
|
|
offset = buf->used;
|
|
pi_buffer_expect(buf, buf->used + 1);
|
|
set_byte(buf->data+offset, 0);
|
|
buf->used = buf->used + 1;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* vi: set ts=8 sw=4 sts=4 noexpandtab: cin */
|
|
/* ex: set tabstop=4 expandtab: */
|
|
/* Local Variables: */
|
|
/* indent-tabs-mode: t */
|
|
/* c-basic-offset: 8 */
|
|
/* End: */
|