00001
00002
00003
00004
00005
00006
00007
00008
00009 #include "LtbReadoutFormat/LtbTime.h"
00010
00011 #include <ctime>
00012
00013 #include "DaqReadoutFormat/ByteBuffer.h"
00014 #include "LtbReadoutFormat/LtbTraits.h"
00015
00016 using DybDaq::ByteBuffer;
00017 using DybDaq::LtbTime;
00018 using DybDaq::LtbTraits;
00019
00020 #define TIME_T_BUILTIN_TYPE unsigned long
00021
00022 static const unsigned int kYearZero = 1970;
00023 static const unsigned int kTmBaseYear = 1900;
00024
00025 LtbTime::LtbTime(const time_t& dateTime,
00026 const unsigned int halfNanoseconds,
00027 const unsigned int accumulation,
00028 const LtbTraits& traits) :
00029 LtbBuffer(new char[traits.timeSize() * kBytesInInt],
00030 traits) {
00031 traits.initializeTime(buffer());
00032 setDateTime(dateTime);
00033 setHalfNanoseconds(halfNanoseconds);
00034 setAccumulation(accumulation);
00035 }
00036
00037 LtbTime::LtbTime(const LtbTraits::LtbDateTime& dateTime,
00038 const unsigned int halfNanoseconds,
00039 const unsigned int accumulation,
00040 const LtbTraits& traits) :
00041 LtbBuffer(new char[traits.timeSize() * kBytesInInt],
00042 traits) {
00043 traits.initializeTime(buffer());
00044 setDateTime(dateTime);
00045 setHalfNanoseconds(halfNanoseconds);
00046 setAccumulation(accumulation);
00047 }
00048
00049 LtbTime::LtbTime(const DybDaq::ByteBuffer& byteBuffer,
00050 const LtbTraits& traits) :
00051 LtbBuffer(byteBuffer,
00052 traits) {
00053 }
00054
00055 LtbTime::~LtbTime() {
00056 }
00057
00058 unsigned int LtbTime::formatComponent() const {
00059 return LtbTraits::kUnixTime;
00060 }
00061
00062 unsigned int LtbTime::year() const {
00063 if (4 > ltbTraits().majorVersion()) {
00064 unsigned int result = readUnsignedInt(LtbTraits::kYear);
00065 if (0 == result) {
00066 return kYearZero;
00067 }
00068 return result;
00069 }
00070 const time_t time = unixTime();
00071 struct tm* tmStruct = gmtime(&time);
00072 return tmStruct->tm_year + kTmBaseYear;
00073 }
00074
00075 unsigned int LtbTime::month() const {
00076 if (4 > ltbTraits().majorVersion()) {
00077 return readUnsignedInt(LtbTraits::kMonth);
00078 }
00079 const time_t time = unixTime();
00080 struct tm* tmStruct = gmtime(&time);
00081 return tmStruct->tm_mon + 1;
00082 }
00083
00084 unsigned int LtbTime::day() const {
00085 if (4 > ltbTraits().majorVersion()) {
00086 return readUnsignedInt(LtbTraits::kDay);
00087 }
00088 const time_t time = unixTime();
00089 struct tm* tmStruct = gmtime(&time);
00090 return tmStruct->tm_mday;
00091 }
00092
00093 unsigned int LtbTime::hour() const {
00094 if (4 > ltbTraits().majorVersion()) {
00095 return readUnsignedInt(LtbTraits::kHour);
00096 }
00097 const time_t time = unixTime();
00098 struct tm* tmStruct = gmtime(&time);
00099 return tmStruct->tm_hour;
00100 }
00101
00102 unsigned int LtbTime::minutes() const {
00103 if (4 > ltbTraits().majorVersion()) {
00104 return readUnsignedInt(LtbTraits::kMinutes);
00105 }
00106 const time_t time = unixTime();
00107 struct tm* tmStruct = gmtime(&time);
00108 return tmStruct->tm_min;
00109 }
00110
00111 unsigned int LtbTime::seconds() const {
00112 if (4 > ltbTraits().majorVersion()) {
00113 return readUnsignedInt(LtbTraits::kSeconds);
00114 }
00115 const time_t time = unixTime();
00116 struct tm* tmStruct = gmtime(&time);
00117 return tmStruct->tm_sec;
00118 }
00119
00120 unsigned int LtbTime::ticks() const {
00121 if (4 > ltbTraits().majorVersion()) {
00122 return readUnsignedInt(LtbTraits::kTicks);
00123 }
00124 return (halfNanoseconds() / 25U);
00125 }
00126
00127 time_t LtbTime::unixTime() const {
00128 if (4 > ltbTraits().majorVersion()) {
00129 struct tm gmtAsLocal;
00130 gmtAsLocal.tm_sec = seconds();
00131 gmtAsLocal.tm_min = minutes();
00132 gmtAsLocal.tm_hour = hour();
00133 gmtAsLocal.tm_mday = day();
00134 gmtAsLocal.tm_mon = month() - 1;
00135 gmtAsLocal.tm_year = year() - kTmBaseYear;
00136 const time_t local = mktime(&gmtAsLocal);
00137 struct tm lcl = *localtime(&local);
00138 struct tm gmt = *gmtime(&local);
00139 gmt.tm_isdst = gmtAsLocal.tm_isdst;
00140 const time_t a = mktime(&lcl);
00141 const time_t b = mktime(&gmt);
00142 return local + (a - b);
00143 }
00144 const unsigned int highUnixTime = readUnsignedInt(LtbTraits::kHighUnixTime);
00145 const unsigned int lowUnixTime = readUnsignedInt(LtbTraits::kLowUnixTime);
00146 const TIME_T_BUILTIN_TYPE unixTime = (highUnixTime << 16U) | lowUnixTime;
00147 return *((const time_t*)(&unixTime));
00148 }
00149
00150 unsigned int LtbTime::halfNanoseconds() const {
00151 if (4 > ltbTraits().majorVersion()) {
00152 return ticks() * 25U;
00153 }
00154 const unsigned int highNonaseconds = readUnsignedInt(LtbTraits::kHighNanoseconds);
00155 const unsigned int lowNanoseconds = readUnsignedInt(LtbTraits::kLowNanoseconds);
00156 return (highNonaseconds << 4U) | lowNanoseconds;
00157 }
00158
00159 int LtbTime::accumulation() const {
00160 if (4 > ltbTraits().majorVersion()) {
00161 return 0;
00162 }
00163 const unsigned int highAccumulation = readUnsignedInt(LtbTraits::kHighAccumulation);
00164 const unsigned int lowAccumulation = readUnsignedInt(LtbTraits::kLowAccumulation);
00165 return (highAccumulation << 4U) + lowAccumulation;
00166 }
00167
00168 unsigned int LtbTime::bufferSize() const {
00169 return ltbTraits().timeSize();
00170 }
00171
00172 void LtbTime::setDateTime(const LtbTraits::LtbDateTime& dateTime) {
00173 if (4 > ltbTraits().majorVersion()) {
00174 writeField(dateTime.year(),
00175 LtbTraits::kYear);
00176 writeField(dateTime.month(),
00177 LtbTraits::kMonth);
00178 writeField(dateTime.day(),
00179 LtbTraits::kDay);
00180 writeField(dateTime.hour(),
00181 LtbTraits::kHour);
00182 writeField(dateTime.minutes(),
00183 LtbTraits::kMinutes);
00184 writeField(dateTime.seconds(),
00185 LtbTraits::kSeconds);
00186 return;
00187 }
00188 const time_t timeToCopy = dateTime.unixTime();
00189 const TIME_T_BUILTIN_TYPE time = *((TIME_T_BUILTIN_TYPE*)(&timeToCopy));
00190 writeField((((unsigned int)time) >> 16U) & 0x0000ffffU,
00191 LtbTraits::kHighUnixTime);
00192 writeField(((unsigned int)time) & 0x0000ffffU,
00193 LtbTraits::kLowUnixTime);
00194
00195 }
00196
00197 void LtbTime::setDateTime(const time_t& dateTime) {
00198 if (4 > ltbTraits().majorVersion()) {
00199 const tm* time = gmtime(&dateTime);
00200 writeField(time->tm_year + kTmBaseYear,
00201 LtbTraits::kYear);
00202 writeField(time->tm_mon + 1,
00203 LtbTraits::kMonth);
00204 writeField(time->tm_mday,
00205 LtbTraits::kDay);
00206 writeField(time->tm_hour,
00207 LtbTraits::kHour);
00208 writeField(time->tm_min,
00209 LtbTraits::kMinutes);
00210 writeField(time->tm_sec,
00211 LtbTraits::kSeconds);
00212 return;
00213 }
00214 const TIME_T_BUILTIN_TYPE time = *((TIME_T_BUILTIN_TYPE*)(&dateTime));
00215 writeField((((unsigned int)time) >> 16U) & 0x0000ffffU,
00216 LtbTraits::kHighUnixTime);
00217 writeField(((unsigned int)time) & 0x0000ffffU,
00218 LtbTraits::kLowUnixTime);
00219
00220 }
00221
00222 void LtbTime::setHalfNanoseconds(const unsigned int halfNanoseconds) {
00223 if (4 > ltbTraits().majorVersion()) {
00224 writeField(halfNanoseconds / 25U,
00225 LtbTraits::kTicks);
00226 return;
00227 }
00228 writeField((halfNanoseconds >> 4U) & 0x0fffffffU,
00229 LtbTraits::kHighNanoseconds);
00230 writeField(halfNanoseconds & 0x0000000fU,
00231 LtbTraits::kLowNanoseconds);
00232 }
00233
00234 void LtbTime::setAccumulation(const int accumulation) {
00235 if (4 > ltbTraits().majorVersion()) {
00236 return;
00237 }
00238 writeField((accumulation >> 4U) & 0x0fffffffU,
00239 LtbTraits::kHighAccumulation);
00240 writeField(accumulation & 0x0000000fU,
00241 LtbTraits::kLowAccumulation);
00242 }