1 /***************************************************************************
2 ofmt.cpp - formatted input/output
3 -------------------
4 begin : July 22 2002
5 copyright : (C) 2002 by Marc Schellens
6 email : m_schellens@users.sf.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17 //#include "datatypes.hpp" // for friend declaration
18 #include "dstructgdl.hpp"
19 #include "real2int.hpp"
20 #include "calendar.hpp"
21
22 #include "ofmt.hpp"
23 using namespace std;
24
25 // for double -> string
double2string(DDouble d)26 inline string double2string( DDouble d)
27 {
28 std::ostringstream os;
29 OutAuto( os, d, 16, 8, ' ');
30 return os.str();
31 }
32
33 // for float -> string
float2string(DFloat f)34 inline string float2string( DFloat f)
35 {
36 std::ostringstream os;
37 OutAuto( os, f, 13, 6, ' ');
38 return os.str();
39 }
40
41
42 static const std::string allstars="****************************************************************************************************************************";
43 template< typename Ty>
binstr(const Ty v,int w,int d,int code)44 std::string binstr( const Ty v, int w, int d, int code)
45 {
46 bool dofill=( ( (code & fmtPAD) > 0 ) );
47 SizeT bitsetsize=sizeof(Ty)*8;
48 if ( v==Ty(0.0) ) {
49 if ( w<=0 ) return "0";
50 if ( (code & fmtALIGN_LEFT) > 0 ) {
51 return "0";
52 } else {
53 if (d>0) {
54 if (d<=w) {
55 std::string z(d,'0');
56 std::string s(w-d,' ');
57 s+=z;
58 return s;
59 } else {
60 std::string s(w+10,' '); //overfill to get ***
61 return s;
62 }
63 } else {
64 std::string s(w-1,dofill?'0':' ');
65 s+='0';
66 return s;
67 }
68 }
69 }
70
71 if (w==0) w=bitsetsize;
72
73 SizeT first=0;
74 if (bitsetsize == 8) {
75 std::bitset<8> me(v);
76 for (SizeT i=0; i<8; ++i) if (me.test(7-i)) {first=i; break;}
77 if (8-first > w) return allstars.substr(0,w); else
78 return me.to_string<char,char_traits<char>,allocator<char> >().substr(first);
79 } else if (bitsetsize == 16) {
80 std::bitset<16> me(v);
81 for (SizeT i=0; i<16; ++i) if (me.test(15-i)) {first=i; break;}
82 if (16-first > w) return allstars.substr(0,w); else
83 return me.to_string<char,char_traits<char>,allocator<char> >().substr(first);
84 } else if (bitsetsize == 32) {
85 std::bitset<32> me(v);
86 for (SizeT i=0; i<32; ++i) if (me.test(31-i)) {first=i; break;}
87 if (32-first > w) return allstars.substr(0,w); else
88 return me.to_string<char,char_traits<char>,allocator<char> >().substr(first);
89 } else {
90 std::bitset<64> me(v);
91 for (SizeT i=0; i<64; ++i) if (me.test(63-i)) {first=i; break;}
92 if (64-first > w) return allstars.substr(0,w); else
93 return me.to_string<char,char_traits<char>,allocator<char> >().substr(first);
94 }
95 }
96
97 #include "ofmt.hpp"
98
99 template <typename T>
OutInteger(std::ostream & os,const T & val,const int w,const int d,int code,const BaseGDL::IOMode oMode)100 void OutInteger(std::ostream& os, const T &val, const int w, const int d, int code, const BaseGDL::IOMode oMode) {
101 std::ostringstream oss;
102 if (d > 0) {
103 std::ostringstream ossI;
104 if (code & fmtSHOWPOS) ossI << std::showpos;
105 if (oMode == BaseGDL::DEC) ossI << val;
106 else if (oMode == BaseGDL::OCT) ossI << std::oct << val;
107 else if (oMode == BaseGDL::BIN) ossI << binstr(val, w, d, code);
108 else if (oMode == BaseGDL::HEX) ossI << std::uppercase << std::hex << val;
109 else ossI << std::nouppercase << std::hex << val; // HEXL
110 //force PADDING
111 code |= fmtPAD;
112 OutAdjustFill(oss, ossI.str(), d, code);
113 //remove PAD for next treatment ---> must be blanks
114 code &= (~fmtPAD);
115 } else {
116 if (code & fmtSHOWPOS) oss << std::showpos;
117 if (d > 0) oss << std::setw(d) << std::setfill('0');
118 if (oMode == BaseGDL::DEC) oss << val;
119 else if (oMode == BaseGDL::OCT) oss << std::oct << val;
120 else if (oMode == BaseGDL::BIN) oss << binstr(val, w, d, code);
121 else if (oMode == BaseGDL::HEX) oss << std::uppercase << std::hex << val;
122 else oss << std::nouppercase << std::hex << val; // HEXL
123 }
124 if (w == 0)
125 os << oss.str();
126 else if (oss.tellp() > w)
127 OutStars(os, w);
128 else if (code & fmtALIGN_LEFT) {
129 os << std::left;
130 os << std::setw(w);
131 os << oss.str();
132 os << std::right;
133 } else
134 OutFixFill(os, oss.str(), w, code);
135 }
136
137
138 template <>
OutFixed(ostream & os,const DComplex & val,const int w,const int d,const int code)139 void OutFixed<DComplex>(ostream& os, const DComplex &val, const int w, const int d, const int code)
140 {
141 OutFixed(os, val.real(), w, d, code);
142 OutFixed(os, val.imag(), w, d, code);
143 }
144
145 template <>
OutFixed(ostream & os,const DComplexDbl & val,const int w,const int d,const int code)146 void OutFixed<DComplexDbl>( ostream& os, const DComplexDbl &val, const int w, const int d, const int code)
147 {
148 OutFixed(os, val.real(), w, d, code);
149 OutFixed(os, val.imag(), w, d, code);
150 }
151
152 template <>
OutScientific(ostream & os,const DComplex & val,const int w,const int d,const int code)153 void OutScientific<DComplex>( ostream& os, const DComplex &val, const int w, const int d, const int code)
154 {
155 OutScientific( os, val.real(), w, d, code);
156 OutScientific( os, val.imag(), w, d, code);
157 }
158
159 template <>
OutScientific(ostream & os,const DComplexDbl & val,const int w,const int d,const int code)160 void OutScientific<DComplexDbl>( ostream& os, const DComplexDbl &val, const int w, const int d, const int code)
161 {
162 OutScientific( os, val.real(), w, d, code);
163 OutScientific( os, val.imag(), w, d, code);
164 }
165
166 template <>
OutAuto(ostream & os,const DComplex & val,const int w,const int d,const int code)167 void OutAuto<DComplex>( ostream& os, const DComplex &val, const int w, const int d, const int code)
168 {
169 OutAuto( os, val.real(), w, d, code);
170 OutAuto( os, val.imag(), w, d, code);
171 }
172
173 template <>
OutAuto(ostream & os,const DComplexDbl & val,const int w,const int d,const int code)174 void OutAuto<DComplexDbl>( ostream& os, const DComplexDbl &val, const int w, const int d, const int code)
175 {
176 OutAuto( os, val.real(), w, d, code);
177 OutAuto( os, val.imag(), w, d, code);
178 }
179
SetDefaultFieldLengths(int & w,int & d,const SizeT defPrec,const SizeT maxPrec,const SizeT wDef)180 void SetDefaultFieldLengths( int& w, int& d, const SizeT defPrec, const SizeT maxPrec, const SizeT wDef)
181 {
182 if( w == -1) // (X)
183 {
184 d = maxPrec;
185 w = wDef;
186 }
187 else if( w == 0) // (X0)
188 {
189 if( d <= 0) d = defPrec;
190 }
191 else if( d < 0) //should never happen now.
192 d = maxPrec;
193 }
194
OFmtAll(SizeT offs,SizeT r,SizeT & firstOut,SizeT & firstOffs,SizeT & tCount,SizeT & tCountOut)195 void DStructGDL::OFmtAll( SizeT offs, SizeT r,
196 SizeT& firstOut, SizeT& firstOffs,
197 SizeT& tCount, SizeT& tCountOut)
198 {
199 SizeT nTrans = ToTransfer();
200
201 // transfer count
202 tCount = nTrans - offs;
203 if( r < tCount) tCount = r;
204 tCountOut = tCount;
205
206 // find first Element
207 SizeT oneElTr = nTrans / N_Elements();
208
209 SizeT firstEl = offs / oneElTr;
210 firstOffs = offs % oneElTr;
211
212 // find first tag
213 SizeT nB = 0;
214 SizeT nTags=NTags();
215 SizeT firstTag = 0;
216 for( firstTag=0; firstTag < nTags; firstTag++)
217 {
218 SizeT tt=(*this)[firstTag]->ToTransfer();
219 nB += tt;
220 if( nB > firstOffs)
221 {
222 nB -= tt;
223 break;
224 }
225 }
226
227 firstOut = firstEl * NTags() + firstTag;
228 firstOffs -= nB;
229 }
230
231 // A code ****************************************************
232 // other
233 template<class Sp> SizeT
OFmtA(ostream * os,SizeT offs,SizeT r,int w,const int code)234 Data_<Sp>::OFmtA( ostream* os, SizeT offs, SizeT r, int w, const int code)
235 {
236 DStringGDL* stringVal = static_cast<DStringGDL*> ( this->Convert2( GDL_STRING, BaseGDL::COPY_BYTE_AS_INT));
237 SizeT retVal = stringVal->OFmtA( os, offs, r, w, code);
238 delete stringVal;
239 return retVal;
240 }
241 // string
242 template<> SizeT Data_<SpDString>::
OFmtA(ostream * os,SizeT offs,SizeT r,int w,const int code)243 OFmtA( ostream* os, SizeT offs, SizeT r, int w, const int code)
244 {
245 SizeT nTrans = ToTransfer();
246
247 // transfer count
248 SizeT tCount = nTrans - offs;
249 if( r < tCount) tCount = r;
250
251 SizeT endEl = offs + tCount;
252
253
254 if( w <= 0)
255 {
256 (*os) << left;
257 for( SizeT i=offs; i<endEl; ++i) (*os) << (*this)[ i];
258 }
259 else
260 {
261 if (code & fmtALIGN_LEFT) (*os)<< left ; else (*os) << right;
262 for( SizeT i=offs; i<endEl; ++i) (*os) << setw(w) << (*this)[ i].substr(0,w);
263 }
264
265 return tCount;
266 }
267 // complex
268 template<> SizeT Data_<SpDComplex>::
OFmtA(ostream * os,SizeT offs,SizeT r,int w,const int code)269 OFmtA(ostream* os, SizeT offs, SizeT r, int w, const int code)
270 {
271
272 SizeT nTrans = ToTransfer();
273
274 // transfer count
275 SizeT tCount = nTrans - offs;
276 if (r < tCount) tCount = r;
277 SizeT tCountOut = tCount;
278
279 SizeT firstEl = offs / 2;
280
281 (*os) << right;
282
283 if (offs & 0x01) {
284 if (w <= 0)
285 (*os) << float2string((*this)[ firstEl++].imag());
286 else {
287 if (code & fmtALIGN_LEFT) (*os) << left;
288 else (*os) << right;
289 (*os) << setw(w) << float2string((*this)[ firstEl++].imag()).substr(0,w);
290 }
291 tCount--;
292
293 }
294
295 SizeT endEl = firstEl + tCount / 2;
296
297 if (w <= 0)
298 for (SizeT i = firstEl; i < endEl; ++i) {
299 (*os) << float2string((*this)[ firstEl++].real());
300 (*os) << float2string((*this)[ firstEl++].imag());
301 } else {
302 if (code & fmtALIGN_LEFT) (*os) << left;
303 else (*os) << right;
304 for (SizeT i = firstEl; i < endEl; ++i) {
305 (*os) << setw(w) << float2string((*this)[ firstEl++].real()).substr(0,w);
306 (*os) << setw(w) << float2string((*this)[ firstEl++].imag()).substr(0,w);
307 }
308 }
309
310 if (tCount & 0x01) {
311 if (w <= 0)
312 (*os) << float2string((*this)[ firstEl++].real());
313 else {
314 if (code & fmtALIGN_LEFT) (*os) << left;
315 else (*os) << right;
316 (*os) << setw(w) << float2string((*this)[ firstEl++].real()).substr(0,w);
317 }
318 }
319
320 return tCountOut;
321 }
322 template<> SizeT Data_<SpDComplexDbl>::
OFmtA(ostream * os,SizeT offs,SizeT r,int w,const int code)323 OFmtA( ostream* os, SizeT offs, SizeT r, int w, const int code)
324 {
325 SizeT nTrans = ToTransfer();
326
327 // transfer count
328 SizeT tCount = nTrans - offs;
329 if (r < tCount) tCount = r;
330 SizeT tCountOut = tCount;
331
332 SizeT firstEl = offs / 2;
333
334 (*os) << right;
335
336 if (offs & 0x01) {
337 if (w <= 0)
338 (*os) << double2string((*this)[ firstEl++].imag());
339 else {
340 if (code & fmtALIGN_LEFT) (*os) << left;
341 else (*os) << right;
342 (*os) << setw(w) << double2string((*this)[ firstEl++].imag()).substr(0,w);
343 }
344 tCount--;
345
346 }
347
348 SizeT endEl = firstEl + tCount / 2;
349
350 if (w <= 0)
351 for (SizeT i = firstEl; i < endEl; ++i) {
352 (*os) << double2string((*this)[ firstEl++].real());
353 (*os) << double2string((*this)[ firstEl++].imag());
354 } else {
355 if (code & fmtALIGN_LEFT) (*os) << left;
356 else (*os) << right;
357 for (SizeT i = firstEl; i < endEl; ++i) {
358 (*os) << setw(w) << double2string((*this)[ firstEl++].real()).substr(0,w);
359 (*os) << setw(w) << double2string((*this)[ firstEl++].imag()).substr(0,w);
360 }
361 }
362
363 if (tCount & 0x01) {
364 if (w <= 0)
365 (*os) << double2string((*this)[ firstEl++].real());
366 else {
367 if (code & fmtALIGN_LEFT) (*os) << left;
368 else (*os) << right;
369 (*os) << setw(w) << double2string((*this)[ firstEl++].real()).substr(0,w);
370 }
371 }
372
373 return tCountOut;
374 }
375 // struct
376 SizeT DStructGDL::
OFmtA(ostream * os,SizeT offs,SizeT r,int w,const int code)377 OFmtA( ostream* os, SizeT offs, SizeT r, int w, const int code)
378 {
379 SizeT firstOut, firstOffs, tCount, tCountOut;
380 OFmtAll( offs, r, firstOut, firstOffs, tCount, tCountOut);
381
382 SizeT trans = (*this)[ firstOut]->OFmtA( os, firstOffs, tCount, w, code);
383 if( trans >= tCount) return tCountOut;
384 tCount -= trans;
385
386 SizeT ddSize = dd.size();
387 for( SizeT i = (firstOut+1); i < ddSize; ++i)
388 {
389 trans = (*this)[ i]->OFmtA( os, 0, tCount, w, code);
390 if( trans >= tCount) return tCountOut;
391 tCount -= trans;
392 }
393
394 return tCountOut;
395 }
396 // F code ****************************************************
397 // other
398 template<class Sp> SizeT Data_<Sp>::
OFmtF(ostream * os,SizeT offs,SizeT r,int w,int d,const int code,const BaseGDL::IOMode oMode)399 OFmtF( ostream* os, SizeT offs, SizeT r, int w, int d, const int code, const BaseGDL::IOMode oMode)
400 {
401 DDoubleGDL* cVal = static_cast<DDoubleGDL*>
402 ( this->Convert2( GDL_DOUBLE, BaseGDL::COPY));
403 SizeT retVal = cVal->OFmtF( os, offs, r, w, d, code, oMode);
404 delete cVal;
405 return retVal;
406 }
407 // double
408 template<> SizeT Data_<SpDDouble>::
OFmtF(ostream * os,SizeT offs,SizeT r,int w,int d,const int code,const BaseGDL::IOMode oMode)409 OFmtF( ostream* os, SizeT offs, SizeT r, int w, int d, const int code, const BaseGDL::IOMode oMode)
410 {
411 SizeT nTrans = ToTransfer();
412
413 // transfer count
414 SizeT tCount = nTrans - offs;
415 if( r < tCount) tCount = r;
416
417 SizeT endEl = offs + tCount;
418
419 SetDefaultFieldLengths( w, d, 6, 16, 25);
420
421 if( oMode == AUTO) // G
422 {
423 for( SizeT i=offs; i<endEl; ++i)
424 OutAuto( *os, (*this)[ i], w, d, code);
425 }
426 else if( oMode == FIXED) // F, D
427 {
428 for( SizeT i=offs; i<endEl; ++i)
429 OutFixed(*os, (*this)[ i], w, d, code);
430 }
431 else if ( oMode == SCIENTIFIC) // E
432 {
433 for( SizeT i=offs; i<endEl; ++i)
434 OutScientific( *os, (*this)[ i], w, d, code);
435 }
436
437 return tCount;
438 }
439 // float (same code as double)
440 template<> SizeT Data_<SpDFloat>::
OFmtF(ostream * os,SizeT offs,SizeT r,int w,int d,const int code,const BaseGDL::IOMode oMode)441 OFmtF( ostream* os, SizeT offs, SizeT r, int w, int d, const int code, const BaseGDL::IOMode oMode)
442 {
443 SizeT nTrans = ToTransfer();
444
445 // transfer count
446 SizeT tCount = nTrans - offs;
447 if( r < tCount) tCount = r;
448
449 SizeT endEl = offs + tCount;
450
451 SetDefaultFieldLengths( w, d, 6, 7, 15);
452
453 if( oMode == AUTO) // G
454 {
455 for( SizeT i=offs; i<endEl; ++i)
456 OutAuto( *os, (*this)[ i], w, d, code);
457 }
458 else if( oMode == FIXED) // F, D
459 {
460 for( SizeT i=offs; i<endEl; ++i)
461 OutFixed(*os, (*this)[ i], w, d, code);
462 }
463 else if ( oMode == SCIENTIFIC) // E
464 {
465 for( SizeT i=offs; i<endEl; ++i)
466 OutScientific( *os, (*this)[ i], w, d, code);
467 }
468
469 return tCount;
470 }
471 // complex
472 template<> SizeT Data_<SpDComplex>::
OFmtF(ostream * os,SizeT offs,SizeT r,int w,int d,const int code,const BaseGDL::IOMode oMode)473 OFmtF( ostream* os, SizeT offs, SizeT r, int w, int d, const int code, const BaseGDL::IOMode oMode)
474 {
475 SizeT nTrans = ToTransfer();
476
477 // transfer count
478 SizeT tCount = nTrans - offs;
479 if( r < tCount) tCount = r;
480 SizeT tCountOut = tCount;
481
482 SizeT firstEl = offs / 2;
483
484 SetDefaultFieldLengths( w, d, 6, 7, 15);
485
486 if( oMode == AUTO)
487 {
488 if( offs & 0x01)
489 {
490 OutAuto( *os, (*this)[ firstEl++].imag(), w, d, code);
491 tCount--;
492 }
493
494 SizeT endEl = firstEl + tCount / 2;
495
496 for( SizeT i= firstEl; i<endEl; ++i)
497 {
498 OutAuto( *os, (*this)[ i], w, d, code);
499 }
500
501 if( tCount & 0x01)
502 {
503 OutAuto( *os, (*this)[ endEl].real(), w, d, code);
504 }
505 }
506 else if( oMode == FIXED)
507 {
508 if( offs & 0x01)
509 {
510 OutFixed(*os, (*this)[ firstEl++].imag(), w, d, code);
511 tCount--;
512 }
513
514 SizeT endEl = firstEl + tCount / 2;
515
516 for( SizeT i= firstEl; i<endEl; ++i)
517 {
518 OutFixed(*os, (*this)[ i], w, d, code);
519 }
520
521 if( tCount & 0x01)
522 {
523 OutFixed(*os, (*this)[ endEl].real(), w, d, code);
524 }
525 }
526 else if ( oMode == SCIENTIFIC)
527 {
528 if( offs & 0x01)
529 {
530 OutScientific( *os, (*this)[ firstEl++].imag(), w, d, code);
531 tCount--;
532 }
533
534 SizeT endEl = firstEl + tCount / 2;
535
536 for( SizeT i= firstEl; i<endEl; ++i)
537 {
538 OutScientific( *os, (*this)[ i], w, d, code);
539 }
540
541 if( tCount & 0x01)
542 {
543 OutScientific( *os, (*this)[ endEl].real(), w, d, code);
544 }
545 }
546
547 return tCountOut;
548 }
549 // same code a float
550 template<> SizeT Data_<SpDComplexDbl>::
OFmtF(ostream * os,SizeT offs,SizeT r,int w,int d,const int code,const BaseGDL::IOMode oMode)551 OFmtF( ostream* os, SizeT offs, SizeT r, int w, int d, const int code, const BaseGDL::IOMode oMode)
552 {
553 SizeT nTrans = ToTransfer();
554
555 // transfer count
556 SizeT tCount = nTrans - offs;
557 if( r < tCount) tCount = r;
558 SizeT tCountOut = tCount;
559
560 SizeT firstEl = offs / 2;
561
562 SetDefaultFieldLengths( w, d, 6, 16, 25);
563
564 if( oMode == AUTO)
565 {
566 if( offs & 0x01)
567 {
568 OutAuto( *os, (*this)[ firstEl++].imag(), w, d, code);
569 tCount--;
570 }
571
572 SizeT endEl = firstEl + tCount / 2;
573
574 for( SizeT i= firstEl; i<endEl; ++i)
575 {
576 OutAuto( *os, (*this)[ i], w, d, code);
577 }
578
579 if( tCount & 0x01)
580 {
581 OutAuto( *os, (*this)[ endEl].real(), w, d, code);
582 }
583 }
584 else if( oMode == FIXED)
585 {
586 if( offs & 0x01)
587 {
588 OutFixed(*os, (*this)[ firstEl++].imag(), w, d, code);
589 tCount--;
590 }
591
592 SizeT endEl = firstEl + tCount / 2;
593
594 for( SizeT i= firstEl; i<endEl; ++i)
595 {
596 OutFixed(*os, (*this)[ i], w, d, code);
597 }
598
599 if( tCount & 0x01)
600 {
601 OutFixed(*os, (*this)[ endEl].real(), w, d, code);
602 }
603 }
604 else if ( oMode == SCIENTIFIC)
605 {
606 if( offs & 0x01)
607 {
608 OutScientific( *os, (*this)[ firstEl++].imag(), w, d, code);
609 tCount--;
610 }
611
612 SizeT endEl = firstEl + tCount / 2;
613
614 for( SizeT i= firstEl; i<endEl; ++i)
615 {
616 OutScientific( *os, (*this)[ i], w, d, code);
617 }
618
619 if( tCount & 0x01)
620 {
621 OutScientific( *os, (*this)[ endEl].real(), w, d, code);
622 }
623 }
624
625 return tCountOut;
626 }
627 // struct
628 SizeT DStructGDL::
OFmtF(ostream * os,SizeT offs,SizeT r,int w,int d,const int code,BaseGDL::IOMode oMode)629 OFmtF( ostream* os, SizeT offs, SizeT r, int w, int d, const int code, BaseGDL::IOMode oMode)
630 {
631 SizeT firstOut, firstOffs, tCount, tCountOut;
632 OFmtAll( offs, r, firstOut, firstOffs, tCount, tCountOut);
633
634 SizeT trans = (*this)[ firstOut]->OFmtF( os, firstOffs, tCount, w, d, code, oMode);
635 if( trans >= tCount) return tCountOut;
636 tCount -= trans;
637
638 SizeT ddSize = dd.size();
639 for( SizeT i = (firstOut+1); i < ddSize; ++i)
640 {
641 trans = (*this)[ i]->OFmtF( os, 0, tCount, w, d, code, oMode);
642 if( trans >= tCount) return tCountOut;
643 tCount -= trans;
644 }
645
646 return tCountOut;
647 }
648
649 // I code ****************************************************
650 // other
651
652 // undf byte int lint real dbl cplx str strct dcplx ptr obj uint ulon int64 uint64
653 const int iFmtWidth[] = { -1, 7, 7, 12, 12, 12, 12, 12, -1, 12, -1, -1, 7, 12, 22, 22};
654 const int iFmtWidthBIN[] = { -1, 8, 16, 32, 32, 32, 32, 32, -1, 64, -1, -1, 16, 32, 64, 64};
655 // GDL_STRUCT-GDL_ULONG64
656
657 template<class Sp> SizeT Data_<Sp>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)658 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
659 BaseGDL::IOMode oMode) {
660 if ( this->Sizeof()==2 ) {
661 DIntGDL* cVal = static_cast<DIntGDL*>
662 (this->Convert2( GDL_INT, BaseGDL::COPY ));
663 if ( w < 0 ) w = (oMode == BaseGDL::BIN ? iFmtWidthBIN[ this->t] : iFmtWidth[ this->t]);
664 SizeT retVal = cVal->OFmtI( os, offs, r, w, d, code, oMode);
665 delete cVal;
666 return retVal;
667 //FIXME THIS MAY DEPEND ON THE MACHINE NATURAL SIZE. ON 64 BITS it is promoted to 64 bits.
668 // } else if ( this->Sizeof()==4 ) {
669 // DLongGDL* cVal = static_cast<DLongGDL*>
670 // (this->Convert2( GDL_LONG, BaseGDL::COPY ));
671 // if ( w < 0 ) w = (oMode == BaseGDL::BIN ? iFmtWidthBIN[ this->t] : iFmtWidth[ this->t]);
672 // SizeT retVal = cVal->OFmtI( os, offs, r, w, d, code, oMode);
673 // delete cVal;
674 // return retVal;
675 } else {
676 DLong64GDL* cVal = static_cast<DLong64GDL*>
677 (this->Convert2( GDL_LONG64, BaseGDL::COPY ));
678 if ( w < 0 ) w = (oMode == BaseGDL::BIN ? iFmtWidthBIN[ this->t] : iFmtWidth[ this->t]);
679 SizeT retVal = cVal->OFmtI( os, offs, r, w, d, code, oMode);
680 delete cVal;
681 return retVal;
682 }
683 }
684 template<> SizeT Data_<SpDByte>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)685 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
686 BaseGDL::IOMode oMode)
687 {
688 if( w < 0) w = (oMode == BIN ? 8 : 7);
689 SizeT nTrans = ToTransfer();
690 DIntGDL* cVal = static_cast<DIntGDL*> (this->Convert2( GDL_INT, BaseGDL::COPY )); //necessary for non-b formats.
691
692 // transfer count
693 SizeT tCount = nTrans - offs;
694 if( r < tCount) tCount = r;
695
696 SizeT endEl = offs + tCount;
697
698 for( SizeT i=offs; i<endEl; ++i) OutInteger( *os, (*cVal)[ i], w, d, code, oMode);
699 return tCount;
700 }
701
702 //GDL_UINT
703 template<> SizeT Data_<SpDUInt>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)704 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
705 BaseGDL::IOMode oMode)
706 {
707 if( w < 0) w = (oMode == BIN ? 16 : 7);
708 SizeT nTrans = ToTransfer();
709 DLongGDL* cVal = static_cast<DLongGDL*> (this->Convert2( GDL_LONG, BaseGDL::COPY )); //necessary as IDL affixes the '+' when format="+".
710 //meaning it does not pass an unsigned int!
711
712 // transfer count
713 SizeT tCount = nTrans - offs;
714 if( r < tCount) tCount = r;
715
716 SizeT endEl = offs + tCount;
717
718 for( SizeT i=offs; i<endEl; ++i) OutInteger( *os, (*cVal)[ i], w, d, code, oMode);
719 return tCount;
720 }
721 //GDL_INT
722 template<> SizeT Data_<SpDInt>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)723 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
724 BaseGDL::IOMode oMode)
725 {
726 if( w < 0) w = (oMode == BIN ? 16 : 7);
727 SizeT nTrans = ToTransfer();
728
729 // transfer count
730 SizeT tCount = nTrans - offs;
731 if( r < tCount) tCount = r;
732
733 SizeT endEl = offs + tCount;
734
735 for( SizeT i=offs; i<endEl; ++i) OutInteger( *os, (*this)[ i], w, d, code, oMode);
736 return tCount;
737 }
738
739 // GDL_LONG
740 template<> SizeT Data_<SpDLong>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)741 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
742 BaseGDL::IOMode oMode)
743 {
744 if( w < 0) w = (oMode == BIN ? 32 : 12);
745 SizeT nTrans = ToTransfer();
746
747 // transfer count
748 SizeT tCount = nTrans - offs;
749 if( r < tCount) tCount = r;
750
751 SizeT endEl = offs + tCount;
752
753 for( SizeT i=offs; i<endEl; ++i) OutInteger( *os, (*this)[ i], w, d, code, oMode);
754 return tCount;
755 }
756 // GDL_ULONG
757 template<> SizeT Data_<SpDULong>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)758 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
759 BaseGDL::IOMode oMode)
760 {
761 if( w < 0) w = (oMode == BIN ? 32 : 12);
762 SizeT nTrans = ToTransfer();
763
764 // transfer count
765 SizeT tCount = nTrans - offs;
766 if( r < tCount) tCount = r;
767
768 SizeT endEl = offs + tCount;
769
770 for( SizeT i=offs; i<endEl; ++i) OutInteger( *os, (*this)[ i], w, d, code, oMode);
771 return tCount;
772 }
773 // GDL_LONG64
774 template<> SizeT Data_<SpDLong64>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)775 OFmtI(ostream* os, SizeT offs, SizeT r, int w, int d, int code,
776 BaseGDL::IOMode oMode)
777 {
778 if (w < 0) w = (oMode == BIN ? 64 : 22);
779 SizeT nTrans = ToTransfer();
780
781 // transfer count
782 SizeT tCount = nTrans - offs;
783 if (r < tCount) tCount = r;
784
785 SizeT endEl = offs + tCount;
786
787 for (SizeT i = offs; i < endEl; ++i) OutInteger(*os, (*this)[ i], w, d, code, oMode);
788 return tCount;
789 }
790 // GDL_ULONG64
791 template<> SizeT Data_<SpDULong64>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)792 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
793 BaseGDL::IOMode oMode)
794 {
795 if( w < 0) w = (oMode == BIN ? 64 : 22);
796 SizeT nTrans = ToTransfer();
797
798 // transfer count
799 SizeT tCount = nTrans - offs;
800 if( r < tCount) tCount = r;
801
802 SizeT endEl = offs + tCount;
803
804 for( SizeT i=offs; i<endEl; ++i) OutInteger( *os, (*this)[ i], w, d, code, oMode);
805 return tCount;
806 }
807
808 template<> SizeT Data_<SpDComplex>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)809 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
810 BaseGDL::IOMode oMode)
811 {
812 if( w < 0) w = (oMode == BIN ? 32 : 12);
813 SizeT nTrans = ToTransfer();
814
815 // transfer count
816 SizeT tCount = nTrans - offs;
817 if( r < tCount) tCount = r;
818 SizeT tCountOut = tCount;
819
820 SizeT firstEl = offs / 2;
821 if( offs & 0x01)
822 {
823 OutInteger( *os, static_cast<DLong64>((*this)[ firstEl++].imag()), w, d, code, oMode);
824 tCount--;
825 }
826
827 SizeT endEl = firstEl + tCount / 2;
828
829 for ( SizeT i = firstEl; i < endEl; ++i ) {
830 OutInteger( *os, static_cast<DLong64>((*this)[ i].real()), w, d, code, oMode);
831 OutInteger( *os, static_cast<DLong64>((*this)[ i].imag()), w, d, code, oMode);
832 }
833
834 if( tCount & 0x01)
835 {
836 OutInteger( *os, static_cast<DLong64>((*this)[ endEl++].real()), w, d, code, oMode);
837 }
838 return tCountOut;
839 }
840 template<> SizeT Data_<SpDComplexDbl>::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)841 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
842 BaseGDL::IOMode oMode)
843 {
844 if( w < 0) w = (oMode == BIN ? 32 : 12);
845 SizeT nTrans = ToTransfer();
846
847 // transfer count
848 SizeT tCount = nTrans - offs;
849 if( r < tCount) tCount = r;
850 SizeT tCountOut = tCount;
851
852 SizeT firstEl = offs / 2;
853 if( offs & 0x01)
854 {
855 OutInteger( *os, static_cast<DLong64>((*this)[ firstEl++].imag()), w, d, code, oMode);
856 tCount--;
857 }
858
859 SizeT endEl = firstEl + tCount / 2;
860
861 for ( SizeT i = firstEl; i < endEl; ++i ) {
862 OutInteger( *os, static_cast<DLong64>((*this)[ i].real()), w, d, code, oMode);
863 OutInteger( *os, static_cast<DLong64>((*this)[ i].imag()), w, d, code, oMode);
864 }
865
866 if( tCount & 0x01)
867 {
868 OutInteger( *os, static_cast<DLong64>((*this)[ endEl++].real()), w, d, code, oMode);
869 }
870 return tCountOut;
871 }
872
873 SizeT DStructGDL::
OFmtI(ostream * os,SizeT offs,SizeT r,int w,int d,int code,BaseGDL::IOMode oMode)874 OFmtI( ostream* os, SizeT offs, SizeT r, int w, int d, int code,
875 BaseGDL::IOMode oMode)
876 {
877 SizeT firstOut, firstOffs, tCount, tCountOut;
878 OFmtAll( offs, r, firstOut, firstOffs, tCount, tCountOut);
879
880 SizeT trans = (*this)[ firstOut]->OFmtI( os, firstOffs, tCount, w, d, code, oMode);
881 if( trans >= tCount) return tCountOut;
882 tCount -= trans;
883
884 SizeT ddSize = dd.size();
885 for( SizeT i = (firstOut+1); i < ddSize; ++i)
886 {
887 trans = (*this)[ i]->OFmtI( os, 0, tCount, w, d, code, oMode);
888 if( trans >= tCount) return tCountOut;
889 tCount -= trans;
890 }
891
892 return tCountOut;
893 }
894
outA(ostream * os,string s,int w,const int code)895 void outA( ostream* os, string s, int w, const int code)
896 {
897 if (w <= 0) {
898 (*os) << left;
899 (*os) << s;
900 }
901 else {
902 if (code & fmtALIGN_LEFT) {
903 (*os) << setw(w) << s.substr(0, w);
904 } else {
905 (*os) << right;
906 (*os) << setw(w) << s.substr(0, w);
907 }
908 }
909 }
910 // struct
911 SizeT DStructGDL::
OFmtCal(ostream * os,SizeT offs,SizeT r,int w,int d,char * f,int code,BaseGDL::Cal_IOMode cMode)912 OFmtCal( ostream* os, SizeT offs, SizeT r, int w, int d, char *f, int code, BaseGDL::Cal_IOMode cMode)
913 {
914 SizeT firstOut, firstOffs, tCount, tCountOut;
915 OFmtAll( offs, r, firstOut, firstOffs, tCount, tCountOut);
916
917 SizeT trans = (*this)[ firstOut]->OFmtCal( os, firstOffs, tCount, w, d, f, code, cMode);
918 if( trans >= tCount) return tCountOut;
919 tCount -= trans;
920
921 SizeT ddSize = dd.size();
922 for( SizeT i = (firstOut+1); i < ddSize; ++i)
923 {
924 trans = (*this)[ i]->OFmtCal( os, 0, tCount, w, d, f, code, cMode);
925 if( trans >= tCount) return tCountOut;
926 tCount -= trans;
927 }
928
929 return tCountOut;
930 }
931
932 template<class Sp> SizeT Data_<Sp>::
OFmtCal(ostream * os,SizeT offs,SizeT repeat,int w,int d,char * fill,int code,BaseGDL::Cal_IOMode cMode)933 OFmtCal( ostream* os, SizeT offs, SizeT repeat, int w, int d, char *fill, int code, BaseGDL::Cal_IOMode cMode)
934 {
935
936 static string theMonth[12]={"January","February","March","April","May","June",
937 "July","August","September","October","November","December"};
938 static string theMONTH[12]={"JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE",
939 "JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER"};
940 static string themonth[12]={"january","february","march","april","may","june",
941 "july","august","september","october","november","december"};
942 static string theDAY[7]={"MONDAY","TUESDAY","WEDNESDAY","THURSDAY","FRIDAY","SATURDAY","SUNDAY"};
943 static string theDay[7]={"Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"};
944 static string theday[7]={"monday","tuesday","wednesday","thursday","friday","saturday","sunday"};
945 static string capa[2]={"am","pm"};
946 static string cApa[2]={"Am","Pm"};
947 static string cAPa[2]={"AM","PM"};
948
949 static DLong *iMonth, *iDay, *iYear, *iHour, *iMinute, *dow, *icap;
950 static DDouble *Second;
951 static ostringstream **local_os;
952 bool cmplx=FALSE;
953 SizeT nTrans = ToTransfer();
954 // transfer count
955 SizeT tCount = nTrans - offs;
956 SizeT r=tCount;
957 if ( Data_<Sp>::IS_COMPLEX ) { cmplx=TRUE;} //tCount in this case is twice the size of the complex array
958
959 switch ( cMode ) {
960 case BaseGDL::WRITE:
961 for (SizeT i=0, j=0; j<r; j++){
962 if (i >= repeat) {i=0; (*os)<<'\n';}
963 (*os)<<(local_os[j]->str()).c_str();
964 i++;
965 delete local_os[j];
966 }
967 delete local_os;
968 delete iMonth;
969 delete iDay ;
970 delete iYear;
971 delete iHour;
972 delete iMinute;
973 delete dow;
974 delete icap;
975 delete Second;
976 break;
977 case BaseGDL::COMPUTE:
978 iMonth=(DLong*)calloc(r,sizeof(DLong));
979 iDay=(DLong*)calloc(r,sizeof(DLong));
980 iYear=(DLong*)calloc(r,sizeof(DLong));
981 iHour=(DLong*)calloc(r,sizeof(DLong));
982 iMinute=(DLong*)calloc(r,sizeof(DLong));
983 dow=(DLong*)calloc(r,sizeof(DLong));
984 icap=(DLong*)calloc(r,sizeof(DLong));
985 Second=(DDouble*)calloc(r,sizeof(DDouble));
986 local_os=(ostringstream**)calloc(r,sizeof(ostringstream*));
987 if ( cmplx ) {
988 DComplexDblGDL* cVal = static_cast<DComplexDblGDL*> (this->Convert2( GDL_COMPLEXDBL, BaseGDL::COPY ));
989 for( SizeT i=0, j=0; j<(r/2); ++j)
990 {
991 local_os[i]=new ostringstream();
992 if (!j2ymdhms( (*cVal)[offs +j].real(), iMonth[i], iDay[i], iYear[i], iHour[i], iMinute[i], Second[i], dow[i], icap[i] )) throw GDLException("Value of Julian date is out of allowed range.");
993 i++;
994 local_os[i]=new ostringstream();
995 if (!j2ymdhms( (*cVal)[offs+j].imag(), iMonth[i], iDay[i], iYear[i], iHour[i], iMinute[i], Second[i], dow[i], icap[i] )) throw GDLException("Value of Julian date is out of allowed range.");
996 i++;
997 }
998 delete cVal;
999 } else {
1000 for ( SizeT i = 0; i < r; i++ ) {
1001 local_os[i]=new ostringstream();
1002 DDoubleGDL* cVal = static_cast<DDoubleGDL*> (this->Convert2( GDL_DOUBLE, BaseGDL::COPY ));
1003 if (!j2ymdhms( (*cVal)[offs + i], iMonth[i], iDay[i], iYear[i], iHour[i], iMinute[i], Second[i], dow[i], icap[i] )) throw GDLException("Value of Julian date is out of allowed range.");
1004 delete cVal;
1005 // cerr<<"Dow="<<dow[i]<<" iDay="<<iDay[i]<<" iMonth="<<iMonth[i]<<" iYear="<<iYear[i]<<" iHour="<<iHour[i]<<" iMinute="<<iMinute[i]<<" Second="<<Second[i]<<" icap="<<icap[i]<<endl;
1006 }
1007 }
1008 break;
1009 case BaseGDL::DEFAULT:
1010 for (SizeT i=0; i<r; i++){
1011 outA( local_os[i], theDay[dow[i]], 3 , code);
1012 (*local_os[i]) << " ";
1013 outA( local_os[i], theMonth[iMonth[i]], 3 , code);
1014 (*local_os[i]) << " ";
1015 OutInteger( *(local_os[i]), iDay[i], 2, 2, code, BaseGDL::DEC);
1016 (*local_os[i]) << " ";
1017 OutInteger( *(local_os[i]), iHour[i], 2, 2, code, BaseGDL::DEC);
1018 (*local_os[i]) << ":";
1019 OutInteger( *(local_os[i]), iMinute[i], 2, 2, code, BaseGDL::DEC);
1020 (*local_os[i]) << ":";
1021 OutInteger( *(local_os[i]), (DLong) (Second[i]) , 2, 2, code, BaseGDL::DEC);
1022 std::stringbuf buffer; // empty buffer
1023 std::ostream os (&buffer); // associate stream buffer to stream
1024 os.width(6);
1025 os << iYear[i];
1026 outA( local_os[i], buffer.str().substr(buffer.str().size()-5,5), 5 , code); //selects the 5 last digits of year.
1027 }
1028 break;
1029 case BaseGDL::STRING:
1030 for (SizeT i=0; i<r; i++){
1031 (*local_os[i]) << *fill;
1032 }
1033 break;
1034 case BaseGDL::CMOA:
1035 for (SizeT i=0; i<r; i++){
1036 outA( local_os[i], theMONTH[iMonth[i]], w, code);
1037 }
1038 break;
1039 case BaseGDL::CMoA:
1040 for (SizeT i=0; i<r; i++){
1041 outA( local_os[i], theMonth[iMonth[i]], w, code);
1042 }
1043 break;
1044 case BaseGDL::CmoA:
1045 for (SizeT i=0; i<r; i++){
1046 outA( local_os[i], themonth[iMonth[i]], w, code);
1047 }
1048 break;
1049 case BaseGDL::CDWA:
1050 for (SizeT i=0; i<r; i++){
1051 outA( local_os[i], theDAY[dow[i]], w, code);
1052 }
1053 break;
1054 case BaseGDL::CDwA:
1055 for (SizeT i=0; i<r; i++){
1056 outA( local_os[i], theDay[dow[i]], w, code);
1057 }
1058 break;
1059 case BaseGDL::CdwA:
1060 for (SizeT i=0; i<r; i++){
1061 outA( local_os[i], theday[dow[i]], w, code );
1062 }
1063 break;
1064 case BaseGDL::CapA:
1065 if ( w == -1 ) w = 2;
1066 for (SizeT i=0; i<r; i++){
1067 outA( local_os[i], capa[icap[i]], w, code );
1068 }
1069 break;
1070 case BaseGDL::CApA:
1071 if ( w == -1 ) w = 2;
1072 for (SizeT i=0; i<r; i++){
1073 outA( local_os[i], cApa[icap[i]], w, code );
1074 }
1075 break;
1076 case BaseGDL::CAPA:
1077 if ( w == -1 ) w = 2;
1078 for (SizeT i=0; i<r; i++){
1079 outA( local_os[i], cAPa[icap[i]], w, code );
1080 }
1081 break;
1082 //integer
1083 case BaseGDL::CMOI:
1084 if ( w == -1 ) w = 2;
1085 for (SizeT i=0; i<r; i++){
1086 OutInteger( *(local_os[i]), iMonth[i]+1, w, d, code, BaseGDL::DEC);
1087 }
1088 break;
1089 case BaseGDL::CYI:
1090 if ( w == -1 ) w = 4;
1091 for (SizeT i=0; i<r; i++){ //convert to string before outing only the w last characters as this is what IDL does.
1092 std::stringbuf buffer; // empty buffer
1093 std::ostream os (&buffer); // associate stream buffer to stream
1094 os.width(w);
1095 os << iYear[i];
1096 outA( local_os[i], buffer.str().substr(buffer.str().size()-w,w), w , code); //CYI2.2 selects the two last digits of year.
1097 }
1098 break;
1099 case BaseGDL::ChI:
1100 if ( w == -1 ) w = 2;
1101 for (SizeT i=0; i<r; i++){
1102 OutInteger( *(local_os[i]), iHour[i]%12, w, d, code, BaseGDL::DEC);
1103 }
1104 break;
1105 case BaseGDL::CHI:
1106 if ( w == -1 ) w = 2;
1107 for (SizeT i=0; i<r; i++){
1108 OutInteger( *(local_os[i]), iHour[i], w, d, code, BaseGDL::DEC);
1109 }
1110 break;
1111 case BaseGDL::CDI:
1112 if ( w == -1 ) w = 2;
1113 for (SizeT i=0; i<r; i++){
1114 OutInteger( *(local_os[i]), iDay[i], w, d, code, BaseGDL::DEC);
1115 }
1116 break;
1117 case BaseGDL::CMI:
1118 if ( w == -1 ) w = 2;
1119 for (SizeT i=0; i<r; i++){
1120 OutInteger( *(local_os[i]), iMinute[i], w, d, code, BaseGDL::DEC);
1121 }
1122 break;
1123 case BaseGDL::CSI:
1124 if ( w == -1 ) {
1125 w = 2;
1126 d = 0;
1127 }
1128 for (SizeT i=0; i<r; i++){
1129 OutInteger( *(local_os[i]), (DLong) (Second[i]), w, d, code, BaseGDL::DEC);
1130 }
1131 break;
1132 //Float
1133 case BaseGDL::CSF:
1134 if ( w == -1 ) {
1135 w = 5;
1136 d = 2;
1137 }
1138 // SetField( w, d, 6, 16, 25);
1139 for (SizeT i=0; i<r; i++){
1140 //this may print Second as 60.xxx but IDL DOES THE SAME!
1141 OutFixed(*local_os[i], Second[i], w, d, code);
1142 }
1143 break;
1144 }
1145 return tCount;
1146 }
1147
1148 #include "instantiate_templates.hpp"
1149