1 #ifdef STANDALONE_PARSER
8 #include "rapidjson/document.h"
9 #include "rapidjson/reader.h"
10 #include "rapidjson/filereadstream.h"
19 : mDirectoryFile(path), mNextAvailableIndex(0), mStoreRequest(0)
25 int n = mNetEntries.size();
26 for (
int i=0; i<n; i++)
29 mByName.insert(std::make_pair(sdne.
name(),i));
30 if (sdne.
id()) mById.insert(std::make_pair(sdne.
id(),i));
43 mComposedEntryMap.clear();
46 mNextAvailableIndex = 0;
53 FILE*
ff = fopen(mDirectoryFile.c_str(),
"rb");
56 std::cerr <<
"cannot open SALEAE directory file <" << mDirectoryFile <<
">" << std::endl;
65 rapidjson::FileReadStream frs(
ff, buffer,
sizeof(buffer));
66 rapidjson::Document document;
67 document.ParseStream<0, rapidjson::UTF8<>, rapidjson::FileReadStream>(frs);
70 if (document.HasParseError() || !document.HasMember(
"saleae"))
72 std::cerr <<
"cannot parse SALEAE directory file <" << mDirectoryFile <<
">" << std::endl;
75 auto jsaleae = document[
"saleae"].GetObject();
76 if (jsaleae.HasMember(
"nets"))
78 for (
auto& jnet : jsaleae[
"nets"].GetArray())
82 if (jnet.HasMember(
"id"))
id = jnet[
"id"].GetUint();
83 if (jnet.HasMember(
"name"))
name = jnet[
"name"].GetString();
85 if (jnet.HasMember(
"indexes"))
87 for (
auto& jinx : jnet[
"indexes"].GetArray())
89 int inx = jinx[
"index"].GetInt();
90 uint64_t tBeg = jinx[
"t_beg"].GetUint64();
91 uint64_t tEnd = jinx[
"t_end"].GetUint64();
92 uint64_t nVal = jinx[
"n_val"].GetUint64();
94 if (inx >= mNextAvailableIndex) mNextAvailableIndex = inx + 1;
97 int n = mNetEntries.size();
98 mNetEntries.push_back(sdne);
99 if (
id) mById.insert(std::make_pair(
id,n));
100 mByName.insert(std::make_pair(
name,n));
105 if (jsaleae.HasMember(
"groups"))
107 for (
auto& jgrp : jsaleae[
"groups"].GetArray())
111 if (jgrp.HasMember(
"id")) gid = jgrp[
"id"].GetUint();
112 if (jgrp.HasMember(
"name")) gname = jgrp[
"name"].GetString();
114 if (jgrp.HasMember(
"nets"))
116 for (
auto& jgnet : jgrp[
"nets"].GetArray())
118 uint32_t nid = jgnet[
"id"].GetInt();
122 mComposedEntryMap[sdce.
uniqueKey()] = sdce;
126 if (jsaleae.HasMember(
"composed"))
128 for (
auto& jcmpsd : jsaleae[
"composed"].GetArray())
134 if (jcmpsd.HasMember(
"id"))
id = jcmpsd[
"id"].GetUint();
135 if (jcmpsd.HasMember(
"name"))
name = jcmpsd[
"name"].GetString();
140 if (jcmpsd.HasMember(
"nets"))
142 for (
auto& jgnet : jcmpsd[
"nets"].GetArray())
144 uint32_t nid = jgnet[
"id"].GetInt();
148 if (jcmpsd.HasMember(
"children"))
150 for (
auto& jchld : jcmpsd[
"children"].GetArray())
155 if (jcmpsd.HasMember(
"data"))
157 std::vector<int> vdata;
158 for (
auto& jdata : jcmpsd[
"data"].GetArray())
159 vdata.push_back(jdata.GetInt());
167 if (jcmpsd.HasMember(
"filter"))
171 mComposedEntryMap[sdce.
uniqueKey()]=sdce;
178 #ifndef STANDALONE_PARSER
179 bool SaleaeDirectory::write_json()
const
187 jnet[
"id"] = (int)
net.id();
188 jnet[
"name"] =
net.name();
193 jinx[
"index"] = inx.index();
194 jinx[
"t_beg"] = inx.beginTime();
195 jinx[
"t_end"] = inx.endTime();
196 jinx[
"n_val"] = inx.numberValues();
203 if (!mComposedEntryMap.empty())
205 JsonWriteArray& jcmpsds = jsaleae.
add_array((
"composed"));
206 for (
auto it=mComposedEntryMap.begin(); it!=mComposedEntryMap.end(); ++it)
208 const SaleaeDirectoryComposedEntry& cmpsd = it->second;
209 JsonWriteObject& jcmpsd = jcmpsds.
add_object();
210 jcmpsd[
"id"] = (int) cmpsd.id();
211 jcmpsd[
"name"] = cmpsd.name();
212 jcmpsd[
"type"] = (int) cmpsd.type();
213 JsonWriteArray& jgnets = jcmpsd.
add_array(
"children");
214 for (
int childKey : cmpsd.get_children())
219 if (!cmpsd.get_data().empty())
221 JsonWriteArray& jdata = jcmpsd.add_array(
"data");
222 for (
int dat : cmpsd.get_data())
226 if (cmpsd.get_filter_entry())
228 jcmpsd[
"filter"] = cmpsd.get_filter_entry();
257 if (sdne.mFileIndexes.empty())
continue;
258 int inx = sdne.mFileIndexes.back().index();
259 auto it = fileIndexes.find(inx);
260 if (it != fileIndexes.end())
262 sdne.mFileIndexes.pop_back();
263 sdne.mFileIndexes.push_back(it->second);
273 auto it = mById.find(sdne.
id());
274 if (it != mById.end()) inetentry = it->second;
278 auto it = mByName.find(sdne.
name());
279 if (it != mByName.end())
281 inetentry = it->second;
283 mById.insert(std::make_pair(sdne.
id(),inetentry));
288 int n = mNetEntries.size();
289 mByName.insert(std::make_pair(sdne.
name(),n));
290 if (sdne.
id()) mById.insert(std::make_pair(sdne.
id(),n));
291 mNetEntries.push_back(sdne);
295 mNetEntries[inetentry] = sdne;
298 if (sdfi.index() >= mNextAvailableIndex) mNextAvailableIndex = sdfi.index() + 1;
314 if (
index < 0)
return std::string();
322 auto it = mById.find(
id);
323 if (it != mById.end())
return getIndex(mNetEntries.at(it->second));
325 auto jt = mByName.find(nam);
326 if (jt == mByName.end())
return -1;
327 return getIndex(mNetEntries.at(jt->second));
337 if (sdfi.endTime() > retval) retval = sdfi.endTime();
345 #ifndef STANDALONE_PARSER
348 auto it = mById.find(
id);
349 if (it == mById.end())
return;
350 mNetEntries[it->second].rename(nam);
355 std::vector<ListEntry> retval;
362 if (inx < 0) inx = sdfi.index();
363 size += sdfi.numberValues();
365 retval.push_back({sdne.id(),sdne.name(),inx,
size});
378 if (
index < 0)
return std::string();
379 std::ostringstream fname;
380 fname <<
"digital_" <<
index <<
".bin";
387 if (pos==std::string::npos)
return std::string();
388 return mDirectoryFile.substr(0,pos);
393 return mDirectoryFile;
397 :
SaleaeDirectoryNetEntry(other), mChildKeys(other.mChildKeys), mData(other.mData), mFilterEntry(other.mFilterEntry)
410 auto it = mChildKeys.begin();
411 while (it != mChildKeys.end())
414 it = mChildKeys.erase(it);
422 const char* ctype[] = {
"None",
"Group",
"Boolean",
"Trigger" };
423 std::cout << ctype[
mType] <<
": " <<
mId <<
" <" <<
mName <<
">\n";
424 for (
int childKey : mChildKeys)
425 std::cout <<
" <" << childKey <<
">\n";
426 std::cout <<
"data:";
427 for (
int x : mData) std::cout <<
" " <<
x;
428 std::cout <<
"\nfilter:";
430 std::cout <<
" <" << mFilterEntry <<
">\n";
432 std::cout <<
" ---\n";
433 std::cout <<
"=============" << std::endl;
444 #ifndef STANDALONE_PARSER
447 mComposedEntryMap[sdce.
uniqueKey()] = sdce;
452 #ifndef STANDALONE_PARSER
456 auto it = mComposedEntryMap.find(needle.
uniqueKey());
457 if (it != mComposedEntryMap.end())
458 mComposedEntryMap.erase(it);
464 auto it = mComposedEntryMap.find(needle.
uniqueKey());
471 std::vector<SaleaeDirectoryComposedEntry> retval;
472 for (
auto it=mComposedEntryMap.begin(); it!=mComposedEntryMap.end(); ++it)
473 retval.push_back(it->second);
478 #ifndef STANDALONE_PARSER
482 : mSaleaeDirectory(sd)
484 ++mSaleaeDirectory->mStoreRequest;
489 if (--mSaleaeDirectory->mStoreRequest <= 0)
492 mSaleaeDirectory->write_json();
JsonWriteObject & add_object()
bool serialize(const std::string &filename)
JsonWriteObject & add_object(const std::string &tag)
JsonWriteArray & add_array(const std::string &tag)
The SaleaeDirectoryComposedEntry class represents a composed waveform. There are currently three type...
void add_child(int key)
Add an additional child key to composed.
SaleaeDirectoryComposedEntry(const std::string nam=std::string(), uint32_t id_=0, Type tp=None)
void dump() const
Dump to stdout.
~SaleaeDirectoryComposedEntry()
void set_data(const std::vector< int > &dat)
Setter for data list described above.
void set_filter_entry(int filt)
Setter for filter pointer described above.
void remove_child(int key)
Remove child key from composed.
The SaleaeDirectoryFileIndex class represents a single SALEAE data file. The class comprises the inde...
The SaleaeDirectory class provides the API for the SALEAE directory file. The SALEAE directory file w...
void rename_net(uint32_t id, const std::string &nam)
Change waveform name entry for net identified by id.
int get_datafile_index(const std::string &nam, uint32_t id) const
Get waveform datafile index for net identified by name and id.
void clearAll()
Remove all files and reset internal variables.
void add_or_replace_net(SaleaeDirectoryNetEntry &sdne)
Add net entry if not yet existing, replace existing entry otherwise.
bool parse_json()
Parse .json file into class instance.
std::string get_directory() const
Get path to SALEAE directory without filename.
std::vector< SaleaeDirectoryNetEntry > dump() const
Dump content of class instance to console for debugging purpose.
std::string get_datafile_name(int index) const
Get waveform datafile name without path (digital_XXX.bin)
SaleaeDirectory(const std::string &path, bool create=false)
constructor
std::vector< SaleaeDirectoryComposedEntry > get_composed_list() const
Getter to list of all composed waveform entries.
void add_or_replace_composed(SaleaeDirectoryComposedEntry sdce)
Add composed waveform entry (Group, Boolean, Trigger)
void remove_composed(uint32_t id, SaleaeDirectoryNetEntry::Type tp)
Remove composed waveform entry identified by id an type.
void update_file_indexes(std::unordered_map< int, SaleaeDirectoryFileIndex > &fileIndexes)
Update file index information (like number of transitions, end time ...) after writing SALEAE files.
SaleaeDirectoryComposedEntry get_composed(uint32_t id, SaleaeDirectoryNetEntry::Type tp) const
Getter for pointer to composed waveform entry allowing modifications.
std::vector< ListEntry > get_net_list() const
Getter for all net entries.
std::string get_datafile_path(int index) const
Get full path to waveform data file.
std::string get_filename() const
Get full path to saleae directory file including filename (/.../saleae.json)
uint64_t get_max_time() const
Getter for maximum time.
The SaleaeDirectoryNetEntry class represents a regular waveform for a single simulated net....
int dataFileIndex() const
Return last data file index (currently there should be no more than one)
int uniqueKey() const
Unique key as reference (used e.g. in mComposedEntryMap)
uint32_t id() const
Getter for waveform ID = simulated net ID.
const std::vector< SaleaeDirectoryFileIndex > & indexes() const
Getter for list of associated binary files indexes.
std::vector< SaleaeDirectoryFileIndex > mFileIndexes
static const int sComposedBaseKey
void addIndex(const SaleaeDirectoryFileIndex &sdfe)
Add index for binary file to net entry instance.
std::string name() const
Getter for waveform name.
The SaleaeDirectoryStoreRequest class is useful to bundle requests for updating SALEAE directory....
static bool sWriteDisabled
~SaleaeDirectoryStoreRequest()
void remove(std::filesystem::path file_path)
bool save(std::filesystem::path file_path, GateLibrary *gate_lib, bool overwrite=false)
const char folderSeparator