📄 circularbuffer.h
字号:
// return: none//template<class TObject>CircularBuffer<TObject>::CircularBuffer(long capacity_a) { // initialize the stored item // v_d.setLength(capacity_a); v_d.setCapacity(capacity_a); // initialize the position indices // read_d = DEF_READ_IDX; write_d = DEF_WRITE_IDX; curr_d = DEF_CURR_IDX; // exit gracefully //}//------------------------------------------------------------------------//// required assign methods////-------------------------------------------------------------------------// method: assign//// arguments:// const CircularBuffer<TObject>& copy_cbuf: (input) CircularBuffer to copy//// return: a boolean value indicating status//// this method copies the contents of the input to this CircularBuffer//template<class TObject>boolean CircularBuffer<TObject>::assign(const CircularBuffer<TObject>& copy_cbuf_a) { // if the input CircularBuffer contains a null item, error and return without // changing this CircularBuffer // long in_capacity = copy_cbuf_a.getCapacity(); if (in_capacity == 0) { return Error::handle(name(), L"assign", Error::NOMEM, __FILE__, __LINE__); } // it may be necessary to clear the CircularBuffer and reset the capacity // if (getCapacity() != in_capacity) { setCapacity(in_capacity, false); } // copy the position indices // read_d = copy_cbuf_a.read_d; curr_d = copy_cbuf_a.curr_d; write_d = copy_cbuf_a.write_d; // copy the valid data // // find the start index for the loop // long j = read_d; long capacity = getCapacity(); if (write_d < read_d) { j -= capacity; } // loop all the valid elements // for (; j <= (long)write_d; j++) { // get the physical index // long i = j; if (i < 0) { i += capacity; } v_d(i).assign(copy_cbuf_a.v_d(i)); } // exit gracefully // return true;}//------------------------------------------------------------------------//// required i/o methods////------------------------------------------------------------------------// method: sofSize//// arguments: none//// return: size of object as written to disk via the i/o methods//// this method determines the size of the object on disk//template<class TObject>long CircularBuffer<TObject>::sofSize() const { // get the size of the storage vector // long byte = v_d.sofSize(); // add the sizes of other internal data // Long capacity = getCapacity(); byte += capacity.sofSize(); byte += read_d.sofSize(); byte += write_d.sofSize(); byte += curr_d.sofSize(); // exit gracefully // return byte;}// method: read//// arguments:// Sof& sof: (input) sof file object// const String& name: (input) sof object instance name// long tag: (input) sof object instance tag//// return: a boolean value indicating status//// this method has the object read itself from an Sof file//template<class TObject>boolean CircularBuffer<TObject>::read(Sof& sof_a, long tag_a, const String& name_a) { // get the instance of the object from an Sof file // if (!sof_a.find(name_a, tag_a)) { return false; } // read the actual data from an Sof file // if (!readData(sof_a)) { return false; } // exit gracefully // return true; }// method: write//// arguments:// Sof& sof: (input) sof file object// long tag: (input) sof object instance tag// const String& name: (input) sof object instance name//// return: a boolean value indicating status//// this method has the object write itself to an Sof file//template<class TObject>boolean CircularBuffer<TObject>::write(Sof& sof_a, long tag_a, const String& name_a) const { // declare a temporary size variable // long obj_size = 0; // switch on ascii or binary mode // if (sof_a.isText()) { // set the size to be dynamic // obj_size = Sof::ANY_SIZE; } else { // the size of the binary data to write // obj_size = sofSize(); } // put the object into the sof file's index // if (!sof_a.put(name_a, tag_a, obj_size)) { return false; } // exit gracefully // return writeData(sof_a); }// method: readData//// arguments:// Sof& sof: (input) sof file object// String& pname: (input) parameter name// long size: (input) size of the object// boolean param: (input) is the parameter specified?// boolean nested: (input) is this nested?//// return: a boolean value indicating status//// this method has the object read itself from an Sof file. it assumes// that the Sof file is already positioned correctly.//template<class TObject>boolean CircularBuffer<TObject>::readData(Sof& sof_a, const String& pname_a, long size_a, boolean param_a, boolean nested_a) { // first clear the buffer // if (!clear()) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } SofParser parser; parser.setDebug(debug_level_d); // ignore implicit parameter setting // // are we nested? // if (nested_a) { parser.setNest(); } // load the parse // if (!parser.load(sof_a, size_a)) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } // read the capacity of the CircularBuffer // Long capacity; if (!capacity.readData(sof_a, PARAM_CAPACITY, parser.getEntry(sof_a, PARAM_CAPACITY), false, false)) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } // set the capacity // setCapacity(capacity); // read the pointers // Long read; if (!read.readData(sof_a, PARAM_READ, parser.getEntry(sof_a, PARAM_READ), false, false)) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } Long write; if (!write.readData(sof_a, PARAM_WRITE, parser.getEntry(sof_a, PARAM_WRITE), false, false)) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } Long curr; if (!curr.readData(sof_a, PARAM_CURR, parser.getEntry(sof_a, PARAM_CURR), false, false)) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } // read Vector in a temporary object // Vector<TObject> temp_vec; if (!temp_vec.readData(sof_a, PARAM_VALUES, parser.getEntry(sof_a, PARAM_VALUES), false, false)) { return Error::handle(name(), L"readData", Error::READ, __FILE__, __LINE__, Error::WARNING); } v_d.setLength(capacity); v_d.setCapacity(capacity); for (long i = 0; i < temp_vec.length(); i++) { v_d(i + read) = temp_vec(i); } read_d = read; write_d = write; curr_d = curr; // append to CircularBuffer // // append(temp_vec); // exit gracefully // return true; }// method: writeData//// arguments:// Sof& sof: (input) sof file object// String& pname: (input) parameter name//// return: a boolean value indicating status//// this method writes the object to the Sof file. it assumes that the// Sof file is already positioned correctly.//template<class TObject>boolean CircularBuffer<TObject>::writeData(Sof& sof_a, const String& pname_a) const { // write a start string if necessary // sof_a.writeLabelPrefix(pname_a); // write the capacity // Long capacity = getCapacity(); capacity.writeData(sof_a, PARAM_CAPACITY); read_d.writeData(sof_a, PARAM_READ); write_d.writeData(sof_a, PARAM_WRITE); curr_d.writeData(sof_a, PARAM_CURR); // get the valid number of elements in the buffer // long num_valid_element = write_d - read_d + 1; v_d.writeStart(sof_a); v_d.writePartialData(sof_a, read_d, num_valid_element); v_d.writeTerminate(sof_a); // put an end string if necessary // sof_a.writeLabelSuffix(pname_a); // exit gracefully // return true; }// ----------------------------------------------------------------------//// required equality methods////------------------------------------------------------------------------// method: eq//// arguments:// const CircularBuffer<TObject>& compare_cbuf: (input) the CircularBuffer// to compare//// return: a boolean value indicating status//// this method compares two CircularBuffers for equivalence. two// CircularBuffers are equivalent if all corresponding valid items are// equivalent//template<class TObject>boolean CircularBuffer<TObject>::eq(const CircularBuffer<TObject>& compare_cbuf_a) const { // remember the old curr_d // long old_curr = curr_d; long compare_old_curr = compare_cbuf_a.curr_d; // two circular buffers can not be equivalent if they have different // number of elements // long num_elements = getNumElements(); if (num_elements != compare_cbuf_a.getNumElements()) { // exit ungracefully // return false; } // temporarily set the curr_d to be same as read_d // const_cast<CircularBuffer<TObject>*>(this)->curr_d = read_d; const_cast<CircularBuffer<TObject>&>(compare_cbuf_a).curr_d = compare_cbuf_a.read_d; // loop over each valid element and see if each is equivalent // for (long i = 0; i < num_elements; i++) { // see if the current items are equal // TObject value; getElement(value, i); if (!value.eq(compare_cbuf_a(i))) { // resume the curr_d and exit // const_cast<CircularBuffer<TObject>*>(this)->curr_d = old_curr; const_cast<CircularBuffer<TObject>&>(compare_cbuf_a).curr_d = compare_old_curr; return false; } } // resume the curr_d // const_cast<CircularBuffer<TObject>*>(this)->curr_d = old_curr; const_cast<CircularBuffer<TObject>&>(compare_cbuf_a).curr_d = compare_old_curr; // number of forward and backward should also be equal // if ((getNumForward() != compare_cbuf_a.getNumForward()) || (getNumBackward() != compare_cbuf_a.getNumBackward())) { // exit ungracefully // return false; } // equal, exit gracefully // return true;}//-------------------------------------------------------------------------//// required clear methods////-------------------------------------------------------------------------// method: clear//// arguments:// Integral::CMODE cmode_a: (input) clear mode//// return: a boolean value indicating status//// set the class variables to default values and call the clear method// for the vector.// template<class TObject>boolean CircularBuffer<TObject>::clear(Integral::CMODE cmode_a) { // cmode_a: RESET, RELEASE or FREE // if (cmode_a != Integral::RETAIN) { // reset the position indices // read_d = DEF_READ_IDX; write_d = DEF_WRITE_IDX; curr_d = DEF_CURR_IDX; } // cmode_a: RETAIN, RELEASE or FREE // if (cmode_a != Integral::RESET) { // pass the release mode along to the vector and let it take care // of clearing // return v_d.clear(cmode_a); } // cmode_a: RESET // else { // exit gracefully // return true; }}// ----------------------------------------------------------------------//// class-specific public methods:// operator overload methods////------------------------------------------------------------------------// method: operator()//// arguments:// long offset: (input) the offset with respect to the curr_d//// return: the TObect element//// this method gets an element of the circular buffer//template<class TObject>TObject& CircularBuffer<TObject>::operator() (long offset_a) { if ((offset_a > 0 && offset_a > getNumForward()) || (offset_a < 0 && offset_a < (-1 * getNumBackward()))) { Error::handle(name(), L"operator()", Error::ARG, __FILE__, __LINE__); } // get the element // long index = curr_d + offset_a; long capacity = getCapacity(); while (index > capacity -1) { index -= capacity; } while (index < 0) { index += capacity; } // return the value // return v_d(index);}// method: operator()//// arguments:// long offset: (input) the offset with respect to the curr_d//// return: the TObect element//// this method gets an element of the circular buffer//template<class TObject>const TObject& CircularBuffer<TObject>::operator() (long offset_a) const {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -