General Purpose Geodetic Library
SgDbhFormat.cpp
Go to the documentation of this file.
1 /*
2  *
3  * This file is a part of Space Geodetic Library. The library is used by
4  * nuSolve, a part of CALC/SOLVE system, and designed to make analysis of
5  * geodetic VLBI observations.
6  * Copyright (C) 2010-2020 Sergei Bolotin.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  *
21  */
22 
23 #include <iostream>
24 #include <stdlib.h>
25 
26 
27 #include <SgDbhFormat.h>
28 #include <SgLogger.h>
29 
30 
31 
32 
33 
34 
35 
36 /***===================================================================================================*/
42 // static first:
44 {
45  return "SgDbhPhysicalRecord";
46 };
47 
48 
49 
50 //
52 {
53  length_ = -1;
54  logicalRecord_ = NULL;
55  *this = record;
56 };
57 
58 
59 
60 //
62 {
63  if (logicalRecord_)
64  delete[] logicalRecord_;
65  logicalRecord_ = NULL;
66 };
67 
68 
69 
70 //
72 {
73  length_ = record.length();
74  isOK_ = record.isOk();
75  if (record.logicalRecord_)
76  {
77  if (logicalRecord_)
78  delete[] logicalRecord_;
79  logicalRecord_ = new char[length_+1];
80  memcpy((void*)logicalRecord_, (void*)record.logicalRecord_, length_+1);
81  }
82  else
83  logicalRecord_ = NULL;
84  return *this;
85 };
86 
87 
88 
89 //
91 {
92  if (length%2)
93  length++;
94  length_ = length;
95  if (logicalRecord_) // it was non-NULL, rearrange the area and clear it:
96  delete []logicalRecord_;
97  logicalRecord_ = new char[length_+1];
98  memset((void*)logicalRecord_, 0, length_+1);
99 };
100 
101 
102 
103 //
105 {
106  if (logicalRecord_)
107  delete []logicalRecord_;
108  logicalRecord_ = new char[length_+1];
109  int readBytes = s.readRawData(logicalRecord_, length_);
110  *(logicalRecord_+length_) = 0;
111  return readBytes; // could be =length_, <length_ or -1
112 };
113 
114 
115 
116 //
118 {
119  return logicalRecord_ ? s.writeRawData(logicalRecord_, length_) : 0;
120 };
121 
122 
123 
124 //
126 {
127  int hdd1, edd1, hd2, ed2;
128  short dd1;
129  char c;
130  record.isOK_ = true;
131  s >> (qint32 &)hdd1;
132  if (hdd1!=2)
133  {
134  // complain:
136  QString().sprintf("DBH input error: format violation: HDD1!=2 (HDD1=%d)", hdd1));
137  record.isOK_ = false;
138  return s;
139  };
140  s >> (qint16 &)dd1 >> (qint32 &)edd1;
141  if (edd1!=hdd1)
142  {
143  // complain:
145  QString().sprintf("DBH input error: format violation: EDD1!=HDD1 (EDD1=%d, HDD1=%d)",
146  edd1, hdd1));
147  record.isOK_ = false;
148  return s;
149  };
150  s >> (qint32 &)hd2;
151  if (hd2!=dd1+dd1)
152  {
154  QString().sprintf("DBH input error: format violation: HD2!=DD1+DD1 (HD2=%d, DD1=%d)",
155  hd2, dd1));
156  record.isOK_ = false;
157  return s;
158  };
159  record.length_ = hd2;
160  int parsedBytes = record.readLR(s);
161  if (parsedBytes>record.length_)
162  {
163  // complain:
165  QString().sprintf("DBH input error: number of read bytes (%d) exceed record length (%d)",
166  parsedBytes, record.length_));
167  record.isOK_ = false;
168  return s;
169  }
170  else
171  for (int j=parsedBytes; j<record.length_; j++)
172  s >> (qint8 &)c;
173 
174  s >> (qint32 &)ed2;
175  if (ed2!=hd2)
176  {
177  // complain:
179  QString().sprintf("DBH input error: format violation: ED2!=HD2 (ED2=%d, HD2=%d)",
180  ed2, hd2));
181  record.isOK_ = false;
182  };
183  return s;
184 };
185 
186 
187 
188 //
190 {
191  int hdd1, edd1, hd2, ed2;
192  short dd1;
193  char c=0;
194 
195  hdd1 = edd1 = 2;
196  hd2 = ed2 = record.length();
197  dd1 = (short) record.length()/2;
198  s << (const qint32 &)hdd1 << (const qint16 &)dd1 << (const qint32 &)edd1 << (const qint32 &)hd2;
199  int writtenBytes = record.writeLR(s);
200  if (writtenBytes<record.length())
201  for (int j=writtenBytes; j<record.length(); j++)
202  s << (qint8)c;
203  s << (qint32)ed2;
204  return s;
205 };
206 /*=====================================================================================================*/
207 
208 
209 
210 
211 
212 
213 /***===================================================================================================*/
219 //
221 {
222  return "SgDbhDataRecordString";
223 };
224 
225 
226 
227 //
229 {
230 };
231 
232 
233 
234 //
235 QString SgDbhDataRecordString::getValue(SgDbhDatumDescriptor* descriptor, int dim2, int dim3)
236 {
237  int l = 2*descriptor->dim1() + 1; // space to copy array of chars + 0-terminator
238  char *c = new char[l];
239  char *p = logicalRecord_ + 2*(descriptor->offset()
240  + descriptor->dim1()*dim2 + descriptor->dim1()*descriptor->dim2()*dim3);
241  for (int i=0; i<l-1; i++) // copy actual data
242  *(c+i) = *(p+i);
243  *(c+l-1) = 0; // put a string terminator
244  QString Ret = (const char*)c; // convert to QString
245  delete []c;
246  return Ret;
247 };
248 
249 
250 
251 //
253  int dim2, int dim3, const QString& str)
254 {
255  int l = 2*descriptor->dim1();
256  char *p= logicalRecord_ + 2*(descriptor->offset()
257  + descriptor->dim1()*dim2 + descriptor->dim1()*descriptor->dim2()*dim3);
258  int i, n2copy = std::min(l,str.length());
259  for (i=0; i<n2copy; i++)
260  *(p+i) = str.at(i).toLatin1();
261  for (; i<l; i++)
262  *(p+i) = ' '; // fill the rest of the fields with "space" chars.
263 };
264 
265 
266 
267 //
268 void SgDbhDataRecordString::setText(const QString& text)
269 {
270  // save in the cashe,
271  text_ = text;
272  if (length_<0) // this is just created record, arrange space to store data:
273  reSize(text_.length());
274  // and copy it to the logical record:
275  char *p = logicalRecord_;
276  int i, n2copy = std::min(length(), text_.length());
277  for (i=0; i<n2copy; i++)
278  *(p+i) = text_.at(i).toLatin1();
279  for (; i<length(); i++)
280  *(p+i) = ' '; // fill the rest of the fields with "space" chars.
281 };
282 
283 
284 
285 //
287 {
288  int i=SgDbhPhysicalRecord::readLR(s);
289  if(isOK_)
290  text_= (const char*)logicalRecord_;
291  return i;
292 };
293 
294 
295 
296 //
298 {
300  text_ = rec.getText();
301  return *this;
302 };
303 /*=====================================================================================================*/
304 
305 
306 
307 
308 
309 
310 /***===================================================================================================*/
316 /*
317 template<class C> SgDbhDataRecord<C>::SgDbhDataRecord(SgDbhDataRecord<C> const & rec)
318  : SgDbhPhysicalRecord(rec)
319 {
320  num_ = rec.num_;
321  if (base_)
322  delete []base_;
323  base_ = new C[num_];
324  memcpy((void*)base_, (void*)rec.base_, sizeof(C)*num_);
325 };
326 */
327 template<class C> SgDbhDataRecord<C>::~SgDbhDataRecord<C>()
328 {
329  if (base_)
330  delete []base_;
331  base_=NULL;
332 };
333 
334 
335 
336 //
337 template<class C> C& SgDbhDataRecord<C>::operator[](int i)
338 {
339  return *(base_+i);
340 };
341 
342 
343 
344 //
345 template<class C> C SgDbhDataRecord<C>::at(int i) const
346 {
347  return base_&&-1<i&&i<num_ ? *(base_+i) : (C)0;
348 };
349 
350 
351 
352 //
353 template<class C> C SgDbhDataRecord<C>::value(SgDbhDatumDescriptor* d, int dim1, int dim2, int dim3)
354 {
355  // make additional checks for each index:
356  return (dim1<d->dim1() && dim2<d->dim2() && dim3<d->dim3() && dim1>=0 && dim2>=0 && dim3>=0) ?
357  operator[](d->offset() + dim1 + d->dim1()*dim2 + d->dim1()*d->dim2()*dim3) : (C)0;
358 };
359 
360 
361 
362 //
363 template<class C> char* SgDbhDataRecord<C>::base()
364 {
365  return (char*)base_;
366 };
367 
368 
369 
370 //
372 {
374  if (base_)
375  delete []base_;
376  num_ = rec.num_;
377  base_ = new C[num_];
378  memcpy((void*)base_, (void*)rec.base_, sizeof(C)*num_);
379  return *this;
380 };
381 
382 
383 
384 //
385 template<class C> C& SgDbhDataRecord<C>::access(SgDbhDatumDescriptor* d, int i, int j, int k)
386 {
387 #ifdef DEBUG
388  // make additional checks for each index:
389  if (i<0 || i>=d->dim1())
391  + QString().sprintf(": access: the first index <%d> out of range [0:%d]", i, d->dim1()));
392  if (j<0 || j>=d->dim2())
394  + QString().sprintf(": access: the second index <%d> out of range [0:%d]", j, d->dim2()));
395  if (k<0 || k>=d->dim3())
397  + QString().sprintf(": access: the third index <%d> out of range [0:%d]", k, d->dim3()));
398 #endif
399  return operator[](d->offset() + i + d->dim1()*j + d->dim1()*d->dim2()*k);
400 };
401 
402 
403 
404 //
405 template<class C> int SgDbhDataRecord<C>::readLR(SgDbhStream& s)
406 {
407  if (base_)
408  delete []base_;
409  base_ = new C[(num_=length_/sizeof(C))];
410  C *p = base_;
411  for(int i=0; i<num_; i++,p++)
412  s >> *p;
413  return length_;
414 };
415 
416 
417 
418 //
419 template<class C> int SgDbhDataRecord<C>::writeLR(SgDbhStream& s) const
420 {
421  C *p = base_;
422  for(int i=0; i<num_; i++,p++)
423  s << *p;
424  return length_;
425 };
426 
427 
428 
429 //
430 template<class C> void SgDbhDataRecord<C>::reSize(int length)
431 {
432  length_ = length;
433  if (base_)
434  delete []base_;
435  base_ = new C[(num_=length_/sizeof(C))];
436  memset((void*)base_, 0, num_*sizeof(C));
437 };
438 
439 
440 template<class C> QString SgDbhDataRecord<C>::className() const
441 {
442  return "SgDbhDataRecord<C>";
443 };
444 
445 /*=====================================================================================================*/
446 
447 
448 
449 
450 
451 
452 /***===================================================================================================*/
458 //
460 {
461  s >> (qint8 &)prefix_[0] >> (qint8 &)prefix_[1];
462  if (!isCorrectPrefix() && !isAltered())
463  return (isOK_=false);
464  else
465  return true;
466 };
467 /*=====================================================================================================*/
468 
469 
470 
471 
472 
473 
474 /***===================================================================================================*/
480 //
482 {
483  int nYear, nMonth, nDay, nHour, nMin;
484  double dSec;
485  SgMJD::MJD_reverse(t.getDate(), t.getTime(), nYear, nMonth, nDay, nHour, nMin, dSec);
486 
487  epoch_[0] = (short)nYear;
488  epoch_[1] = (short)t.calcDayOfYear();
489  epoch_[2] = (short)nHour;
490  epoch_[3] = (short)nMin;
491  epoch_[4] = (short)round(dSec);
492 };
493 
494 
495 
496 //
498 {
499  short p8, p9, p10, p11;
501  epoch_[0] = epoch_[1] = epoch_[2] = epoch_[3] = epoch_[4] = 0;
502  versionNumber_ = 0;
503 
504  if (isPrefixParsed(s) && !isAltered())
505  {
506  s >> (qint16 &)lengthOfHistoryString_
507  >> (qint16 &)epoch_[0] >> (qint16 &)epoch_[1] >> (qint16 &)epoch_[2]
508  >> (qint16 &)epoch_[3] >> (qint16 &)epoch_[4]
509  >> (qint16 &)versionNumber_
510  >> (qint16 &)p8 >> (qint16 &)p9 >> (qint16 &)p10 >> (qint16 &)p11; // unused fields
511  return 24;
512  };
513  return 2;
514 };
515 
516 
517 
518 //
520 {
521  int writtenBytes = SgDbhServiceRecord::writeLR(s); // write prefix
522  if (!isAltered())
523  {
524  s << (qint16)lengthOfHistoryString_
525  << (qint16)epoch_[0] << (qint16)epoch_[1] << (qint16)epoch_[2]
526  << (qint16)epoch_[3] << (qint16)epoch_[4]
527  << (qint16)versionNumber_
528  << (qint16)0 << (qint16)0 << (qint16)0 << (qint16)0; // unused fields
529  writtenBytes+=22;
530  };
531  return writtenBytes;
532 };
533 /*=====================================================================================================*/
534 
535 
536 
537 
538 
539 
540 /***===================================================================================================*/
546 //
548 {
549  // mimic current DBH files:
550  machineTypeNumber_ = 1;
551  machineNumber_ = 1;
553  dbhVersionNumber_ = 1996;
554  semiName_[0] = 'U';
555  semiName_[1] = 'N';
556  semiName_[2] = 'D';
557  semiName_[3] = 'E';
558  semiName_[4] = 'F';
559  semiName_[5] = '.';
560  semiName_[6] = 0;
561  length_ = 24;
562 };
563 
564 
565 
566 //
567 void SgDbhServiceRecordHS2::setSemiName(const QString& semiName)
568 {
569  for (int i=0; i<6; i++)
570  semiName_[i] = semiName.at(i).toLatin1();
571 };
572 
573 
574 
575 //
577 {
578  short p5, p6, p7, p8;
580  semiName_[0] = 'U';
581  semiName_[1] = 'N';
582  semiName_[2] = 'D';
583  semiName_[3] = 'E';
584  semiName_[4] = 'F';
585  semiName_[5] = '.';
586  semiName_[6] = 0;
587  if (!isPrefixParsed(s))
588  return 2;
589  else
590  s >> (qint16 &)machineTypeNumber_ >> (qint16 &)machineNumber_ >> (qint16 &)installationNumber_
591  >> (qint16 &)dbhVersionNumber_
592  >> (qint8 &)semiName_[0] >> (qint8 &)semiName_[1] >> (qint8 &)semiName_[2]
593  >> (qint8 &)semiName_[3] >> (qint8 &)semiName_[4] >> (qint8 &)semiName_[5]
594  >> (qint16 &)p5 >> (qint16 &)p6 >> (qint16 &)p7 >> (qint16 &)p8; // unused fields
595  return 24;
596 };
597 
598 
599 
600 //
602 {
603  int writtenBytes = SgDbhServiceRecord::writeLR(s); // write prefix
604  s << (qint16)machineTypeNumber_ << (qint16)machineNumber_ << (qint16)installationNumber_
605  << (qint16)dbhVersionNumber_
606  << (qint8)semiName_[0] << (qint8)semiName_[1] << (qint8)semiName_[2]
607  << (qint8)semiName_[3] << (qint8)semiName_[4] << (qint8)semiName_[5]
608  << (qint16)0 << (qint16)0 << (qint16)0 << (qint16)0; // unused fields
609  writtenBytes += 22;
610  return writtenBytes;
611 };
612 /*=====================================================================================================*/
613 
614 
615 
616 
617 
618 
619 /***===================================================================================================*/
625 //
626 void SgDbhServiceRecordTc::dump(QTextStream& s) const
627 {
628  s << "TC record: TOC Type: " << tocType_
629  << "; number of TE blocks: " << numTeBlocks_
630  << ", rest part: [" << pRest[0] << ":" << pRest[1] << ":" << pRest[2]
631  << ":" << pRest[3] << ":" << pRest[4] << ":" << pRest[5] << ":" << pRest[6]
632  << ":" << pRest[7] << ":" << pRest[8] << "]"
633  << endl;
634 };
635 
636 
637 
638 //
640 {
641  tocType_ = numTeBlocks_ = 0;
642  isZ2_ = false;
643  if (isPrefixParsed(s) && !isAltered())
644  {
645  s >> (qint16 &)tocType_ >> (qint16 &)numTeBlocks_
646  >> (qint16 &)pRest[0] >> (qint16 &)pRest[1] >> (qint16 &)pRest[2] >> (qint16 &)pRest[3]
647  >> (qint16 &)pRest[4] >> (qint16 &)pRest[5] >> (qint16 &)pRest[6] >> (qint16 &)pRest[7]
648  >> (qint16 &)pRest[8]
649  ;
650 // return 6;
651  return 24;
652  }
653  else if (isAltered())
654  {
655  unsigned char c[2];
656  s >> (qint8 &)c[0] >> (qint8 &)c[1];
657  if (c[0]==(unsigned char)7 && c[1]==(unsigned char)208)
658  {
659  isOK_ = true;
660  isZ2_ = true;
661  }
662  else
664  QString().sprintf(": format violation: c[0]!=7 || c[1]!=208 (%d:%d)", c[0], c[1]));
665  return 4;
666  };
667  return 2;
668 };
669 
670 
671 
672 //
674 {
675  int writtenBytes = SgDbhServiceRecord::writeLR(s); // write prefix
676  if (!isAltered())
677  {
678  s << (const qint16 &)tocType_ << (const qint16 &)numTeBlocks_
679  << (const qint16 &)pRest[0] << (const qint16 &)pRest[1] << (const qint16 &)pRest[2]
680  << (const qint16 &)pRest[3] << (const qint16 &)pRest[4] << (const qint16 &)pRest[5]
681  << (const qint16 &)pRest[6] << (const qint16 &)pRest[7] << (const qint16 &)pRest[8];
682  writtenBytes += 22;
683  }
684  else
685  {
686  s << (const qint8 &)7 << (const qint8 &)208;
687  writtenBytes += 2;
688  };
689  return writtenBytes;
690 };
691 /*=====================================================================================================*/
692 
693 
694 
695 /***===================================================================================================*/
701 //
703  : SgDbhServiceRecord("TE")
704 {
707  r8Num_ = i2Num_ = a2Num_ = d8Num_ = j4Num_ = 0;
708 };
709 
710 
711 
712 //
713 void SgDbhServiceRecordTe::dump(QTextStream& s) const
714 {
715  s << "TE record: TE block number: " << teBlockNum_ << "; number of descriptors: "
716  << numberOfDescriptors_ << endl
717  << "Offsets: I2:" << offsetI_ << " A2:" << offsetA_ << " D8:" << offsetD_ << " J4:" << offsetJ_
718  << " (bytes)" << endl
719  << "Numbers: I2:" << i2Num_ << " A2:" << a2Num_ << " D8:" << d8Num_ << " J4:" << j4Num_
720  << " R8:" << r8Num_ << endl;
721 };
722 
723 
724 
725 //
727 {
730  r8Num_ = i2Num_ = a2Num_ = d8Num_ = j4Num_ = 0;
731  if (!isPrefixParsed(s))
732  return 2;
733  else
734  s >> (qint16 &)teBlockNum_ >> (qint16 &)offsetI_ >> (qint16 &)offsetA_ >> (qint16 &)offsetD_
735  >> (qint16 &)r8Num_ >> (qint16 &)i2Num_ >> (qint16 &)a2Num_ >> (qint16 &)offsetJ_
736  >> (qint16 &)numberOfDescriptors_ >> (qint16 &)d8Num_ >> (qint16 &)j4Num_;
737  return 24;
738 };
739 
740 
741 
742 //
744 {
745  int writtenBytes = SgDbhServiceRecord::writeLR(s); // write prefix
746  s << (const qint16 &)teBlockNum_ << (const qint16 &)offsetI_ << (const qint16 &)offsetA_
747  << (const qint16 &)offsetD_ << (const qint16 &)r8Num_ << (const qint16 &)i2Num_
748  << (const qint16 &)a2Num_ << (const qint16 &)offsetJ_ << (const qint16 &)numberOfDescriptors_
749  << (const qint16 &)d8Num_ << (const qint16 &)j4Num_;
750  writtenBytes += 22;
751  return writtenBytes;
752 };
753 /*=====================================================================================================*/
754 
755 
756 
757 
758 
759 
760 /***===================================================================================================*/
766 //
768 {
769  tcNo_ = numOfTeBlocks_ = 0;
770  if (!isPrefixParsed(s)) // reads two bytes
771  return 2;
772  else
773  {
774  s >> (qint16 &)tcNo_ >> (qint16 &)numOfTeBlocks_
775  >> (qint16 &)pRest_[0] >> (qint16 &)pRest_[1] >> (qint16 &)pRest_[2] >> (qint16 &)pRest_[3]
776  >> (qint16 &)pRest_[4] >> (qint16 &)pRest_[5] >> (qint16 &)pRest_[6] >> (qint16 &)pRest_[7]
777  >> (qint16 &)pRest_[8]
778  ;
779  };
780 // return 6;
781  return 24; //+ prefix
782 };
783 
784 
785 
786 //
788 {
789  int writtenBytes = SgDbhServiceRecord::writeLR(s); // write prefix
790  s << (const qint16 &)tcNo_ << (const qint16 &)numOfTeBlocks_
791  << (const qint16 &)pRest_[0] << (const qint16 &)pRest_[1] << (const qint16 &)pRest_[2]
792  << (const qint16 &)pRest_[3] << (const qint16 &)pRest_[4] << (const qint16 &)pRest_[5]
793  << (const qint16 &)pRest_[6] << (const qint16 &)pRest_[7] << (const qint16 &)pRest_[8];
794  writtenBytes += 22;
795  return writtenBytes;
796 };
797 
798 
799 
800 //
801 void SgDbhServiceRecordDr::dump(QTextStream& s) const
802 {
803  s << "DR record (length=" << length() << "): TC#: " << tcNo_ << "; NumOf TE Blocks: "
804  << numOfTeBlocks_ << "; Prefix: [" << prefix_[0] << prefix_[1] << "]"
805  << ", rest part: [" << pRest_[0] << ":" << pRest_[1] << ":"
806  << pRest_[2] << ":" << pRest_[3] << ":" << pRest_[4] << ":" << pRest_[5] << ":"
807  << pRest_[6] << ":" << pRest_[7] << ":" << pRest_[8] << "]"
808  << endl;
809 };
810 /*=====================================================================================================*/
811 
812 
813 
814 
815 
816 
817 /***===================================================================================================*/
823 //
825 {
826  short p5=0, p6=0, p7=0;
828  isZ3_ = false;
829  if (isPrefixParsed(s) && !isAltered())
830  {
831  s >> (qint16 &)teNo_ >> (qint16 &)numOfR8_ >> (qint16 &)numOfI2_ >> (qint16 &)numOfA2_
832  >> (qint16 &)p5 >> (qint16 &)p6 >> (qint16 &)p7
833  >> (qint16 &)numOfD8_ >> (qint16 &)numOfJ4_ >> (qint16 &)pRest_[0] >> (qint16 &)pRest_[1];
834  if (p5!=0 || p6!=0 || p7!=0)
836  QString().sprintf(": surprise, non-null unused data (%d:%d:%d)", p5, p6, p7));
837  return 24;
838 // return 16;
839  }
840  else if (isAltered())
841  {
842  short z3p1;
843  s >> (qint16 &)z3p1;
844  isOK_ = true;
845  isZ3_ = true;
846  numOfPhRecs_ = z3p1;
847  pRest_[0] = pRest_[1] = 0;
848  return 4;
849  };
850  return 2;
851 };
852 
853 
854 
855 //
857 {
858  int writtenBytes = SgDbhServiceRecord::writeLR(s); // write prefix
859  if (!isAltered())
860  {
861  s << (const qint16 &)teNo_ << (const qint16 &)numOfR8_
862  << (const qint16 &)numOfI2_ << (const qint16 &)numOfA2_
863  << (const qint16 &)0 << (const qint16 &)0 << (const qint16 &)0
864  << (const qint16 &)numOfD8_ << (const qint16 &)numOfJ4_
865  << (const qint16 &)pRest_[0] << (const qint16 &)pRest_[1];
866  writtenBytes += 22;
867  }
868  else
869  {
870  s << (const qint16 &)numOfPhRecs_;
871  writtenBytes += 2;
872  };
873  return writtenBytes;
874 };
875 
876 
877 
878 //
879 void SgDbhServiceRecordDe::dump(QTextStream& s) const
880 {
881  s << "DE record (length=" << length() << ")";
882  if (!isZ3())
883  s << ": TE#: " << teNo_
884  << "; NumOf R8:" << numOfR8_ << "; NumOf I2:" << numOfI2_ << "; NumOf A2:" << numOfA2_
885  << "; NumOf D8:" << numOfD8_ << "; NumOf J4:" << numOfJ4_;
886  s << "; Prefix: [" << prefix_[0] << prefix_[1] << "]";
887  if (isZ3())
888  s << "; this is a Z3 record, number of phys.records above: " << numOfPhRecs_ << endl;
889  else
890  s << ", rest part: [" << pRest_[0] << ":" << pRest_[1] << "]" << endl;
891 };
892 /*=====================================================================================================*/
893 
894 
895 
896 
897 
898 
899 /***===================================================================================================*/
905 //
907  dbNameRec_(),
908  expDescriptRec_(),
909  sessIDRec_(),
910  prevDbRec_(),
911  prevRec_(),
912  epochRec_(),
913  versionRec_()
914 {
915  isOK_=false;
916  epoch_[0]=epoch_[1]=epoch_[2]=epoch_[3]=epoch_[4]=0;
917 };
918 
919 
920 
921 //
922 void SgDbhStartBlock::dump(QTextStream& s) const
923 {
924  s << "== Start Block dump: ==" << endl
925  << "Database name : " << dbNameRec_.getText() << endl
926  << "Date of creation : " << epoch().toString(SgMJD::F_Verbose)
927  << " (" << epoch_[0] << ":" << epoch_[1] << ":" << epoch_[2] << ":"
928  << epoch_[3] << ":" << epoch_[4] << ")" << endl
929  << "Experiment description: " << expDescript().simplified() << endl
930  << "Session ID : " << sessionID() << endl
931  << "Version : " << version() << endl
932  << "Previous Database name: " << prevDb() << endl
933  << "Previous description : " << prevDescript() << endl
934  << "== End of dump ==" << endl;
935 };
936 
937 
938 
939 //
940 void SgDbhStartBlock::rotateVersion(int newVersion, const QString& newFileName)
941 {
942  versionRec_[0] = (short)newVersion;
943 
944  QString str = dbNameRec_.getText();
945  prevDbRec_.setText(str);
946  dbNameRec_.setText(newFileName);
947  prevRec_.reSize(36);
948  prevRec_.setText("$" + str.left(9) + str.right(2) + "DBH880930 GSFC GNU/Linux");
949 };
950 
951 
952 
953 //
954 void SgDbhStartBlock::alternateCode(const QString& code)
955 {
956  if (!code.size())
957  return;
958 
959  QString str;
960  QChar c=code.at(0);
961  // name:
962  str = dbNameRec_.getText();
963  str.replace(8, 1, c);
964  dbNameRec_.setText(str);
965  // ID:
966  str = sessIDRec_.getText();
967  str.replace(9, 1, c);
968  sessIDRec_.setText(str);
969  // Prev name:
970  str = prevDbRec_.getText();
971  str.replace(8, 1, c);
972  prevDbRec_.setText(str);
973  // Prev descr:
974  str = prevRec_.getText();
975  str.replace(9, 1, c);
976  prevRec_.setText(str);
977 };
978 
979 
980 
981 //
983 {
984  s >> block.dbNameRec_ >> block.epochRec_ >> block.expDescriptRec_
985  >> block.sessIDRec_ >> block.versionRec_ >> block.prevDbRec_ >> block.prevRec_;
986  if ((block.isOK_ = block.dbNameRec_.isOk() && block.epochRec_.isOk()
987  && block.expDescriptRec_.isOk() && block.sessIDRec_.isOk() && block.versionRec_.isOk()
988  && block.prevDbRec_.isOk() && block.prevRec_.isOk()))
989  {
990  block.epoch_[0] = block.epochRec_[0];
991  block.epoch_[1] = block.epochRec_[1];
992  block.epoch_[2] = block.epochRec_[2];
993  block.epoch_[3] = block.epochRec_[3];
994  block.epoch_[4] = block.epochRec_[4];
995  };
996  return s;
997 };
998 
999 
1000 
1001 //
1003 {
1004  SgDbhDataRecord<short> currentEpochRecord=block.epochRec_;
1006  int nYear, nMonth, nDay, nHour, nMin;
1007  double dSec;
1008  SgMJD::MJD_reverse(t.getDate(), t.getTime(), nYear, nMonth, nDay, nHour, nMin, dSec);
1009 
1010  currentEpochRecord[0] = (short)nYear;
1011  currentEpochRecord[1] = (short)t.calcDayOfYear();
1012  currentEpochRecord[2] = (short)nHour;
1013  currentEpochRecord[3] = (short)nMin;
1014  currentEpochRecord[4] = (short)round(dSec);
1015 
1016  s << block.dbNameRec_ << currentEpochRecord << block.expDescriptRec_
1017  << block.sessIDRec_ << block.versionRec_ << block.prevDbRec_ << block.prevRec_;
1018  return s;
1019 };
1020 /*=====================================================================================================*/
1021 
1022 
1023 
1024 
1025 
1026 
1027 /***===================================================================================================*/
1033 //
1034 void SgDbhHistoryEntry::dump(QTextStream& s) const
1035 {
1036  s << record1_.getHistoryEpoch().toString() << " (" << record1_.getVersionNumber() << "): \""
1037  << record3_.getText() << "\" ["
1039  << record2_.installationNumber_ << ":"
1040  << record2_.dbhVersionNumber_ << "] SN=(" << record2_.semiName_ << ")"
1041  << endl;
1042 };
1043 
1044 
1045 
1046 //
1047 void SgDbhHistoryEntry::setText(const QString& text)
1048 {
1049  record3_.setText(text);
1051 };
1052 
1053 
1054 
1055 //
1056 void SgDbhHistoryEntry::setEvent(const QString& text, const QString& sessionID,
1057  int version, const SgMJD& t)
1058 {
1059  setVersion(version);
1060  setEpoch(t);
1061  setText(text);
1062  record1_.setPrefix("HS");
1063  record2_.setPrefix("HS");
1064  record2_.setSemiName(sessionID);
1065 };
1066 
1067 
1068 
1069 //
1071 {
1072  s >> entry.record1_;
1073  if (entry.record1_.isCorrectPrefix())
1074  {
1075  s >> entry.record2_ >> entry.record3_;
1076  if (2*entry.record1_.getLengthOfHistoryString()!=entry.record3_.length()) // complain:
1078  QString().sprintf("SgDbhStream: corrupted DBH file: wrong history string length for "
1079  "[%s]: %d, expected: %d", qPrintable(entry.record3_.getText()),
1080  2*entry.record1_.getLengthOfHistoryString(), entry.record3_.length()));
1081  };
1082  entry.isOK_ = entry.record1_.isOk() && entry.record2_.isOk() && entry.record3_.isOk();
1083  return s;
1084 };
1085 
1086 
1087 
1088 //
1090 {
1091  if (entry.isOk())
1092  s << entry.record1_ << entry.record2_ << entry.record3_;
1093  else
1094  {
1095  SgDbhServiceRecordHS1 rec1;
1096  rec1.setAltered();
1097  s << rec1;
1098  };
1099  return s;
1100 };
1101 /*=====================================================================================================*/
1102 
1103 
1104 
1105 
1106 
1107 
1108 /*=======================================================================================================
1109 *
1110 * List of descriptors, one per a Te block:
1111 *
1112 *======================================================================================================*/
1113 //
1114 void SgDbhListOfDescriptors::dump(QTextStream& s) const
1115 {
1116  const char *sTypes[] = {"R8", "I2", "A2", "D8", "J4", "UN"};
1117  QString str;
1118  s << "List of descriptors (=format) dump (Offsets are in sizeof(Par)):" << endl
1119  << "---- -------- --- --- --- --- ---- -- --------------------------------" << endl
1120  << " Num Abbrev. D1 D2 D3 Ver Offs Tp Description" << endl
1121  << "---- -------- --- --- --- --- ---- -- --------------------------------" << endl;
1122  for (int i=0; i<listOfDescriptors_.size(); i++)
1123  {
1124  SgDbhDatumDescriptor* descriptor = listOfDescriptors_.at(i);
1125  str.sprintf("%3d. %8s [%3d,%3d,%3d] %3d %4d %2s %32s",
1126  i, qPrintable(descriptor->getLCode()),
1127  descriptor->dim1(), descriptor->dim2(), descriptor->dim3(),
1128  descriptor->getModifiedAtVersion(), descriptor->offset(),
1129  sTypes[descriptor->type()], qPrintable(descriptor->getDescription()));
1130  s << str << endl;
1131  };
1132  s << "------------------------------------------------------------------------" << endl;
1133 };
1134 
1135 
1136 
1137 //
1139 {
1140  // clear the list:
1141  while (!listOfDescriptors_.isEmpty())
1142  delete listOfDescriptors_.takeFirst();
1143 
1144  // refill the list of descriptors (deep copy):
1145  for (int i=0; i<dList.listOfDescriptors_.size(); i++)
1146  {
1147  SgDbhDatumDescriptor *descriptor = new SgDbhDatumDescriptor;
1148  *descriptor = *dList.listOfDescriptors_.at(i);
1149  listOfDescriptors_.append(descriptor);
1150  };
1151  return *this;
1152 };
1153 /*=====================================================================================================*/
1154 
1155 
1156 
1157 
1158 
1159 
1160 /*=======================================================================================================
1161 *
1162 * A collection of data records, one per TE block:
1163 *
1164 *======================================================================================================*/
1165 //
1167 {
1168  recordByType_.clear();
1169  for (int i=0; i<listOfRecords_.size(); i++)
1170  delete listOfRecords_.at(i);
1171  listOfRecords_.clear();
1172 };
1173 
1174 
1175 
1176 //
1178 {
1179  // clear the list and the hash:
1180  recordByType_.clear();
1181  while (!listOfRecords_.isEmpty())
1182  delete listOfRecords_.takeFirst();
1183 
1184  // refill the list of records (deep copy) and the hash:
1185  QHash<int, SgDbhPhysicalRecord*>::const_iterator j;
1186  for (j=block.recordByType_.constBegin(); j!=block.recordByType_.constEnd(); ++j)
1187  {
1188  SgDbhPhysicalRecord *rec_in = j.value(), *record;
1189  switch (j.key())
1190  {
1192  record = new SgDbhDataRecord<double>;
1193  *(SgDbhDataRecord<double>*)record = *(SgDbhDataRecord<double>*)rec_in;
1194  listOfRecords_.append(record);
1195  recordByType_.insert(SgDbhDatumDescriptor::T_R8, record);
1196  break;
1198  record = new SgDbhDataRecord<short>;
1199  *(SgDbhDataRecord<short>*)record = *(SgDbhDataRecord<short>*)rec_in;
1200  listOfRecords_.append(record);
1201  recordByType_.insert(SgDbhDatumDescriptor::T_I2, record);
1202  break;
1204  record = new SgDbhDataRecordString;
1205  *(SgDbhDataRecordString*)record = *(SgDbhDataRecordString*)rec_in;
1206  listOfRecords_.append(record);
1207  recordByType_.insert(SgDbhDatumDescriptor::T_A2, record);
1208  break;
1210  record = new SgDbhDataRecord<double>;
1211  *(SgDbhDataRecord<double>*)record = *(SgDbhDataRecord<double>*)rec_in;
1212  listOfRecords_.append(record);
1213  recordByType_.insert(SgDbhDatumDescriptor::T_D8, record);
1214  break;
1216  record = new SgDbhDataRecord<int>;
1217  *(SgDbhDataRecord<int>*)record = *(SgDbhDataRecord<int>*)rec_in;
1218  listOfRecords_.append(record);
1219  recordByType_.insert(SgDbhDatumDescriptor::T_J4, record);
1220  break;
1222  default:
1223  // complain:
1225  ": SgDbhStream: operator=(): Wrong type of data record");
1226  break;
1227  };
1228  };
1229  return *this;
1230 };
1231 /*=====================================================================================================*/
1232 
1233 
1234 
1235 
1236 
1237 
1238 /*=======================================================================================================
1239 *
1240 * TE block of MK-III database format:
1241 *
1242 *======================================================================================================*/
1243 //
1245 {
1246  // copy the members:
1247  recTe_ = teBlock.recTe_;
1248  recP3_ = teBlock.recP3_;
1249  recP4_ = teBlock.recP4_;
1250  isOK_ = teBlock.isOK_;
1251  *(SgDbhListOfDescriptors*)this = teBlock;
1252  *(SgDbhDataBlock*)this = teBlock;
1253  return *this;
1254 };
1255 
1256 
1257 
1258 //
1260 {
1261  char tmps[9];
1262  for (int i=0; i<recTe_.numberOfDescriptors_; i++)
1263  {
1264  SgDbhDatumDescriptor *descriptor = new SgDbhDatumDescriptor;
1265  s.readRawData(tmps, 8);
1266  *(tmps + 8) = 0;
1267  descriptor->lCode_ = (const char*)tmps;
1268  s >> (qint16 &)descriptor->modifiedAtVersion_
1269  >> (qint16 &)descriptor->dim1_
1270  >> (qint16 &)descriptor->dim2_
1271  >> (qint16 &)descriptor->dim3_;
1272  listOfDescriptors_.append(descriptor);
1273  };
1274  return 16*recTe_.numberOfDescriptors_;
1275 };
1276 
1277 
1278 
1279 //
1281 {
1282  char tmps[33];
1283  for (int i=0; i<recTe_.numberOfDescriptors_; i++)
1284  {
1285  s.readRawData(tmps, 32);
1286  *(tmps + 32) = 0;
1287  listOfDescriptors_.at(i)->description_ = (const char*)tmps;
1288  };
1289  return 32*recTe_.numberOfDescriptors_;
1290 };
1291 
1292 
1293 
1294 //
1296 {
1297  char tmps[8];
1298  int num = recTe_.numberOfDescriptors_;
1299  for (int dIdx=0; dIdx<num; dIdx++)
1300  {
1301  SgDbhDatumDescriptor *descriptor = listOfDescriptors_.at(dIdx);
1302  for (int i=0; i<8; i++)
1303  tmps[i] = descriptor->lCode_.at(i).toLatin1();
1304  s.writeRawData(tmps, 8);
1305  s << (const qint16 &)descriptor->modifiedAtVersion_
1306  << (const qint16 &)descriptor->dim1_
1307  << (const qint16 &)descriptor->dim2_
1308  << (const qint16 &)descriptor->dim3_;
1309  };
1310  return 16*num;
1311 };
1312 
1313 
1314 
1315 //
1317 {
1318  char tmps[32];
1319  int num = recTe_.numberOfDescriptors_;
1320  for (int dIdx=0; dIdx<num; dIdx++)
1321  {
1322  SgDbhDatumDescriptor *descriptor = listOfDescriptors_.at(dIdx);
1323  int n2write = std::min(descriptor->description_.size(), 32), i;
1324  for (i=0; i<n2write; i++)
1325  tmps[i] = descriptor->description_.at(i).toLatin1();
1326  for (; i<32; i++)
1327  tmps[i] = 0;
1328  s.writeRawData(tmps, 32);
1329  };
1330  return 32*num;
1331 };
1332 
1333 
1334 
1335 //
1336 void SgDbhTeBlock::dump(QTextStream& s) const
1337 {
1338  s << "== TE[" << recTe_.teBlockNum_ << "] Block dump: ==" << endl;
1339  s << "Block length: " << calcDataSize() << " (bytes)" << endl;
1340  recTe_.dump(s);
1342  s << "== End of TE Block dump" << endl;
1343 };
1344 
1345 
1346 
1347 //
1349 {
1350  int numOfData=0;
1352  for (i=listOfDescriptors_.constBegin(); i!=listOfDescriptors_.constEnd(); ++i)
1353  {
1354  SgDbhDatumDescriptor *descriptor=*i;
1355  if (descriptor->type()==type)
1356  numOfData += descriptor->dim1()*descriptor->dim2()*descriptor->dim3();
1357  };
1358  return numOfData;
1359 };
1360 
1361 
1362 
1363 //
1365 {
1366  int num = listOfDescriptors_.size();
1367  recP3_.reSize(16*num);
1368  recP4_.reSize(32*num);
1369  recTe_.numberOfDescriptors_ = (short)num;
1371  int i=0;
1372  for (it=listOfDescriptors_.constBegin(); it!=listOfDescriptors_.constEnd(); ++it, i++)
1373  {
1374  SgDbhDatumDescriptor *descriptor = *it;
1375  if (descriptor->getLCode()=="I-FILLER")
1376  recTe_.offsetI_ = (short)i;
1377  else if (descriptor->getLCode()=="A-FILLER")
1378  recTe_.offsetA_ = (short)i;
1379  else if (descriptor->getLCode()=="D-FILLER")
1380  recTe_.offsetD_ = (short)i;
1381  else if (descriptor->getLCode()=="J-FILLER")
1382  recTe_.offsetJ_ = (short)i;
1383  };
1389 };
1390 
1391 
1392 
1393 //
1395 {
1396  int dataSize=0;
1397  int sizeOfType=0;
1398  for (int i=0; i<listOfDescriptors_.size(); i++)
1399  {
1400  SgDbhDatumDescriptor *descriptor=listOfDescriptors_.at(i);
1401  switch (descriptor->type())
1402  {
1404  sizeOfType = sizeof(double);
1405  break;
1407  sizeOfType = sizeof(short);
1408  break;
1410  sizeOfType = 2*sizeof(char);
1411  break;
1413  sizeOfType = sizeof(double);
1414  break;
1416  sizeOfType = sizeof(int);
1417  break;
1418  default:
1420  sizeOfType = 0;
1421  break;
1422  };
1423  dataSize += descriptor->dim1()*descriptor->dim2()*descriptor->dim3()*sizeOfType;
1424  };
1425  return dataSize;
1426 };
1427 
1428 
1429 
1430 //
1432 {
1433  s >> B.recTe_ >> B.recP3_ >> B.recP4_;
1434  B.isOK_ = B.isOK_ && B.recTe_.isOk() && B.recP3_.isOk() && B.recP4_.isOk();
1435  return s;
1436 };
1437 
1438 
1439 
1440 //
1442 {
1443  s << B.recTe_ << B.recP3_ << B.recP4_;
1444  return s;
1445 };
1446 /*=====================================================================================================*/
1447 
1448 
1449 
1450 
1451 
1452 
1453 /*=======================================================================================================
1454 *
1455 * TC block of MK-III database format:
1456 *
1457 *======================================================================================================*/
1458 //
1460 {
1461  while (!listOfTeBlocks_.isEmpty())
1462  delete listOfTeBlocks_.takeFirst();
1463  descriptorByLCode_.clear();
1464 };
1465 
1466 
1467 
1468 //
1469 void SgDbhTcBlock::dump(QTextStream& s) const
1470 {
1471  s << "== TC[" << tocType() << "] Block dump: ==" << endl;
1472  recTc_.dump(s);
1473  for (int i=0; i<listOfTeBlocks_.size(); i++)
1474  listOfTeBlocks_.at(i)->dump(s);
1475  s << "==" << endl;
1476 };
1477 
1478 
1479 
1480 //
1482 {
1483  // copy the members:
1484  isOK_ = tcBlock.isOK_;
1485  recTc_= tcBlock.recTc_;
1486 
1487  // clear the lists and the hash:
1488  while (!listOfTeBlocks_.isEmpty())
1489  delete listOfTeBlocks_.takeFirst();
1490  descriptorByLCode_.clear();
1491 
1492  for (int teCount=0; teCount<tcBlock.listOfTeBlocks_.size(); teCount++)
1493  {
1494  SgDbhTeBlock *teBlock = new SgDbhTeBlock;
1495  *teBlock = *tcBlock.listOfTeBlocks_.at(teCount);
1496  listOfTeBlocks_.append(teBlock);
1497 
1498  for (int i=0; i<teBlock->listOfDescriptors()->size(); i++)
1499  {
1500  SgDbhDatumDescriptor* descriptor=teBlock->listOfDescriptors()->at(i);
1501  if (descriptor->getLCode()!="R-FILLER" &&
1502  descriptor->getLCode()!="I-FILLER" &&
1503  descriptor->getLCode()!="A-FILLER" &&
1504  descriptor->getLCode()!="D-FILLER" &&
1505  descriptor->getLCode()!="J-FILLER")
1506  descriptorByLCode_.insert(descriptor->getLCode(), descriptor);
1507  };
1508  };
1509  return *this;
1510 };
1511 
1512 
1513 
1514 //
1516 {
1517  s >> B.recTc_;
1518  while (!B.listOfTeBlocks_.isEmpty())
1519  delete B.listOfTeBlocks_.takeFirst();
1520  if (!B.isLast() && (B.isOK_=B.recTc_.isOk()))
1521  for (int i=0; i<B.recTc_.numTeBlocks(); i++)
1522  {
1523  SgDbhTeBlock *teBlock = new SgDbhTeBlock;
1524  s >> *teBlock;
1525  if ((B.isOK_ = B.isOK_ && teBlock->isOk()))
1526  B.listOfTeBlocks_.append(teBlock);
1527  else
1528  delete teBlock;
1529  };
1530  return s;
1531 };
1532 
1533 
1534 
1535 //
1537 {
1538  s << B.recTc_;
1539  for (int i=0; i<B.listOfTeBlocks_.size(); i++)
1540  s << *B.listOfTeBlocks_.at(i);
1541  return s;
1542 };
1543 /*=====================================================================================================*/
1544 
1545 
1546 
1547 
1548 
1549 
1550 /*=======================================================================================================
1551 *
1552 * A list of data blocks that represent one observation (several TOCs):
1553 *
1554 *======================================================================================================*/
1555 //
1557 {
1558  // clear data from all TOCs for current observation entry:
1559 
1560  while (!listOfTcsData_.isEmpty())
1561  {
1562  QList<SgDbhDataBlock*> *listOfDataBlocks=listOfTcsData_.first();
1563  while (!listOfDataBlocks->isEmpty())
1564  delete listOfDataBlocks->takeFirst();
1565  listOfTcsData_.removeFirst();
1566  delete listOfDataBlocks;
1567  };
1568 };
1569 
1570 
1571 
1572 //
1574 {
1575  tocNumber--; // adjust for TOC General
1576  if (listOfTcsData_.size()!=tocNumber) // should not happen, complain:
1578  ": listOfTcsData_.size()>tocNumber (need to replace QList with QHash)");
1579 
1580  QList<SgDbhDataBlock*> *listOfDataBlocks = new QList<SgDbhDataBlock*>;
1581  listOfTcsData_.append(listOfDataBlocks);
1582 
1583  for (int teCount=0; teCount<tcBlock.listOfTeBlocks()->size(); teCount++)
1584  {
1585  SgDbhDataBlock *dataBlock = new SgDbhDataBlock;
1586  *dataBlock = *tcBlock.listOfTeBlocks()->at(teCount);
1587  listOfDataBlocks->append(dataBlock);
1588  };
1589 };
1590 /*=====================================================================================================*/
1591 
1592 
1593 
1594 
1595 
1596 
1597 /*=======================================================================================================
1598 *
1599 * METHODS:
1600 *
1601 *======================================================================================================*/
1602 //
1604 {
1605  // check:
1606  if (!isOk())
1607  {
1609  ": properRecord(): called while the format is not ready");
1610  return NULL;
1611  }
1612  if (!descriptor)
1613  {
1615  ": properRecord(): argument is NULL");
1616  return NULL;
1617  };
1618  if (descriptor->nTc()!=currentTcNumber())
1619  {
1621  QString().sprintf(": properRecord(): the descriptor [%s] aka \"%s\", is from other TOC, %d;"
1622  " current TOC is %d", qPrintable(descriptor->getLCode()),
1623  qPrintable(descriptor->getDescription()), descriptor->nTc(), currentTcNumber()));
1624  return NULL;
1625  };
1626  SgDbhTcBlock *tcBlock = currentTcBlock();
1627  if (!tcBlock)
1628  {
1630  QString().sprintf(": properRecord(): current TC block is NULL, TC# %d", currentTcNumber()));
1631  return NULL;
1632  };
1633  SgDbhTeBlock *teBlock = tcBlock->listOfTeBlocks()->at(descriptor->nTe());
1634  return teBlock ? (
1635  teBlock->recordByType()->contains(descriptor->type()) ?
1636  teBlock->recordByType()->value(descriptor->type()) : NULL
1637  ) : NULL;
1638 };
1639 
1640 
1641 
1642 //
1644 {
1645  int offset;
1646  short tcCount, teCount;
1648 
1649  for (tcCount=0; tcCount<listOfTcBlocks_.size(); tcCount++)
1650  {
1651  SgDbhTcBlock *tcBlock = listOfTcBlocks_.at(tcCount);
1652  tcBlock->descriptorByLCode_.clear();
1653 
1654  for (teCount=0; teCount<tcBlock->listOfTeBlocks()->size(); teCount++)
1655  {
1656  SgDbhTeBlock* teBlock = tcBlock->listOfTeBlocks()->at(teCount);
1657  SgDbhPhysicalRecord *record;
1658  offset = 0;
1659  teBlock->recordByType_.clear();
1660  while (!teBlock->listOfRecords()->isEmpty())
1661  delete teBlock->listOfRecords()->takeFirst();
1662  for (int i=0; i<teBlock->listOfDescriptors()->size(); i++)
1663  {
1664  SgDbhDatumDescriptor* descriptor=teBlock->listOfDescriptors()->at(i);
1665  if (descriptor->getLCode()=="R-FILLER")
1666  {
1667  offset=0;
1668  teBlock->listOfRecords()->append((record = new SgDbhDataRecord<double>));
1669  teBlock->recordByType()->insert((type=SgDbhDatumDescriptor::T_R8), record);
1670  }
1671  else if (descriptor->getLCode()=="I-FILLER")
1672  {
1673  offset=0;
1674  teBlock->listOfRecords()->append((record = new SgDbhDataRecord<short>));
1675  teBlock->recordByType()->insert((type=SgDbhDatumDescriptor::T_I2), record);
1676  }
1677  else if (descriptor->getLCode()=="A-FILLER")
1678  {
1679  offset=0;
1680  teBlock->listOfRecords()->append((record = new SgDbhDataRecordString));
1681  teBlock->recordByType()->insert((type=SgDbhDatumDescriptor::T_A2), record);
1682  }
1683  else if (descriptor->getLCode()=="D-FILLER")
1684  {
1685  offset=0;
1686  teBlock->listOfRecords()->append((record = new SgDbhDataRecord<double>));
1687  teBlock->recordByType()->insert((type=SgDbhDatumDescriptor::T_D8), record);
1688  }
1689  else if (descriptor->getLCode()=="J-FILLER")
1690  {
1691  offset=0;
1692  teBlock->listOfRecords()->append((record = new SgDbhDataRecord<int>));
1693  teBlock->recordByType()->insert((type=SgDbhDatumDescriptor::T_J4), record);
1694  }
1695  else if (!tcBlock->descriptorByLCode()->contains(descriptor->getLCode()))
1696  tcBlock->descriptorByLCode()->insert(descriptor->getLCode(), descriptor);
1697  else
1699  QString().sprintf(": postRead(): descriptor [%s] already in the hash",
1700  qPrintable(descriptor->getLCode())));
1701  descriptor->setOffset(offset);
1702  descriptor->setType(type);
1703  descriptor->setNTc(tcCount);
1704  descriptor->setNTe(teCount);
1705  offset += descriptor->dim1()*descriptor->dim2()*descriptor->dim3();
1706  };
1707  switch (teBlock->listOfRecords()->count())
1708  {
1709  case 0:
1711  ": postRead(): the order of records is not parsed correctly");
1712  break;
1713  case 1 ... 4:
1715  ": postRead(): some data records are missed");
1716  break;
1717  case 5:
1719  ": postRead(): the order of records is parsed correctly");
1720  break;
1721  default:
1723  ": postRead(): too many records");
1724  };
1725  };
1726  };
1727 };
1728 
1729 
1730 
1731 //
1733 {
1734  return currentTcBlock()->descriptorByLCode()->contains(tag) ?
1735  currentTcBlock()->descriptorByLCode()->value(tag) : NULL;
1736 };
1737 
1738 
1739 
1740 //
1742 {
1745  SgDbhPhysicalRecord *record = NULL;
1746  SgDbhTcBlock *tcBlock = NULL;
1747  SgDbhTeBlock *teBlock = NULL;
1748 
1749  s >> DR;
1750  if (dumpStream_)
1751  {
1752  *dumpStream_ << "== Data Block dump: ==" << endl;
1753  DR.dump(*dumpStream_);
1754  };
1755 
1756  if (!(isOK_ = isOK_ && DR.isOk()))
1758  ": getBlock: error reading DR record");
1759  else
1760  tcBlock = listOfTcBlocks_.at((currentTcNumber_=(short)(DR.getTcNo()))); // is it right????????????
1761 
1762  while (!DE.isZ3() && isOK_)
1763  {
1764  s >> DE;
1765  if (!(isOK_ = isOK_ && DE.isOk()))
1767  ": getBlock: error reading DE record");
1768  if (dumpStream_ && isOK_)
1769  DE.dump(*dumpStream_);
1770  if (DE.isCorrectPrefix() && isOK_)
1771  {
1772  teBlock = tcBlock->listOfTeBlocks()->at(DE.getTeNo());
1773  for (int i=0; i<teBlock->listOfRecords()->size() && isOK_; i++)
1774  {
1775  record = teBlock->listOfRecords()->at(i);
1776  s >> *record;
1777  isOK_ = isOK_ && record->isOk();
1778  };
1779  };
1780  };
1781 
1782  if (!isOK_)
1784  ": getBlock: error reading data record");
1785 
1786  // make dump:
1787  if (dumpStream_ && isOK_)
1788  {
1789  *dumpStream_ << "== TC[" << currentTcNumber_ << "] Data Block dump: ==" << endl;
1790  for (int i=0; i<tcBlock->listOfTeBlocks()->size(); i++)
1791  {
1792  teBlock = tcBlock->listOfTeBlocks()->at(i);
1793  *dumpStream_ << "== TE[" << i << "] Data Block dump: ==" << endl;
1794  *dumpStream_ << "The sizes of data records are:" << endl;
1795  for (int j=0; j<teBlock->listOfRecords()->size(); j++)
1796  *dumpStream_ << " " << j << ": " << teBlock->listOfRecords()->at(j)->length() << endl;
1797  *dumpStream_ << "--" << endl;
1798  teBlock->recTe_.dump(*dumpStream_);
1799  for (int j=0; j<teBlock->listOfDescriptors()->size(); j++)
1800  {
1801  SgDbhDatumDescriptor* descriptor = teBlock->listOfDescriptors()->at(j);
1802  if ((record = teBlock->recordByType()->value(descriptor->type())))
1803  {
1804  *dumpStream_<< "\"" << descriptor->getLCode() << "\" (aka \""
1805  << descriptor->getDescription().simplified() << "\") ["
1806  << descriptor->dim1() << "," << descriptor->dim2() << ","
1807  << descriptor->dim3() << "] =" << endl << "(" << endl;
1808  for (int li=0; li<descriptor->dim3(); li++)
1809  {
1810  *dumpStream_ << " (";
1811  for (int lj=0; lj<descriptor->dim2(); lj++)
1812  {
1813  if (descriptor->type()==SgDbhDatumDescriptor::T_A2)
1814  *dumpStream_ << "\""
1815  << ((SgDbhDataRecordString*)record)->getValue(descriptor, lj, li)
1816  << "\"";
1817  else
1818  {
1819  *dumpStream_ << "(";
1820  for (int lk=0; lk<descriptor->dim1(); lk++)
1821  {
1822  switch(descriptor->type())
1823  {
1825  *dumpStream_ << ((SgDbhDataRecord<double>*)record)->value(descriptor, lk, lj, li);
1826  break;
1828  *dumpStream_ << ((SgDbhDataRecord<short>*)record)->value(descriptor, lk, lj, li);
1829  break;
1831  *dumpStream_ << ((SgDbhDataRecord<double>*)record)->value(descriptor, lk, lj, li);
1832  break;
1834  *dumpStream_ << ((SgDbhDataRecord<int>*)record)->value(descriptor, lk, lj, li);
1835  break;
1836  default: *dumpStream_ << "????";
1837  };
1838  *dumpStream_ << (lk<descriptor->dim1()-1?", ":"");
1839  };
1840  *dumpStream_ << ")";
1841  };
1842  *dumpStream_ << (lj<descriptor->dim2()-1?", ":"");
1843  };
1844  *dumpStream_ << ")" << (li<descriptor->dim3()-1 ? "," : "") << endl;
1845  };
1846  *dumpStream_ << ");" << endl;
1847  }
1848  else
1850  QString().sprintf(": getBlock: can't find record for [%s] descriptor",
1851  qPrintable(descriptor->getLCode())));
1852  };
1853  };
1854  *dumpStream_ << endl;
1855  };
1856 };
1857 /*=====================================================================================================*/
1858 
1859 
1860 
1861 
1862 
1863 
1864 /*=======================================================================================================
1865 *
1866 * FRIENDS:
1867 *
1868 *======================================================================================================*/
1869 //
1871 {
1872  SgDbhTcBlock *tcBlock;
1873  do
1874  {
1875  tcBlock = new SgDbhTcBlock;
1876  s >> *tcBlock;
1877  if (!tcBlock->isLast() && (F.isOK_ = F.isOK_ && tcBlock->isOk()))
1878  F.listOfTcBlocks_.append(tcBlock);
1879  else
1880  delete tcBlock;
1881  } while (tcBlock && !tcBlock->isLast() && F.isOK_);
1882  F.postRead();
1883  return s;
1884 };
1885 
1886 
1887 
1888 //
1890 {
1891  for (int i=0; i<F.listOfTcBlocks_.size(); i++)
1892  s << *F.listOfTcBlocks_.at(i);
1893  SgDbhServiceRecordTc tcRec = F.listOfTcBlocks_.at(0)->recTc();
1894  tcRec.setAltered();
1895  return s << tcRec;
1896 };
1897 /*=====================================================================================================*/
1898 
1899 //
1900 // aux functions:
1901 //
1902 
1903 
1904 // i/o:
1905 
1906 
1907 /*=====================================================================================================*/
1908 //
1909 // constants:
1910 //
1911 
1912 
1913 /*=====================================================================================================*/
SgDbhStream & operator<<(SgDbhStream &s, const SgDbhPhysicalRecord &record)
SgDbhStream & operator>>(SgDbhStream &s, SgDbhPhysicalRecord &record)
SgLogger * logger
Definition: SgLogger.cpp:231
QHash< int, SgDbhPhysicalRecord * > * recordByType()
Definition: SgDbhFormat.h:575
QList< SgDbhPhysicalRecord * > * listOfRecords()
Definition: SgDbhFormat.h:574
QList< SgDbhPhysicalRecord * > listOfRecords_
Definition: SgDbhFormat.h:580
QHash< int, SgDbhPhysicalRecord * > recordByType_
Definition: SgDbhFormat.h:584
QString className() const
Definition: SgDbhFormat.h:580
SgDbhDataBlock & operator=(const SgDbhDataBlock &)
virtual SgDbhDataRecordString & operator=(const SgDbhDataRecordString &rec)
void setText(const QString &text)
const QString & getText() const
Definition: SgDbhFormat.h:115
virtual int readLR(SgDbhStream &s)
static const QString className()
virtual QString getValue(SgDbhDatumDescriptor *, int dim2, int dim3)
virtual ~SgDbhDataRecordString()
void setValue(SgDbhDatumDescriptor *, int dim2, int dim3, const QString &)
virtual C & access(SgDbhDatumDescriptor *descriptor, int d1, int d2, int d3)
virtual char * base()
virtual C at(int i) const
virtual int readLR(SgDbhStream &s)
virtual C & operator[](int i)
virtual void reSize(int length)
virtual QString className() const
virtual SgDbhDataRecord< C > & operator=(const SgDbhDataRecord< C > &rec)
virtual C value(SgDbhDatumDescriptor *descriptor, int d1, int d2, int d3)
virtual int writeLR(SgDbhStream &s) const
short nTe() const
Definition: SgDbhImage.h:97
int offset() const
Definition: SgDbhImage.h:98
short dim2() const
Definition: SgDbhImage.h:93
short getModifiedAtVersion() const
Definition: SgDbhImage.h:95
const QString & getLCode() const
Definition: SgDbhImage.h:90
const QString & getDescription() const
Definition: SgDbhImage.h:91
short nTc() const
Definition: SgDbhImage.h:96
void setType(Type type)
Definition: SgDbhImage.h:103
void setNTe(int nTe)
Definition: SgDbhImage.h:108
Type type() const
Definition: SgDbhImage.h:99
void setOffset(int offset)
Definition: SgDbhImage.h:109
short dim3() const
Definition: SgDbhImage.h:94
short dim1() const
Definition: SgDbhImage.h:92
void setNTc(int nTc)
Definition: SgDbhImage.h:107
short currentTcNumber()
Definition: SgDbhFormat.h:781
QTextStream * dumpStream_
Definition: SgDbhFormat.h:838
SgDbhTcBlock * currentTcBlock()
Definition: SgDbhFormat.h:797
SgDbhPhysicalRecord * properRecord(SgDbhDatumDescriptor *)
bool isOk() const
Definition: SgDbhFormat.h:779
QString className() const
Definition: SgDbhFormat.h:819
SgDbhDatumDescriptor * lookupDescriptor(const char *)
short currentTcNumber_
Definition: SgDbhFormat.h:840
void getBlock(SgDbhStream &)
QList< SgDbhTcBlock * > listOfTcBlocks_
Definition: SgDbhFormat.h:837
void setEvent(const QString &, const QString &, int, const SgMJD &)
SgDbhDataRecordString record3_
Definition: SgDbhFormat.h:492
bool isOk() const
Definition: SgDbhFormat.h:497
void setEpoch(const SgMJD &t)
Definition: SgDbhFormat.h:508
SgDbhServiceRecordHS2 record2_
Definition: SgDbhFormat.h:491
void dump(QTextStream &s) const
void setText(const QString &text)
void setVersion(int version)
Definition: SgDbhFormat.h:507
SgDbhServiceRecordHS1 record1_
Definition: SgDbhFormat.h:490
SgDbhListOfDescriptors & operator=(const SgDbhListOfDescriptors &)
QList< SgDbhDatumDescriptor * > listOfDescriptors_
Definition: SgDbhFormat.h:546
QList< SgDbhDatumDescriptor * > * listOfDescriptors()
Definition: SgDbhFormat.h:540
void dump(QTextStream &) const
void saveDataBlocksFromTcBlock(int TocNumber, SgDbhTcBlock &tcBlock)
QString className() const
Definition: SgDbhFormat.h:740
QList< QList< SgDbhDataBlock * > * > listOfTcsData_
Definition: SgDbhFormat.h:740
int length() const
Definition: SgDbhFormat.h:70
virtual int readLR(SgDbhStream &s)
static const QString className()
Definition: SgDbhFormat.cpp:43
virtual int writeLR(SgDbhStream &s) const
virtual SgDbhPhysicalRecord & operator=(const SgDbhPhysicalRecord &)
Definition: SgDbhFormat.cpp:71
virtual void reSize(int length)
Definition: SgDbhFormat.cpp:90
bool isOk() const
Definition: SgDbhFormat.h:69
virtual ~SgDbhPhysicalRecord()
Definition: SgDbhFormat.cpp:61
bool isZ3() const
Definition: SgDbhFormat.h:421
void dump(QTextStream &s) const
virtual int writeLR(SgDbhStream &s) const
virtual int readLR(SgDbhStream &)
virtual QString className() const
Definition: SgDbhFormat.h:429
virtual bool isAltered() const
Definition: SgDbhFormat.h:420
virtual int readLR(SgDbhStream &s)
virtual int writeLR(SgDbhStream &s) const
int getTcNo() const
Definition: SgDbhFormat.h:367
void dump(QTextStream &s) const
void setLengthOfHistoryString(int length)
Definition: SgDbhFormat.h:223
int getLengthOfHistoryString() const
Definition: SgDbhFormat.h:219
SgMJD getHistoryEpoch() const
Definition: SgDbhFormat.h:221
int getVersionNumber() const
Definition: SgDbhFormat.h:220
virtual bool isAltered() const
Definition: SgDbhFormat.h:229
virtual int writeLR(SgDbhStream &s) const
void setHistoryEpoch(const SgMJD &)
virtual int readLR(SgDbhStream &s)
virtual int readLR(SgDbhStream &s)
virtual int writeLR(SgDbhStream &s) const
void setSemiName(const QString &)
virtual bool isAltered() const
Definition: SgDbhFormat.h:294
virtual QString className() const
Definition: SgDbhFormat.h:303
virtual int writeLR(SgDbhStream &s) const
virtual int readLR(SgDbhStream &)
void dump(QTextStream &s) const
short numTeBlocks() const
Definition: SgDbhFormat.h:292
void dump(QTextStream &s) const
virtual int writeLR(SgDbhStream &s) const
virtual int readLR(SgDbhStream &)
virtual int writeLR(SgDbhStream &s) const
Definition: SgDbhFormat.h:191
bool isCorrectPrefix() const
Definition: SgDbhFormat.h:179
void setPrefix(const char prefix[2])
Definition: SgDbhFormat.h:183
virtual bool isAltered() const
Definition: SgDbhFormat.h:181
bool isPrefixParsed(SgDbhStream &)
void rotateVersion(int newVersion, const QString &newFileName)
SgDbhDataRecord< short > epochRec_
Definition: SgDbhFormat.h:452
const QString & prevDescript() const
Definition: SgDbhFormat.h:466
const QString & prevDb() const
Definition: SgDbhFormat.h:465
void dump(QTextStream &) const
void alternateCode(const QString &)
SgDbhDataRecord< short > versionRec_
Definition: SgDbhFormat.h:453
SgDbhDataRecordString prevDbRec_
Definition: SgDbhFormat.h:450
SgDbhDataRecordString expDescriptRec_
Definition: SgDbhFormat.h:448
SgDbhDataRecordString prevRec_
Definition: SgDbhFormat.h:451
const QString & expDescript() const
Definition: SgDbhFormat.h:463
short epoch_[5]
Definition: SgDbhFormat.h:455
int version() const
Definition: SgDbhFormat.h:461
const QString & sessionID() const
Definition: SgDbhFormat.h:464
SgDbhDataRecordString dbNameRec_
Definition: SgDbhFormat.h:447
SgMJD epoch() const
Definition: SgDbhFormat.h:460
SgDbhDataRecordString sessIDRec_
Definition: SgDbhFormat.h:449
bool isLast() const
Definition: SgDbhFormat.h:692
QList< SgDbhTeBlock * > * listOfTeBlocks()
Definition: SgDbhFormat.h:685
QHash< QString, SgDbhDatumDescriptor * > * descriptorByLCode()
Definition: SgDbhFormat.h:686
QList< SgDbhTeBlock * > listOfTeBlocks_
Definition: SgDbhFormat.h:707
SgDbhServiceRecordTc recTc_
Definition: SgDbhFormat.h:706
QHash< QString, SgDbhDatumDescriptor * > descriptorByLCode_
Definition: SgDbhFormat.h:708
void dump(QTextStream &s) const
short tocType() const
Definition: SgDbhFormat.h:694
SgDbhTcBlock & operator=(const SgDbhTcBlock &)
int readRecordP3(SgDbhStream &)
SgDbhServiceRecordP3 recP3_
Definition: SgDbhFormat.h:656
int writeRecordP3(SgDbhStream &) const
SgDbhServiceRecordP4 recP4_
Definition: SgDbhFormat.h:657
int readRecordP4(SgDbhStream &)
void adjustServiceRecords()
void dump(QTextStream &) const
SgDbhTeBlock & operator=(const SgDbhTeBlock &)
bool isOk() const
Definition: SgDbhFormat.h:613
int writeRecordP4(SgDbhStream &) const
int calcDataSize() const
int calculateNumOfData(SgDbhDatumDescriptor::Type type) const
SgDbhServiceRecordTe recTe_
Definition: SgDbhFormat.h:655
virtual void write(LogLevel, quint32, const QString &, bool=false)
Definition: SgLogger.cpp:88
@ IO_DBH
Definition: SgLogger.h:67
Definition: SgMJD.h:59
double getTime() const
Definition: SgMJD.h:457
@ F_Verbose
Definition: SgMJD.h:65
QString toString(Format format=F_Verbose) const
Definition: SgMJD.cpp:1007
int getDate() const
Definition: SgMJD.h:449
int calcDayOfYear() const
Definition: SgMJD.cpp:237
static SgMJD currentMJD()
Definition: SgMJD.cpp:118
static void MJD_reverse(int date, double time, int &nYear, int &nMonth, int &nDay, int &nHour, int &nMin, double &dSec)
Definition: SgMJD.cpp:74