ALT Linux Bugzilla
– Attachment 3419 Details for
Bug 19331
Похоже сломана работа таймеров с созданием потока в качестве уведомления.
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
Архиватор значений
tarchval.cpp (text/x-c++src), 79.89 KB, created by
Roman Savochenko
on 2009-03-30 20:01:27 MSD
(
hide
)
Description:
Архиватор значений
Filename:
MIME Type:
Creator:
Roman Savochenko
Created:
2009-03-30 20:01:27 MSD
Size:
79.89 KB
patch
obsolete
> >//OpenSCADA system file: tarchval.cpp >/*************************************************************************** > * Copyright (C) 2006-2008 by Roman Savochenko * > * rom_as@fromru.com * > * * > * This program is free software; you can redistribute it and/or modify * > * it under the terms of the GNU General Public License as published by * > * the Free Software Foundation; version 2 of the License. * > * * > * This program is distributed in the hope that it will be useful, * > * but WITHOUT ANY WARRANTY; without even the implied warranty of * > * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * > * GNU General Public License for more details. * > * * > * You should have received a copy of the GNU General Public License * > * along with this program; if not, write to the * > * Free Software Foundation, Inc., * > * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * > ***************************************************************************/ > >#include <signal.h> >#include <string.h> >#include <time.h> >#include <sys/types.h> >#include <sys/stat.h> >#include <fcntl.h> >#include <math.h> > >#include <gd.h> >#include <gdfonts.h> >#include <gdfontt.h> > >#include "tsys.h" >#include "tvalue.h" >#include "tarchives.h" >#include "tarchval.h" > > >//************************************************* >//* Value archivator * >//************************************************* > >//************************************************* >//* TValBuf * >//************************************************* >TValBuf::TValBuf( ) : > m_val_tp(TFld::Integer), m_size(100), m_per(0), m_hrd_grd(false), m_hg_res_tm(false), m_end(0), m_beg(0) >{ > buf.bl = NULL; > > makeBuf(m_val_tp,m_size,m_per,m_hrd_grd,m_hg_res_tm); >} > >TValBuf::TValBuf( TFld::Type vtp, int isz, long long ipr, bool ihgrd, bool ihres ) : > m_val_tp(vtp), m_size(isz), m_per(ipr), m_hrd_grd(ihgrd), m_hg_res_tm(ihres), m_end(0), m_beg(0) >{ > buf.bl = NULL; > > makeBuf(m_val_tp,m_size,m_per,m_hrd_grd,m_hg_res_tm); >} > >void TValBuf::clear() >{ > switch(m_val_tp) > { > case TFld::Boolean: buf.bl->clear(); break; > case TFld::Integer: buf.dec->clear(); break; > case TFld::Real: buf.real->clear(); break; > case TFld::String: buf.str->clear(); break; > } >} > >TValBuf::~TValBuf( ) >{ > switch(m_val_tp) > { > case TFld::Boolean: delete buf.bl; break; > case TFld::Integer: delete buf.dec; break; > case TFld::Real: delete buf.real;break; > case TFld::String: delete buf.str; break; > } >} > >int TValBuf::realSize() >{ > switch(valType()) > { > case TFld::Boolean: return buf.bl->realSize(); > case TFld::Integer: return buf.dec->realSize(); > case TFld::Real: return buf.real->realSize(); > case TFld::String: return buf.str->realSize(); > } > > return 0; >} > >bool TValBuf::vOK( long long ibeg, long long iend ) >{ > if( !begin() || !end() || iend < begin() || ibeg > end() || ibeg > iend ) > return false; > return true; >} > >void TValBuf::setValType( TFld::Type vl ) >{ > makeBuf(vl, m_size, m_per, m_hrd_grd, m_hg_res_tm ); >} > >void TValBuf::setHardGrid( bool vl ) >{ > makeBuf( m_val_tp, m_size, m_per, vl, m_hg_res_tm ); >} > >void TValBuf::setHighResTm( bool vl ) >{ > makeBuf( m_val_tp, m_size, m_per, m_hrd_grd, vl ); >} > >void TValBuf::setSize( int vl ) >{ > makeBuf( m_val_tp, vl, m_per, m_hrd_grd, m_hg_res_tm ); >} > >void TValBuf::setPeriod( long long vl ) >{ > makeBuf( m_val_tp, m_size, vl, m_hrd_grd, m_hg_res_tm ); >} > >void TValBuf::makeBuf( TFld::Type v_tp, int isz, long long ipr, bool hd_grd, bool hg_res ) >{ > ResAlloc res(b_res,true); > > //Destroy buffer > if( v_tp != m_val_tp && buf.bl ) > { > switch(m_val_tp) > { > case TFld::Boolean: delete buf.bl; break; > case TFld::Integer: delete buf.dec; break; > case TFld::Real: delete buf.real;break; > case TFld::String: delete buf.str; break; > } > buf.bl = NULL; > } > > if( !buf.bl ) > { > //Make new buffer > switch(v_tp) > { > case TFld::Boolean: buf.bl = new TBuf<char>(EVAL_BOOL,m_size,m_per,m_hrd_grd,m_hg_res_tm,m_end,m_beg); break; > case TFld::Integer: buf.dec = new TBuf<int>(EVAL_INT,m_size,m_per,m_hrd_grd,m_hg_res_tm,m_end,m_beg); break; > case TFld::Real: buf.real = new TBuf<double>(EVAL_REAL,m_size,m_per,m_hrd_grd,m_hg_res_tm,m_end,m_beg); break; > case TFld::String: buf.str = new TBuf<string>(EVAL_STR,m_size,m_per,m_hrd_grd,m_hg_res_tm,m_end,m_beg); break; > } > m_val_tp = v_tp; > } > if( isz != m_size || ipr != m_per || hd_grd != m_hrd_grd || hg_res != m_hg_res_tm ) > switch(m_val_tp) > { > case TFld::Boolean: buf.bl->makeBuf(isz, ipr, hd_grd, hg_res); break; > case TFld::Integer: buf.dec->makeBuf(isz, ipr, hd_grd, hg_res); break; > case TFld::Real: buf.real->makeBuf(isz, ipr, hd_grd, hg_res); break; > case TFld::String: buf.str->makeBuf(isz, ipr, hd_grd, hg_res); break; > } >} > >string TValBuf::getS( long long *itm, bool up_ord ) >{ > switch(valType()) > { > case TFld::Boolean: > { char vl = getB(itm,up_ord); return (vl==EVAL_BOOL)?EVAL_STR:TSYS::int2str((bool)vl); } > case TFld::Integer: > { int vl = getI(itm,up_ord); return (vl==EVAL_INT)?EVAL_STR:TSYS::int2str(vl); } > case TFld::Real: > { double vl = getR(itm,up_ord); return (vl==EVAL_REAL)?EVAL_STR:TSYS::real2str(vl); } > case TFld::String: > ResAlloc res(b_res,false); return buf.str->get(itm,up_ord); > } > return EVAL_STR; >} > >double TValBuf::getR( long long *itm, bool up_ord ) >{ > switch(valType()) > { > case TFld::Boolean: > { char vl = getB(itm,up_ord); return (vl==EVAL_BOOL)?EVAL_REAL:(bool)vl; } > case TFld::Integer: > { int vl = getI(itm,up_ord); return (vl==EVAL_INT)?EVAL_REAL:(double)vl; } > case TFld::String: > { string vl = getS(itm,up_ord); return (vl==EVAL_STR)?EVAL_REAL:atof(vl.c_str()); } > case TFld::Real: > ResAlloc res(b_res,false); return buf.real->get(itm,up_ord); > } > return EVAL_REAL; >} > >int TValBuf::getI( long long *itm, bool up_ord ) >{ > switch(valType()) > { > case TFld::Boolean: > { char vl = getB(itm,up_ord); return (vl==EVAL_BOOL)?EVAL_INT:(bool)vl; } > case TFld::String: > { string vl = getS(itm,up_ord); return (vl==EVAL_STR)?EVAL_INT:atoi(vl.c_str()); } > case TFld::Real: > { double vl = getR(itm,up_ord); return (vl==EVAL_REAL)?EVAL_INT:(int)vl; } > case TFld::Integer: > ResAlloc res(b_res,false); return buf.dec->get(itm,up_ord); > } > return EVAL_INT; >} > >char TValBuf::getB( long long *itm, bool up_ord ) >{ > switch(valType()) > { > case TFld::Integer: > { int vl = getI(itm,up_ord); return (vl==EVAL_INT)?EVAL_BOOL:(bool)vl; } > case TFld::String: > { string vl = getS(itm,up_ord); return (vl==EVAL_STR)?EVAL_BOOL:(bool)atoi(vl.c_str()); } > case TFld::Real: > { double vl = getR(itm,up_ord); return (vl==EVAL_REAL)?EVAL_BOOL:(bool)vl; } > case TFld::Boolean: > ResAlloc res(b_res,false); return buf.bl->get(itm,up_ord); > } > return EVAL_BOOL; >} > >void TValBuf::setS( const string &value, long long tm ) >{ > switch(valType()) > { > case TFld::Boolean: > setB((value==EVAL_STR)?EVAL_BOOL:(bool)atoi(value.c_str()),tm); break; > case TFld::Integer: > setI((value==EVAL_STR)?EVAL_INT:atoi(value.c_str()),tm); break; > case TFld::Real: > setR((value==EVAL_STR)?EVAL_REAL:atof(value.c_str()),tm); break; > case TFld::String: > ResAlloc res(b_res,true); buf.str->set(value,tm); break; > } >} > >void TValBuf::setR( double value, long long tm ) >{ > switch(valType()) > { > case TFld::Boolean: > setB((value==EVAL_REAL)?EVAL_BOOL:(bool)value,tm); break; > case TFld::Integer: > setI((value==EVAL_REAL)?EVAL_INT:(int)value,tm); break; > case TFld::String: > setS((value==EVAL_REAL)?EVAL_STR:TSYS::real2str(value),tm); break; > case TFld::Real: > ResAlloc res(b_res,true); buf.real->set(value,tm); break; > } >} > >void TValBuf::setI( int value, long long tm ) >{ > switch(valType()) > { > case TFld::Boolean: > setB((value==EVAL_INT)?EVAL_BOOL:(bool)value,tm); break; > case TFld::String: > setS((value==EVAL_INT)?EVAL_STR:TSYS::int2str(value),tm); break; > case TFld::Real: > setR((value==EVAL_INT)?EVAL_REAL:value,tm); break; > case TFld::Integer: > ResAlloc res(b_res,true); buf.dec->set(value,tm); break; > } >} > >void TValBuf::setB( char value, long long tm ) >{ > switch(valType()) > { > case TFld::Integer: > setI((value==EVAL_BOOL)?EVAL_INT:(bool)value,tm); break; > case TFld::String: > setS((value==EVAL_BOOL)?EVAL_STR:TSYS::int2str((bool)value),tm); break; > case TFld::Real: > setR((value==EVAL_BOOL)?EVAL_REAL:(bool)value,tm); break; > case TFld::Boolean: > ResAlloc res(b_res,true); buf.bl->set(value,tm); break; > } >} > >void TValBuf::getVal( TValBuf &buf, long long ibeg, long long iend ) >{ > if(!vOK(ibeg,iend)) return; > ibeg = vmax(ibeg,begin()); > iend = vmin(iend,end()); > > while(ibeg<iend) > { > switch(valType()) > { > case TFld::Boolean: > { > char val = getB(&ibeg,true); > buf.setB(val,ibeg); > break; > } > case TFld::Integer: > { > int val = getI(&ibeg,true); > buf.setI(val,ibeg); > break; > } > case TFld::Real: > { > double val = getR(&ibeg,true); > buf.setR(val,ibeg); > break; > } > case TFld::String: > { > string val = getS(&ibeg,true); > buf.setS(val,ibeg); > break; > } > } > ibeg++; > } >} > >void TValBuf::setVal( TValBuf &buf, long long ibeg, long long iend ) >{ > buf.getVal( *this, ibeg, iend ); >} > >//************************************************* >//* TValBuf::TBuf * >//************************************************* >template <class TpVal> TValBuf::TBuf<TpVal>::TBuf( TpVal ieval, int &isz, long long &ipr, bool &ihgrd, bool &ihres, long long& iend, long long& ibeg ) : > eval(ieval), size(isz), per(ipr), hrd_grd(ihgrd), hg_res_tm(ihres), end(iend), beg(ibeg), cur(0) >{ > buf.grid = NULL; > > makeBuf(size,per,hrd_grd,hg_res_tm); >} > >template <class TpVal> TValBuf::TBuf<TpVal>::~TBuf( ) >{ > if( hrd_grd ) delete buf.grid; > else if( hg_res_tm ) delete buf.tm_high; > else delete buf.tm_low; >} > >template <class TpVal> void TValBuf::TBuf<TpVal>::clear() >{ > if( !buf.grid ) return; > if( hrd_grd ) buf.grid->clear(); > else if(hg_res_tm) buf.tm_high->clear(); > else buf.tm_low->clear(); > cur = end = beg = 0; >} > >template <class TpVal> int TValBuf::TBuf<TpVal>::realSize() >{ > if( !buf.grid ) return 0; > if( hrd_grd ) return buf.grid->size(); > else if(hg_res_tm) return buf.tm_high->size(); > else return buf.tm_low->size(); >} > >template <class TpVal> void TValBuf::TBuf<TpVal>::makeBuf( int isz, long long ipr, bool ihd_grd, bool ihg_res ) >{ > bool recr_buf = false; > if( !buf.grid ) recr_buf = true; > if( isz < size ) recr_buf = true; > if( hrd_grd != ihd_grd ) > { > if( ihd_grd && !ipr ) ipr = 1000000; > recr_buf =true; > } > if( hg_res_tm != ihg_res ) recr_buf =true; > if( per != ipr ) > { > if( hrd_grd && !ipr ) ipr = 1000000; > recr_buf =true; > } > > size = isz; > hrd_grd = ihd_grd; > hg_res_tm = ihg_res; > per = ipr; > > if(recr_buf) > { > //- Destroy buffer - > cur = end = beg = 0; > if( buf.grid ) > { > if( hrd_grd ) delete buf.grid; > else if( hg_res_tm ) delete buf.tm_high; > else delete buf.tm_low; > } > buf.grid = NULL; > > //- Make new buffer - > if( ihd_grd ) buf.grid = new vector<TpVal>; > else if(ihg_res)buf.tm_high = new vector<SHg>; > else buf.tm_low = new vector<SLw>; > } >} > >template <class TpVal> TpVal TValBuf::TBuf<TpVal>::get( long long *itm, bool up_ord ) >{ > long long tm = (itm)?(*itm):TSYS::curTime(); > > if((up_ord && tm > end) || (!up_ord && tm < beg)) > throw TError("ValBuf",_("Value is not present.")); > if( hrd_grd ) > { > //- Process hard grid buffer - > int npos = up_ord?(end-tm)/per:(long long)buf.grid->size()-1-(tm-beg)/per; > if( npos < 0 || npos >= buf.grid->size() ) { if(itm) *itm = 0; return eval; } > if(itm) *itm = end-npos*per; > return (*buf.grid)[((cur-npos-1)>=0)?(cur-npos-1):(buf.grid->size()+(cur-npos-1))]; > } > else if( per ) > { > //- Process soft grid buffer - > int npos = (up_ord?(end-tm):(tm-beg))/per; > if( hg_res_tm ) > { > int c_cur = (cur)?cur-1:buf.tm_high->size()-1; > int c_end = c_cur; > do > { > int w_pos = (up_ord?end-(*buf.tm_high)[c_end].tm:(*buf.tm_high)[c_end].tm-beg)/per; > if( up_ord && w_pos >= npos ) > { > if(itm) *itm = (w_pos==npos)?(*buf.tm_high)[c_end].tm:end-npos*per; > return (*buf.tm_high)[c_end].val; > } > else if( !up_ord && w_pos <= npos ) > { > if(itm) *itm = (w_pos==npos)?(*buf.tm_high)[c_end].tm:beg+npos*per; > return (*buf.tm_high)[c_end].val; > } > if( --c_end < 0 ) c_end = buf.tm_high->size()-1; > }while(c_end != c_cur); > > if(itm) *itm = 0; > return eval; > } > else > { > int c_cur = (cur)?cur-1:buf.tm_low->size()-1; > int c_end = c_cur; > do > { > int w_pos = (up_ord?end-(long long)(*buf.tm_low)[c_end].tm*1000000:(long long)(*buf.tm_low)[c_end].tm*1000000-beg)/per; > if( up_ord && w_pos >= npos ) > { > if(itm) *itm = (w_pos==npos)?(long long)(*buf.tm_low)[c_end].tm*1000000:end-npos*per; > return (*buf.tm_low)[c_end].val; > } > if( !up_ord && w_pos <= npos ) > { > if(itm) *itm = (w_pos==npos)?(long long)(*buf.tm_low)[c_end].tm*1000000:beg+npos*per; > return (*buf.tm_low)[c_end].val; > } > if( --c_end < 0 ) c_end = buf.tm_low->size()-1; > }while(c_end != c_cur); > > if(itm) *itm = 0; > return eval; > } > } > else > { > //- Proccess flow buffer - > if( hg_res_tm ) > { > int c_end = buf.tm_high->size()-1; > //-- Half divider -- > for( int d_win = c_end/2; d_win > 10; d_win/=2 ) > if( !((!up_ord && tm >= (*buf.tm_high)[c_end-d_win].tm) || > (up_ord && tm <= (*buf.tm_high)[buf.tm_high->size()-(c_end-d_win)-1].tm)) ) > c_end-=d_win; > //-- Scan last window -- > while(c_end >= 0) > { > if( !up_ord && tm >= (*buf.tm_high)[c_end].tm ) > { > if(itm) *itm = (*buf.tm_high)[c_end].tm; > return (*buf.tm_high)[c_end].val; > } > else if( up_ord && tm <= (*buf.tm_high)[buf.tm_high->size()-c_end-1].tm ) > { > if(itm) *itm = (*buf.tm_high)[buf.tm_high->size()-c_end-1].tm; > return (*buf.tm_high)[buf.tm_high->size()-c_end-1].val; > } > c_end--; > } > if(itm) *itm = 0; > return eval; > } > else > { > int c_end = buf.tm_low->size()-1; > //-- Half divider -- > for( int d_win = c_end/2; d_win>10; d_win/=2 ) > if( !((!up_ord && tm/1000000 >= (*buf.tm_low)[c_end-d_win].tm) || > (up_ord && tm <= (long long)(*buf.tm_low)[buf.tm_low->size()-(c_end-d_win)-1].tm*1000000)) ) > c_end-=d_win; > //-- Scan last window -- > while(c_end >= 0) > { > if( !up_ord && tm/1000000 >= (*buf.tm_low)[c_end].tm ) > { > if(itm) *itm = (long long)(*buf.tm_low)[c_end].tm*1000000; > return (*buf.tm_low)[c_end].val; > } > else if( up_ord && tm <= (long long)(*buf.tm_low)[buf.tm_low->size()-c_end-1].tm*1000000 ) > { > if(itm) *itm = (long long)(*buf.tm_low)[buf.tm_low->size()-c_end-1].tm*1000000; > return (*buf.tm_low)[buf.tm_low->size()-c_end-1].val; > } > c_end--; > } > if(itm) *itm = 0; > return eval; > } > } >} > >template <class TpVal> void TValBuf::TBuf<TpVal>::set( TpVal value, long long tm ) >{ > if( !tm ) tm = TSYS::curTime(); > if( !end ) end = (per) ? per*(tm/per-1) : tm; > if( !beg ) beg = (per) ? per*(tm/per) : tm; > > if( hrd_grd ) > { > //- Process hard grid buffer - > int npos = (tm-end)/per; > //-- Set value -- > if( !npos ) > { > (*buf.grid)[ (cur) ? cur-1 : buf.grid->size()-1 ] = value; //Update last value > return; > } > else if( npos < 0 ) throw TError("ValBuf",_("Grid mode doesn't support inserting old values.")); > else > while( npos-- ) > { > TpVal w_val = (npos)?eval:value; > //--- Set new value --- > if( cur >= buf.grid->size() ) buf.grid->push_back(w_val); > else > { > beg += per; > (*buf.grid)[cur] = w_val; > } > //--- Update cursor --- > if( ++cur >= size ) cur = 0; > //--- Update end time --- > end += per; > } > } > else if( per ) > { > //- Process soft grid buffer - > int npos = (tm-end)/per; > //-- Set value -- > if( npos < 0 ) throw TError("ValBuf",_("Grid mode doesn't support inserting old values.")); > else > { > if( hg_res_tm ) > { > SHg b_el; > > //--- Update current end value --- > if( npos == 0) > { > b_el.tm = end; > b_el.val = value; > int h_el = (cur)?cur-1:buf.tm_high->size()-1; > if( ((*buf.tm_high)[h_el].tm-end)/per ) > { > //---- Write new value ---- > if(cur >= buf.tm_high->size()) buf.tm_high->push_back(b_el); > else > { > if( cur+1 >= buf.tm_high->size() ) > beg = (*buf.tm_high)[0].tm; > else beg = (*buf.tm_high)[cur+1].tm; > beg = per*(beg/per); > (*buf.tm_high)[cur] = b_el; > } > //---- Update cursor ---- > if( ++cur >= size ) cur = 0; > } > else (*buf.tm_high)[h_el] = b_el; > return; > } > > //--- Insert new value ---- > int c_npos = npos; > while( c_npos-- ) > { > //---- Prepare data ---- > if(c_npos) { b_el.tm = end+(npos-c_npos)*per; b_el.val = eval; } > else { b_el.tm = tm; b_el.val = value; } > //---- Check previous value ---- > if( !buf.tm_high->size() || > (cur && (*buf.tm_high)[cur-1].val != b_el.val ) || > (!cur && (*buf.tm_high)[buf.tm_high->size()-1].val != b_el.val) ) > { > //---- Write new value ---- > if(cur >= buf.tm_high->size()) buf.tm_high->push_back(b_el); > else > { > if( cur+1 >= buf.tm_high->size() ) > beg = (*buf.tm_high)[0].tm; > else beg = (*buf.tm_high)[cur+1].tm; > beg = per*(beg/per); > (*buf.tm_high)[cur]=b_el; > } > //---- Update cursor ---- > if( ++cur >= size ) cur = 0; > } > //---- Update end time ---- > end += per; > } > } > else > { > SLw b_el; > > //--- Update current end value --- > if( npos == 0) > { > b_el.tm = end/1000000; > b_el.val = value; > int h_el = (cur) ? cur-1 : buf.tm_low->size()-1; > if( ((long long)(*buf.tm_low)[h_el].tm*1000000-end)/per ) > { > //---- Write new value ---- > if( cur >= buf.tm_low->size() ) buf.tm_low->push_back(b_el); > else > { > if( cur+1 >= buf.tm_low->size() ) > beg = (long long)(*buf.tm_low)[0].tm * 1000000; > else beg = (long long)(*buf.tm_low)[cur+1].tm * 1000000; > beg = per*(beg/per); > (*buf.tm_low)[cur] = b_el; > } > //---- Update cursor ---- > if( ++cur >= size ) cur = 0; > } > else (*buf.tm_low)[h_el] = b_el; > return; > } > > //--- Insert new value --- > int c_npos = npos; > while( c_npos-- ) > { > //---- Prepare data ---- > if(c_npos) { b_el.tm = (end+(npos-c_npos)*per)/1000000; b_el.val = eval; } > else { b_el.tm = tm/1000000; b_el.val = value; } > //---- Check previous value ---- > if( !buf.tm_low->size() || > (cur && (*buf.tm_low)[cur-1].val != b_el.val ) || > (!cur && (*buf.tm_low)[buf.tm_low->size()-1].val != b_el.val) ) > { > //---- Write new value ---- > if(cur >= buf.tm_low->size()) buf.tm_low->push_back(b_el); > else > { > if( cur+1 >= buf.tm_low->size() ) > beg = (long long)(*buf.tm_low)[0].tm * 1000000; > else beg = (long long)(*buf.tm_low)[cur+1].tm * 1000000; > beg = per*(beg/per); > (*buf.tm_low)[cur]=b_el; > } > //---- Update cursor ---- > if( ++cur >= size ) cur = 0; > } > //---- Update end time ---- > end+=per; > } > } > } > } > else > { > //- Proccess flow buffer - > if( hg_res_tm ) > { > SHg b_el = { tm, value }; > if( tm < beg && size && buf.tm_high->size() >= size ) > throw TError("ValBuf",_("Set too old value to buffer.")); > int c_pos = 0; > > //-- Half divider -- > int d_win = buf.tm_high->size()/2; > while(d_win>10) > { > if( tm > (*buf.tm_high)[c_pos+d_win].tm ) > c_pos+=d_win; > d_win/=2; > } > //-- Scan last window -- > while( true ) > { > if( c_pos >= buf.tm_high->size() || tm < (*buf.tm_high)[c_pos].tm ) > { > if( c_pos == buf.tm_high->size() ) buf.tm_high->push_back(b_el); > else buf.tm_high->insert(buf.tm_high->begin()+c_pos,b_el); > if( size && buf.tm_high->size() > size ) buf.tm_high->erase(buf.tm_high->begin()); > beg = (*buf.tm_high)[0].tm; > end = (*buf.tm_high)[buf.tm_high->size()-1].tm; > return; > } > else if( tm == (*buf.tm_high)[c_pos].tm ) > { > (*buf.tm_high)[c_pos] = b_el; > return; > } > c_pos++; > } > } > else > { > SLw b_el = { tm/1000000, value }; > if( tm < beg && size && buf.tm_low->size() >= size ) > throw TError("ValBuf",_("Set too old value to buffer.")); > int c_pos = 0; > //-- Half divider -- > int d_win = buf.tm_low->size()/2; > while( d_win > 10 ) > { > if( tm/1000000 > (*buf.tm_low)[c_pos+d_win].tm ) > c_pos += d_win; > d_win /= 2; > } > //-- Scan last window -- > while( true ) > { > if( c_pos >= buf.tm_low->size() || tm/1000000 < (*buf.tm_low)[c_pos].tm ) > { > if( c_pos == buf.tm_low->size() ) buf.tm_low->push_back(b_el); > else buf.tm_low->insert(buf.tm_low->begin()+c_pos,b_el); > if( size && buf.tm_low->size() > size ) buf.tm_low->erase(buf.tm_low->begin()); > beg = (long long)(*buf.tm_low)[0].tm*1000000; > end = (long long)(*buf.tm_low)[buf.tm_low->size()-1].tm*1000000; > return; > } > else if( tm/1000000 == (*buf.tm_low)[c_pos].tm ) > { > (*buf.tm_low)[c_pos] = b_el; > return; > } > c_pos++; > } > } > } >} > > >//************************************************* >//* TVArchive * >//************************************************* >TVArchive::TVArchive( const string &iid, const string &idb, TElem *cf_el ) : > TConfig(cf_el), run_st(false), m_db(idb), > m_id(cfg("ID").getSd()), m_name(cfg("NAME").getSd()), m_dscr(cfg("DESCR").getSd()), m_start(cfg("START").getBd()), > m_vtype(cfg("VTYPE").getId()), m_bper(cfg("BPER").getRd()), m_bsize(cfg("BSIZE").getId()), > m_bhgrd(cfg("BHGRD").getBd()), m_bhres(cfg("BHRES").getBd()), m_srcmode(cfg("SrcMode").getId()), > m_dsourc(cfg("Source").getSd()), m_archs(cfg("ArchS").getSd()) >{ > m_id = iid; > m_vtype = TFld::Real; > > setUpBuf(); >} > >TVArchive::~TVArchive( ) >{ > >} > >TCntrNode &TVArchive::operator=( TCntrNode &node ) >{ > TVArchive *src_n = dynamic_cast<TVArchive*>(&node); > if( !src_n ) return *this; > > //- Configuration copy - > string tid = id(); > *(TConfig*)this = *(TConfig*)src_n; > m_id = tid; > m_db = src_n->m_db; > > if( src_n->startStat() && toStart() && !startStat() ) > start( ); > > return *this; >} > >void TVArchive::preDisable( int flag ) >{ > stop( flag ); >} > >void TVArchive::postDisable(int flag) >{ > try > { > if( flag ) > SYS->db().at().dataDel(fullDB(),owner().nodePath()+tbl(),*this,true); > }catch(TError err) > { mess_warning(err.cat.c_str(),"%s",err.mess.c_str()); } >} > >string TVArchive::name() >{ > return (m_name.size())?m_name:m_id; >} > >TArchiveS &TVArchive::owner() >{ > return *(TArchiveS *)nodePrev(); >} > >string TVArchive::tbl( ) >{ > return owner().subId()+"_val"; >} > >long long TVArchive::end( const string &arch ) >{ > long long rez = 0; > if( arch.empty() || arch == BUF_ARCH_NM ) > { > rez = TValBuf::end(); > if( !arch.empty() ) return rez; > } > > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && arch_el[i_a]->end() > rez ) > { > rez = arch_el[i_a]->end(); > if( !arch.empty() ) break; > } > return rez; >} > >long long TVArchive::begin( const string &arch ) >{ > long long rez = TSYS::curTime(); > if( arch.empty() || arch == BUF_ARCH_NM ) > { > rez = TValBuf::begin(); > if( !arch.empty() ) return rez; > } > > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && arch_el[i_a]->begin() < rez ) > { > rez = arch_el[i_a]->begin(); > if( !arch.empty() ) break; > } > return rez; >} > >void TVArchive::setValType( TFld::Type vl ) >{ > m_vtype = vl; > setUpBuf( ); > modif( ); >} > >void TVArchive::setHardGrid( bool vl ) >{ > m_bhgrd = vl; > setUpBuf( ); > modif( ); >} > >void TVArchive::setHighResTm( bool vl ) >{ > m_bhres = vl; > setUpBuf( ); > modif( ); >} > >void TVArchive::setSize( int vl ) >{ > m_bsize = vmax(10,vmin(10000000,vl)); > setUpBuf( ); > modif( ); >} > >void TVArchive::setPeriod( long long vl ) >{ > if( !vl ) vl = 1000000; > m_bper = (double)vl/1000000.; > m_bsize = vmax(10,(int)vmin(1e7,100.0/m_bper)); > setUpBuf( ); > modif( ); >} > >void TVArchive::setUpBuf( ) >{ > makeBuf( (TFld::Type)m_vtype, m_bsize, (long long)(m_bper*1000000.), m_bhgrd, m_bhres ); >} > >void TVArchive::load_( ) >{ > if( !SYS->chkSelDB(DB()) ) return; > SYS->db().at().dataGet(fullDB(),owner().nodePath()+tbl(),*this); > setUpBuf(); >} > >void TVArchive::save_( ) >{ > //- Update Archivators list - > if( startStat() ) > { > vector<string> arch_ls; > archivatorList(arch_ls); > m_archs = ""; > for( int i_l = 0; i_l < arch_ls.size(); i_l++ ) > m_archs += arch_ls[i_l]+";"; > } > > SYS->db().at().dataSet(fullDB(),owner().nodePath()+tbl(),*this); >} > >void TVArchive::start( ) >{ > if( run_st ) return; > > run_st = true; > > setSrcMode((TVArchive::SrcMode)m_srcmode,m_dsourc); > > //- Attach to archivators - > string arch; > for( int i_off = 0; (arch = TSYS::strSepParse(m_archs,0,';',&i_off)).size(); ) > if(!archivatorPresent(arch)) > try{ archivatorAttach(arch); } > catch(TError err) { mess_err(err.cat.c_str(),"%s",err.mess.c_str()); } >} > >void TVArchive::stop( bool full_del ) >{ > if( !run_st ) return; > > run_st = false; > > setSrcMode((TVArchive::SrcMode)m_srcmode,m_dsourc); > > //- Detach all archivators - > vector<string> arch_ls; > archivatorList(arch_ls); > for( int i_l = 0; i_l < arch_ls.size(); i_l++ ) > archivatorDetach(arch_ls[i_l],full_del); >} > >void TVArchive::setSrcMode( SrcMode vl, const string &isrc ) >{ > //- Disable all links - > if( (!run_st || vl != ActiveAttr || isrc != m_dsourc) && !pattr_src.freeStat() ) > { > owner().setActValArch( id(), false ); > pattr_src.free(); > dynamic_cast<TVal&>(SYS->nodeAt(m_dsourc,0,'.').at()).setArch(AutoHD<TVArchive>()); > } > > try > { > if( (!run_st || vl != PassiveAttr || isrc != m_dsourc) && > dynamic_cast<TVal *>(&SYS->nodeAt(m_dsourc,0,'.').at()) ) > dynamic_cast<TVal&>(SYS->nodeAt(m_dsourc,0,'.').at()).setArch(AutoHD<TVArchive>()); > }catch(...){ } > > //- Set all links - > if( run_st && vl == ActiveAttr && dynamic_cast<TVal *>(&SYS->nodeAt(isrc,0,'.').at()) ) > { > dynamic_cast<TVal&>(SYS->nodeAt(isrc,0,'.').at()).setArch(AutoHD<TVArchive>(this)); > pattr_src = SYS->nodeAt(isrc,0,'.'); > owner().setActValArch( id(), true ); > } > > if( run_st && vl == PassiveAttr && dynamic_cast<TVal *>(&SYS->nodeAt(isrc,0,'.').at()) ) > dynamic_cast<TVal&>(SYS->nodeAt(isrc,0,'.').at()).setArch(AutoHD<TVArchive>(this)); > > if( m_srcmode != vl || m_dsourc != isrc ) modif(); > > m_srcmode = vl; > m_dsourc = isrc; >} > >string TVArchive::getS( long long *tm, bool up_ord, const string &arch ) >{ > //- Get from buffer - > if( (arch.empty() || arch == BUF_ARCH_NM) && (!tm || (*tm >= begin() && *tm <= end())) ) > return TValBuf::getS(tm,up_ord); > //- Get from archivators - > else > { > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && > (!tm || > (up_ord && *tm <= arch_el[i_a]->end() && *tm > arch_el[i_a]->begin()-(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod())) || > (!up_ord && *tm < arch_el[i_a]->end()+(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod()) && *tm >= arch_el[i_a]->begin()) ) ) > //(!tm || (*tm >= arch_el[i_a]->begin() && *tm <= arch_el[i_a]->end())) ) > return arch_el[i_a]->getS(tm,up_ord); > } > return EVAL_STR; >} > >double TVArchive::getR( long long *tm, bool up_ord, const string &arch ) >{ > //- Get from buffer - > if( (arch.empty() || arch == BUF_ARCH_NM) && (!tm || (*tm >= begin() && *tm <= end())) ) > return TValBuf::getR(tm,up_ord); > //- Get from archivators - > else > { > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && > (!tm || > (up_ord && *tm <= arch_el[i_a]->end() && *tm > arch_el[i_a]->begin()-(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod())) || > (!up_ord && *tm < arch_el[i_a]->end()+(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod()) && *tm >= arch_el[i_a]->begin()) ) ) > //(!tm || (*tm >= arch_el[i_a]->begin() && *tm <= arch_el[i_a]->end())) ) > return arch_el[i_a]->getR(tm,up_ord); > } > return EVAL_REAL; >} > >int TVArchive::getI( long long *tm, bool up_ord, const string &arch ) >{ > //> Get from buffer > if( (arch.empty() || arch == BUF_ARCH_NM) && (!tm || (*tm >= begin() && *tm <= end())) ) > return TValBuf::getI(tm,up_ord); > //> Get from archivators > else > { > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && > (!tm || > (up_ord && *tm <= arch_el[i_a]->end() && *tm > arch_el[i_a]->begin()-(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod())) || > (!up_ord && *tm < arch_el[i_a]->end()+(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod()) && *tm >= arch_el[i_a]->begin()) ) ) > //(!tm || (*tm >= arch_el[i_a]->begin() && *tm <= arch_el[i_a]->end())) ) > return arch_el[i_a]->getI(tm,up_ord); > } > return EVAL_INT; >} > >char TVArchive::getB( long long *tm, bool up_ord, const string &arch ) >{ > //- Get from buffer - > if( (arch.empty() || arch == BUF_ARCH_NM) && (!tm || (*tm >= begin() && *tm <= end())) ) > return TValBuf::getB(tm,up_ord); > //- Get from archivators - > else > { > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && > (!tm || > (up_ord && *tm <= arch_el[i_a]->end() && *tm > arch_el[i_a]->begin()-(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod())) || > (!up_ord && *tm < arch_el[i_a]->end()+(long long)(1000000.*arch_el[i_a]->archivator( ).valPeriod()) && *tm >= arch_el[i_a]->begin()) ) ) > //(!tm || (*tm >= arch_el[i_a]->begin() && *tm <= arch_el[i_a]->end())) ) > return arch_el[i_a]->getB(tm,up_ord); > } > return EVAL_BOOL; >} > >void TVArchive::getVal( TValBuf &buf, long long ibeg, long long iend, const string &arch, int limit ) >{ > //- Get from buffer - > if( (arch.empty() || arch == BUF_ARCH_NM) && vOK(ibeg,iend) ) > { > ibeg = vmax(ibeg,iend-TValBuf::period()*limit); > TValBuf::getVal(buf,ibeg,iend); > iend = buf.begin()-1; > } > //- Get from archivators - > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && > ((!ibeg || ibeg <= arch_el[i_a]->end()) && (!iend || iend > arch_el[i_a]->begin())) && ibeg <= iend ) > { > ibeg = vmax(ibeg,iend-(long long)(1000000.*arch_el[i_a]->archivator().valPeriod())*(limit-buf.realSize())); > arch_el[i_a]->getVal(buf,ibeg,iend); > iend = buf.begin()-1; > } >} > >void TVArchive::setVal( TValBuf &buf, long long ibeg, long long iend, const string &arch ) >{ > //- Put to archivators - > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) ) > arch_el[i_a]->setVal(buf,ibeg,iend); >} > >void TVArchive::getActiveData() >{ > long long tm = TSYS::curTime(); > if( !pattr_src.freeStat() ) > { > switch(valType()) > { > case TFld::Boolean: setB(pattr_src.at().getB(&tm),tm); break; > case TFld::Integer: setI(pattr_src.at().getI(&tm),tm); break; > case TFld::Real: setR(pattr_src.at().getR(&tm),tm); break; > case TFld::String: setS(pattr_src.at().getS(&tm),tm); break; > } > } >} > >void TVArchive::archivatorList( vector<string> &ls ) >{ > ResAlloc res(a_res,false); > ls.clear(); > for( int i_l = 0; i_l < arch_el.size(); i_l++ ) > ls.push_back(arch_el[i_l]->archivator().workId()); >} > >bool TVArchive::archivatorPresent( const string &arch ) >{ > ResAlloc res(a_res,false); > try > { > AutoHD<TVArchivator> archivat = owner().at(TSYS::strSepParse(arch,0,'.')).at(). > valAt(TSYS::strSepParse(arch,1,'.')); > for( int i_l = 0; i_l < arch_el.size(); i_l++ ) > if( &arch_el[i_l]->archivator() == &archivat.at() ) > return true; > } catch(TError err){ } > return false; >} > >void TVArchive::archivatorAttach( const string &arch ) >{ > ResAlloc res(a_res,true); > > AutoHD<TVArchivator> archivat = owner().at(TSYS::strSepParse(arch,0,'.')).at(). > valAt(TSYS::strSepParse(arch,1,'.')); > > if(!archivat.at().startStat()) > throw TError(nodePath().c_str(),"Archivator <%s> error or it is not started.",arch.c_str()); > > //- Find already present archivator - > for( int i_l = 0; i_l < arch_el.size(); i_l++ ) > if( &arch_el[i_l]->archivator() == &archivat.at() ) > return; > //- Find position - > for( int i_l = 0; i_l < arch_el.size(); i_l++ ) > if( archivat.at().valPeriod() <= arch_el[i_l]->archivator().valPeriod() ) > { > arch_el.insert(arch_el.begin()+i_l,archivat.at().archivePlace(*this)); > return; > } > arch_el.push_back(archivat.at().archivePlace(*this)); >} > >void TVArchive::archivatorDetach( const string &arch, bool full ) >{ > ResAlloc res(a_res,true); > > AutoHD<TVArchivator> archivat = owner().at(TSYS::strSepParse(arch,0,'.')).at(). > valAt(TSYS::strSepParse(arch,1,'.')); > //- Find archivator - > for( int i_l = 0; i_l < arch_el.size(); i_l++ ) > if( &arch_el[i_l]->archivator() == &archivat.at() ) > { > archivat.at().archiveRemove(id(),full); > arch_el.erase(arch_el.begin()+i_l); > } >} > >void TVArchive::archivatorSort() >{ > int rep_try; > > ResAlloc res(a_res,true); > > do > { > rep_try = false; > for( int i_l = 1; i_l < arch_el.size(); i_l++ ) > if( arch_el[i_l-1]->archivator().valPeriod() > arch_el[i_l]->archivator().valPeriod() ) > { > TVArchEl *t_el = arch_el[i_l-1]; > arch_el[i_l-1] = arch_el[i_l]; > arch_el[i_l] = t_el; > rep_try=true; > } > } > while(rep_try); >} > >string TVArchive::makeTrendImg( long long ibeg, long long iend, const string &iarch, int hsz, int vsz, double valmax, double valmin ) >{ > string lab_tm, lab_dt; > time_t tm_t; > struct tm ttm, ttm1; > long long c_tm; > string rez; > int hv_border, //Image border size > h_w_start, h_w_size, //Trend window horizontal start and size > h_border_serv, //Horizontal service border size > v_w_start, v_w_size, //Trend window vertical start and size > v_border_serv; //Vertical service border size > > //> Check and get data > if( ibeg >= iend || valType( ) == TFld::String ) return rez; > TValBuf buf( TFld::Real, 0, 0, false, true ); > > //> Calc base image parameters > hv_border = 5; > h_border_serv = 30; > v_border_serv = 20; > h_w_start = hv_border; > h_w_size = hsz-h_w_start-hv_border; > v_w_start = hv_border; > v_w_size = vsz-v_w_start-v_border_serv-hv_border; > > //> Create image > gdImagePtr im = gdImageCreate(hsz,vsz); > int clr_backgr = gdImageColorAllocate(im,0x35,0x35,0x35); > int clr_grid = gdImageColorAllocate(im,0x8e,0x8e,0x8e); > int clr_symb = gdImageColorAllocate(im,0x11,0xff,0x5f); > int clr_trnd = gdImageColorAllocate(im,0x1f,0xf2,0xff); > > gdImageFilledRectangle(im,0,0,hsz-1,vsz-1,clr_backgr); > gdImageRectangle(im,h_w_start,v_w_start,h_w_start+h_w_size,v_w_start+v_w_size,clr_grid); > > //> Make horisontal grid and symbols > long long h_div = 1; > long long h_min = ibeg; > long long h_max = iend; > int hmax_ln = vsz/(gdFontTiny->w*6); > if( hmax_ln >= 2 ) > { > int hvLev = 0; > long long hLen = iend - ibeg; > if( hLen/86400000000ll >= 2 ) { hvLev = 5; h_div = 86400000000ll; } //Days > else if( hLen/3600000000ll >= 2 ) { hvLev = 4; h_div = 3600000000ll; } //Hours > else if( hLen/60000000 >= 2 ) { hvLev = 3; h_div = 60000000; } //Minutes > else if( hLen/1000000 >= 2 ) { hvLev = 2; h_div = 1000000; } //Seconds > else if( hLen/1000 >= 2 ) { hvLev = 1; h_div = 1000; } //Milliseconds > while( hLen/h_div > hmax_ln ) h_div *= 10; > while( hLen/h_div < hmax_ln/2 ) h_div /= 2; > > //>> Select most like archivator > string rarch = iarch; > if( rarch.empty() && !vOK(ibeg,iend) ) > { > double best_a_per = 0; > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( arch_el[i_a]->archivator().valPeriod() > best_a_per && > arch_el[i_a]->archivator().valPeriod() <= (double)(h_max-h_min)/(1e5*hsz) ) > { > best_a_per = arch_el[i_a]->archivator().valPeriod(); > rarch = arch_el[i_a]->archivator().workId(); > } > } > > getVal(buf,h_min,h_max,rarch,600000); > if(!buf.end() || !buf.begin()) { gdImageDestroy(im); return rez; } > > //>> Draw full trend's data and time to the trend end position > tm_t = iend/1000000; > localtime_r(&tm_t,&ttm); > lab_dt = TSYS::strMess("%d-%02d-%d",ttm.tm_mday,ttm.tm_mon+1,ttm.tm_year+1900); > if( ttm.tm_sec == 0 && iend%1000000 == 0 ) lab_tm = TSYS::strMess("%d:%02d",ttm.tm_hour,ttm.tm_min); > else if( iend%1000000 == 0 ) lab_tm = TSYS::strMess("%d:%02d:%02d",ttm.tm_hour,ttm.tm_min,ttm.tm_sec); > else lab_tm = TSYS::strMess("%d:%02d:%g",ttm.tm_hour,ttm.tm_min,(float)ttm.tm_sec+(float)(iend%1000000)/1e6); > gdImageString(im,gdFontTiny,h_w_start+h_w_size-gdFontTiny->w*lab_dt.size(),v_w_start+v_w_size+3+gdFontTiny->h,(unsigned char*)lab_dt.c_str(),clr_symb); > gdImageString(im,gdFontTiny,h_w_start+h_w_size-gdFontTiny->w*lab_tm.size(),v_w_start+v_w_size+3,(unsigned char*)lab_tm.c_str(),clr_symb); > int begMarkBrd = -1; > int endMarkBrd = vmin(h_w_start+h_w_size-gdFontTiny->w*lab_dt.size(),h_w_start+h_w_size-gdFontTiny->w*lab_tm.size()); > > //>> Draw grid and/or markers > bool first_m = true; > for( long long i_h = h_min; true; ) > { > //>>> Draw grid > int h_pos = h_w_start+h_w_size*(i_h-h_min)/(h_max-h_min); > gdImageLine(im,h_pos,v_w_start,h_pos,v_w_start+v_w_size,clr_grid); > > if( !(i_h%h_div) && i_h != iend ) > { > tm_t = i_h/1000000; > localtime_r(&tm_t,&ttm); > int chLev = -1; > if( !first_m ) > { > if( ttm.tm_mon > ttm1.tm_mon || ttm.tm_year > ttm1.tm_year ) chLev = 5; > else if( ttm.tm_mday > ttm1.tm_mday ) chLev = 4; > else if( ttm.tm_hour > ttm1.tm_hour ) chLev = 3; > else if( ttm.tm_min > ttm1.tm_min ) chLev = 2; > else if( ttm.tm_sec > ttm1.tm_sec ) chLev = 1; > else chLev = 0; > } > lab_dt = lab_tm = ""; > //Date > if( hvLev == 5 || chLev >= 4 ) > lab_dt = (chLev>=5 || chLev==-1) ? TSYS::strMess("%d-%02d-%d",ttm.tm_mday,ttm.tm_mon+1,ttm.tm_year+1900) : TSYS::strMess("%d",ttm.tm_mday); > //Hours and minuts > if( (hvLev == 4 || hvLev == 3 || ttm.tm_min) && !ttm.tm_sec ) lab_tm = TSYS::strMess("%d:%02d",ttm.tm_hour,ttm.tm_min); > //Seconds > else if( (hvLev == 2 || ttm.tm_sec) && !(i_h%1000000) ) > lab_tm = (chLev>=2 || chLev==-1) ? TSYS::strMess("%d:%02d:%02d",ttm.tm_hour,ttm.tm_min,ttm.tm_sec) : TSYS::strMess(_("%ds"),ttm.tm_sec); > //Milliseconds > else if( hvLev <= 1 || i_h%1000000 ) > lab_tm = (chLev>=2 || chLev==-1) ? TSYS::strMess("%d:%02d:%g",ttm.tm_hour,ttm.tm_min,(float)ttm.tm_sec+(float)(i_h%1000000)/1e6) : > (chLev>=1) ? TSYS::strMess(_("%gs"),(float)ttm.tm_sec+(float)(i_h%1000000)/1e6) : > TSYS::strMess(_("%gms"),(double)(i_h%1000000)/1000.); > int wdth, tpos, endPosTm = 0, endPosDt = 0; > if( lab_dt.size() ) > { > wdth = gdFontTiny->w*lab_dt.size(); > tpos = vmax(h_pos-wdth/2,hv_border); > if( (tpos+wdth) < endMarkBrd && tpos > begMarkBrd ) > { > gdImageString(im,gdFontTiny,tpos,v_w_start+v_w_size+3+gdFontTiny->h,(unsigned char*)lab_dt.c_str(),clr_symb); > endPosTm = tpos+wdth; > } > } > if( lab_tm.size() ) > { > wdth = gdFontTiny->w*lab_tm.size(); > tpos = vmax(h_pos-wdth/2,hv_border); > if( (tpos+wdth) < endMarkBrd && tpos > begMarkBrd ) > { > gdImageString(im,gdFontTiny,tpos,v_w_start+v_w_size+3,(unsigned char*)lab_tm.c_str(),clr_symb); > endPosDt = tpos+wdth; > } > } > begMarkBrd = vmax(begMarkBrd,vmax(endPosTm,endPosDt)); > memcpy((char*)&ttm1,(char*)&ttm,sizeof(tm)); > first_m = false; > } > //>>> Next > if( i_h >= iend ) break; > i_h = (i_h/h_div)*h_div + h_div; > if( i_h > iend ) i_h = iend; > } > } > > //> Make vertical grid and symbols > double c_val, > v_max = -3e300, > v_min = 3e300; > for( c_tm = buf.begin(); c_tm <= buf.end(); c_tm++ ) > { > c_val = buf.getR(&c_tm,true); > if(c_val == EVAL_REAL) continue; > v_min = vmin(v_min,c_val); > v_max = vmax(v_max,c_val); > } > if( valmax!=valmin ) > { > v_max = vmax(v_max,valmax); > v_min = vmin(v_min,valmin); > } > if( v_max==-3e300 ) { gdImageDestroy(im); return rez; } > if( TSYS::realRound(v_max,3) == TSYS::realRound(v_min,3) ) { v_max+=1.0; v_min-=1.0; } > double v_div = 1; > double v_len = v_max - v_min; > while( v_len > 10 ) { v_div *= 10; v_len /= 10; } > while( v_len < 1 ) { v_div /= 10; v_len *= 10; } > v_min = floor(v_min/v_div)*v_div; > v_max = ceil(v_max/v_div)*v_div; > while( ((v_max-v_min)/v_div) < 5 ) v_div /= 2; > //>> Draw vertical grid and symbols > for( double i_v = v_min; (v_max-i_v)/v_div > -0.1; i_v += v_div ) > { > int v_pos = v_w_start+v_w_size-(int)((double)v_w_size*(i_v-v_min)/(v_max-v_min)); > gdImageLine(im,h_w_start,v_pos,h_w_start+h_w_size,v_pos,clr_grid); > bool isMax = (fabs((v_max-i_v)/v_div) < 0.1); > gdImageString(im,gdFontTiny,hv_border+2,v_pos-(isMax?0:gdFontTiny->h),(unsigned char*)TSYS::strMess("%g",i_v).c_str(),clr_symb); > } > > //> Draw trend > double aver_vl = EVAL_REAL; > int aver_pos= 0; > long long aver_tm = 0; > long long aver_lsttm = 0; > double prev_vl = EVAL_REAL; > int prev_pos = 0; > for( c_tm = buf.begin(); true; c_tm++ ) > { > int c_pos; > if(c_tm <= buf.end()) > { > c_val = buf.getR(&c_tm,true); > c_pos = h_w_start+h_w_size*(vmax(vmin(c_tm,h_max),h_min)-h_min)/(h_max-h_min); > }else c_pos = 0; > //Square Average > if( aver_pos == c_pos ) > { > if( aver_vl == EVAL_REAL ) aver_vl = c_val; > else if( c_val != EVAL_REAL ) > aver_vl = (aver_vl*(double)(c_tm-aver_tm)+c_val*(double)(c_tm-aver_lsttm))/ > ((double)(2*c_tm-aver_tm-aver_lsttm)); > aver_lsttm = c_tm; > continue; > } > //Write point and line > if( aver_vl != EVAL_REAL ) > { > int c_vpos = v_w_start+v_w_size-(int)((double)v_w_size*(aver_vl-v_min)/(v_max-v_min)); > gdImageSetPixel(im,aver_pos,c_vpos,clr_trnd); > if( prev_vl != EVAL_REAL ) > { > int c_vpos_prv = v_w_start+v_w_size-(int)((double)v_w_size*(prev_vl-v_min)/(v_max-v_min)); > gdImageLine(im,prev_pos,c_vpos_prv,aver_pos,c_vpos,clr_trnd); > } > } > prev_vl = aver_vl; > prev_pos = aver_pos; > aver_vl = c_val; > aver_pos = c_pos; > aver_tm = aver_lsttm = c_tm; > if( !c_pos ) break; > } > > //> Get image and transfer it > int img_sz; > char *img_ptr = (char *)gdImagePngPtr(im, &img_sz); > rez.assign(img_ptr,img_sz); > gdFree(img_ptr); > gdImageDestroy(im); > > return rez; >} > >void TVArchive::cntrCmdProc( XMLNode *opt ) >{ > string a_path = opt->attr("path"); > //- Service commands process - > if( a_path == "/serv/val" ) //Values access > { > if( ctrChkNode(opt,"info",RWRWRW,"root","root",SEQ_RD) ) //Value's data information > { > string arch = opt->attr("arch"); > opt->setAttr("end",TSYS::ll2str(end(arch))); > opt->setAttr("beg",TSYS::ll2str(begin(arch))); > opt->setAttr("vtp",TSYS::int2str(TValBuf::valType())); > if( arch.empty() || arch == BUF_ARCH_NM ) > opt->setAttr("per",TSYS::ll2str(TValBuf::period())); > else > { > ResAlloc res(a_res,false); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( arch == arch_el[i_a]->archivator().workId() ) > { opt->setAttr("per",TSYS::ll2str((long long)(1000000.*arch_el[i_a]->archivator().valPeriod()))); break; } > } > } > else if( ctrChkNode(opt,"get",RWRWRW,"root","root",SEQ_RD) ) //Value's data request > { > long long tm = atoll(opt->attr("tm").c_str()); > long long tm_grnd = atoll(opt->attr("tm_grnd").c_str()); > string arch = opt->attr("arch"); > > //-- Process one value request -- > if( !tm ) tm = TSYS::curTime(); > if( !tm_grnd ) > { > opt->setText(getS(&tm,false,arch)); > opt->setAttr("tm",TSYS::ll2str(tm)); > return; > } > if( tm < tm_grnd ) throw TError(nodePath().c_str(),"Range error"); > > //-- Process of archive block request -- > TValBuf buf( TValBuf::valType(), 100000, TValBuf::period(), true, true ); > > //--- Get values buffer --- > if( (arch.empty() || arch == BUF_ARCH_NM) && vOK(tm_grnd,tm) ) > { > TValBuf::getVal(buf,tm_grnd,tm); > opt->setAttr("arch",BUF_ARCH_NM); > } > else > { > ResAlloc res( a_res, false ); > for( int i_a = 0; i_a < arch_el.size(); i_a++ ) > if( (arch.empty() || arch == arch_el[i_a]->archivator().workId()) && > (tm_grnd <= arch_el[i_a]->end() && tm > arch_el[i_a]->begin()) ) > { > buf.setPeriod( (long long)(1000000.*arch_el[i_a]->archivator().valPeriod()) ); > arch_el[i_a]->getVal( buf, tm_grnd, tm ); > opt->setAttr("arch",arch_el[i_a]->archivator().workId()); > break; > } > res.release(); > } > //--- Prepare buffer's data for transfer --- > bool isEnd = false; //Last archive value process > string text; > text.reserve(100); > int vpos_beg = 0, vpos_end = 0, vpos_cur; > long long ibeg = buf.begin(), iend = buf.end(), period = vmax(atoll(opt->attr("per").c_str()),buf.period()); > int mode = atoi(opt->attr("mode").c_str()); > if( mode < 0 || mode > 2 ) throw TError(nodePath().c_str(),"No support data mode '%d'",mode); > switch(buf.valType()) > { > case TFld::Boolean: > { > char tval_pr, tval_pr1; > while( ibeg <= iend ) > { > char tval = buf.getB(&ibeg,true); > vpos_cur = (ibeg-buf.begin())/period; > if( vpos_cur > vpos_end ) > bool1: switch(mode) > { > case 0: text+=TSYS::int2str(tval_pr)+"\n"; break; > case 1: > if( !vpos_end || tval_pr != tval_pr1 ) > text+=TSYS::int2str(vpos_end)+" "+TSYS::int2str(tval_pr)+"\n"; > tval_pr1 = tval_pr; > break; > case 2: text+=tval_pr; break; > } > tval_pr = tval; > vpos_end = vpos_cur; > ibeg++; > if( isEnd ) break; > if( ibeg > iend ) { isEnd = true; goto bool1; } //Flush last value > } > break; > } > case TFld::Integer: > { > float round_perc = atof(opt->attr("round_perc").c_str()); > int tval_pr = EVAL_INT, tval_pr1; > while( ibeg <= iend ) > { > int tval = buf.getI(&ibeg,true); > vpos_cur = (ibeg-buf.begin())/period; > if( vpos_cur <= vpos_end ) > { > if( tval == EVAL_INT ) tval = tval_pr; > if( tval != EVAL_INT && tval_pr != EVAL_INT ) > { > int s_k = ibeg-period*(ibeg/period); > int n_k = buf.period(); > tval = ((long long)tval_pr*s_k+(long long)tval*n_k)/(s_k+n_k); > } > } > else int1: switch(mode) > { > case 0: text+=TSYS::int2str(tval_pr)+"\n"; break; > case 1: > if( !(vpos_end && ( tval_pr==tval_pr1 || (((tval_pr1 > 0 && tval_pr > 0) || (tval_pr1 < 0 && tval_pr < 0)) && > 100.*(double)abs(tval_pr1-tval_pr)/(double)vmax(abs(tval_pr1),abs(tval_pr)) <= round_perc))) ) > { > text+=TSYS::int2str(vpos_end)+" "+TSYS::int2str(tval_pr)+"\n"; > tval_pr1 = tval_pr; > } > break; > case 2: text+=string((char*)&tval_pr,sizeof(int)); break; > } > tval_pr = tval; > vpos_end = vpos_cur; > ibeg++; > if( isEnd ) break; > if( ibeg > iend ) { isEnd = true; goto int1; } //Flush last value > } > break; > } > case TFld::Real: > { > float round_perc = atof(opt->attr("round_perc").c_str()); > int real_prec = atoi(opt->attr("real_prec").c_str()); > if( !real_prec ) real_prec = 10; > double tval_pr = EVAL_REAL, tval_pr1; > while( ibeg <= iend ) > { > double tval = buf.getR(&ibeg,true); > vpos_cur = (ibeg-buf.begin())/period; > if( vpos_cur <= vpos_end ) > { > if( tval == EVAL_REAL ) tval = tval_pr; > if( tval != EVAL_REAL && tval_pr != EVAL_REAL ) > { > int s_k = ibeg-period*(ibeg/period); > int n_k = buf.period(); > tval = (tval_pr*s_k+tval*n_k)/(s_k+n_k); > } > } > else real1: switch(mode) > { > case 0: text+=TSYS::real2str(tval_pr,real_prec)+"\n"; break; > case 1: > if( !(vpos_end && ( tval_pr==tval_pr1 || (((tval_pr1 > 0 && tval_pr > 0) || (tval_pr1 < 0 && tval_pr < 0)) && > 100.*fabs(tval_pr1-tval_pr)/vmax(fabs(tval_pr1),fabs(tval_pr)) <= round_perc))) ) > { > text+=TSYS::int2str(vpos_end)+" "+TSYS::real2str(tval_pr,real_prec)+"\n"; > tval_pr1 = tval_pr; > } > break; > case 2: text+=string((char*)&tval_pr,sizeof(double)); break; > } > tval_pr = tval; > vpos_end = vpos_cur; > ibeg++; > if( isEnd ) break; > if( ibeg > iend ) { isEnd = true; goto real1; } //Flush last value > } > break; > } > case TFld::String: > { > string tval_pr = EVAL_STR, tval_pr1; > while( ibeg <= iend ) > { > string tval = buf.getS(&ibeg,true); > vpos_cur = (ibeg-buf.begin())/period; > if( vpos_cur > vpos_end ) > str1: switch(mode) > { > case 0: text+=TSYS::strEncode(tval_pr,TSYS::Custom,"\n")+"\n"; break; > case 1: > if( !vpos_end || tval_pr != tval_pr1 ) > text+=TSYS::int2str(vpos_end)+" "+TSYS::strEncode(tval_pr,TSYS::Custom,"\n")+"\n"; > tval_pr1 = tval_pr; > break; > case 2: throw TError(nodePath().c_str(),"Binary mode no support for string data"); > } > tval_pr = tval; > vpos_end = vpos_cur; > ibeg++; > if( isEnd ) break; > if( ibeg > iend ) { isEnd = true; goto str1; } //Flush last value > } > break; > } > } > //--- Set result and information attributes --- > opt->setAttr("tm",TSYS::ll2str( (buf.end()/period)*period )); > opt->setAttr("tm_grnd",TSYS::ll2str( (buf.begin()/period)*period + ((buf.begin()%period)?period:0) )); > opt->setAttr("per",TSYS::ll2str(period)); > opt->setText( (mode==2) ? TSYS::strEncode(text,TSYS::base64) : text); > } > return; > } > > //- Interface comands process - > //-- Info command process -- > if( opt->name() == "info" ) > { > TCntrNode::cntrCmdProc(opt); > ctrMkNode("oscada_cntr",opt,-1,"/",_("Value archive: ")+name(),0664,"root","Archive"); > if(ctrMkNode("area",opt,-1,"/prm",_("Archive"))) > { > if(ctrMkNode("area",opt,-1,"/prm/st",_("State"))) > { > ctrMkNode("fld",opt,-1,"/prm/st/st",_("Runing"),0664,"root","Archive",1,"tp","bool"); > ctrMkNode("fld",opt,-1,"/prm/st/db",_("Archive DB"),0664,"root","Archive",4,"tp","str","dest","select","select","/db/list", > "help",_("DB address in format [<DB module>.<DB name>].\nFor use main work DB set '*.*'.")); > } > if(ctrMkNode("area",opt,-1,"/prm/cfg",_("Config"))) > { > ctrMkNode("fld",opt,-1,"/prm/cfg/id",cfg("ID").fld().descr(),0444,"root","Archive",1,"tp","str"); > ctrMkNode("fld",opt,-1,"/prm/cfg/nm",cfg("NAME").fld().descr(),0664,"root","Archive",2,"tp","str","len","50"); > ctrMkNode("fld",opt,-1,"/prm/cfg/dscr",cfg("DESCR").fld().descr(),0664,"root","Archive",3,"tp","str","cols","50","rows","3"); > ctrMkNode("fld",opt,-1,"/prm/cfg/start",_("To start"),0664,"root","Archive",1,"tp","bool"); > ctrMkNode("fld",opt,-1,"/prm/cfg/vtp",cfg("VTYPE").fld().descr(),0664,"root","Archive",3,"tp","dec","dest","select","select","/cfg/vtp_ls"); > ctrMkNode("fld",opt,-1,"/prm/cfg/srcm",cfg("Source").fld().descr(),0664,"root","Archive",3,"tp","dec","dest","select","select","/cfg/srcm_ls"); > if( srcMode() == PassiveAttr || srcMode() == ActiveAttr ) > ctrMkNode("fld",opt,-1,"/prm/cfg/src","",0664,"root","Archive",3,"tp","str","dest","sel_ed","select","/cfg/prm_atr_ls"); > ctrMkNode("fld",opt,-1,"/prm/cfg/b_per",cfg("BPER").fld().descr(),0664,"root","Archive",1,"tp","real"); > ctrMkNode("fld",opt,-1,"/prm/cfg/b_size",cfg("BSIZE").fld().descr(),0664,"root","Archive",1,"tp","dec"); > ctrMkNode("fld",opt,-1,"/prm/cfg/b_hgrd",cfg("BHGRD").fld().descr(),0664,"root","Archive",1,"tp","bool"); > ctrMkNode("fld",opt,-1,"/prm/cfg/b_hres",cfg("BHRES").fld().descr(),0664,"root","Archive",1,"tp","bool"); > } > } > if(ctrMkNode("area",opt,-1,"/arch",_("Archivators"),0444,"root","Archive")) > { > if(ctrMkNode("table",opt,-1,"/arch/arch",_("Archivators"),0664,"root","root",1,"key","arch")) > { > ctrMkNode("list",opt,-1,"/arch/arch/arch",_("Archivator"),0444,"root","root",1,"tp","str"); > ctrMkNode("list",opt,-1,"/arch/arch/start",_("Start"),0444,"root","root",1,"tp","bool"); > ctrMkNode("list",opt,-1,"/arch/arch/proc",_("Process"),0664,"root","root",1,"tp","bool"); > ctrMkNode("list",opt,-1,"/arch/arch/per",_("Period (s)"),0444,"root","root",1,"tp","real"); > ctrMkNode("list",opt,-1,"/arch/arch/beg",_("Begin"),0444,"root","root",1,"tp","str"); > ctrMkNode("list",opt,-1,"/arch/arch/end",_("End"),0444,"root","root",1,"tp","str"); > } > } > if( run_st && ctrMkNode("area",opt,-1,"/val",_("Values"),0440,"root","Archive") ) > { > ctrMkNode("fld",opt,-1,"/val/tm",_("Time"),0660,"root","Archive",1,"tp","time"); > ctrMkNode("fld",opt,-1,"/val/utm","",0660,"root","Archive",4,"tp","dec","len","6","min","0","max","999999"); > ctrMkNode("fld",opt,-1,"/val/size",_("Size (s)"),0660,"root","Archive",1,"tp","real"); > ctrMkNode("fld",opt,-1,"/val/arch",_("Archivator"),0660,"root","Archive",4,"tp","str","dest","select","select","/val/lstAVal", > "help",_("Values archivator.\nNo set archivator for process by buffer and all archivators.\nSet '<buffer>' for process by buffer.")); > ctrMkNode("fld",opt,-1,"/val/sw_trend",_("Show trend"),0660,"root","Archive",1,"tp","bool"); > if(!atoi(TBDS::genDBGet(owner().nodePath()+"vShowTrnd","0",opt->attr("user")).c_str())) > { > if(ctrMkNode("table",opt,-1,"/val/val",_("Values table"),0440,"root","Archive")) > { > ctrMkNode("list",opt,-1,"/val/val/0",_("Time"),0440,"root","Archive",1,"tp","str"); > ctrMkNode("list",opt,-1,"/val/val/1",_("Value"),0440,"root","Archive",1,"tp","str"); > } > } > else > { > ctrMkNode("fld",opt,-1,"/val/pct_w",_("Picture size"),0660,"root","Archive",3,"tp","dec","min","100","max","1024"); > ctrMkNode("fld",opt,-1,"/val/pct_h","",0660,"root","Archive",3,"tp","dec","min","50","max","800"); > ctrMkNode("fld",opt,-1,"/val/max",_("Value scale"),0660,"root","Archive",1,"tp","dec"); > ctrMkNode("fld",opt,-1,"/val/min","",0660,"root","Archive",1,"tp","dec"); > ctrMkNode("img",opt,-1,"/val/trend",_("Values trend"),0440,"root","Archive"); > } > } > return; > } > //-- Process command to page -- > if( a_path == "/prm/st/st" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( startStat() ? "1" : "0" ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) atoi(opt->text().c_str()) ? start() : stop(); > } > else if( a_path == "/prm/st/db" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( DB() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setDB( opt->text() ); > } > else if( a_path == "/prm/cfg/id" && ctrChkNode(opt) ) opt->setText(id()); > else if( a_path == "/prm/cfg/nm" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( name() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setName( opt->text() ); > } > else if( a_path == "/prm/cfg/dscr" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( dscr() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setDscr( opt->text() ); > } > else if( a_path == "/prm/cfg/start" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( toStart() ? "1" : "0" ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setToStart( atoi(opt->text().c_str()) ); > } > else if( a_path == "/prm/cfg/vtp" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(TSYS::int2str(m_vtype)); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setValType((TFld::Type)atoi(opt->text().c_str())); > } > else if( a_path == "/prm/cfg/srcm" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(TSYS::int2str(m_srcmode)); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setSrcMode((TVArchive::SrcMode)atoi(opt->text().c_str()),m_dsourc); > } > else if( a_path == "/prm/cfg/src" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(m_dsourc); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setSrcMode((TVArchive::SrcMode)m_srcmode,opt->text()); > } > else if( a_path == "/prm/cfg/b_per" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(TSYS::real2str(m_bper,6)); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setPeriod((long long)(1000000.*atof(opt->text().c_str()))); > } > else if( a_path == "/prm/cfg/b_size" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(TSYS::int2str(m_bsize)); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setSize(atoi(opt->text().c_str())); > } > else if( a_path == "/prm/cfg/b_hgrd" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(m_bhgrd?"1":"0"); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setHardGrid(atoi(opt->text().c_str())); > } > else if( a_path == "/prm/cfg/b_hres" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(m_bhres?"1":"0"); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setHighResTm(atoi(opt->text().c_str())); > } > else if( a_path == "/cfg/vtp_ls" && ctrChkNode(opt) ) > { > opt->childAdd("el")->setAttr("id",TSYS::int2str(TFld::Boolean))->setText(_("Boolean")); > opt->childAdd("el")->setAttr("id",TSYS::int2str(TFld::Integer))->setText(_("Integer")); > opt->childAdd("el")->setAttr("id",TSYS::int2str(TFld::Real))->setText(_("Real")); > opt->childAdd("el")->setAttr("id",TSYS::int2str(TFld::String))->setText(_("String")); > } > else if( a_path == "/cfg/srcm_ls" && ctrChkNode(opt) ) > { > opt->childAdd("el")->setAttr("id",TSYS::int2str(TVArchive::Passive))->setText(_("Passive")); > opt->childAdd("el")->setAttr("id",TSYS::int2str(TVArchive::PassiveAttr))->setText(_("Passive param. atribute")); > opt->childAdd("el")->setAttr("id",TSYS::int2str(TVArchive::ActiveAttr))->setText(_("Active param. atribute")); > } > else if( a_path == "/cfg/prm_atr_ls" && ctrChkNode(opt) ) > { > vector<string> list; > int c_lv = 0; > string c_path = "", c_el; > for( int c_off = 0; (c_el=TSYS::strSepParse(m_dsourc,0,'.',&c_off)).size(); c_lv++ ) > { > opt->childAdd("el")->setText(c_path); > if( c_lv ) c_path+="."; > c_path+=c_el; > } > opt->childAdd("el")->setText(c_path); > if( c_lv != 0 ) c_path += "."; > SYS->nodeAt(c_path,0,'.').at().nodeList(list); > for( unsigned i_a=0; i_a < list.size(); i_a++ ) > opt->childAdd("el")->setText(c_path+list[i_a]); > } > else if( a_path == "/arch/arch" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) > { > //Fill Archivators table > XMLNode *n_arch = ctrMkNode("list",opt,-1,"/arch/arch/arch","",0444); > XMLNode *n_start= ctrMkNode("list",opt,-1,"/arch/arch/start","",0444); > XMLNode *n_prc = ctrMkNode("list",opt,-1,"/arch/arch/proc","",0664); > XMLNode *n_per = ctrMkNode("list",opt,-1,"/arch/arch/per","",0444); > XMLNode *n_beg = ctrMkNode("list",opt,-1,"/arch/arch/beg","",0444); > XMLNode *n_end = ctrMkNode("list",opt,-1,"/arch/arch/end","",0444); > > vector<string> t_arch_ls, arch_ls; > owner().modList(t_arch_ls); > for( int i_ta = 0; i_ta < t_arch_ls.size(); i_ta++ ) > { > owner().at(t_arch_ls[i_ta]).at().valList(arch_ls); > for( int i_a = 0; i_a < arch_ls.size(); i_a++ ) > { > TVArchEl *a_el = NULL; > //Find attached > ResAlloc res(a_res,false); > for( int i_l = 0; i_l < arch_el.size(); i_l++ ) > if( arch_el[i_l]->archivator().owner().modId() == t_arch_ls[i_ta] && > arch_el[i_l]->archivator().id() == arch_ls[i_a] ) > a_el = arch_el[i_l]; > //Fill table element > if(n_arch) n_arch->childAdd("el")->setText(owner().at(t_arch_ls[i_ta]).at().valAt(arch_ls[i_a]).at().workId()); > if(n_start) n_start->childAdd("el")->setText(owner().at(t_arch_ls[i_ta]).at().valAt(arch_ls[i_a]).at().startStat()?"1":"0"); > if(n_per) n_per->childAdd("el")->setText(TSYS::real2str(owner().at(t_arch_ls[i_ta]).at().valAt(arch_ls[i_a]).at().valPeriod(),6)); > if(a_el) > { > if(n_prc) n_prc->childAdd("el")->setText("1"); > struct tm ttm; > if(n_end) > { > time_t tm_t = a_el->end()/1000000; localtime_r(&tm_t,&ttm); > n_end->childAdd("el")->setText(TSYS::strMess("%d-%02d-%d %d:%02d:%02d.%d", > ttm.tm_mday,ttm.tm_mon+1,ttm.tm_year+1900,ttm.tm_hour,ttm.tm_min,ttm.tm_sec,a_el->end()%1000000)); > } > if(n_beg) > { > time_t tm_t = a_el->begin()/1000000; localtime_r(&tm_t,&ttm); > n_beg->childAdd("el")->setText(TSYS::strMess("%d-%02d-%d %d:%02d:%02d.%d", > ttm.tm_mday,ttm.tm_mon+1,ttm.tm_year+1900,ttm.tm_hour,ttm.tm_min,ttm.tm_sec,a_el->begin()%1000000)); > } > } > else > { > if(n_prc) n_prc->childAdd("el")->setText("0"); > if(n_end) n_end->childAdd("el")->setText(""); > if(n_beg) n_beg->childAdd("el")->setText(""); > } > } > } > } > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) > { > if( opt->attr("col") == "proc" ) > { > atoi(opt->text().c_str()) ? archivatorAttach( opt->attr("key_arch") ) : > archivatorDetach( opt->attr("key_arch"), true ); > modif(); > } > } > } > else if( a_path == "/val/tm" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) > { > opt->setText(TBDS::genDBGet(owner().nodePath()+"vaTm","0",opt->attr("user"))); > if( !atoi(opt->text().c_str()) ) opt->setText(TSYS::int2str(time(NULL))); > } > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) > TBDS::genDBSet(owner().nodePath()+"vaTm",(atoi(opt->text().c_str())>=time(NULL))?"0":opt->text(),opt->attr("user")); > } > else if( a_path == "/val/utm" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vaTm_u","0",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vaTm_u",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/size" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vaSize","1",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vaSize",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/arch") > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vArch","",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vArch",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/sw_trend" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vShowTrnd","0",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vShowTrnd",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/pct_w" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vPctW","650",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vPctW",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/pct_h" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vPctH","230",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vPctH",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/max" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vMax","0",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vMax",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/min" ) > { > if( ctrChkNode(opt,"get",0660,"root","Archive",SEQ_RD) ) opt->setText(TBDS::genDBGet(owner().nodePath()+"vMin","0",opt->attr("user"))); > if( ctrChkNode(opt,"set",0660,"root","Archive",SEQ_WR) ) TBDS::genDBSet(owner().nodePath()+"vMin",opt->text(),opt->attr("user")); > } > else if( a_path == "/val/lstAVal" && ctrChkNode(opt,"get",0440) ) > { > opt->childAdd("el")->setText(""); > opt->childAdd("el")->setText(BUF_ARCH_NM); > vector<string> lsm, lsa; > owner().modList(lsm); > for( int i_m = 0; i_m < lsm.size(); i_m++ ) > { > owner().at(lsm[i_m]).at().valList(lsa); > for( int i_a = 0; i_a < lsa.size(); i_a++ ) > opt->childAdd("el")->setText(lsm[i_m]+"."+lsa[i_a]); > } > } > else if( a_path == "/val/val" && ctrChkNode(opt,"get",0440,"root","Archive",SEQ_RD) ) > { > long long end = (long long)atoi(TBDS::genDBGet(owner().nodePath()+"vaTm","0",opt->attr("user")).c_str())*1000000; > if( !(end/1000000) ) end = (long long)time(NULL) * 1000000; > end += atoi(TBDS::genDBGet(owner().nodePath()+"vaTm_u","0",opt->attr("user")).c_str()); > long long beg = end - (long long)(atof(TBDS::genDBGet(owner().nodePath()+"vaSize","1",opt->attr("user")).c_str())*1e6); > > TValBuf buf( TFld::String, 0, 0, false, true ); > getVal( buf, beg, end, TBDS::genDBGet(owner().nodePath()+"vArch","",opt->attr("user")), 2000 ); > > XMLNode *n_tm = ctrMkNode("list",opt,-1,"/val/val/0","",0440); > XMLNode *n_val = ctrMkNode("list",opt,-1,"/val/val/1","",0440); > > struct tm ttm; > time_t tm_t; > long long c_tm = buf.begin(); > if(buf.end() && buf.begin()) > while(c_tm <= buf.end()) > { > string val = buf.getS(&c_tm,true); > if( n_tm ) > { > tm_t = c_tm/1000000; > localtime_r(&tm_t,&ttm); > n_tm->childAdd("el")->setText(TSYS::strMess("%d-%02d-%d %d:%02d:%02d.%d", > ttm.tm_mday,ttm.tm_mon+1,ttm.tm_year+1900,ttm.tm_hour,ttm.tm_min,ttm.tm_sec,c_tm%1000000)); > } > if( n_val ) n_val->childAdd("el")->setText(val); > c_tm++; > } > } > else if( a_path == "/val/trend" && ctrChkNode(opt,"get",0444,"root","Archive",SEQ_RD) ) > { > int vPctW = vmin(1024,vmax(100,atoi(TBDS::genDBGet(owner().nodePath()+"vPctW","650",opt->attr("user")).c_str()))); > int vPctH = vmin(800,vmax(50,atoi(TBDS::genDBGet(owner().nodePath()+"vPctH","230",opt->attr("user")).c_str()))); > double vMax = atof(TBDS::genDBGet(owner().nodePath()+"vMax","0",opt->attr("user")).c_str()); > double vMin = atof(TBDS::genDBGet(owner().nodePath()+"vMin","0",opt->attr("user")).c_str()); > long long end = (long long) atoi(TBDS::genDBGet(owner().nodePath()+"vaTm",TSYS::int2str(time(NULL)),opt->attr("user")).c_str())*1000000+ > atoi(TBDS::genDBGet(owner().nodePath()+"vaTm_u","0",opt->attr("user")).c_str()); > if( !(end/1000000) ) end = (long long)time(NULL) * 1000000; > long long beg = end - (long long)(atof(TBDS::genDBGet(owner().nodePath()+"vaSize","1",opt->attr("user")).c_str())*1e6); > > opt->setText(TSYS::strEncode(makeTrendImg(beg,end,TBDS::genDBGet(owner().nodePath()+"vArch","",opt->attr("user")),vPctW,vPctH,vMax,vMin),TSYS::base64)); > opt->setAttr("tp","png"); > } > else TCntrNode::cntrCmdProc(opt); >} > >//************************************************* >//* TVArchivator * >//************************************************* >TVArchivator::TVArchivator( const string &iid, const string &idb, TElem *cf_el ) : run_st(false), prc_st(false), > tm_calc(0.0), TConfig(cf_el), m_db(idb), m_id(cfg("ID").getSd()), m_name(cfg("NAME").getSd()), > m_dscr(cfg("DESCR").getSd()), m_addr(cfg("ADDR").getSd()), m_start(cfg("START").getBd()), > m_v_per(cfg("V_PER").getRd()), m_a_per(cfg("A_PER").getId()) >{ > m_id = iid; > > //> Create calc timer > struct sigevent sigev; > memset(&sigev,0,sizeof(sigev)); > sigev.sigev_notify = SIGEV_THREAD; > sigev.sigev_value.sival_ptr = this; > sigev.sigev_notify_function = Task; > sigev.sigev_notify_attributes = NULL; > timer_create(CLOCK_REALTIME,&sigev,&tmId); >} > >TVArchivator::~TVArchivator() >{ > timer_delete(tmId); >} > >TCntrNode &TVArchivator::operator=( TCntrNode &node ) >{ > TVArchivator *src_n = dynamic_cast<TVArchivator*>(&node); > if( !src_n ) return *this; > > //> Configuration copy > string tid = id(); > *(TConfig*)this = *(TConfig*)src_n; > m_id = tid; > m_db = src_n->m_db; > > if( src_n->startStat() && toStart() && !startStat() ) > start( ); > > return *this; >} > >string TVArchivator::name() >{ > return (m_name.size())?m_name:m_id; >} > >string TVArchivator::tbl( ) >{ > return owner().owner().subId()+"_val_proc"; >} > >void TVArchivator::setValPeriod( double iper ) >{ > m_v_per = iper ? iper : 1.; > > //> Call sort for all archives > ResAlloc res(a_res,false); > for( map<string,TVArchEl*>::iterator iel = archEl.begin(); iel != archEl.end(); ++iel ) > iel->second->archive().archivatorSort(); > > modif(); >} > >void TVArchivator::postEnable(int flag) >{ > cfg("MODUL").setS(owner().modId()); >} > >void TVArchivator::preDisable( int flag ) >{ > if( startStat() ) stop( flag ); >} > >void TVArchivator::postDisable( int flag ) >{ > try > { > if( flag ) > SYS->db().at().dataDel(fullDB(),SYS->archive().at().nodePath()+tbl(),*this,true); > }catch(TError err) > { mess_warning(err.cat.c_str(),"%s",err.mess.c_str()); } >} > >string TVArchivator::workId() >{ > return owner().modId()+"."+id(); >} > >void TVArchivator::start() >{ > if( run_st ) return; > //> Start interval timer for periodic thread creating > struct itimerspec itval; > itval.it_interval.tv_sec = itval.it_value.tv_sec = m_a_per; > itval.it_interval.tv_nsec = itval.it_value.tv_nsec = 0; > timer_settime(tmId, 0, &itval, NULL); > > run_st = true; >}; > >void TVArchivator::stop( bool full_del ) >{ > if( !run_st ) return; > > //> Stop interval timer for periodic thread creating > struct itimerspec itval; > itval.it_interval.tv_sec = itval.it_interval.tv_nsec = itval.it_value.tv_sec = itval.it_value.tv_nsec = 0; > timer_settime(tmId, 0, &itval, NULL); > if( TSYS::eventWait( prc_st, false, nodePath()+"stop",5) ) > throw TError(nodePath().c_str(),_("Archive thread is not stopped!")); > > //> Detach from all archives > ResAlloc res(a_res,false); > while(archEl.size()) > { > AutoHD<TVArchive> arch(&archEl.begin()->second->archive()); > res.release(); > arch.at().archivatorDetach(workId(),full_del); > res.request(false); > } > > run_st = false; >}; > >void TVArchivator::archiveList( vector<string> &ls ) >{ > ResAlloc res(a_res,false); > ls.clear(); > for( map<string,TVArchEl*>::iterator iel = archEl.begin(); iel != archEl.end(); ++iel ) > ls.push_back(iel->first); >} > >bool TVArchivator::archivePresent( const string &iid ) >{ > ResAlloc res(a_res,false); > if( archEl.find(iid) != archEl.end() ) return true; > return false; >} > >TVArchEl *TVArchivator::archivePlace( TVArchive &item ) >{ > ResAlloc res(a_res,true); > map<string,TVArchEl*>::iterator iel = archEl.find(item.id()); > if( iel != archEl.end() ) return iel->second; > TVArchEl *it_el = getArchEl( item ); > archEl[item.id()] = it_el; > > return it_el; >} > >void TVArchivator::archiveRemove( const string &iid, bool full ) >{ > ResAlloc res(a_res,true); > map<string,TVArchEl*>::iterator iel = archEl.find(iid); > if( iel != archEl.end() ) > { > if( full ) iel->second->fullErase(); > delete iel->second; > archEl.erase(iel); > } >} > >TVArchEl *TVArchivator::getArchEl( TVArchive &arch ) >{ > return new TVArchEl( arch, *this ); >} > >TTipArchivator &TVArchivator::owner() >{ > return *(TTipArchivator *)nodePrev(); >} > >void TVArchivator::load_( ) >{ > if( !SYS->chkSelDB(DB()) ) return; > SYS->db().at().dataGet(fullDB(),SYS->archive().at().nodePath()+tbl(),*this); >} > >void TVArchivator::save_( ) >{ > SYS->db().at().dataSet(fullDB(),SYS->archive().at().nodePath()+tbl(),*this); >} > >void TVArchivator::Task(union sigval obj) >{ > TVArchivator *arch = (TVArchivator*)obj.sival_ptr; > if( arch->prc_st ) return; > arch->prc_st = true; > >#if OSC_DEBUG >= 2 > mess_debug(arch->nodePath().c_str(),_("Timer's thread <%u> call. TID: %ld"),pthread_self(),(long int)syscall(224)); >#endif > > //- Archiving - > try > { > unsigned long long t_cnt = SYS->shrtCnt(); > > ResAlloc res(arch->a_res,false); > long long beg, end; > for( map<string,TVArchEl*>::iterator iel = arch->archEl.begin(); iel != arch->archEl.end(); ++iel ) > if( iel->second->archive().startStat() ) > { > TVArchEl *arch_el = iel->second; > beg = vmax(arch_el->m_last_get,arch_el->archive().begin()); > end = arch_el->archive().end(); > if(!beg || !end || beg > end ) continue; > //-- Averaging -- > long long a_per = (long long)(1000000.*arch->valPeriod()); > if( a_per > arch_el->archive().period() ) > { > TValBuf buf(arch_el->archive().valType(),((end-beg)/a_per)+1,a_per,true,true); > for( long long c_tm = beg; c_tm <= end;) > { > switch(arch_el->archive().valType()) > { > case TFld::Boolean: > { > char c_val = arch_el->archive().getB(&c_tm,true); > buf.setB(c_val,c_tm); > c_tm+=a_per; > break; > } > case TFld::String: > { > string c_val = arch_el->archive().getS(&c_tm,true); > buf.setS(c_val,c_tm); > c_tm+=a_per; > break; > } > case TFld::Integer: > { > int c_val = arch_el->archive().getI(&c_tm,true); > int vdif = c_tm/a_per - arch_el->prev_tm/a_per; > if( !vdif ) > { > int v_o = *(int*)arch_el->prev_val.c_str(); > if( c_val == EVAL_INT ) c_val = v_o; > if( c_val != EVAL_INT && v_o != EVAL_INT ) > { > long long s_k = c_tm-a_per*(c_tm/a_per); > long long n_k = arch_el->archive().period(); > c_val = ((long long)v_o*s_k+(long long)c_val*n_k)/(s_k+n_k); > } > arch_el->prev_val.assign((char*)&c_val,sizeof(int)); > arch_el->prev_tm = c_tm; > } > if( vdif == 1 || c_tm+1 > end ) > buf.setI(*(int*)arch_el->prev_val.c_str(),arch_el->prev_tm); > if( vdif ) > { > arch_el->prev_val.assign((char*)&c_val,sizeof(int)); > arch_el->prev_tm = c_tm; > } > c_tm++; > break; > } > case TFld::Real: > { > double c_val = arch_el->archive().getR(&c_tm,true); > int vdif = c_tm/a_per - arch_el->prev_tm/a_per; > if( !vdif ) > { > double v_o = *(double*)arch_el->prev_val.c_str(); > if( c_val == EVAL_REAL ) c_val = v_o; > if( c_val != EVAL_REAL && v_o != EVAL_REAL ) > { > long long s_k = c_tm-a_per*(c_tm/a_per); > long long n_k = arch_el->archive().period(); > c_val = (v_o*s_k+c_val*n_k)/(s_k+n_k); > } > arch_el->prev_val.assign((char*)&c_val,sizeof(double)); > arch_el->prev_tm = c_tm; > } > if( vdif == 1 || c_tm+1 > end ) > buf.setR(*(double*)arch_el->prev_val.c_str(),arch_el->prev_tm); > if( vdif ) > { > arch_el->prev_val.assign((char*)&c_val,sizeof(double)); > arch_el->prev_tm = c_tm; > } > c_tm++; > break; > } > } > } > arch_el->setVal( buf, buf.begin(), end ); > } > else arch_el->setVal( arch_el->archive(), beg, end ); > > arch_el->m_last_get = end+1; > } > > arch->tm_calc = 1.0e3*((double)(SYS->shrtCnt()-t_cnt))/((double)SYS->sysClk()); > } catch(TError err) > { mess_err(err.cat.c_str(),"%s",err.mess.c_str() ); } > > arch->prc_st = false; >} > >void TVArchivator::setArchPeriod( int iper ) >{ > m_a_per = iper ? iper : 1; > if( startStat() ) > { > struct itimerspec itval; > itval.it_interval.tv_sec = itval.it_value.tv_sec = m_a_per; > itval.it_interval.tv_nsec = itval.it_value.tv_nsec = 0; > timer_settime(tmId, 0, &itval, NULL); > } > > modif(); >} > >void TVArchivator::cntrCmdProc( XMLNode *opt ) >{ > //- Get page info - > if( opt->name() == "info" ) > { > TCntrNode::cntrCmdProc(opt); > ctrMkNode("oscada_cntr",opt,-1,"/",_("Value archivator: ")+name(),0664,"root","Archive"); > if(ctrMkNode("area",opt,-1,"/prm",_("Archivator"))) > { > if(ctrMkNode("area",opt,-1,"/prm/st",_("State"))) > { > ctrMkNode("fld",opt,-1,"/prm/st/st",_("Runing"),0664,"root","Archive",1,"tp","bool"); > ctrMkNode("fld",opt,-1,"/prm/st/tarch",_("Archiving time (msek)"),0444,"root","Archive",1,"tp","real"); > ctrMkNode("fld",opt,-1,"/prm/st/db",_("Archivator DB"),0664,"root","root",4,"tp","str","dest","select","select","/db/list", > "help",_("DB address in format [<DB module>.<DB name>].\nFor use main work DB set '*.*'.")); > } > if(ctrMkNode("area",opt,-1,"/prm/cfg",_("Config"))) > { > ctrMkNode("fld",opt,-1,"/prm/cfg/id",cfg("ID").fld().descr(),0444,"root","Archive",1,"tp","str"); > ctrMkNode("fld",opt,-1,"/prm/cfg/nm",cfg("NAME").fld().descr(),0664,"root","Archive",2,"tp","str","len","50"); > ctrMkNode("fld",opt,-1,"/prm/cfg/dscr",cfg("DESCR").fld().descr(),0664,"root","Archive",3,"tp","str","cols","50","rows","3"); > ctrMkNode("fld",opt,-1,"/prm/cfg/vper",cfg("V_PER").fld().descr(),0664,"root","Archive",1,"tp","real"); > ctrMkNode("fld",opt,-1,"/prm/cfg/aper",cfg("A_PER").fld().descr(),0664,"root","Archive",1,"tp","dec"); > ctrMkNode("fld",opt,-1,"/prm/cfg/addr",cfg("ADDR").fld().descr(),0664,"root","Archive",1,"tp","str"); > ctrMkNode("fld",opt,-1,"/prm/cfg/start",_("To start"),0664,"root","Archive",1,"tp","bool"); > } > } > if(ctrMkNode("area",opt,-1,"/arch",_("Archives"))) > if(ctrMkNode("table",opt,-1,"/arch/arch",_("Archives"),0444,"root","Archive")) > { > ctrMkNode("list",opt,-1,"/arch/arch/0",_("Archive"),0444,"root","Archive",1,"tp","str"); > ctrMkNode("list",opt,-1,"/arch/arch/1",_("Period (s)"),0444,"root","Archive",1,"tp","real"); > ctrMkNode("list",opt,-1,"/arch/arch/2",_("Buffer size"),0444,"root","Archive",1,"tp","dec"); > } > return; > } > > //- Process command to page - > string a_path = opt->attr("path"); > if( a_path == "/prm/st/st" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( startStat() ? "1" : "0" ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) atoi(opt->text().c_str()) ? start() : stop(); > } > else if( a_path == "/prm/st/tarch" && ctrChkNode(opt) ) opt->setText(TSYS::real2str(tm_calc,6)); > else if( a_path == "/prm/st/db" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( DB() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setDB( opt->text() ); > } > else if( a_path == "/prm/cfg/id" && ctrChkNode(opt) ) opt->setText(id()); > else if( a_path == "/prm/cfg/nm" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( name() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setName( opt->text() ); > } > else if( a_path == "/prm/cfg/dscr" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( dscr() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setDscr( opt->text() ); > } > else if( a_path == "/prm/cfg/addr" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( addr() ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setAddr( opt->text() ); > } > else if( a_path == "/prm/cfg/start" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText( toStart() ? "1" : "0" ); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setToStart( atoi(opt->text().c_str()) ); > } > else if( a_path == "/prm/cfg/vper" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(TSYS::real2str(valPeriod(),6)); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setValPeriod(atof(opt->text().c_str())); > } > else if( a_path == "/prm/cfg/aper" ) > { > if( ctrChkNode(opt,"get",0664,"root","Archive",SEQ_RD) ) opt->setText(TSYS::int2str(archPeriod())); > if( ctrChkNode(opt,"set",0664,"root","Archive",SEQ_WR) ) setArchPeriod(atoi(opt->text().c_str())); > } > else if( a_path == "/arch/arch" && ctrChkNode(opt) ) > { > //-- Fill Archives table -- > XMLNode *n_arch = ctrMkNode("list",opt,-1,"/arch/arch/0",""); > XMLNode *n_per = ctrMkNode("list",opt,-1,"/arch/arch/1",""); > XMLNode *n_size = ctrMkNode("list",opt,-1,"/arch/arch/2",""); > > ResAlloc res(a_res,false); > for( map<string,TVArchEl*>::iterator iel = archEl.begin(); iel != archEl.end(); ++iel ) > { > if(n_arch) n_arch->childAdd("el")->setText(iel->second->archive().id()); > if(n_per) n_per->childAdd("el")->setText(TSYS::real2str((double)iel->second->archive().period()/1000000.,6)); > if(n_size) n_size->childAdd("el")->setText(TSYS::int2str(iel->second->archive().size())); > } > } > else TCntrNode::cntrCmdProc(opt); >} > >//************************************************* >//* TVArchEl * >//************************************************* >TVArchEl::TVArchEl( TVArchive &iarchive, TVArchivator &iarchivator ) : > m_achive(iarchive), m_archivator(iarchivator), m_last_get(0), prev_tm(0) >{ > >} > >TVArchEl::~TVArchEl() >{ > >} > >TVArchive &TVArchEl::archive() >{ > return m_achive; >} > >TVArchivator &TVArchEl::archivator() >{ > return m_archivator; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 19331
: 3419