Commit f3023e79 authored by DreamSourceLab's avatar DreamSourceLab

add RLE compress function

parent 91938e44
......@@ -42,13 +42,18 @@ Annotation::Annotation(const srd_proto_data *const pdata) :
_format = pda->ann_class;
const char *const *annotations = (char**)pda->ann_text;
const char *const *annotations = (char**)pda->ann_text;
while(*annotations) {
_annotations.push_back(QString::fromUtf8(*annotations));
_annotations.push_back(QString::fromUtf8(*annotations));
annotations++;
}
}
Annotation::~Annotation()
{
_annotations.clear();
}
uint64_t Annotation::start_sample() const
{
return _start_sample;
......
......@@ -35,6 +35,7 @@ class Annotation
{
public:
Annotation(const srd_proto_data *const pdata);
~Annotation();
uint64_t start_sample() const;
uint64_t end_sample() const;
......
......@@ -46,6 +46,10 @@ Decoder::~Decoder()
for (map<string, GVariant*>::const_iterator i = _options.begin();
i != _options.end(); i++)
g_variant_unref((*i).second);
for (map<string, GVariant*>::const_iterator i = _options_back.begin();
i != _options_back.end(); i++)
g_variant_unref((*i).second);
}
const srd_decoder* Decoder::decoder() const
......@@ -164,7 +168,7 @@ srd_decoder_inst* Decoder::create_decoder_inst(srd_session *session, int unit_si
g_hash_table_insert(probes, (*i).first->id, gvar);
}
srd_inst_channel_set_all(decoder_inst, probes, unit_size);
srd_inst_channel_set_all(decoder_inst, probes);
return decoder_inst;
}
......
......@@ -38,6 +38,11 @@ Row::Row(const srd_decoder *decoder, const srd_decoder_annotation_row *row) :
{
}
Row::~Row()
{
}
const srd_decoder* Row::decoder() const
{
return _decoder;
......
......@@ -36,6 +36,7 @@ class Row
{
public:
Row();
~Row();
Row(const srd_decoder *decoder,
const srd_decoder_annotation_row *row = NULL);
......
......@@ -34,6 +34,11 @@ RowData::RowData() :
{
}
RowData::~RowData()
{
_annotations.clear();
}
uint64_t RowData::get_max_sample() const
{
if (_annotations.empty())
......
......@@ -33,6 +33,7 @@ class RowData
{
public:
RowData();
~RowData();
public:
uint64_t get_max_sample() const;
......
......@@ -88,6 +88,8 @@ DecoderStack::~DecoderStack()
// _decode_thread.join();
// }
stop_decode();
_stack.clear();
clear();
}
const std::list< boost::shared_ptr<decode::Decoder> >&
......@@ -335,7 +337,7 @@ void DecoderStack::decode_data(
{
//uint8_t chunk[DecodeChunkLength];
uint8_t *chunk = NULL;
chunk = (uint8_t *)realloc(chunk, DecodeChunkLength);
//chunk = (uint8_t *)realloc(chunk, DecodeChunkLength);
const uint64_t chunk_sample_count =
DecodeChunkLength / _snapshot->unit_size();
......@@ -349,10 +351,10 @@ void DecoderStack::decode_data(
const uint64_t chunk_end = min(
i + chunk_sample_count, sample_count);
_snapshot->get_samples(chunk, i, chunk_end);
chunk = _snapshot->get_samples(i, chunk_end);
if (srd_session_send(session, i, i + sample_count, chunk,
(chunk_end - i) * unit_size) != SRD_OK) {
(chunk_end - i) * unit_size, unit_size) != SRD_OK) {
_error_message = tr("Decoder reported an error");
break;
}
......
......@@ -74,10 +74,9 @@ void LogicSnapshot::append_payload(
append_payload_to_mipmap();
}
void LogicSnapshot::get_samples(uint8_t *const data,
int64_t start_sample, int64_t end_sample) const
uint8_t * LogicSnapshot::get_samples(int64_t start_sample, int64_t end_sample) const
{
assert(data);
//assert(data);
assert(start_sample >= 0);
assert(start_sample <= (int64_t)_sample_count);
assert(end_sample >= 0);
......@@ -86,8 +85,9 @@ void LogicSnapshot::get_samples(uint8_t *const data,
//lock_guard<recursive_mutex> lock(_mutex);
const size_t size = (end_sample - start_sample) * _unit_size;
memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size);
//const size_t size = (end_sample - start_sample) * _unit_size;
//memcpy(data, (const uint8_t*)_data + start_sample * _unit_size, size);
return (uint8_t*)_data + start_sample * _unit_size;
}
void LogicSnapshot::reallocate_mipmap_level(MipMapLevel &m)
......
......@@ -67,8 +67,7 @@ public:
void append_payload(const sr_datafeed_logic &logic);
void get_samples(uint8_t *const data,
int64_t start_sample, int64_t end_sample) const;
uint8_t * get_samples(int64_t start_sample, int64_t end_sample) const;
private:
void reallocate_mipmap_level(MipMapLevel &m);
......
......@@ -41,7 +41,7 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptr<pv::device::DevI
QDialog(parent),
_dev_inst(dev_inst),
_layout(this),
_button_box(QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
_button_box(QDialogButtonBox::Ok,
Qt::Horizontal, this),
_device_options_binding(_dev_inst->dev_inst())
{
......@@ -68,7 +68,16 @@ DeviceOptions::DeviceOptions(QWidget *parent, boost::shared_ptr<pv::device::DevI
_layout.addWidget(&_button_box);
connect(&_button_box, SIGNAL(accepted()), this, SLOT(accept()));
connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject()));
//connect(&_button_box, SIGNAL(rejected()), this, SLOT(reject()));
GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_OPERATION_MODE);
if (gvar != NULL) {
_mode = g_variant_get_string(gvar, NULL);
g_variant_unref(gvar);
}
connect(&_mode_check, SIGNAL(timeout()), this, SLOT(mode_check()));
_mode_check.setInterval(100);
_mode_check.start();
}
void DeviceOptions::accept()
......@@ -100,9 +109,7 @@ void DeviceOptions::accept()
void DeviceOptions::reject()
{
using namespace Qt;
QDialog::reject();
accept();
}
QWidget* DeviceOptions::get_property_form()
......@@ -116,8 +123,11 @@ QWidget* DeviceOptions::get_property_form()
BOOST_FOREACH(boost::shared_ptr<pv::prop::Property> p, properties)
{
assert(p);
const QString label = p->labeled_widget() ? QString() : p->name();
layout->addRow(label, p->get_widget(form));
const QString label = p->labeled_widget() ? QString() : p->name();
if (label == "Operation Mode")
layout->addRow(label, p->get_widget(form, true));
else
layout->addRow(label, p->get_widget(form));
}
return form;
......@@ -127,8 +137,9 @@ void DeviceOptions::setup_probes()
{
using namespace Qt;
int row = 0, col = 0;
int row0 = 0, row1 = 0, col = 0;
int index = 0;
uint16_t ch_mode;
while(_probes_box_layout.count() > 0)
{
......@@ -140,6 +151,29 @@ void DeviceOptions::setup_probes()
_probes_label_list.clear();
_probes_checkBox_list.clear();
if (_dev_inst->dev_inst()->mode == LOGIC) {
GVariant *gvar_opts;
gsize num_opts;
if (sr_config_list(_dev_inst->dev_inst()->driver, _dev_inst->dev_inst(), NULL, SR_CONF_CHANNEL_MODE,
&gvar_opts) == SR_OK) {
const char **const options = g_variant_get_strv(gvar_opts, &num_opts);
GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_CHANNEL_MODE);
if (gvar != NULL) {
ch_mode = g_variant_get_uint16(gvar);
g_variant_unref(gvar);
}
for (int i=0; i<num_opts; i++){
QRadioButton *ch_opts = new QRadioButton(options[i]);
_probes_box_layout.addWidget(ch_opts, row0, col, 1, 8);
connect(ch_opts, SIGNAL(pressed()), this, SLOT(channel_check()));
row0++;
if (i == ch_mode)
ch_opts->setChecked(true);
}
}
g_variant_unref(gvar_opts);
}
for (const GSList *l = _dev_inst->dev_inst()->channels; l; l = l->next) {
sr_channel *const probe = (sr_channel*)l->data;
assert(probe);
......@@ -147,14 +181,14 @@ void DeviceOptions::setup_probes()
QLabel *probe_label = new QLabel(QString::number(probe->index), this);
QCheckBox *probe_checkBox = new QCheckBox(this);
probe_checkBox->setCheckState(probe->enabled ? Qt::Checked : Qt::Unchecked);
_probes_box_layout.addWidget(probe_label, row * 2, col);
_probes_box_layout.addWidget(probe_checkBox, row * 2 + 1, col);
_probes_box_layout.addWidget(probe_label, row1 * 2 + row0, col);
_probes_box_layout.addWidget(probe_checkBox, row1 * 2 + 1 + row0, col);
_probes_label_list.push_back(probe_label);
_probes_checkBox_list.push_back(probe_checkBox);
index++;
col = index % 8;
row = index / 8;
row1 = index / 8;
}
QPushButton *_enable_all_probes = new QPushButton(tr("Enable All"), this);
......@@ -165,8 +199,8 @@ void DeviceOptions::setup_probes()
connect(_disable_all_probes, SIGNAL(clicked()),
this, SLOT(disable_all_probes()));
_probes_box_layout.addWidget(_enable_all_probes, (row + 1) * 2, 0, 1, 4);
_probes_box_layout.addWidget(_disable_all_probes, (row + 1) * 2, 4, 1, 4);
_probes_box_layout.addWidget(_enable_all_probes, (row1 + 1) * 2 + row0, 0, 1, 4);
_probes_box_layout.addWidget(_disable_all_probes, (row1 + 1) * 2 + row0, 4, 1, 4);
}
void DeviceOptions::set_all_probes(bool set)
......@@ -206,5 +240,44 @@ void DeviceOptions::zero_adj()
}
}
void DeviceOptions::mode_check()
{
bool test;
QString mode;
GVariant* gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_OPERATION_MODE);
if (gvar != NULL) {
mode = g_variant_get_string(gvar, NULL);
g_variant_unref(gvar);
if (mode != _mode) {
setup_probes();
_mode = mode;
}
}
gvar = _dev_inst->get_config(NULL, NULL, SR_CONF_TEST);
if (gvar != NULL) {
test = g_variant_get_boolean(gvar);
g_variant_unref(gvar);
if (test) {
QVector<QCheckBox *>::iterator i = _probes_checkBox_list.begin();
while(i != _probes_checkBox_list.end()) {
(*i)->setCheckState(Qt::Checked);
(*i)->setDisabled(TRUE);
i++;
}
}
}
}
void DeviceOptions::channel_check()
{
QRadioButton* sc=dynamic_cast<QRadioButton*>(sender());
if(sc != NULL)
_dev_inst->set_config(NULL, NULL, SR_CONF_CHANNEL_MODE, g_variant_new_string(sc->text().toLocal8Bit()));
setup_probes();
}
} // namespace dialogs
} // namespace pv
......@@ -36,6 +36,7 @@
#include <QCheckBox>
#include <QComboBox>
#include <QRadioButton>
#include <QTimer>
#include <boost/shared_ptr.hpp>
......@@ -68,6 +69,8 @@ private slots:
void enable_all_probes();
void disable_all_probes();
void zero_adj();
void mode_check();
void channel_check();
private:
boost::shared_ptr<pv::device::DevInst> _dev_inst;
......@@ -84,6 +87,9 @@ private:
QPushButton *_config_button;
QDialogButtonBox _button_box;
QTimer _mode_check;
QString _mode;
pv::prop::binding::DeviceOptions _device_options_binding;
};
......
......@@ -91,7 +91,7 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
case SR_CONF_TEST:
case SR_CONF_STATUS:
case SR_CONF_FACTOR:
bind_enum(name, key, gvar_list);
bind_enum(name, key, gvar_list);
break;
case SR_CONF_VTH:
......@@ -110,11 +110,11 @@ DeviceOptions::DeviceOptions(struct sr_dev_inst *sdi) :
break;
case SR_CONF_TIMEBASE:
bind_enum(name, key, gvar_list, print_timebase);
bind_enum(name, key, gvar_list, print_timebase);
break;
case SR_CONF_VDIV:
bind_enum(name, key, gvar_list, print_vdiv);
bind_enum(name, key, gvar_list, print_vdiv);
break;
default:
gvar_list = NULL;
......@@ -153,7 +153,7 @@ void DeviceOptions::bind_bool(const QString &name, int key)
}
void DeviceOptions::bind_enum(const QString &name, int key,
GVariant *const gvar_list, boost::function<QString (GVariant*)> printer)
GVariant *const gvar_list, boost::function<QString (GVariant*)> printer)
{
GVariant *gvar;
GVariantIter iter;
......@@ -166,7 +166,7 @@ void DeviceOptions::bind_enum(const QString &name, int key,
values.push_back(make_pair(gvar, printer(gvar)));
_properties.push_back(boost::shared_ptr<Property>(
new Enum(name, values,
new Enum(name, values,
bind(config_getter, _sdi, key),
bind(config_setter, _sdi, key, _1))));
}
......@@ -235,7 +235,7 @@ void DeviceOptions::bind_samplerate(const QString &name,
else if ((gvar_list_samplerates = g_variant_lookup_value(gvar_list,
"samplerates", G_VARIANT_TYPE("at"))))
{
bind_enum(name, SR_CONF_SAMPLERATE,
bind_enum(name, SR_CONF_SAMPLERATE,
gvar_list_samplerates, print_samplerate);
g_variant_unref(gvar_list_samplerates);
}
......
......@@ -29,7 +29,7 @@ namespace prop {
Property::Property(QString name, Getter getter, Setter setter) :
_getter(getter),
_setter(setter),
_name(name)
_name(name)
{
}
......
......@@ -45,10 +45,10 @@ public:
typedef boost::function<void (GVariant*)> Setter;
protected:
Property(QString name, Getter getter, Setter setter);
Property(QString name, Getter getter, Setter setter);
public:
const QString& name() const;
const QString& name() const;
virtual QWidget* get_widget(QWidget *parent,
bool auto_commit = false) = 0;
......@@ -61,7 +61,7 @@ protected:
const Setter _setter;
private:
QString _name;
QString _name;
};
} // prop
......
......@@ -793,12 +793,20 @@ void SigSession::reload()
signal.reset();
switch(probe->type) {
case SR_CHANNEL_LOGIC:
if (probe->enabled && probe->index < _signals.size())
signal = boost::shared_ptr<view::Signal>(
new view::LogicSignal(*_signals[probe->index].get(), _logic_data, probe));
else if (probe->enabled)
signal = boost::shared_ptr<view::Signal>(
new view::LogicSignal(_dev_inst, _logic_data, probe));
if (probe->enabled) {
std::vector< boost::shared_ptr<view::Signal> >::iterator i = _signals.begin();
while (i != _signals.end()) {
if ((*i)->get_index() == probe->index) {
signal = boost::shared_ptr<view::Signal>(
new view::LogicSignal(**i, _logic_data, probe));
break;
}
i++;
}
if (!signal.get())
signal = boost::shared_ptr<view::Signal>(
new view::LogicSignal(_dev_inst, _logic_data, probe));
}
break;
case SR_CHANNEL_DSO:
......
......@@ -150,8 +150,9 @@ void StoreSession::store_proc(shared_ptr<data::LogicSnapshot> snapshot)
uint64_t start_sample = 0;
/// TODO: Wrap this in a std::unique_ptr when we transition to C++11
uint8_t *const data = new uint8_t[BlockSize];
assert(data);
uint8_t *data = NULL;
//uint8_t *const data = new uint8_t[BlockSize];
//assert(data);
const int unit_size = snapshot->unit_size();
assert(unit_size != 0);
......@@ -170,7 +171,7 @@ void StoreSession::store_proc(shared_ptr<data::LogicSnapshot> snapshot)
const uint64_t end_sample = min(
start_sample + samples_per_block, _unit_count);
snapshot->get_samples(data, start_sample, end_sample);
data = snapshot->get_samples(start_sample, end_sample);
if(sr_session_append(_file_name.c_str(), data, unit_size,
end_sample - start_sample) != SR_OK)
......@@ -189,7 +190,7 @@ void StoreSession::store_proc(shared_ptr<data::LogicSnapshot> snapshot)
progress_updated();
delete[] data;
//delete[] data;
}
} // pv
......@@ -222,8 +222,10 @@ void SamplingBar::on_configure()
pv::dialogs::DeviceOptions dlg(this, dev_inst);
ret = dlg.exec();
if (ret == QDialog::Accepted)
if (ret == QDialog::Accepted) {
device_updated();
update_sample_rate_selector();
}
GVariant* gvar = dev_inst->get_config(NULL, NULL, SR_CONF_ZERO);
if (gvar != NULL) {
......@@ -479,10 +481,10 @@ void SamplingBar::on_samplecount_sel(int index)
{
uint64_t sample_count = 0;
uint64_t max_sample_count = 0;
uint64_t last_sample_count = 0;
//uint64_t last_sample_count = 0;
bool stream_mode = false;
bool buffer2stream = false;
bool stream2buffer = false;
//bool buffer2stream = false;
//bool stream2buffer = false;
if (index >= 0)
sample_count = _sample_count.itemData(
......@@ -492,7 +494,7 @@ void SamplingBar::on_samplecount_sel(int index)
assert(_devInst);
if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) {
GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES);
/*GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES);
if (gvar != NULL) {
last_sample_count = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
......@@ -515,7 +517,7 @@ void SamplingBar::on_samplecount_sel(int index)
} else if (stream_mode && sample_count <= max_sample_count) {
stream_mode = sample_count > max_sample_count;
stream2buffer = true;
}
}*/
// Set the sample count
_devInst->set_config(NULL, NULL,
......@@ -523,8 +525,29 @@ void SamplingBar::on_samplecount_sel(int index)
g_variant_new_uint64(sample_count));
GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_STREAM);
if (gvar != NULL) {
stream_mode = g_variant_get_boolean(gvar);
g_variant_unref(gvar);
}
gvar = _devInst->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS);
if (gvar != NULL) {
max_sample_count = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
}
if (!stream_mode) {
if (sample_count > max_sample_count) {
_devInst->set_config(NULL, NULL,
SR_CONF_RLE,
g_variant_new_boolean(true));
} else {
_devInst->set_config(NULL, NULL,
SR_CONF_RLE,
g_variant_new_boolean(false));
}
}
if (buffer2stream) {
/*if (buffer2stream) {
pv::dialogs::StreamOptions stream(this, _devInst, sample_count, stream_mode);
stream.setFixedSize(300, 150);
stream.exec();
......@@ -543,7 +566,7 @@ void SamplingBar::on_samplecount_sel(int index)
g_variant_new_boolean(false));
}
device_updated();
device_updated();*/
update_scale();
}
}
......@@ -552,24 +575,53 @@ void SamplingBar::on_samplerate_sel(int index)
{
uint64_t sample_rate = 0;
//uint64_t last_sample_rate = 0;
uint64_t max_sample_count = 0;
uint64_t sample_count = 0;
bool stream_mode = false;
if (index >= 0)
sample_rate = _sample_rate.itemData(
index).value<uint64_t>();
const sr_dev_inst* _sdi = get_selected_device()->dev_inst();
assert(_sdi);
boost::shared_ptr<pv::device::DevInst> _devInst = get_selected_device();
assert(_devInst);
// Get last samplerate
//last_sample_rate = get_selected_device()->get_sample_rate();
if (strcmp(_sdi->driver->name, "DSLogic") == 0 && _sdi->mode != DSO) {
if (strcmp(_devInst->dev_inst()->driver->name, "DSLogic") == 0 && _devInst->dev_inst()->mode != DSO) {
// Set the samplerate
get_selected_device()->set_config(NULL, NULL,
SR_CONF_SAMPLERATE,
g_variant_new_uint64(sample_rate));
update_sample_count_selector_value();
device_updated();
GVariant* gvar = _devInst->get_config(NULL, NULL, SR_CONF_STREAM);
if (gvar != NULL) {
stream_mode = g_variant_get_boolean(gvar);
g_variant_unref(gvar);
}
gvar = _devInst->get_config(NULL, NULL, SR_CONF_LIMIT_SAMPLES);
if (gvar != NULL) {
sample_count = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
}
gvar = _devInst->get_config(NULL, NULL, SR_CONF_MAX_LOGIC_SAMPLELIMITS);
if (gvar != NULL) {
max_sample_count = g_variant_get_uint64(gvar);
g_variant_unref(gvar);
}
if (!stream_mode) {
if (sample_count > max_sample_count) {
_devInst->set_config(NULL, NULL,
SR_CONF_RLE,
g_variant_new_boolean(true));
} else {
_devInst->set_config(NULL, NULL,
SR_CONF_RLE,
g_variant_new_boolean(false));
}
}
update_scale();
}
}
......
......@@ -136,6 +136,18 @@ DecodeTrace::DecodeTrace(pv::SigSession &session,
this, SLOT(on_show_hide_decoder(int)));
}
DecodeTrace::~DecodeTrace()
{
if (_popup_form)
delete _popup_form;
if (_popup)
delete _popup;
_cur_row_headings.clear();
_decoder_forms.clear();
_probe_selectors.clear();
_bindings.clear();
}
bool DecodeTrace::enabled() const
{
return true;
......
......@@ -89,6 +89,7 @@ public:
DecodeTrace(pv::SigSession &session,
boost::shared_ptr<pv::data::DecoderStack> decoder_stack,
int index);
~DecodeTrace();
bool enabled() const;
......
......@@ -85,6 +85,7 @@ LogicSignal::LogicSignal(const Signal &s,
LogicSignal::~LogicSignal()
{
_cur_edges.clear();
}
const sr_channel* LogicSignal::probe() const
......
......@@ -48,8 +48,6 @@ static struct sr_dev_mode mode_list[] = {
static const char *opmodes[] = {
"Normal",
"Internal Test",
"External Test",
"DRAM Loopback Test",
};
static const char *thresholds[] = {
......@@ -254,7 +252,7 @@ static int fpga_setting(const struct sr_dev_inst *sdi)
((devc->op_mode == SR_OP_EXTERNAL_TEST) << 14) +
((devc->op_mode == SR_OP_LOOPBACK_TEST) << 13) +
trigger->trigger_en +
((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 1) +
((sdi->mode > 0) << 4) + (devc->clock_type << 1) + (devc->clock_edge << 2) +
(((devc->cur_samplerate == SR_MHZ(200) && sdi->mode != DSO) || (sdi->mode == ANALOG)) << 5) +
((devc->cur_samplerate == SR_MHZ(400)) << 6) +
((sdi->mode == ANALOG) << 7) +
......@@ -579,7 +577,7 @@ static struct DSL_context *DSCope_dev_new(void)
devc->clock_type = FALSE;
devc->clock_edge = FALSE;
devc->instant = FALSE;
devc->op_mode = SR_OP_NORMAL;
devc->op_mode = SR_OP_BUFFER;
devc->th_level = SR_TH_3V3;
devc->filter = SR_FILTER_NONE;
devc->timebase = 10000;
......@@ -1386,8 +1384,8 @@ static int config_set(int id, GVariant *data, struct sr_dev_inst *sdi,
} else if (id == SR_CONF_OPERATION_MODE) {
stropt = g_variant_get_string(data, NULL);
ret = SR_OK;
if (!strcmp(stropt, opmodes[SR_OP_NORMAL])) {
devc->op_mode = SR_OP_NORMAL;
if (!strcmp(stropt, opmodes[SR_OP_BUFFER])) {
devc->op_mode = SR_OP_BUFFER;