|
|
@@ -1,579 +0,0 @@
|
|
|
-/*
|
|
|
- * Copyright (C) 2007-2012 Siemens AG
|
|
|
- *
|
|
|
- * This program is free software: you can redistribute it and/or modify
|
|
|
- * it under the terms of the GNU Lesser General Public License as published
|
|
|
- * by the Free Software Foundation, either version 3 of the License, or
|
|
|
- * (at your option) any later version.
|
|
|
- *
|
|
|
- * This program 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 Lesser General Public License for more details.
|
|
|
- * GNU Lesser General Public License for more details.
|
|
|
- *
|
|
|
- * You should have received a copy of the GNU Lesser General Public License
|
|
|
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
- */
|
|
|
-
|
|
|
-/*******************************************************************
|
|
|
- *
|
|
|
- * @author Daniel.Peintner.EXT@siemens.com
|
|
|
- * @version 0.6
|
|
|
- * @contact Joerg.Heuer@siemens.com
|
|
|
- *
|
|
|
- * <p>Code generated by EXIdizer</p>
|
|
|
- ********************************************************************/
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-#include "DecoderChannel.h"
|
|
|
-#include "CoderChannel.h"
|
|
|
-#include "BitInputStream.h"
|
|
|
-#include "EXITypes.h"
|
|
|
-
|
|
|
-#ifndef ABSTRACT_DECODER_CHANNEL_C
|
|
|
-#define ABSTRACT_DECODER_CHANNEL_C
|
|
|
-
|
|
|
-/* unsigned long == 64 bits, 10 * 7bits = 70 bits */
|
|
|
-#define MAX_OCTETS_FOR_UNSIGNED_INTEGER_64 10
|
|
|
-/* unsigned int == 32 bits, 5 * 7bits = 35 bits */
|
|
|
-#define MAX_OCTETS_FOR_UNSIGNED_INTEGER_32 5
|
|
|
-
|
|
|
-/* buffer for reading (arbitrary) large integer values */
|
|
|
-static unsigned int maskedOctets[MAX_OCTETS_FOR_UNSIGNED_INTEGER_64];
|
|
|
-
|
|
|
-
|
|
|
-static int _decodeUnsignedInteger(bitstream_t* stream, integer_t* iv, int negative) {
|
|
|
- int errn = 0;
|
|
|
- int i, k;
|
|
|
- uint8_t b;
|
|
|
-
|
|
|
- for (i = 0; i < MAX_OCTETS_FOR_UNSIGNED_INTEGER_64; i++) {
|
|
|
- /* Read the next octet */
|
|
|
- errn = decode(stream, &b);
|
|
|
- /* If the most significant bit of the octet was 1,
|
|
|
- another octet is going to come */
|
|
|
- if (b < 128) {
|
|
|
- /* no more octets */
|
|
|
-
|
|
|
- /* For negative values, the Unsigned Integer holds the
|
|
|
- * magnitude of the value minus 1 */
|
|
|
-
|
|
|
- switch(i) {
|
|
|
- case 0: /* 7 bits */
|
|
|
- if (negative) {
|
|
|
- iv->val.int8 = - ( b + 1);
|
|
|
- iv->type = EXI_INTEGER_8;
|
|
|
- } else {
|
|
|
- iv->val.uint8 = b;
|
|
|
- iv->type = EXI_UNSIGNED_INTEGER_8;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- case 1: /* 14 bits */
|
|
|
- maskedOctets[i] = b;
|
|
|
- iv->val.uint16 = 0;
|
|
|
- for (k = i; k >= 0 ; k--) {
|
|
|
- iv->val.uint16 = (iv->val.uint16 << 7) | maskedOctets[k];
|
|
|
- }
|
|
|
- if (negative) {
|
|
|
- iv->val.int16 = - ( iv->val.uint16 + 1 );
|
|
|
- iv->type = EXI_INTEGER_16;
|
|
|
- } else {
|
|
|
- iv->type = EXI_UNSIGNED_INTEGER_16;
|
|
|
- }
|
|
|
- return 0;
|
|
|
- case 2: /* 21 bits */
|
|
|
- case 3: /* 28 bits */
|
|
|
- maskedOctets[i] = b;
|
|
|
- iv->val.uint32 = 0;
|
|
|
- for (k = i; k >= 0 ; k--) {
|
|
|
- iv->val.uint32 = (iv->val.uint32 << 7) | maskedOctets[k];
|
|
|
- }
|
|
|
- if (negative) {
|
|
|
- iv->val.int32 = - ( iv->val.uint32 + 1 );
|
|
|
- if (iv->val.int32 <= INT16_MAX && iv->val.int32 >= INT16_MIN ) {
|
|
|
- iv->type = EXI_INTEGER_16;
|
|
|
- } else {
|
|
|
- iv->type = EXI_INTEGER_32;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (iv->val.uint32 <= UINT16_MAX) {
|
|
|
- iv->type = EXI_UNSIGNED_INTEGER_16;
|
|
|
- } else {
|
|
|
- iv->type = EXI_UNSIGNED_INTEGER_32;
|
|
|
- }
|
|
|
- }
|
|
|
- return 0;
|
|
|
- case 4: /* 35 bits */
|
|
|
- case 5: /* 42 bits */
|
|
|
- case 6: /* 49 bits */
|
|
|
- case 7: /* 56 bits */
|
|
|
- case 8: /* 63 bits */
|
|
|
- case 9: /* 70 bits */
|
|
|
- maskedOctets[i] = b;
|
|
|
- iv->val.uint64 = 0;
|
|
|
- for (k = i; k >= 0 ; k--) {
|
|
|
- iv->val.uint64 = (iv->val.uint64 << 7) | maskedOctets[k];
|
|
|
- }
|
|
|
- if (negative) {
|
|
|
- if (i > 8) {
|
|
|
- /* too large */
|
|
|
- return EXI_UNSUPPORTED_INTEGER_VALUE;
|
|
|
- }
|
|
|
- iv->val.int64 = - ( iv->val.uint64 + 1 );
|
|
|
- if (iv->val.int64 <= INT32_MAX && iv->val.int64 >= INT32_MIN ) {
|
|
|
- iv->type = EXI_INTEGER_32;
|
|
|
- } else {
|
|
|
- iv->type = EXI_INTEGER_64;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (iv->val.uint64 <= UINT32_MAX) {
|
|
|
- iv->type = EXI_UNSIGNED_INTEGER_32;
|
|
|
- /* iv->val.uint32 = iv->val.uint64;*/
|
|
|
- } else {
|
|
|
- iv->type = EXI_UNSIGNED_INTEGER_64;
|
|
|
- }
|
|
|
- }
|
|
|
- return 0;
|
|
|
- default:
|
|
|
- return EXI_UNSUPPORTED_INTEGER_VALUE;
|
|
|
- }
|
|
|
- } else {
|
|
|
- /* the 7 least significant bits hold the actual value */
|
|
|
- maskedOctets[i] = (b & 127);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- return EXI_UNSUPPORTED_INTEGER_VALUE;
|
|
|
-}
|
|
|
-
|
|
|
-int decodeUnsignedInteger(bitstream_t* stream, integer_t* iv) {
|
|
|
- return _decodeUnsignedInteger(stream, iv, 0);
|
|
|
-}
|
|
|
-
|
|
|
-int decodeUnsignedInteger16(bitstream_t* stream, uint16_t* uint16) {
|
|
|
- unsigned int mShift = 0;
|
|
|
- int errn = 0;
|
|
|
- uint8_t b;
|
|
|
- *uint16 = 0;
|
|
|
-
|
|
|
- do {
|
|
|
- /* 1. Read the next octet */
|
|
|
- errn = decode(stream, &b);
|
|
|
- /* 2. Multiply the value of the unsigned number represented by the 7
|
|
|
- * least significant
|
|
|
- * bits of the octet by the current multiplier and add the result to
|
|
|
- * the current value */
|
|
|
- *uint16 += (b & 127) << mShift;
|
|
|
- /* 3. Multiply the multiplier by 128 */
|
|
|
- mShift += 7;
|
|
|
- /* 4. If the most significant bit of the octet was 1, go back to step 1 */
|
|
|
- } while (errn >= 0 && (b >> 7) == 1);
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-int decodeUnsignedInteger32(bitstream_t* stream, uint32_t* uint32) {
|
|
|
- /* 0XXXXXXX ... 1XXXXXXX 1XXXXXXX */
|
|
|
- unsigned int mShift = 0;
|
|
|
- int errn = 0;
|
|
|
- uint8_t b;
|
|
|
- *uint32 = 0;
|
|
|
-
|
|
|
- do {
|
|
|
- /* 1. Read the next octet */
|
|
|
- errn = decode(stream, &b);
|
|
|
- /* 2. Multiply the value of the unsigned number represented by the 7
|
|
|
- * least significant
|
|
|
- * bits of the octet by the current multiplier and add the result to
|
|
|
- * the current value */
|
|
|
- *uint32 += (b & 127) << mShift;
|
|
|
- /* 3. Multiply the multiplier by 128 */
|
|
|
- mShift += 7;
|
|
|
- /* 4. If the most significant bit of the octet was 1, go back to step 1 */
|
|
|
- } while (errn >= 0 && (b >> 7) == 1);
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode an arbitrary precision non negative integer using a sequence of
|
|
|
- * octets. The most significant bit of the last octet is set to zero to
|
|
|
- * indicate sequence termination. Only seven bits per octet are used to
|
|
|
- * store the integer's value.
|
|
|
- */
|
|
|
-int decodeUnsignedInteger64(bitstream_t* stream, uint64_t* uint64) {
|
|
|
- unsigned int mShift = 0;
|
|
|
- int errn = 0;
|
|
|
- uint8_t b;
|
|
|
- *uint64 = 0L;
|
|
|
-
|
|
|
- do {
|
|
|
- errn = decode(stream, &b);
|
|
|
- *uint64 += ((uint64_t) (b & 127)) << mShift;
|
|
|
- mShift += 7;
|
|
|
- } while (errn >= 0 && (b >> 7) == 1);
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-int decodeInteger(bitstream_t* stream, integer_t* iv) {
|
|
|
- int b;
|
|
|
- int errn = decodeBoolean(stream, &b);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
-
|
|
|
- return _decodeUnsignedInteger(stream, iv, b);
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode an arbitrary precision integer using a sign bit followed by a
|
|
|
- * sequence of octets. The most significant bit of the last octet is set to
|
|
|
- * zero to indicate sequence termination. Only seven bits per octet are used
|
|
|
- * to store the integer's value.
|
|
|
- */
|
|
|
-int decodeInteger32(bitstream_t* stream, int32_t* int32) {
|
|
|
- int b;
|
|
|
- uint32_t uint32;
|
|
|
- int errn = decodeBoolean(stream, &b);
|
|
|
-
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
-
|
|
|
- if (b) {
|
|
|
- /* For negative values, the Unsigned Integer holds the
|
|
|
- * magnitude of the value minus 1 */
|
|
|
- errn = decodeUnsignedInteger32(stream, &uint32);
|
|
|
- *int32 = -(uint32 + 1);
|
|
|
- } else {
|
|
|
- /* positive */
|
|
|
- errn = decodeUnsignedInteger32(stream, &uint32);
|
|
|
- *int32 = (int32_t)(uint32);
|
|
|
- }
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode an arbitrary precision integer using a sign bit followed by a
|
|
|
- * sequence of octets. The most significant bit of the last octet is set to
|
|
|
- * zero to indicate sequence termination. Only seven bits per octet are used
|
|
|
- * to store the integer's value.
|
|
|
- */
|
|
|
-int decodeInteger64(bitstream_t* stream, int64_t* int64) {
|
|
|
- int b;
|
|
|
- uint64_t uint64;
|
|
|
- int errn = decodeBoolean(stream, &b);
|
|
|
-
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
-
|
|
|
- if (b) {
|
|
|
- /* For negative values, the Unsigned Integer holds the
|
|
|
- * magnitude of the value minus 1 */
|
|
|
- errn = decodeUnsignedInteger64(stream, &uint64);
|
|
|
- *int64 = -(uint64 + 1);
|
|
|
- } else {
|
|
|
- /* positive */
|
|
|
- errn = decodeUnsignedInteger64(stream, &uint64);
|
|
|
- *int64 = (int64_t)(uint64);
|
|
|
- }
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode a Float datatype as two consecutive Integers.
|
|
|
- * The first Integer represents the mantissa of the floating point
|
|
|
- * number and the second Integer represents the base-10 exponent
|
|
|
- * of the floating point number.
|
|
|
- */
|
|
|
-int decodeFloat(bitstream_t* stream, float_me_t* f) {
|
|
|
- int errn = decodeInteger64(stream, &f->mantissa);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- return decodeInteger32(stream, &f->exponent);
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode a decimal represented as a Boolean sign followed by two Unsigned
|
|
|
- * Integers. A sign value of zero (0) is used to represent positive Decimal
|
|
|
- * values and a sign value of one (1) is used to represent negative Decimal
|
|
|
- * values The first Integer represents the integral portion of the Decimal
|
|
|
- * value. The second positive integer represents the fractional portion of
|
|
|
- * the decimal with the digits in reverse order to preserve leading zeros.
|
|
|
- */
|
|
|
-int decodeDecimal(bitstream_t* stream, decimal_t* d) {
|
|
|
- int errn = decodeBoolean(stream, &d->negative);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- errn = decodeUnsignedInteger(stream, &d->integral);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- errn = decodeUnsignedInteger(stream, &d->reverseFraction);
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode a sequence of characters for a given length.
|
|
|
- */
|
|
|
-int decodeStringOnly(bitstream_t* stream, uint16_t len, string_ucs_t* s) {
|
|
|
- if (len > s->size) {
|
|
|
- /* not enough space */
|
|
|
- return EXI_ERROR_OUT_OF_STRING_BUFFER;
|
|
|
- }
|
|
|
- decodeCharacters(stream, len, s->codepoints);
|
|
|
- s->len = len;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode a length prefixed sequence of characters.
|
|
|
- */
|
|
|
-int decodeString(bitstream_t* stream, string_ucs_t* s) {
|
|
|
- int errn = decodeUnsignedInteger16(stream, &s->len);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- return decodeStringOnly(stream, s->len, s);
|
|
|
-}
|
|
|
-
|
|
|
-int decodeStringASCII(bitstream_t* stream, string_ascii_t* s) {
|
|
|
- uint16_t slen;
|
|
|
- int errn = decodeUnsignedInteger16(stream, &slen);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- if (s->size < slen) {
|
|
|
- return EXI_ERROR_OUT_OF_ASCII_BUFFER;
|
|
|
- }
|
|
|
-
|
|
|
- return decodeCharactersASCII(stream, slen, s->chars);
|
|
|
-
|
|
|
-}
|
|
|
-
|
|
|
-int decodeStringValue(bitstream_t* stream, string_ucs_t* s) {
|
|
|
- int errn = decodeUnsignedInteger16(stream, &s->len);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
-
|
|
|
- switch (s->len) {
|
|
|
- case 0:
|
|
|
- /* local value partition */
|
|
|
- return EXI_UNSUPPORTED_STRING_TABLE_LOCAL_HIT;
|
|
|
- case 1:
|
|
|
- /* found in global value partition */
|
|
|
- return EXI_UNSUPPORTED_STRING_TABLE_GLOBAL_HIT;
|
|
|
- default:
|
|
|
- /* not found in global value (and local value) partition
|
|
|
- * ==> string literal is encoded as a String with the length
|
|
|
- * incremented by two */
|
|
|
- return decodeStringOnly(stream, ((s->len) - 2), s);
|
|
|
- /* After encoding the string value, it is added to both the
|
|
|
- * associated "local" value string table partition and the global
|
|
|
- * value string table partition */
|
|
|
- /* addValue(context, value); */
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-int decodeRCSStringValue(bitstream_t* stream, rcs_t* rcs, string_ucs_t* s) {
|
|
|
- unsigned int i;
|
|
|
- uint32_t cp;
|
|
|
- int errn = decodeUnsignedInteger16(stream, &s->len);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
-
|
|
|
- switch (s->len) {
|
|
|
- case 0:
|
|
|
- /* local value partition */
|
|
|
- return EXI_UNSUPPORTED_STRING_TABLE_LOCAL_HIT;
|
|
|
- case 1:
|
|
|
- /* found in global value partition */
|
|
|
- return EXI_UNSUPPORTED_STRING_TABLE_GLOBAL_HIT;
|
|
|
- default:
|
|
|
- /* not found in global value (and local value) partition
|
|
|
- * ==> string literal is encoded as a String with the length
|
|
|
- * incremented by two */
|
|
|
- s->len = s->len - 2;
|
|
|
-
|
|
|
- if (s->len > s->size) {
|
|
|
- /* not enough space */
|
|
|
- return EXI_ERROR_OUT_OF_STRING_BUFFER;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < s->len && errn >= 0; i++) {
|
|
|
- errn = decodeNBitUnsignedInteger(stream, rcs->codingLength, &cp);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- s->codepoints[i] = rcs->codepoints[cp];
|
|
|
- }
|
|
|
- /* After encoding the string value, it is added to both the
|
|
|
- * associated "local" value string table partition and the global
|
|
|
- * value string table partition */
|
|
|
- /* addValue(context, value); */
|
|
|
- return 0;
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode a sequence of characters according to a given length.
|
|
|
- * Each character is represented by its UCS [ISO/IEC 10646]
|
|
|
- * code point encoded as an Unsigned Integer
|
|
|
- */
|
|
|
-int decodeCharacters(bitstream_t* stream, uint16_t len, uint32_t* chars) {
|
|
|
- unsigned int i;
|
|
|
- int errn = 0;
|
|
|
- for (i = 0; i < len && errn >= 0; i++) {
|
|
|
- errn = decodeUnsignedInteger32(stream, &chars[i]);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-int decodeCharactersASCII(bitstream_t* stream, uint16_t len, char* chars) {
|
|
|
- unsigned int i;
|
|
|
- uint32_t c;
|
|
|
- int errn = 0;
|
|
|
- for (i = 0; i < len && errn >= 0; i++) {
|
|
|
- errn = decodeUnsignedInteger32(stream, &c);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- if (c > 127) {
|
|
|
- return EXI_ERROR_CONVERSION_NO_ASCII_CHARACTERS;
|
|
|
- }
|
|
|
- chars[i] = c;
|
|
|
- }
|
|
|
- chars[i] = '\0';
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode a binary value as a length-prefixed sequence of octets.
|
|
|
- */
|
|
|
-int decodeBinary(bitstream_t* stream, bytes_t* bytes) {
|
|
|
- unsigned int i;
|
|
|
- uint8_t b;
|
|
|
- int errn = decodeUnsignedInteger16(stream, &bytes->len);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- if (bytes->len > bytes->size) {
|
|
|
- /* not enough space */
|
|
|
- return EXI_ERROR_OUT_OF_BYTE_BUFFER;
|
|
|
- }
|
|
|
-
|
|
|
- for (i = 0; i < bytes->len && errn >= 0; i++) {
|
|
|
- errn = decode(stream, &b);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- bytes->data[i] = (uint8_t)b;
|
|
|
- }
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Decode Date-Time as sequence of values representing the individual
|
|
|
- * components of the Date-Time.
|
|
|
- */
|
|
|
-int decodeDateTime(bitstream_t* stream, exi_datetime_type_t type, datetime_t* datetime){
|
|
|
- int errn;
|
|
|
-
|
|
|
- datetime->type = type;
|
|
|
-
|
|
|
- datetime->year = 0;
|
|
|
- datetime->monthDay = 0;
|
|
|
- datetime->time = 0;
|
|
|
- datetime->presenceFractionalSecs = 0;
|
|
|
- datetime->fractionalSecs = 0;
|
|
|
- datetime->presenceTimezone = 0;
|
|
|
- datetime->timezone = 0;
|
|
|
-
|
|
|
- switch (type) {
|
|
|
- case EXI_DATETIME_GYEAR: /* Year, [Time-Zone] */
|
|
|
- errn = decodeInteger32(stream, &datetime->year);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- datetime->year += DATETIME_YEAR_OFFSET;
|
|
|
- break;
|
|
|
- case EXI_DATETIME_GYEARMONTH: /* Year, MonthDay, [TimeZone] */
|
|
|
- case EXI_DATETIME_DATE:
|
|
|
- errn = decodeInteger32(stream, &datetime->year);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- datetime->year += DATETIME_YEAR_OFFSET;
|
|
|
- errn = decodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_MONTHDAY, &datetime->monthDay);
|
|
|
- break;
|
|
|
- case EXI_DATETIME_DATETIME: /* Year, MonthDay, Time, [FractionalSecs], [TimeZone] */
|
|
|
- /* e.g. "0001-01-01T00:00:00.111+00:33" */
|
|
|
- errn = decodeInteger32(stream, &datetime->year);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- datetime->year += DATETIME_YEAR_OFFSET;
|
|
|
- errn = decodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_MONTHDAY, &datetime->monthDay);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- /* Note: *no* break */
|
|
|
- case EXI_DATETIME_TIME: /* Time, [FractionalSecs], [TimeZone] */
|
|
|
- /* e.g. "12:34:56.135" */
|
|
|
- errn = decodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_TIME, &datetime->time);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- errn = decodeBoolean(stream, &datetime->presenceFractionalSecs);
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- if (datetime->presenceFractionalSecs) {
|
|
|
- errn = decodeUnsignedInteger32(stream, &datetime->fractionalSecs);
|
|
|
- }
|
|
|
- break;
|
|
|
- case EXI_DATETIME_GMONTH: /* MonthDay, [TimeZone] */
|
|
|
- /* e.g. "--12" */
|
|
|
- case EXI_DATETIME_GMONTHDAY: /* MonthDay, [TimeZone] */
|
|
|
- /* e.g. "--01-28" */
|
|
|
- case EXI_DATETIME_GDAY: /* MonthDay, [TimeZone] */
|
|
|
- /* "---16" */
|
|
|
- errn = decodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_MONTHDAY, &datetime->monthDay );
|
|
|
- break;
|
|
|
- default:
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- errn = decodeBoolean(stream, &datetime->presenceTimezone );
|
|
|
- if (errn < 0) {
|
|
|
- return errn;
|
|
|
- }
|
|
|
- if (datetime->presenceTimezone) {
|
|
|
- errn = decodeNBitUnsignedInteger(stream, DATETIME_NUMBER_BITS_TIMEZONE, &datetime->timezone);
|
|
|
- datetime->timezone -= DATETIME_TIMEZONE_OFFSET_IN_MINUTES;
|
|
|
- }
|
|
|
-
|
|
|
- return errn;
|
|
|
-}
|
|
|
-
|
|
|
-#endif
|
|
|
-
|