X-Git-Url: https://git.teslayout.com/public/public/public/?a=blobdiff_plain;f=include%2Fanna%2Ftime%2FDate.hpp;h=c661419c2040f62d79f787cc9aa652785ecff2ca;hb=5a6cba5fde2b2f538a7515f8293cc0a8d9589dfa;hp=8d699ffd9ca924a47ffe528896144d3364bfa08a;hpb=3e258840b15577cb8bda3cdedd0b9b88e16404b3;p=anna.git diff --git a/include/anna/time/Date.hpp b/include/anna/time/Date.hpp index 8d699ff..c661419 100644 --- a/include/anna/time/Date.hpp +++ b/include/anna/time/Date.hpp @@ -1,37 +1,9 @@ -// ANNA - Anna is Not Nothingness Anymore -// -// (c) Copyright 2005-2014 Eduardo Ramos Testillano & Francisco Ruiz Rayo -// -// https://bitbucket.org/testillano/anna -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above -// copyright notice, this list of conditions and the following disclaimer -// in the documentation and/or other materials provided with the -// distribution. -// * Neither the name of Google Inc. nor the names of its -// contributors may be used to endorse or promote products derived from -// this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Authors: eduardo.ramos.testillano@gmail.com -// cisco.tierra@gmail.com +// ANNA - Anna is Not Nothingness Anymore // +// // +// (c) Copyright 2005-2015 Eduardo Ramos Testillano & Francisco Ruiz Rayo // +// // +// See project site at http://redmine.teslayout.com/projects/anna-suite // +// See accompanying file LICENSE or copy at http://www.teslayout.com/projects/public/anna.LICENSE // #ifndef anna_time_Date_hpp @@ -44,7 +16,7 @@ #include // Local -#include +#include namespace anna { @@ -56,27 +28,14 @@ class Node; //------------------------------------------------------------------------------ //---------------------------------------------------------------------- #define //------------------------------------------------------------------------------ -#define _2K38_EFFECT_LIMIT "20380119031407" // UTC - -// Era Unix: 01/01/1970 00:00:00 UTC -// Fecha NTP: 01/01/1900 00:00:00 UTC -// -> Segundos de 70 años ( de 1900 a 1970) : 2207520000 -// -> Entre 1900 y 1970 hay 17años bisiestos, por lo que hay que sumar 17 días: 1468800 Segundos -// TOTAL = 2207520000 + 1468800 : -// Significa que debemos restar el anterior valor para obtener un valor unix, y sumarlo para tener un timestamp NTP: -#define TIMESTAMP_OFFSET_NTP1900_OVER_UNIX1970 2208988800U - -// The NTP timestamp format represents seconds and fraction as a 64-bit unsigned fixed-point -// integer with decimal point to the left of bit 32 numbered from the left. The 32-bit seconds -// field spans about 136 years, while the 32-bit fraction field precision is about 232 picoseconds. - -// Para un timestamp NTP me bastan 32 bits, es decir 'unsigned int'. El tipo time_t es realmente un int. Cojo -// el mayor entre ambos: unsigned int. - - -#define STRING_FORMAT_yyyymmddHHmmss "%04d%02d%02d%02d%02d%02d" -#define STRPTIME_FORMAT_yyyy_mm_dd_HH_mm_ss "%Y-%m-%d-%H-%M-%S" +// Unix time reference: 01/01/1970 00:00:00 UTC +// NTP time reference: 01/01/1900 00:00:00 UTC +// -> 70 years have 2207520000 seconds. +// -> Between 1900 and 1970 there are 17 leap years: 1468800 seconds more (17 days) +// TOTAL DIFFERENCE = 2207520000 + 1468800 = 2208988800 +#define TIMESTAMP_OFFSET_NTP1900_OVER_UNIX1970 2208988800U +//#define _2K38_EFFECT_LIMIT "20380119031407" // UTC namespace anna { @@ -87,72 +46,64 @@ namespace time { /** * Absolute time representation structs class manager. * Allow any time assignment/extraction regarding any timezone. +* Uses shell TZ assignment or rely on system timezone configuration (in ubuntu, /etc/timezone +* stores the abbreviation and /etc/localtime keeps the timezone file from /usr/share/zoneinfo). * -* Certain methods could launch runtime exception when trying to get TZ from shell. +* The internal unix timestamp reamain constant and thedate representation depends on the +* configured timezone. Some store methods could specify a certain origin timezone, but the +* instance inner timezone won't be changed until the user want to do that. * *
 *
-* I.e., supose you have TZ="MET" on host (on Madrid):
+*  Sample code:
 *
-*   resources::time::Date edu_birth("CET");
-*   //resources::time::Date edu_birth; // if Context TZ = shell TZ = "CET"
-*   edu_birth.store ("19741219101500");
-*   std::cout << "'edu_birth.asString()' is: " << edu_birth.asString() << std::endl;
-*   std::cout << "'Timestamp' edu_birth (Madrid:CET): " << edu_birth.getUnixTimestamp() << std::endl;
-*   struct tm Tm = edu_birth.getTm();
-*   std::cout << "'Tm' edu_birth (madrid:CET): " << "tm_mday = " << Tm.tm_mday << ", tm_mon (0-11) = " << Tm.tm_mon
-*   << ", tm_year (since 1900) = " << Tm.tm_year << ", tm_hour = " << Tm.tm_hour
-*   << ", tm_min = " << Tm.tm_min << ", tm_sec = " << Tm.tm_sec << std::endl;
-*   resources::time::Date same_moment_canary_island("GMT");
-*   same_moment_canary_island.store (edu_birth.getUnixTimestamp());
-*   std::cout << "'yyyymmddHHmmss' for 'same_moment_canary_island': " << (same_moment_canary_island.yyyymmddHHmmss()).c_str() << std::endl;
-*   edu_birth.setTzContext ("GMT");
-*   std::cout << "'yyyymmddHHmmss' for edu_birth, Local time on Canary Island: " << (edu_birth.yyyymmddHHmmss()).c_str() << std::endl;
-*   resources::time::Date birthday("EET");
-*   birthday.store (same_moment_canary_island.getTm(), "GMT"); // TZ origin = "GMT"
-*   if (birthday == edu_birth)
-*   {
-*   std::cout << "'birthday' same as 'edu_birth', and 'yyyymmddHHmmss' is: " << (birthday.yyyymmddHHmmss()).c_str()
-*   << " in TZ = " << (birthday.getTzContext()).getValue().c_str() << std::endl;
-*   }
+*  anna::time::functions::initialize();
+*  std::cout << "SystemTimezone: " << anna::time::functions::getSystemTimezone().asString() << std::endl;
 *
-*   std::cout << "'birthday': " << birthday.asString() << std::endl;
-*   std::cout << "'edu_birth': " << edu_birth.asString() << std::endl;
+*  anna::time::Date myBirth ("CET");
+*  myBirth.store("19741219111500", "EET");
+*  std::cout << "myBirth: " << myBirth.asString() << std::endl;
 *
-*   edu_birth.setTzContext (resources::time::functions::getLocalTz().getValue().c_str());
-*   std::cout << "'edu_birth' on local TZ: " << edu_birth.asString() << std::endl;
+*  anna::time::Date same_moment_canary_island("GMT");
+*  same_moment_canary_island.store(myBirth.getUnixTimestamp());
+*  std::cout << "same_moment_canary_island: " << same_moment_canary_island.asString() << std::endl;
+*  myBirth.setTz("GMT");
+*  std::cout << "myBirth on GMT: " << myBirth.asString() << std::endl;
+*  std::cout << "EQUAL: same_moment_canary_island = " << same_moment_canary_island.yyyymmddHHmmss() << "; myBirth in context GMT = " << myBirth.yyyymmddHHmmss() << std::endl;
+*  same_moment_canary_island.setTz("CET");
+*  std::cout << "same_moment_canary_island on CET: " << same_moment_canary_island.asString() << std::endl;
+*  anna::time::Date birthday("EET");
+*  birthday.store(same_moment_canary_island.getTm(), "CET");
+*  std::cout << "EQUAL: birthday TS = " << birthday.getUnixTimestamp() << "; myBirth TS = " << myBirth.getUnixTimestamp() << std::endl;
+*  std::cout << "birthday EET = " << birthday.asString() << std::endl;
 *
-*   //birthday.setTzContext("CET");
-*   birthday.setTzContext (resources::time::functions::getLocalTz().getValue().c_str()); // Go from "EET" to "CET"
-*   std::cout << "'yyyymmddHHmmss' for 'birthday' on Local TZ: " << (birthday.yyyymmddHHmmss()).c_str() << std::endl;
-*   // Adding 18 years to 'edu_birth':
-*   Tm.tm_year += 18;
-*   resources::time::Date eighteen("CET");
-*   eighteen.store (Tm);
-*   if (eighteen >= same_moment_canary_island) // same as compare to 'edu_birth'
-*   {
-*   std::cout << "'eighteen' is 'yyyymmddHHmmss' = " << (eighteen.yyyymmddHHmmss()).c_str() << std::endl;
-*   std::cout << "'eighteen' is later than timestamp for 'same_moment_canary_island' = " << same_moment_canary_island.getUnixTimestamp() << std::endl;
-*   std::cout << "'eighteen' is later than timestamp for 'edu_birth' = " << edu_birth.getUnixTimestamp() << std::endl;
-*   }
+*  std::cout << "Setting Local timezone ..." << std::endl;
+*  myBirth.setSystemTimezone();
+*  birthday.setSystemTimezone();
+*  std::cout << "EQUAL: birthday " << birthday.asString() << "; myBirth " << myBirth.asString() << std::endl;
+*  std::cout << "EQUAL: birthday (Local Timezone)= " << birthday.yyyymmddHHmmss() << "; myBirth (Local Timezone)= " << myBirth.yyyymmddHHmmss() << std::endl;
+*  std::cout << "myBirth TZ  = " << myBirth.getTzAsString() << std::endl;
+*  std::cout << "birthday TZ  = " << myBirth.getTzAsString() << std::endl;
 *
+*  myBirth.setTz("GMT");
+*  std::cout << "myBirth in GMT = " << myBirth.yyyymmddHHmmss() << std::endl;
 *
-* -----------------------------------------------------------------------------------------------------------------------------
-* Program output:
+*  Program output:
 *
-*   'edu_birth.asString()' is: 19/12/1974 10:15:00 CET, isdst = 0 [Unix Timestamp: 156676500], Local TZ = EET
-*   'Timestamp' edu_birth (Madrid:CET): 156676500
-*   'Tm' edu_birth (madrid:CET): tm_mday = 19, tm_mon (0-11) = 11, tm_year (since 1900) = 74, tm_hour = 10, tm_min = 15, tm_sec = 0
-*   'yyyymmddHHmmss' for 'same_moment_canary_island': 19741219091500
-*   'yyyymmddHHmmss' for edu_birth, Local time on Canary Island: 19741219091500
-*   'birthday' same as 'edu_birth', and 'yyyymmddHHmmss' is: 19741219111500 in TZ = EET
-*   'birthday': 19/12/1974 11:15:00 EET, isdst = 0 [Unix Timestamp: 156676500], Local TZ = EET
-*   'edu_birth': 19/12/1974 09:15:00 GMT, isdst = 0 [Unix Timestamp: 156676500], Local TZ = EET
-*   'edu_birth' on local TZ: 19/12/1974 10:15:00 EET, isdst = 0 [Unix Timestamp: 156676500], Local TZ = EET
-*   'yyyymmddHHmmss' for 'birthday' on Local TZ: 19741219101500
-*   'eighteen' is 'yyyymmddHHmmss' = 19921219101500
-*   'eighteen' is later than timestamp for 'same_moment_canary_island' = 156676500
-*   'eighteen' is later than timestamp for 'edu_birth' = 156676500
+*  SystemTimezone: 
+*  myBirth: Thursday 19/12/1974 10:15:00 CET, isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: 
+*  same_moment_canary_island: Thursday 19/12/1974 09:15:00 GMT, isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: 
+*  myBirth on GMT: Thursday 19/12/1974 09:15:00 GMT, isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: 
+*  EQUAL: same_moment_canary_island = 19741219091500; myBirth in context GMT = 19741219091500
+*  same_moment_canary_island on CET: Thursday 19/12/1974 10:15:00 CET, isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: 
+*  EQUAL: birthday TS = 156676500; myBirth TS = 156676500
+*  birthday EET = Thursday 19/12/1974 11:15:00 EET, isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: 
+*  Setting Local timezone ...
+*  EQUAL: birthday Thursday 19/12/1974 10:15:00 , isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: ; myBirth Thursday 19/12/1974 10:15:00 , isdst = 0 [Unix Timestamp: 156676500, Ntp Timestamp: 2365665300], System Timezone: 
+*  EQUAL: birthday (Local Timezone)= 19741219101500; myBirth (Local Timezone)= 19741219101500
+*  myBirth TZ  = 
+*  birthday TZ  = 
+*  myBirth in GMT = 19741219091500
 *
 * 
*/ @@ -163,134 +114,113 @@ class Date { ///////////////////////////////////////////////// // Main data: - TZ a_TZ_context; // timezone for current representation - time_t a_unix_timestamp; // unix timestamp + Timezone a_tz; // timezone for this instance context + time_t a_timestamp; // unix timestamp // Secondary data: - struct tm a_tm_struct; - std::string _yyyymmddHHmmss; // string representation for 'tm' + struct tm a_tm; - // Auxiliar: - TZ a_local_tz; // local tz on host - TZ a_work_tz; // auxiliar tz - void _putenv(const char * Tz) throw(); - void set_tz_context(const char * TzContext) throw(); - const TZ & get_TZ_context(void) const throw(); - void _initialize(const char * TzContext) throw(); + // sets the current date/time (time(NULL)) and provided TimeZone as described in constructor + void initialize(const char *TZ = NULL) ; - void check_yyyymmddHHmmss(const std::string & yyyymmddHHmmss) throw(anna::RuntimeException); - void refresh_regarding_unix_timestamp(void) throw(); // main refresh method + // main refresh method regarding timestamp + void refresh(void) ; anna::Mutex a_mutex; + public: /** * Default Constructor + * @param TZ timezone for date/time representation. Default (NULL) assumes the system + * timezone configuration. Empty string will be interpreted as UTC timezone. */ - Date(const char * TzContext = NULL); + Date(const char *TZ = NULL); /** * Copy Constructor */ - Date(const Date & d); + Date(const Date & d) { *this = d; } /** * Destructor */ - ~Date(); + ~Date() {;} - // sets - + // setters /** - * Class initialization with current date/time (time(NULL)) and provided TimeZone (default is Local TimeZone) - * - * @param TzContext timezone for date/time representation. Default is Local timezone - * - * @see setTzContext() - * @see store() + * Sets the current date/time (time(NULL)) and provided TimeZone as described in constructor */ - void initialize(const char * TzContext = NULL) throw(); + void setNow(const char *TZ = NULL) { initialize(TZ); } /** - * Same as initialize() + * Sets the provided timezone for date/time representation of the class instance. + * This method keeps invariant the unix timestamp, thus, the date representation + * will evolve depending on the configured timezone. + * @warning Be careful with incorrect TZ values because no error will be shown but + * dates could be misleading. The valid TZ could be seen with tzselect tool or + * directly looking at /usr/share/zoneinfo hierarchy. + * + * @param TZ timezone for date/time representation. + * Default (NULL) is the local host (user-supplied) timezone + * Empty string sets UTC0 (GMT, Greenwich) + * Use available timezones in /usr/share/zoneinfo; i.e.: Europe/Madrid, CET, etc. + * You can also use 'tzselect' helper, but that tool don't change the system + * timezone, only helps to know the valid TZ values and shows how to change + * the timezone settings if you would want to do that). */ - void setCurrent(const char * TzContext = NULL) throw() { initialize(TzContext); } + void setTz(const char *TZ = NULL) ; /** - * Sets the provided timezone for date/time representation. default is Local timezone. - * - * @param TzContext timezone for date/time representation. Default is Local timezone - * - * @see initialize() - * @see store() + Sets the local host timezone (even if it is based on TZ or in /usr/share/zoneinfo) */ - void setTzContext(const char * TzContext = NULL) throw(); + void setSystemTimezone() ; /** - * Sets date/time from string 'yyyymmddHHmmss' representation (HH is 24 hour format, and string must be 14 digits-length), - * and optional timezone (default is local) - * - * @param yyyymmddHHmmss 'yyyymmddHHmmss' date/time - * @param OriginTz timezone for date/time provided. Default is Local TZ - * - * @see initialize() - * @see setTzContext() - */ - void store(const std::string & yyyymmddHHmmss, const char * OriginTz = NULL) throw(anna::RuntimeException); - - - /** - * Sets date/time from string representation with certain provided format, and optional timezone (default is local) - * - * @param dateTimeAsStringFormat Date/time string format - * @param dateTimeAsString Date/time string - * @param OriginTz timezone for date/time provided. Default is Local TZ + * Sets date/time providing unix timestamp (seconds since 01-Jan-1970 GMT) * - * @see initialize() - * @see setTzContext() + * @param unixTimestamp Time since 01-Jan-1970 GMT */ - void store(const char* dateTimeAsStringFormat, const std::string & dateTimeAsString, const char * OriginTz = NULL) throw(anna::RuntimeException); + void store(const time_t & unixTimestamp) ; + void storeUnix(const time_t & unixTimestamp) { store(unixTimestamp); } /** - * Sets date/time from standard (time.h) 'tm' struct and optional timezone (default is local) - * - * @param TmOrigen 'tm' struct date/time - * @param OriginTz timezone for date/time provided. Default is Local TZ + * Sets date/time providing ntp timestamp (seconds since 01-Jan-1900 GMT) * - * @see initialize() - * @see setTzContext() + * @param ntpTimestamp Time since 01-Jan-1900 GMT */ - void store(const struct tm & TmOrigen, const char * OriginTz = NULL) throw(anna::RuntimeException); + void storeNtp(const unsigned int &ntpTimestamp) ; /** - * Sets date/time providing unix timestamp (seconds since 01-Jan-1970 GMT) - * - * @param unixTimestamp Time since 01-Jan-1970 GMT + * Sets date/time from standard 'tm' struct and optional timezone * - * @see initialize() - * @see setTzContext() + * @param date 'tm' struct date/time + * @param TZ timezone for date/time provided. Default (NULL) assumes the system + * timezone configuration. Empty string will be interpreted as UTC timezone. */ - void store(const time_t & unixTimestamp) throw(); - void storeUnix(const time_t & unixTimestamp) throw() { store(unixTimestamp); } + void store(const struct tm &date, const char *TZ = NULL) noexcept(false); /** - * Sets date/time providing ntp timestamp (seconds since 01-Jan-1900 GMT) - * - * @param ntpTimestamp Time since 01-Jan-1900 GMT - * - * @see initialize() - * @see setTzContext() + * Sets date/time from string representation with certain provided format, + * and optional timezone + * + * @param stringDate Date/time string + * @param TZ timezone for date/time provided. Default (NULL) assumes the system + * timezone configuration. Empty string will be interpreted as UTC timezone. + * @param strptimeFormat Date/time string format for strptime primitive. + * See format syntax at http://man7.org/linux/man-pages/man3/strptime.3.html */ - void storeNtp(const unsigned int & ntpTimestamp) throw(); + void store(const std::string &stringDate, const char *TZ = NULL, const char *strptimeFormat = "%Y%m%d%H%M%S") noexcept(false); + //void store(const std::string &stringDate, const char *tz = NULL, const char *strptimeFormat = "%Y-%m-%d-%H-%M-%S") noexcept(false); /** @@ -298,7 +228,7 @@ public: * * @param d Source class instance * - * @return Retunrs copied reference + * @return Returns copied reference */ Date & operator = (const Date &d); @@ -356,88 +286,78 @@ public: /** - * Gets context representation TZ + * Gets context instance timezone information * - * @return context representation TZ - * - * @see yyyymmddHHmmss() - * @see getUnixTimestamp() - * @see getTm() - * @see asString() + * @return NULL if TZ is unset, or string for TZ environment variable + * (empty is allowed and use to be understood as UTC. */ - const std::string & getTzContext(void) const throw(); + const char *getTz(void) const { return (a_tz.unsetTZ() ? NULL:a_tz.getValue().c_str()); } /** - * Gets 'yyyymmddHHmmss' stored data - * - * @return Time/date on format 'yyyymmddHHmmss' - * - * @see getTzContext() - * @see getUnixTimestamp() - * @see getTm() - * @see asString() + * Gets the context timezone as string */ - const std::string & yyyymmddHHmmss(void) const throw(); + std::string getTzAsString() const { return a_tz.asString(); } /** - * Gets unix timestamp (01-Jan-1970 GMT) + * Gets 'tm' struct on the current timezone * - * @return Seconds since 01-Jan-1970 GMT + * @return 'tm' struct on the current timezone + */ + const struct tm & getTm(void) const { return a_tm; } + + /** + * Gets the week day abbreviation: Sun, Mon, Tue, Wed, Thu, Fri, Sat * - * @see getTzContext() - * @see yyyymmddHHmmss() - * @see getTm() - * @see asString() + * @return Day of the week */ - const time_t & getUnixTimestamp(void) const throw(); + const char *getDay(void) const ; /** - * Gets ntp timestamp (01-Jan-1900 GMT) + * Gets 'yyyymmddHHmmss' representation for the current timezone * - * @return Seconds since 01-Jan-1900 GMT + * @return Time/date on format 'yyyymmddHHmmss' * - * @see getTzContext() - * @see yyyymmddHHmmss() - * @see getTm() - * @see asString() + * @see getTz */ - unsigned int getNtpTimestamp(void) const throw(); + std::string yyyymmddHHmmss(void) const ; /** - * Gets 'tm' struct on context representation TZ + * Gets unix timestamp (01-Jan-1970 GMT) * - * @return 'tm' struct on context representation TZ + * @return Seconds since 01-Jan-1970 GMT + */ + const time_t & getUnixTimestamp(void) const { return a_timestamp; } + + + /** + * Gets ntp timestamp (01-Jan-1900 GMT) * - * @see getTzContext() - * @see yyyymmddHHmmss() - * @see getUnixTimestamp() - * @see asString() + * @return Seconds since 01-Jan-1900 GMT */ - const struct tm & getTm(void) const throw(); + unsigned int getNtpTimestamp(void) const { + unsigned int ntp_timestamp = a_timestamp + TIMESTAMP_OFFSET_NTP1900_OVER_UNIX1970; + return ntp_timestamp; + } /** * Class string representation * * @return String with class content - * - * @see asXML() */ - std::string asString(void) const throw(); + std::string asString(void) const ; /** * Class XML representation * * @return XML with class content - * - * @see asString() */ - anna::xml::Node* asXML(anna::xml::Node* parent) const throw(); + anna::xml::Node* asXML(anna::xml::Node* parent) const ; };