Guitarix
gx_json.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2009, 2010 Hermann Meyer, James Warden, Andreas Degert
3  * Copyright (C) 2011 Pete Shorthose
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18  * ---------------------------------------------------------------------------
19  *
20  * This is the gx_head system interface
21  *
22  * ----------------------------------------------------------------------------
23  */
24 
25 #include "engine.h" // NOLINT
26 
27 #include <sys/stat.h>
28 
29 namespace gx_system {
30 
31 bool check_mtime(const std::string& filename, time_t& mtime) {
32  struct stat st;
33  if (stat(filename.c_str(), &st) != 0) {
34  mtime = 0;
35  return false;
36  }
37  time_t t = max(st.st_mtime, st.st_ctime);
38  if (t == mtime) {
39  return true;
40  }
41  mtime = t;
42  return false;
43 }
44 
45 /****************************************************************
46  ** JsonWriter
47  */
48 
49 JsonWriter::JsonWriter(ostream *o, bool enable_newlines)
50  : os(o),
51  first(true),
52  deferred_nl(enable_newlines ? 0 : -1),
53  indent("") {}
54 
56  close();
57 }
58 
60  os->flush();
61  first = true;
62  if (deferred_nl == 1) {
63  deferred_nl = 0;
64  }
65  indent.clear();
66 }
67 
69  if (is_closed()) {
70  return;
71  }
72  if (deferred_nl == 1) {
73  *os << endl;
74  }
75  os = 0;
76 }
77 
78 inline void JsonWriter::komma() {
79  if (first)
80  first = false;
81  else if (deferred_nl == 0)
82  *os << ", ";
83  else
84  *os << ",";
85  flush();
86 }
87 
88 inline void JsonWriter::space() {
89  if (first)
90  first = false;
91  else if (deferred_nl == 0)
92  *os << " ";
93  flush();
94 }
95 
96 inline void JsonWriter::iplus() {
97  indent += " ";
98 }
99 
100 inline void JsonWriter::iminus() {
101  if (!indent.empty()) {
102  indent = indent.substr(0, indent.size() - 2);
103  }
104 }
105 
106 template<class T> static inline T fp_sanitize(T v) {
107  switch (fpclassify(v)) {
108  case FP_NORMAL: return v;
109  case FP_NAN: assert(false); return 1e50;
110  case FP_INFINITE: assert(false); return (v < 0 ? -1e50 : 1e50);
111  case FP_SUBNORMAL: return 0;
112  }
113  return v;
114 }
115 
116 void JsonWriter::write(float v, bool nl) {
117  komma();
118  *os << fp_sanitize(v);
119  snl(nl);
120 }
121 
122 void JsonWriter::write(double v, bool nl) {
123  komma();
124  *os << fp_sanitize(v);
125  snl(nl);
126 }
127 
128 void JsonWriter::write(int i, bool nl) {
129  komma();
130  *os << i;
131  snl(nl);
132 }
133 
134 void JsonWriter::write(unsigned int i, bool nl) {
135  komma();
136  *os << i;
137  snl(nl);
138 }
139 
140 void JsonWriter::write_lit(const string& s, bool nl) {
141  komma();
142  *os << s;
143  snl(nl);
144 }
145 
146 void JsonWriter::write(const char* p, bool nl) {
147  if (p) {
148  komma();
149  *os << '"';
150  for (; *p; p++) {
151  switch (*p) {
152  case '\\': case '"': *os << '\\'; break;
153  case '\b': *os << '\\'; *os << 'b'; continue; // NOLINT
154  case '\f': *os << '\\'; *os << 'f'; continue; // NOLINT
155  case '\n': *os << '\\'; *os << 'n'; continue; // NOLINT
156  case '\r': *os << '\\'; *os << 'r'; continue; // NOLINT
157  case '\t': *os << '\\'; *os << 't'; continue; // NOLINT
158  }
159  *os << *p;
160  }
161  *os << '"';
162  } else {
163  write_null();
164  }
165  snl(nl);
166 }
167 
169  komma();
170  *os << '{';
171  snl(nl);
172  first = true;
173  iplus();
174 }
175 
176 void JsonWriter::end_object(bool nl) {
177  iminus();
178  flush();
179  first = false;
180  *os << '}';
181  snl(nl);
182 }
183 
184 void JsonWriter::begin_array(bool nl) {
185  komma();
186  *os << '[';
187  snl(nl);
188  first = true;
189  iplus();
190 }
191 
192 void JsonWriter::end_array(bool nl) {
193  iminus();
194  flush();
195  first = false;
196  *os << ']';
197  snl(nl);
198 }
199 
200 void JsonWriter::write_key(const char* p, bool nl) {
201  write(p, nl);
202  *os << ": ";
203  first = true;
204 }
205 
206 void JsonWriter::write_key(const string& p, bool nl) {
207  write(p, nl);
208  *os << ": ";
209  first = true;
210 }
211 
212 // called before output of next element
214  if (deferred_nl == 1) {
215  *os << endl;
216  deferred_nl = false;
217  *os << indent;
218  }
219 }
220 
221 
222 /****************************************************************
223  ** class JsonStringWriter
224  */
225 
226 void JsonStringWriter::send_notify_begin(const char *method) {
227  begin_object();
228  write_key("jsonrpc");
229  write("2.0");
230  write_key("method");
231  write(method);
232  write_key("params");
233  begin_array();
234 }
235 
237  end_array();
238  end_object();
239 }
240 
241 
242 /****************************************************************
243  ** JsonParser
244  */
245 
246 JsonException::JsonException(const Glib::ustring& desc) {
247  what_str = "Json parse error: " + desc;
248 }
249 
251  depth = 0;
252  cur_tok = no_token;
253  str.clear();
254  nl = false;
255  next_depth = 0;
256  next_tok = no_token;
257  next_str.clear();
258  next_pos = 0;
259 }
260 
262  : is(i),
263  depth(0),
264  cur_tok(no_token),
265  str(),
266  nl(false),
267  next_depth(0),
268  next_tok(no_token),
269  next_str(),
270  next_pos(0) {
271 }
272 
274  close();
275 }
276 
278  if (is_closed()) {
279  return;
280  }
281  is = 0;
282 }
283 
285  switch (tok) {
286  case no_token: return "no_token";
287  case end_token: return "end_token";
288  case begin_object: return "begin_object";
289  case end_object: return "end_object";
290  case begin_array: return "begin_array";
291  case end_array: return "end_array";
292  case value_string: return "value_string";
293  case value_number: return "value_number";
294  case value_key: return "value_key";
295  case value_null: return "value_null";
296  case value_bool: return "value_bool";
297  case value_false: return "value_false";
298  case value_true: return "value_true";
299  default: assert(false); return 0;
300  }
301 }
302 
304  ostringstream b;
305  b << "unexpected token: " << get_token_name(cur_tok)
306  << " (expected: " << get_token_name(expect) << ")"
307  << endl;
308  //cerr << b.str() << endl; assert(false);
309  throw JsonException(b.str().c_str());
310 }
311 
312 const char* unicode2utf8(unsigned int input) {
313  const int maskbits = 0x3F;
314  const int maskbyte = 0x80;
315  const int mask2bytes = 0xC0;
316  const int mask3bytes = 0xE0;
317  static char result[4];
318  int n = 0;
319  // 0xxxxxxx
320  if (input < 0x80) {
321  result[n++] = static_cast<char>(input);
322 
323  // 110xxxxx 10xxxxxx
324  } else if (input < 0x800) {
325  result[n++] = (static_cast<char>(mask2bytes | (input >> 6)));
326  result[n++] = (static_cast<char>(maskbyte | (input & maskbits)));
327 
328  // 1110xxxx 10xxxxxx 10xxxxxx
329  } else {
330  result[n++] = (static_cast<char>(mask3bytes | (input >> 12)));
331  result[n++] = (static_cast<char>(maskbyte | ((input >> 6) & maskbits)));
332  result[n++] = (static_cast<char>(maskbyte | (input & maskbits)));
333  }
334  result[n++] = '\0';
335  return result;
336 }
337 
338 const char* JsonParser::readcode() {
339  int code = 0;
340  for (int i = 0; i < 4; i++) {
341  int n = is->get();
342  if (!is->good())
343  throw JsonExceptionEOF("eof");
344  if ('0' <= n && n <= '9')
345  n = n - '0';
346  else
347  n = 10 + (toupper(n) - 'A');
348  code = code * 16 + n;
349  }
350  return unicode2utf8(code);
351 }
352 
353 string JsonParser::readstring() {
354  ostringstream os("");
355  char c;
356  do {
357  is->get(c);
358  if (!is->good())
359  return "";
360  if (c == '\\') {
361  is->get(c);
362  if (!is->good())
363  return "";
364  switch (c) {
365  case 'b': os << '\b'; break;
366  case 'f': os << '\f'; break;
367  case 'n': os << '\n'; break;
368  case 'r': os << '\r'; break;
369  case 't': os << '\t'; break;
370  case '"': os << '"'; break;
371  case 'u': os << readcode(); break;
372  default: is->get(c); os << c; break;
373  }
374  } else if (c == '"') {
375  return os.str();
376  } else {
377  os << c;
378  }
379  } while (true);
380 }
381 
382 string JsonParser::readnumber(char c) {
383  ostringstream os("");
384  static int count_dn = 0;
385  do {
386  os << c;
387  c = is->peek();
388  switch (c) {
389  case '+': case '-': case '0': case '1': case '2': case '3': case '4':
390  case '5': case '6': case '7': case '8': case '9': case 'e': case 'E':
391  case '.':
392  break;
393  // read denormal value
394  case 'n': case 'a': case 'i': case 'f':
395  ++count_dn;
396  if (count_dn >=3) {
397  gx_print_warning("JsonParser", Glib::ustring::compose("DENORMAL VALUE DETECTED in %1", log_tok));
398  count_dn = 0;
399  }
400  break;
401  default:
402  return os.str();
403  }
404  is->get(c);
405  } while (is->good());
406  return "";
407 }
408 
409 JsonParser::token JsonParser::read_value_token(char c) {
410  ostringstream os("");
411  do {
412  os << c;
413  c = is->peek();
414  if (c < 'a' || c > 'z') {
415  break;
416  }
417  is->get(c);
418  } while (is->good());
419  next_str = os.str();
420  if (next_str == "null") {
421  return value_null;
422  }
423  if (next_str == "true") {
424  return value_true;
425  }
426  if (next_str == "false") {
427  return value_false;
428  }
429  return no_token;
430 }
431 
432 void JsonParser::read_next() {
433  if (next_tok == end_token)
434  return;
435  if (next_tok != no_token and next_depth == 0) {
436  next_tok = end_token;
437  return;
438  }
439  char c;
440  nl = false;
441  while (true) {
442  do {
443  is->get(c);
444  if (!is->good())
445  throw JsonExceptionEOF("eof");
446  if (c == '\n')
447  nl = true;
448  } while (c == ' ' || c == '\t' || c == '\r' || c == '\n');
449  next_pos = is->tellg();
450  switch (c) {
451  case '[': next_tok = begin_array; next_depth++; break;
452 
453  case ']': next_tok = end_array; next_depth--; break;
454 
455  case '{': next_tok = begin_object; next_depth++; break;
456 
457  case '}': next_tok = end_object; next_depth--; break;
458 
459  case ',': continue;
460 
461  case '"':
462  next_str = log_tok = readstring();
463  *is >> c;
464  if (!is->good())
465  throw JsonExceptionEOF("eof");
466  if (c == ':') {
467  next_tok = value_key;
468  } else {
469  is->unget();
470  next_tok = value_string;
471  }
472  break;
473 
474  case '-': case '0': case '1': case '2': case '3': case '4':
475  case '5': case '6': case '7': case '8': case '9':
476  next_str = readnumber(c);
477  next_tok = value_number;
478  break;
479  // read denormal value
480  case 'n': case 'a': case 'i': case 'f':
481  next_str = readnumber(c);
482  next_tok = value_number;
483  break;
484 
485  default:
486  next_tok = read_value_token(c);
487  if (next_tok == no_token) {
488  throw JsonException("bad token");
489  }
490  break;
491  }
492  break;
493  }
494 }
495 
497  if (cur_tok != end_token) {
498  if (next_tok == no_token)
499  read_next();
500  depth = next_depth;
501  cur_tok = next_tok;
502  str = next_str;
503  if (next_tok != end_token)
504  read_next();
505  }
506  if (expect != no_token)
507  check_expect(expect);
508  return cur_tok;
509 }
510 
511 bool JsonParser::read_kv(const char *key, float& v) {
512  if (str == key) {
514  v = current_value_float();
515  return true;
516  } else {
517  return false;
518  }
519 }
520 
521 bool JsonParser::read_kv(const char *key, double& v) {
522  if (str == key) {
524  v = current_value_double();
525  return true;
526  } else {
527  return false;
528  }
529 }
530 
531 bool JsonParser::read_kv(const char *key, int& i) {
532  if (str == key) {
534  i = current_value_int();
535  return true;
536  } else {
537  return false;
538  }
539 }
540 
541 bool JsonParser::read_kv(const char *key, unsigned int& i) {
542  if (str == key) {
544  i = current_value_uint();
545  return true;
546  } else {
547  return false;
548  }
549 }
550 
551 bool JsonParser::read_kv(const char *key, string& s) {
552  if (str == key) {
554  s = current_value();
555  return true;
556  } else {
557  return false;
558  }
559 }
560 
561 bool JsonParser::read_kv(const char *key, Glib::ustring& s) {
562  if (str == key) {
564  s = current_value();
565  return true;
566  } else {
567  return false;
568  }
569 }
570 
571 void JsonParser::set_streampos(streampos pos) {
572  is->seekg(pos);
573  depth = 0;
574  cur_tok = no_token;
575  nl = false;
576  next_depth = 0;
577  next_tok = no_token;
578 }
579 
581  int curdepth = depth;
582  do {
583  switch (next()) {
584  case begin_object:
585  jw.begin_object(nl);
586  break;
587  case end_object:
588  jw.end_object(nl);
589  break;
590  case begin_array:
591  jw.begin_array(nl);
592  break;
593  case end_array:
594  jw.end_array(nl);
595  break;
596  case value_string:
597  jw.write(current_value(), nl);
598  break;
599  case value_number:
600  jw.write_lit(current_value(), nl);
601  break;
602  case value_key:
603  jw.write_key(current_value().c_str(), nl);
604  break;
605  default:
606  throw JsonException("unexpected token");
607  }
608  } while (curdepth != depth);
609 }
610 
612  int curdepth = depth;
613  do {
614  if (next() == end_token) {
615  throw JsonException("unexpected eof");
616  }
617  } while (curdepth != depth);
618 }
619 
621  : JsonParser() {
622  set_stream(jp.get_stream());
623  position = get_stream()->tellg();
624  set_streampos(pos);
625 }
626 
628  get_stream()->seekg(position);
629 }
630 
631 /****************************************************************
632  ** class SettingsFileHeader
633  */
634 
635 const string SettingsFileHeader::gx_version = GX_VERSION;
636 
639  if (jp.current_value() != "gx_head_file_version") {
640  throw JsonException("invalid gx_head file header");
641  }
644  file_major = jp.current_value_int();
646  file_minor = jp.current_value_int();
648  file_gx_version = jp.current_value();
650 }
651 
653  jw.write("gx_head_file_version");
654  jw.begin_array();
655  jw.write(major); // major format version
656  jw.write(minor); // minor format version
657  jw.write(gx_version);
658  jw.end_array(true);
659 }
660 
662  jw.begin_array();
663  jw.write(major);
664  jw.write(minor);
665  jw.end_array();
666 }
667 
669  jw.begin_array();
670  jw.write(file_major);
671  jw.write(file_minor);
672  jw.end_array();
673 }
674 
678  file_major = jp.current_value_int();
680  file_minor = jp.current_value_int();
682 }
683 
685  ofstream os(name.c_str());
686  if (!os.good()) {
687  return false;
688  }
689  JsonWriter jw(&os);
690  jw.begin_array();
692  jw.end_array(true);
693  jw.close();
694  os.close();
695  return true;
696 }
697 
698 
699 /****************************************************************
700  ** class StateFile
701  */
702 
703 class JsonReader: public JsonParser {
704 public:
705  JsonReader(istream* is) : JsonParser(is) {}
706  ~JsonReader();
707  void close();
708 };
709 
711  close();
712 }
713 
715  if (is_closed()) {
716  return;
717  }
721 }
722 
724  if (is) {
725  is->seekg(0);
726  } else {
727  check_mtime(filename, mtime);
728  is = new ifstream(filename.c_str());
729  }
730  JsonReader *jp = new JsonReader(is);
732  header.read(*jp);
733  if (header.is_major_diff()) {
734  if (header.get_major() == 0) {
735  gx_print_info(_("recall settings"), _("loading converted state"));
736  } else {
738  _("recall settings"),
739  boost::format(_("major version mismatch in %1%: found %2%, expected %3%"))
740  % filename % header.get_major() % static_cast<int>(SettingsFileHeader::major));
741  }
742  }
743  return jp;
744 }
745 
746 void StateFile::set_filename(const string& fn) {
747  filename = fn;
748  delete is;
749  is = 0;
750 }
751 
753  if (filename.empty() || !mtime) {
754  return;
755  }
756  if (check_mtime(filename, mtime)) {
757  return;
758  }
759  delete is;
760  is = 0;
761 }
762 
763 
764 class ModifyState: public JsonWriter {
765 private:
766  string filename;
767  string tmpfile;
768  ofstream os;
769 public:
770  ModifyState(const string& name);
771  ~ModifyState();
772  virtual void close();
773 };
774 
775 ModifyState::ModifyState(const string& name)
776  : filename(name),
777  tmpfile(filename + "_tmp"),
778  os(tmpfile.c_str()) {
779  set_stream(&os);
780  begin_array();
782 }
783 
785  close();
786 }
787 
789  if (is_closed()) {
790  return;
791  }
792  end_array(true);
794  os.close();
795  if (!os.good()) {
796  gx_print_error(_("save preset"),
797  boost::format(_("couldn't write %1%")) % tmpfile);
798  } else {
799  int rc = rename(tmpfile.c_str(), filename.c_str());
800  if (rc != 0) {
801  gx_print_error(_("save preset"),
802  boost::format(_("couldn't rename %1% to %2%"))
803  % tmpfile % filename);
804  }
805  }
806 }
807 
809 private:
810  ifstream is;
811  JsonParser jp;
812 public:
813  ModifyStatePreservePreset(const string& name, bool *preserve_preset);
815 };
816 
817 ModifyStatePreservePreset::ModifyStatePreservePreset(const string& name, bool *preserve_preset)
818  : ModifyState(name),
819  is(name.c_str()),
820  jp(&is) {
821  bool copied = false;
822  if (is.good()) {
823  try {
825  SettingsFileHeader header;
826  header.read(jp);
827  while (jp.peek() != JsonParser::end_array) {
829  if (jp.current_value() == "current_preset") {
830  write(jp.current_value());
831  jp.copy_object(*this);
832  copied = true;
833  } else {
834  jp.skip_object();
835  }
836  }
837  } catch(JsonException& e) {
838  // just ignore
839  }
840  }
841  if (!copied) {
842  *preserve_preset = false;
843  }
844 }
845 
847 }
848 
849 JsonWriter *StateFile::create_writer(bool *preserve_preset) {
850  JsonWriter *jw;
851  if (*preserve_preset) {
852  jw = new ModifyStatePreservePreset(filename, preserve_preset);
853  } else {
854  jw = new ModifyState(filename);
855  }
856  delete is;
857  is = 0;
858  return jw;
859 }
860 
861 
862 /****************************************************************
863  ** class PresetFile
864  */
865 
867  : filename(),
868  is(0),
869  mtime(),
870  header(),
871  entries(),
872  name(),
873  tp(),
874  flags() {
875 }
876 
878  entries.clear();
879  flags = 0;
880  name = "";
883  while (jp.peek() != JsonParser::end_object) {
885  if (jp.current_value() == "name") {
887  name = jp.current_value();
888  } else if (jp.current_value() == "type") {
890  if (jp.current_value() == "scratch") {
892  } else if (jp.current_value() == "factory") {
894  } else if (jp.current_value() == "file") {
896  }
897  } else if (jp.current_value() == "mutable") {
898  jp.skip_object();
899  } else if (jp.current_value() == "flag_invalid") {
901  } else if (jp.current_value() == "flag_readonly") {
903  } else if (jp.current_value() == "flag_versiondiff") {
905  } else if (jp.current_value() == "presets") {
907  while (jp.peek() != JsonParser::end_array) {
909  entries.push_back(Position(jp.current_value(), 0));
910  }
912  } else {
914  "PresetFile", Glib::ustring::compose("%1: unknown remote key: %2", name, jp.current_value()));
915  }
916  }
918 }
919 
921  jw.begin_object();
922  jw.write_key("name");
923  jw.write(name);
924  jw.write_key("mutable");
925  jw.write(is_mutable());
926  jw.write_key("type");
927  switch (tp) {
928  case gx_system::PresetFile::PRESET_SCRATCH: jw.write("scratch"); break;
929  case gx_system::PresetFile::PRESET_FACTORY: jw.write("factory"); break;
930  case gx_system::PresetFile::PRESET_FILE: jw.write("file"); break;
931  default: jw.write("unknown"); break;
932  }
934  jw.write_key("flag_invalid");
935  jw.write(1);
936  }
938  jw.write_key("flag_readonly");
939  jw.write(1);
940  }
942  jw.write_key("flag_versiondiff");
943  jw.write(1);
944  }
945  jw.write_key("presets");
946  jw.begin_array();
947  for (int i = 0; i < size(); i++) {
948  jw.write(entries[i].name);
949  }
950  jw.end_array();
951  jw.end_object();
952 }
953 
954 bool PresetFile::set_factory(const Glib::ustring& name_, const std::string& path) {
955  check_mtime(path, mtime);
956  if (mtime == 0) {
958  _("open factory preset"),
959  boost::format(_("couldn't open %1%")) % path);
960  return false;
961  }
962  name = name_;
963  filename = path;
964  tp = PRESET_FACTORY;
965  flags = 0;
967  return true;
968 }
969 
971  try {
972  reopen();
973  } catch (gx_system::JsonException& e) {
974  gx_print_error(filename.c_str(), _("parse error"));
975  return true;
976  }
977  return is->fail();
978 }
979 
980 bool PresetFile::open_file(const Glib::ustring& name_, const std::string& path, int tp_, int flags_) {
981  name = name_;
982  filename = path;
983  tp = tp_;
984  flags = flags_;
985  if (fail()) {
987  return false;
988  }
990  check_flags();
991  return true;
992 }
993 
994 bool PresetFile::create_file(const Glib::ustring& name_, const std::string& path, int tp_, int flags_) {
995  name = name_;
996  filename = path;
997  tp = tp_;
998  flags = flags_;
1000  if (res) {
1002  check_mtime(path, mtime);
1003  } else {
1005  _("create preset bank"),
1006  boost::format(_("couldn't create %1%")) % path);
1007  }
1008  return res;
1009 }
1010 
1012  set_flag(PRESET_FLAG_READONLY, access(filename.c_str(), W_OK) != 0);
1014 }
1015 
1016 bool PresetFile::readJSON(const std::string& dirpath, JsonParser &jp, bool *mtime_diff) {
1019  name = jp.current_value();
1021  filename = Glib::build_filename(dirpath, jp.current_value());
1023  tp = jp.current_value_int();
1025  flags = jp.current_value_int();
1028  mtime = jp.current_value_int();
1030  if (!check_mtime(filename, mtime)) {
1031  *mtime_diff = true;
1032  if (mtime == 0) {
1033  gx_print_error(filename.c_str(), _("not found"));
1034  return false;
1035  }
1036  try {
1037  open();
1038  } catch (gx_system::JsonException& e) {
1040  gx_print_error(filename.c_str(), _("parse error"));
1041  return false;
1042  }
1043  set_flag(PRESET_FLAG_INVALID, false);
1044  check_flags();
1045  }
1046  return true;
1047 }
1048 
1050  assert(tp == PRESET_FILE || tp == PRESET_SCRATCH);
1051  jw.begin_array();
1052  jw.write(name);
1053  jw.write(Gio::File::create_for_path(filename)->get_basename());
1054  jw.write(tp);
1055  jw.write(flags);
1057  jw.write(static_cast<int>(mtime));
1058  jw.end_array(true);
1059 }
1060 
1062  close();
1063  entries.clear();
1064  if (filename.empty()) {
1065  return;
1066  }
1068  is = new ifstream(filename.c_str());
1069  JsonParser jp(is);
1071  header.read(jp);
1072  while (jp.peek() == JsonParser::value_string) {
1073  jp.next();
1074  if (jp.current_value() == "midi_controller") { //FIXME there should be a file signature
1075  if (jp.peek() == JsonParser::begin_array) {
1076  entries.clear();
1077  is->setstate(istream::failbit);
1079  _("open preset"),
1080  boost::format(_("%1% is a state file, not a preset file")) % filename);
1081  throw JsonException(_("This is a state file, not a preset file"));
1082  }
1083  }
1084  streampos pos = jp.get_streampos();
1085  entries.push_back(Position(jp.current_value(), pos));
1086  jp.skip_object();
1087  }
1090 }
1091 
1093  try {
1094  reopen();
1095  } catch (gx_system::JsonException& e) {
1096  gx_print_error(filename.c_str(), _("parse error"));
1097  }
1098  return entries.size();
1099 }
1100 
1102  if (filename.empty() || check_mtime(filename, mtime)) {
1103  return true;
1104  }
1105  if (!mtime) {
1106  return true;
1107  }
1108  close();
1109  return false;
1110 }
1111 
1112 void PresetFile::open(const std::string& fname) {
1113  filename = fname;
1114  open();
1115 }
1116 
1118  reopen();
1119  return header;
1120 }
1121 
1122 void PresetFile::fill_names(vector<Glib::ustring>& l) {
1123  reopen();
1124  for (vector<Position>::const_iterator i = entries.begin(); i != entries.end(); ++i) {
1125  l.push_back(i->name);
1126  }
1127 }
1128 
1129 const Glib::ustring& PresetFile::get_name(int n) {
1130  reopen();
1131  return entries.at(n).name;
1132 }
1133 
1134 int PresetFile::get_index(const Glib::ustring& name) {
1135  try {
1136  reopen();
1137  } catch (gx_system::JsonException& e) {
1138  // will be reported elsewhere
1139  return -1;
1140  }
1141  for (int i = 0; i < size(); i++) {
1142  if (name == entries[i].name) {
1143  return i;
1144  }
1145  }
1146  return -1;
1147 }
1148 
1150  reopen();
1151  JsonParser *jp = new JsonParser(is);
1152  jp->set_streampos(entries.at(n).pos);
1153  return jp;
1154 }
1155 
1156 PresetTransformer::PresetTransformer(string fname, istream* is_)
1157  : JsonWriter(),
1158  filename(fname),
1159  tmpfile(filename + "_tmp"),
1160  os(tmpfile.c_str()),
1161  is(is_),
1162  jp(is_),
1163  header() {
1164  set_stream(&os);
1165  if (!is->fail()) {
1166  is->seekg(0);
1168  header.read(jp);
1169  }
1170  begin_array();
1171  header.write(*this);
1172 }
1173 
1175  // JsonParser destructor will only run JsonParser::close()
1176  close();
1177 }
1178 
1180  if (is_closed()) {
1181  return;
1182  }
1184  delete is;
1185  is = 0;
1186  os.close();
1187  remove(tmpfile.c_str());
1188 }
1189 
1191  end_array(true);
1193  delete is;
1194  is = 0;
1195  os.close();
1196  if (!os.good()) {
1197  gx_print_error(_("save preset"),
1198  boost::format(_("couldn't write %1%")) % tmpfile);
1199  return;
1200  }
1201  int rc = rename(tmpfile.c_str(), filename.c_str());
1202  if (rc != 0) {
1203  gx_print_error(_("save preset"),
1204  boost::format(_("couldn't rename %1% to %2%"))
1205  % tmpfile % filename);
1206  }
1207 }
1208 
1210  if (is_closed()) {
1211  return;
1212  }
1213  if (!is->fail()) {
1216  }
1217  close_nocheck();
1218 }
1219 
1221 public:
1222  ModifyPreset(string filename, istream* is, const Glib::ustring& presname);
1223  ~ModifyPreset();
1224  void close();
1225  void copy_object();
1226 };
1227 
1229  close();
1230 }
1231 
1232 ModifyPreset::ModifyPreset(string fname, istream* is, const Glib::ustring& presname)
1233  : PresetTransformer(fname, is) {
1234  if (!is->fail()) {
1235  while (jp.peek() != JsonParser::end_array) {
1237  if (jp.current_value() == presname) {
1238  return;
1239  } else {
1240  write(jp.current_value());
1241  jp.copy_object(*this);
1242  }
1243  }
1244  }
1245 }
1246 
1248  if (is_closed()) {
1249  return;
1250  }
1251  if (!is->fail()) {
1252  while (jp.peek() != JsonParser::end_array) {
1254  write(jp.current_value());
1255  jp.copy_object(*this);
1256  }
1257  }
1259 }
1260 
1262  jp.copy_object(*this);
1263 }
1264 
1265 JsonWriter *PresetFile::create_writer(const Glib::ustring& name) {
1266  reopen();
1267  ModifyPreset *jw = new ModifyPreset(filename, is, name);
1268  jw->write(name);
1269  if (!is->fail()) {
1270  if (jw->jp.peek() != JsonParser::end_array) {
1271  jw->jp.skip_object(); // we are replacing a setting
1272  }
1273  }
1274  is = 0;
1275  return jw;
1276 }
1277 
1278 JsonWriter *PresetFile::create_writer_at(const Glib::ustring& pos, const Glib::ustring& name) {
1279  reopen();
1280  ModifyPreset *jw = new ModifyPreset(filename, is, pos);
1281  jw->write(name);
1282  is = 0;
1283  return jw;
1284 }
1285 
1287  reopen();
1289  is = 0;
1290  return tr;
1291 }
1292 
1293 bool PresetFile::erase(const Glib::ustring& name) {
1294  reopen();
1295  if (get_index(name) < 0) {
1296  return false;
1297  }
1298  ModifyPreset jw(filename, is, name);
1299  is = 0;
1300  jw.jp.skip_object();
1301  return true;
1302 }
1303 
1306  return false;
1307  }
1308  open(filename);
1309  return true;
1310 }
1311 
1312 bool PresetFile::rename(const Glib::ustring& name, Glib::ustring newname) {
1313  reopen();
1314  if (get_index(name) < 0) {
1315  return false;
1316  }
1317  ModifyPreset jw(filename, is, name);
1318  is = 0;
1319  jw.write(newname);
1320  jw.jp.copy_object(jw);
1321  return true;
1322 }
1323 
1324 bool PresetFile::set_name(const Glib::ustring& n, const std::string& newfile) {
1325  if (!Gio::File::create_for_path(filename)->move(Gio::File::create_for_path(newfile))) {
1326  gx_print_error(_("rename bank"),
1327  boost::format(_("couldn't move to %1%")) % newfile);
1328  return false;
1329  }
1330  name = n;
1331  filename = newfile;
1332  return true;
1333 }
1334 
1336  if (!Gio::File::create_for_path(filename)->remove()) {
1337  gx_print_error(_("remove bank"),
1338  boost::format(_("couldn't remove %1%")) % filename);
1339  return false;
1340  }
1341  filename = "";
1342  return true;
1343 }
1344 
1346  if (flags & PRESET_FLAG_INVALID) {
1347  return entries.end();
1348  }
1349  try {
1350  reopen();
1351  } catch (gx_system::JsonException& e) {
1352  gx_print_error(filename.c_str(), _("parse error"));
1353  }
1354  return entries.begin();
1355 }
1356 
1357 
1358 /****************************************************************
1359  ** class PresetBanks
1360  */
1361 
1362 static const char *std_presetname_postfix = ".gx";
1363 
1365  : banklist(), filepath(), mtime(), preset_dir() {
1366 }
1367 
1369  for (iterator i = begin(); i != end(); ++i) {
1370  delete *i;
1371  }
1372 }
1373 
1375  for (iterator i = begin(); i != end(); ++i) {
1376  delete *i;
1377  }
1378  banklist.clear();
1380  while (jp.peek() != gx_system::JsonParser::end_array) {
1382  pf->readJSON_remote(jp);
1383  banklist.push_back(pf);
1384  }
1386 }
1387 
1389  if (check_mtime(filepath, mtime)) {
1390  bool reload = false;
1391  for (iterator i = begin(); i != end(); ++i) {
1392  int tp = i->get_type();
1394  if (!i->ensure_is_current()) {
1395  try {
1396  i->reopen();
1397  i->set_flag(PRESET_FLAG_INVALID, false);
1398  } catch (gx_system::JsonException& e) {
1399  i->set_flag(PRESET_FLAG_INVALID, true);
1400  // no message, we already know the error
1401  }
1402  i->check_flags();
1403  reload = true;
1404  }
1405  }
1406  }
1407  return reload;
1408  }
1409  for (bl_type::iterator i = banklist.begin(); i != banklist.end();) {
1410  int tp = (*i)->get_type();
1412  bl_type::iterator j = i;
1413  ++i;
1414  delete *j;
1415  banklist.erase(j);
1416  } else {
1417  ++i;
1418  }
1419  }
1420  parse_bank_list(banklist.begin());
1421  return true;
1422 }
1423 
1424 void PresetBanks::parse(const std::string& bank_path, const std::string& preset_dir_,
1425  const std::string& factory_dir, const char* scratchpad_name,
1426  const char* scratchpad_file) {
1427  filepath = bank_path;
1428  preset_dir = preset_dir_;
1429  banklist.clear();
1430  parse_bank_list(banklist.end());
1431  collect_lost_banks(scratchpad_name, scratchpad_file);
1432  parse_factory_list(factory_dir);
1433 }
1434 
1435 void PresetBanks::make_valid_utf8(Glib::ustring& s) {
1436  Glib::ustring::iterator i;
1437  while (!s.validate(i)) {
1438  Glib::ustring::iterator j = i;
1439  s.replace(i,++j,1,'?');
1440  }
1441  if (s.empty()) {
1442  s = "?";
1443  }
1444 }
1445 
1446 std::string PresetBanks::add_preset_postfix(const std::string& filename) {
1447  return filename + std_presetname_postfix;
1448 }
1449 
1450 bool PresetBanks::strip_preset_postfix(std::string& name) {
1451  if (name.compare(name.size()-3, 3, std_presetname_postfix) != 0) {
1452  return false;
1453  }
1454  name = name.substr(0, name.size()-3);
1455  return true;
1456 }
1457 
1458 void PresetBanks::make_bank_unique(Glib::ustring& name, std::string *file) {
1459  int n = 1;
1460  Glib::ustring t = name;
1461  while (true) {
1462  if (file) {
1463  *file = add_preset_postfix(Glib::build_filename(preset_dir, encode_filename(name)));
1464  }
1465  if (!has_entry(name)) {
1466  if (!file || !Gio::File::create_for_path(*file)->query_exists()) {
1467  return;
1468  }
1469  }
1470  name = t + "-" + gx_system::to_string(n);
1471  n += 1;
1472  }
1473 }
1474 
1475 bool PresetBanks::has_file(const std::string& file) const {
1476  for (bl_type::const_iterator i = banklist.begin(); i != banklist.end(); ++i) {
1477  if ((*i)->get_filename() == file) {
1478  return true;
1479  }
1480  }
1481  return false;
1482 }
1483 
1484 void PresetBanks::collect_lost_banks(const char* scratchpad_name, const char* scratchpad_file) {
1485  Glib::RefPtr<Gio::FileEnumerator> en = Gio::File::create_for_path(
1486  preset_dir)->enumerate_children(G_FILE_ATTRIBUTE_STANDARD_NAME);
1487  while (true) {
1488  Glib::RefPtr<Gio::FileInfo> fi = en->next_file();
1489  if (!fi) {
1490  break;
1491  }
1492  std::string n = fi->get_name();
1493  if (n.size() <= 3 || n.substr(n.size()-3) != std_presetname_postfix) {
1494  continue;
1495  }
1496  std::string path = Glib::build_filename(preset_dir, n);
1497  if (has_file(path)) {
1498  continue;
1499  }
1500  PresetFile *f = new PresetFile();
1501  if (n == scratchpad_file) {
1502  Glib::ustring nm = scratchpad_name;
1503  make_bank_unique(nm);
1504  f->open_file(nm, path, PresetFile::PRESET_SCRATCH, 0);
1505  } else {
1507  Glib::ustring nm = decode_filename(n);
1508  make_valid_utf8(nm);
1509  make_bank_unique(nm);
1510  f->open_file(nm, path, PresetFile::PRESET_FILE, 0);
1511  }
1512  insert(f);
1513  }
1514 }
1515 
1516 
1518  if (filepath.empty()) { //FIXME remote operation hack
1519  return;
1520  }
1521  std::string tmpfile = filepath + "_tmp";
1522  ofstream os(tmpfile.c_str());
1523  gx_system::JsonWriter jw(&os);
1524  jw.begin_array(true);
1525  for (iterator i = begin(); i != end(); ++i) {
1526  int tp = i->get_type();
1528  i->writeJSON(jw);
1529  }
1530  }
1531  jw.end_array(true);
1532  jw.close();
1533  os.close();
1534  if (!os.good()) {
1535  gx_print_error(_("save banklist"),
1536  boost::format(_("couldn't write %1%")) % tmpfile);
1537  } else {
1538  int rc = ::rename(tmpfile.c_str(), filepath.c_str());
1539  if (rc != 0) {
1540  gx_print_error(_("save banklist"),
1541  boost::format(_("couldn't rename %1% to %2%"))
1542  % tmpfile % filepath);
1543  }
1544  }
1545  check_mtime(filepath, mtime);
1546 }
1547 
1548 void PresetBanks::parse_factory_list(const std::string& path) {
1549  ifstream is(Glib::build_filename(path, "dirlist.js").c_str());
1550  if (is.fail()) {
1551  gx_print_error(_("Presets"), _("factory preset list not found"));
1552  return;
1553  }
1554  gx_system::JsonParser jp(&is);
1555  PresetFile *f = 0;
1556  try {
1558  while (jp.peek() != gx_system::JsonParser::end_array) {
1561  string name = jp.current_value();
1563  string fname = Glib::build_filename(path, jp.current_value());
1564  PresetFile *f = new PresetFile();
1565  try {
1566  if (f->set_factory(name, fname)) {
1567  banklist.push_back(f);
1568  } else {
1569  delete f;
1570  }
1571  } catch (gx_system::JsonException& e) {
1572  delete f;
1573  gx_print_error(fname.c_str(), _("not found or parse error"));
1574  }
1575  f = 0;
1577  }
1580  } catch (gx_system::JsonException& e) {
1581  delete f;
1582  }
1583  jp.close();
1584  is.close();
1585 }
1586 
1587 void PresetBanks::parse_bank_list(bl_type::iterator pos) {
1588  ifstream is(filepath.c_str());
1589  if (is.fail()) {
1591  _("Presets"), boost::format(_("banks not found: '%1%'")) % filepath);
1592  return;
1593  }
1594  gx_system::JsonParser jp(&is);
1595  bool mtime_diff = false;
1596  PresetFile *f = 0;
1597  try {
1599  while (jp.peek() != gx_system::JsonParser::end_array) {
1600  f = new PresetFile();
1601  if (!f->readJSON(preset_dir, jp, &mtime_diff)) {
1602  delete f;
1603  } else {
1604  banklist.insert(pos, f);
1605  }
1606  f = 0;
1607  }
1610  } catch (gx_system::JsonException& e) {
1611  delete f;
1612  gx_print_error(filepath.c_str(), _("parse error"));
1613  }
1614  jp.close();
1615  is.close();
1616  if (mtime_diff) {
1617  save();
1618  } else {
1619  check_mtime(filepath, mtime);
1620  }
1621 }
1622 
1623 PresetFile *PresetBanks::get_file(const Glib::ustring& bank) const {
1624  for (bl_type::const_iterator i = banklist.begin(); i != banklist.end(); ++i) {
1625  if ((*i)->get_name() == bank) {
1626  return *i;
1627  }
1628  }
1629  return 0;
1630 }
1631 
1632 int PresetBanks::get_index(const Glib::ustring& bank) const {
1633  int n = 0;
1634  for (bl_type::const_iterator i = banklist.begin(); i != banklist.end(); ++i) {
1635  if ((*i)->get_name() == bank) {
1636  return n;
1637  }
1638  n += 1;
1639  }
1640  return -1;
1641 }
1642 
1643 bool PresetBanks::rename(const Glib::ustring& oldname, const Glib::ustring& newname, const std::string& newfile) {
1644  PresetFile *f = get_file(oldname);
1645  if (!f) {
1646  return false;
1647  }
1648  if (!f->set_name(newname, newfile)) {
1649  return false;
1650  }
1651  save();
1652  return true;
1653 }
1654 
1655 bool PresetBanks::remove(const Glib::ustring& bank) {
1656  PresetFile *f = get_file(bank);
1657  if (!f) {
1658  return false;
1659  }
1660  if (!f->remove_file()) {
1661  return false;
1662  }
1663  banklist.remove(f);
1664  delete f;
1665  save();
1666  return true;
1667 }
1668 
1669 void PresetBanks::reorder(const std::vector<Glib::ustring>& neworder) {
1670  bl_type::iterator j = banklist.begin();
1671  for (std::vector<Glib::ustring>::const_iterator i = neworder.begin(); i != neworder.end(); ++i) {
1672  assert(j != banklist.end());
1673  if (*i == (*j)->get_name()) {
1674  ++j;
1675  } else {
1676  for (bl_type::iterator k = j; k != banklist.end(); ++k) {
1677  if (*i == (*k)->get_name()) {
1678  banklist.splice(j, banklist, k);
1679  break;
1680  }
1681  }
1682  }
1683  }
1684  save();
1685 }
1686 
1687 Glib::ustring PresetBanks::get_name(int n) {
1688  for (iterator i = begin(); i != end(); ++i, --n) {
1689  if (n == 0) {
1690  return i->get_name();
1691  }
1692  }
1693  return "";
1694 }
1695 
1696 /****************************************************************
1697  ** class GxSettingsBase
1698  */
1699 
1702 
1703 // seq_ may not yet be initialized, only use address!
1705  : state_io(),
1706  preset_io(),
1707  statefile(),
1708  banks(),
1709  current_bank(),
1710  current_name(),
1711  seq(seq_),
1712  selection_changed(),
1713  presetlist_changed() {
1714 }
1715 
1717 }
1718 
1719 bool GxSettingsBase::loadsetting(PresetFile *p, const Glib::ustring& name) {
1720  try {
1721  if (p) {
1722  JsonParser *jp = p->create_reader(name);
1723  preset_io->read_preset(*jp, p->get_header());
1726  delete jp;
1727  gx_print_info(
1728  _("loaded preset"),
1729  boost::format(_("%1% from file %2%")) % name % p->get_filename());
1730 
1731  } else {
1736  delete jp;
1737  gx_print_info(
1738  _("loaded state"),
1739  boost::format(_("from file %1%")) % statefile.get_filename());
1740  }
1741  return seq.update_module_lists();
1742  } catch(JsonException& e) {
1743  if (p) {
1745  _("load preset"),
1746  boost::format(_("error loading %1% from file %2%")) % name % p->get_filename());
1747  } else {
1749  _("load state"),
1750  boost::format(_("error loading state from file %1%"))
1751  % statefile.get_filename());
1752  }
1753  return false;
1754  }
1755 }
1756 
1759  JsonParser *jp = 0;
1760  jp = p->create_reader(0);
1761  try {
1762  preset_io->read_online(*jp);
1763  } catch(JsonException& e) {
1765  _("load online preset"),
1766  boost::format(_("error loading online presets")) );
1767  }
1768 }
1769 
1770 void GxSettingsBase::load_preset(PresetFile* pf, const Glib::ustring& name) {
1773  JsonWriter *jw = 0;
1774  try {
1775  jw = p->create_writer(current_name);
1776  preset_io->write_preset(*jw);
1777  } catch(JsonException& e) {
1779  _("save preset"),
1780  boost::format(_("parse error in %1%"))
1781  % p->get_filename());
1782  }
1783  delete jw;
1784  }
1785  if (!pf->has_entry(name)) {
1786  gx_print_error(_("open preset"), Glib::ustring::compose("bank %1 does not contain preset %2", pf->get_name(), name));
1787  pf = 0;
1788  }
1789  if (!pf) {
1790  if (setting_is_preset()) {
1791  current_bank = "";
1792  current_name = "";
1794  }
1795  return;
1796  }
1797  current_bank = pf->get_name();
1798  current_name = name;
1799  seq.start_ramp_down();
1800  bool modules_changed = loadsetting(pf, name);
1801  seq.start_ramp_up();
1802  // if no modules changed either there was no change (then
1803  // rack_changed should not be set anyhow) or the modules
1804  // could not be installed because jack is not initialized.
1805  // In that case there is still a rack change left to be
1806  // done
1807  if (modules_changed) {
1809  }
1811 }
1812 
1814  current_bank = current_name = "";
1815  seq.start_ramp_down();
1816  bool modules_changed = loadsetting(0, current_name);
1817  seq.start_ramp_up();
1818  if (modules_changed) { // see comment in load_preset()
1820  }
1823 }
1824 
1826  current_bank = current_name = "";
1828 }
1829 
1830 void GxSettingsBase::save_to_state(bool preserve_preset) {
1831  gx_print_info("write state",boost::format("%2% [%1%]")
1832  % preserve_preset % statefile.get_filename());
1833  JsonWriter *jw = statefile.create_writer(&preserve_preset);
1834  state_io->write_state(*jw, preserve_preset);
1835  delete jw;
1836 #if 0
1837  if (!preserve_preset && setting_is_preset()) {
1840  }
1841 #endif
1842 }
1843 
1844 void GxSettingsBase::append(PresetFile& pf, const Glib::ustring& src, PresetFile& pftgt, const Glib::ustring& name) {
1845  JsonWriter *jw = 0;
1846  JsonParser *jp = 0;
1847  try {
1848  jp = pf.create_reader(src);
1849  jw = pftgt.create_writer(name);
1850  jp->copy_object(*jw);
1851  } catch(JsonException& e) {
1853  _("save preset"),
1854  boost::format(_("parse error in %1%"))
1855  % pf.get_filename());
1856  }
1857  delete jp;
1858  delete jw;
1860 }
1861 
1862 void GxSettingsBase::insert_before(PresetFile& pf, const Glib::ustring& src, PresetFile& pftgt, const Glib::ustring& pos, const Glib::ustring& name) {
1863  JsonWriter *jw = 0;
1864  JsonParser *jp = 0;
1865  try {
1866  jp = pf.create_reader(src);
1867  jw = pftgt.create_writer_at(pos, name);
1868  jp->copy_object(*jw);
1869  jw->write(pos);
1870  dynamic_cast<ModifyPreset*>(jw)->copy_object();
1871  } catch(JsonException& e) {
1873  _("save preset"),
1874  boost::format(_("parse error in %1%"))
1875  % pf.get_filename());
1876  }
1877  delete jp;
1878  delete jw;
1880 }
1881 
1882 void GxSettingsBase::insert_after(PresetFile& pf, const Glib::ustring& src, PresetFile& pftgt, const Glib::ustring& pos, const Glib::ustring& name) {
1883  int i = pftgt.get_index(pos) + 1;
1884  if (i >= pftgt.size()) {
1885  append(pf, src, pftgt, name);
1886  } else {
1887  insert_before(pf, src, pftgt, pftgt.get_name(i), name);
1888  }
1889 }
1890 
1891 void GxSettingsBase::save(PresetFile& pf, const Glib::ustring& name) {
1892  bool newentry = (pf.get_index(name) < 0);
1893  JsonWriter *jw = 0;
1894  try {
1895  jw = pf.create_writer(name);
1896  preset_io->write_preset(*jw);
1897  } catch(JsonException& e) {
1899  _("save preset"),
1900  boost::format(_("parse error in %1%"))
1901  % pf.get_filename());
1902  }
1903  delete jw;
1904  if (newentry) {
1906  }
1907  if (!setting_is_preset()
1908  || (setting_is_preset() && current_name != name)) {
1909  current_name = name;
1910  current_bank = pf.get_name();
1913  }
1914 }
1915 
1916 void GxSettingsBase::reorder_preset(PresetFile& pf, const std::vector<Glib::ustring>& neworder) {
1917  PresetTransformer *jw = 0;
1918  try {
1919  jw = pf.create_transformer();
1920  for (std::vector<Glib::ustring>::const_iterator i = neworder.begin(); i != neworder.end(); ++i) {
1921  JsonParser *jp = pf.create_reader(*i);
1922  jw->write(*i);
1923  jp->copy_object(*jw);
1924  delete jp;
1925  }
1926  jw->close_nocheck();
1927  } catch(JsonException& e) {
1929  _("reorder presetfile"),
1930  boost::format(_("parse error in %1%"))
1931  % pf.get_filename());
1932  jw->abort();
1933  }
1934  delete jw;
1935  pf.close();
1937 }
1938 
1939 void GxSettingsBase::erase_preset(PresetFile& pf, const Glib::ustring& name) {
1940  try {
1941  pf.erase(name);
1942  } catch(JsonException& e) {
1944  _("delete preset"),
1945  boost::format(_("parse error in %1%"))
1946  % pf.get_filename());
1947  }
1948  if (pf.get_name() == current_bank && name == current_name) {
1950  }
1952 }
1953 
1955  seq.start_ramp_down();
1956  bool preset_preset = false;
1957  JsonWriter *sw = statefile.create_writer(&preset_preset);
1958  state_io->write_state(*sw, preset_preset);
1959  delete sw;
1961  PresetTransformer *jw = 0;
1962  bool res = true;
1963  try {
1964  jw = pf.create_transformer();
1965  while (jw->jp.peek() != JsonParser::end_array) {
1967  jw->write(jw->jp.current_value());
1968  preset_io->copy_preset(jw->jp, jw->header, *jw);
1969  }
1970  pf.set_flag(PRESET_FLAG_VERSIONDIFF, false);
1971  } catch(JsonException& e) {
1973  _("convert presetfile"),
1974  boost::format(_("parse error in %1%"))
1975  % pf.get_filename());
1976  res = false;
1977  }
1978  delete jw;
1982  delete sp;
1983  seq.start_ramp_up();
1984  return res;
1985 }
1986 
1987 bool GxSettingsBase::rename_bank(const Glib::ustring& oldname, const Glib::ustring& newname, const std::string& newfile) {
1988  if (!banks.rename(oldname, newname, newfile)) {
1989  return false;
1990  }
1991  if (setting_is_preset() && oldname == current_bank) {
1992  current_bank = newname;
1995  }
1996  return true;
1997 }
1998 
1999 bool GxSettingsBase::remove_bank(const Glib::ustring& bank) {
2000  if (!banks.remove(bank)) {
2001  return false;
2002  }
2003  if (bank == current_bank) {
2005  }
2006  return true;
2007 }
2008 
2009 bool GxSettingsBase::rename_preset(PresetFile& pf, const Glib::ustring& oldname, const Glib::ustring& newname) {
2010  if (!pf.rename(oldname, newname)) {
2011  return false;
2012  }
2013  if (setting_is_preset() && current_bank == pf.get_name()) {
2015  if (current_name == oldname) {
2016  current_name = newname;
2018  }
2019  }
2020  return true;
2021 }
2022 
2023 } /* end of gx_system namespace */
gx_system::JsonParser::copy_object
void copy_object(JsonWriter &jw)
Definition: gx_json.cpp:580
gx_system::JsonParser::value_key
@ value_key
Definition: gx_json.h:130
gx_system::SettingsFileHeader::set_to_current
void set_to_current()
Definition: gx_json.h:244
gx_system::AbstractStateIO::~AbstractStateIO
virtual ~AbstractStateIO()
Definition: gx_json.cpp:1700
gx_system::JsonParser::get_streampos
streampos get_streampos()
Definition: gx_json.h:140
gx_system::GxSettingsBase::preset_io
AbstractPresetIO * preset_io
Definition: gx_json.h:463
gx_system::GxSettingsBase::save
void save(PresetFile &pf, const Glib::ustring &name)
Definition: gx_json.cpp:1891
gx_system::JsonParser::end_token
@ end_token
Definition: gx_json.h:123
gx_system::JsonWriter::JsonWriter
JsonWriter(ostream *o=0, bool enable_newlines=true)
Definition: gx_json.cpp:49
gx_system::AbstractStateIO::read_state
virtual void read_state(JsonParser &, const SettingsFileHeader &)=0
gx_system::JsonParser::begin_object
@ begin_object
Definition: gx_json.h:124
gx_system::PresetFile::set_name
bool set_name(const Glib::ustring &n, const std::string &newfile)
Definition: gx_json.cpp:1324
gx_system::JsonWriter::begin_object
void begin_object(bool nl=false)
Definition: gx_json.cpp:168
gx_system::SettingsFileHeader::write
static void write(JsonWriter &)
Definition: gx_json.cpp:652
gx_system::encode_filename
std::string encode_filename(const std::string &s)
Definition: gx_system.cpp:1013
gx_system::GxSettingsBase::reorder_preset
void reorder_preset(PresetFile &pf, const std::vector< Glib::ustring > &neworder)
Definition: gx_json.cpp:1916
gx_system::JsonParser::value_string
@ value_string
Definition: gx_json.h:128
gx_system::JsonReader::JsonReader
JsonReader(istream *is)
Definition: gx_json.cpp:707
gx_system::GxSettingsBase::GxSettingsBase
GxSettingsBase(gx_engine::EngineControl &seq_)
Definition: gx_json.cpp:1704
gx_system::PresetFile::reopen
void reopen()
Definition: gx_json.h:331
gx_system::JsonParser::value_false
@ value_false
Definition: gx_json.h:132
gx_system::PresetFile::create_reader
JsonParser * create_reader(int n)
Definition: gx_json.cpp:1149
gx_system::PresetFile::has_entry
bool has_entry(const Glib::ustring &name)
Definition: gx_json.h:354
gx_system::AbstractStateIO::write_state
virtual void write_state(JsonWriter &, bool)=0
gx_print_info
void gx_print_info(const char *, const std::string &)
Definition: gx_logging.cpp:183
gx_system::PresetTransformer::jp
JsonParser jp
Definition: gx_json.h:282
gx_system::SettingsFileHeader::is_current
bool is_current() const
Definition: gx_json.h:250
gx_system::PresetBanks::parse
void parse(const std::string &bank_path, const std::string &preset_dir, const std::string &factory_path, const char *scratchpad_name, const char *scratchpad_file)
Definition: gx_json.cpp:1424
gx_system::JsonParser::value_bool
@ value_bool
Definition: gx_json.h:134
gx_system::ModifyPreset::copy_object
void copy_object()
Definition: gx_json.cpp:1261
gx_system::JsonReader::~JsonReader
~JsonReader()
Definition: gx_json.cpp:710
gx_system::JsonParser::get_stream
istream * get_stream()
Definition: gx_json.h:120
gx_system::GxSettingsBase::append
void append(PresetFile &pf, const Glib::ustring &src, PresetFile &pftgt, const Glib::ustring &name)
Definition: gx_json.cpp:1844
gx_system::ModifyState::ModifyState
ModifyState(const string &name)
Definition: gx_json.cpp:775
gx_system::PresetFile::clear
bool clear()
Definition: gx_json.cpp:1304
gx_system::PresetFile::tp
int tp
Definition: gx_json.h:315
gx_system::PresetTransformer::PresetTransformer
PresetTransformer(string filename, istream *is)
Definition: gx_json.cpp:1156
gx_system::SettingsFileHeader::write_current_major_minor
static void write_current_major_minor(JsonWriter &jw)
Definition: gx_json.cpp:661
gx_system::AbstractPresetIO::read_online
virtual void read_online(JsonParser &)=0
gx_system::GxSettingsBase::insert_after
void insert_after(PresetFile &pf, const Glib::ustring &src, PresetFile &pftgt, const Glib::ustring &pos, const Glib::ustring &name)
Definition: gx_json.cpp:1882
gx_system::PresetBanks::begin
iterator begin()
Definition: gx_json.h:443
gx_system::JsonParser::~JsonParser
virtual ~JsonParser()
Definition: gx_json.cpp:273
gx_system::GxSettingsBase::selection_changed
sigc::signal< void > selection_changed
Definition: gx_json.h:469
gx_system::PresetBanks::get_index
int get_index(const Glib::ustring &bank) const
Definition: gx_json.cpp:1632
gx_system::ModifyStatePreservePreset::~ModifyStatePreservePreset
~ModifyStatePreservePreset()
Definition: gx_json.cpp:846
gx_system::GxSettingsBase::remove_bank
bool remove_bank(const Glib::ustring &bank)
Definition: gx_json.cpp:1999
gx_system::JsonParser::current_value
string current_value() const
Definition: gx_json.h:143
gx_system::PresetTransformer::~PresetTransformer
~PresetTransformer()
Definition: gx_json.cpp:1174
gx_system::GxSettingsBase::erase_preset
void erase_preset(const Glib::ustring &name)
gx_system::ModifyPreset::~ModifyPreset
~ModifyPreset()
Definition: gx_json.cpp:1228
gx_system::GxSettingsBase::loadstate
void loadstate()
Definition: gx_json.cpp:1813
gx_system::JsonWriter::write
void write(float v, bool nl=false)
Definition: gx_json.cpp:116
gx_system::JsonSubParser::JsonSubParser
JsonSubParser(JsonParser &jp, streampos pos)
Definition: gx_json.cpp:620
gx_system::GxSettingsBase::set_source_to_state
void set_source_to_state()
Definition: gx_json.cpp:1825
gx_system::StateFile::get_filename
string get_filename() const
Definition: gx_json.h:268
gx_system::GxSettingsBase::~GxSettingsBase
~GxSettingsBase()
Definition: gx_json.cpp:1716
gx_system::ModifyPreset::ModifyPreset
ModifyPreset(string filename, istream *is, const Glib::ustring &presname)
Definition: gx_json.cpp:1232
gx_system::ModifyPreset
Definition: gx_json.cpp:1220
gx_system::GxSettingsBase::banks
PresetBanks banks
Definition: gx_json.h:465
gx_print_warning
void gx_print_warning(const char *, const std::string &)
Definition: gx_logging.cpp:161
gx_system::PresetFile
Definition: gx_json.h:299
gx_system::ModifyState::~ModifyState
~ModifyState()
Definition: gx_json.cpp:784
gx_system::ModifyState
Definition: gx_json.cpp:764
gx_system::PresetFile::get_name
const Glib::ustring & get_name() const
Definition: gx_json.h:362
gx_system::GxSettingsBase::rename_bank
bool rename_bank(const Glib::ustring &oldname, const Glib::ustring &newname, const std::string &newfile)
Definition: gx_json.cpp:1987
gx_system::SettingsFileHeader::make_empty_settingsfile
static bool make_empty_settingsfile(const string &name)
Definition: gx_json.cpp:684
gx_system::PresetFile::iterator
std::vector< Position >::iterator iterator
Definition: gx_json.h:321
gx_system::PresetBanks::has_entry
bool has_entry(const Glib::ustring &bank) const
Definition: gx_json.h:450
gx_system::AbstractPresetIO::copy_preset
virtual void copy_preset(JsonParser &, const SettingsFileHeader &, JsonWriter &)=0
gx_system::PresetFile::PRESET_FACTORY
@ PRESET_FACTORY
Definition: gx_json.h:301
gx_system::JsonParser::value_null
@ value_null
Definition: gx_json.h:131
gx_system::PresetTransformer::close_nocheck
void close_nocheck()
Definition: gx_json.cpp:1190
gx_system::ModifyState::close
virtual void close()
Definition: gx_json.cpp:788
gx_system::JsonException
Definition: gx_json.h:40
gx_system::JsonParser::check_expect
void check_expect(token expect)
Definition: gx_json.h:142
gx_system::JsonParser::close
virtual void close()
Definition: gx_json.cpp:277
max
#define max(x, y)
Definition: gx_faust_support.h:5
gx_system::JsonParser::no_token
@ no_token
Definition: gx_json.h:122
gx_system::PresetBanks::insert
void insert(PresetFile *f)
Definition: gx_json.h:449
gx_system::JsonException::what_str
Glib::ustring what_str
Definition: gx_json.h:45
gx_system::to_string
std::string to_string(const T &t)
Definition: gx_system.h:529
gx_system::PresetBanks::iterator
Definition: gx_json.h:425
gx_system::GxSettingsBase::convert_preset
bool convert_preset(PresetFile &pf)
Definition: gx_json.cpp:1954
gx_system::JsonWriter::end_object
void end_object(bool nl=false)
Definition: gx_json.cpp:176
gx_system::GxSettingsBase::statefile
StateFile statefile
Definition: gx_json.h:464
gx_system::JsonWriter::close
virtual void close()
Definition: gx_json.cpp:68
gx_system::PresetFile::PresetFile
PresetFile()
Definition: gx_json.cpp:866
gx_system::decode_filename
std::string decode_filename(const std::string &s)
Definition: gx_system.cpp:1048
gx_system::PresetFile::filename
std::string filename
Definition: gx_json.h:309
gx_system::JsonSubParser::~JsonSubParser
~JsonSubParser()
Definition: gx_json.cpp:627
gx_system::JsonParser::set_stream
void set_stream(istream *i)
Definition: gx_json.h:119
gx_system::SettingsFileHeader::read
void read(JsonParser &)
Definition: gx_json.cpp:637
gx_system::PresetBanks::make_valid_utf8
static void make_valid_utf8(Glib::ustring &s)
Definition: gx_json.cpp:1435
gx_system::JsonParser::JsonParser
JsonParser(istream *i=0)
Definition: gx_json.cpp:261
gx_system::PresetBanks::has_file
bool has_file(const std::string &file) const
Definition: gx_json.cpp:1475
gx_system::SettingsFileHeader
Definition: gx_json.h:224
gx_system::JsonWriter::write_null
void write_null(bool nl=false)
Definition: gx_json.h:94
gx_system::JsonParser::next
token next(token expect=no_token)
Definition: gx_json.cpp:496
gx_system::PresetFile::is
ifstream * is
Definition: gx_json.h:310
gx_system::GxSettingsBase::state_io
AbstractStateIO * state_io
Definition: gx_json.h:462
gx_system::JsonParser::current_value_double
double current_value_double()
Definition: gx_json.h:152
gx_system::GxSettingsBase::presetlist_changed
sigc::signal< void > presetlist_changed
Definition: gx_json.h:470
gx_system::check_mtime
bool check_mtime(const std::string &filename, time_t &mtime)
Definition: gx_json.cpp:31
gx_system::GxSettingsBase::rename_preset
bool rename_preset(PresetFile &pf, const Glib::ustring &oldname, const Glib::ustring &newname)
Definition: gx_json.cpp:2009
gx_system::PresetFile::set_flag
void set_flag(int flag, bool v)
Definition: gx_json.h:360
gx_system::GxSettingsBase::current_bank
Glib::ustring current_bank
Definition: gx_json.h:466
gx_engine::EngineControl::wait_ramp_down_finished
virtual void wait_ramp_down_finished()=0
gx_system::PresetBanks::readJSON_remote
void readJSON_remote(gx_system::JsonParser &jp)
Definition: gx_json.cpp:1374
gx_system::PresetFile::get_name
const Glib::ustring & get_name(int n)
Definition: gx_json.cpp:1129
gx_system::JsonWriter
Definition: gx_json.h:55
gx_system::PresetBanks::get_file
PresetFile * get_file(const Glib::ustring &bank) const
Definition: gx_json.cpp:1623
gx_system::PresetBanks::check_reparse
bool check_reparse()
Definition: gx_json.cpp:1388
gx_system::PresetFile::open
void open()
Definition: gx_json.cpp:1061
gx_system::PresetFile::create_writer
JsonWriter * create_writer(int n)
Definition: gx_json.h:346
gx_system::JsonParser::throw_unexpected
void throw_unexpected(token expect)
Definition: gx_json.cpp:303
gx_engine::EngineControl::start_ramp_up
virtual void start_ramp_up()=0
gx_system::PresetBanks::reorder
void reorder(const std::vector< Glib::ustring > &neworder)
Definition: gx_json.cpp:1669
gx_system::PresetFile::PRESET_FILE
@ PRESET_FILE
Definition: gx_json.h:301
gx_system::GxSettingsBase::insert_before
void insert_before(PresetFile &pf, const Glib::ustring &src, PresetFile &pftgt, const Glib::ustring &pos, const Glib::ustring &name)
Definition: gx_json.cpp:1862
gx_system::PresetTransformer::close
void close()
Definition: gx_json.cpp:1209
gx_system::JsonParser::is_closed
bool is_closed()
Definition: gx_json.h:118
gx_system::PresetFile::open_file
bool open_file(const Glib::ustring &name, const std::string &path, int tp, int flags)
Definition: gx_json.cpp:980
gx_system::SettingsFileHeader::major
@ major
Definition: gx_json.h:236
gx_system::JsonParser
Definition: gx_json.h:112
gx_engine::EngineControl::start_ramp_down
virtual void start_ramp_down()=0
gx_system::ModifyPreset::close
void close()
Definition: gx_json.cpp:1247
gx_system::PresetFile::create_writer_at
JsonWriter * create_writer_at(const Glib::ustring &pos, const Glib::ustring &name)
Definition: gx_json.cpp:1278
gx_engine::EngineControl::clear_rack_changed
void clear_rack_changed()
Definition: gx_engine_audio.cpp:546
gx_system::PresetFile::mtime
time_t mtime
Definition: gx_json.h:311
gx_system::PresetFile::create_transformer
PresetTransformer * create_transformer()
Definition: gx_json.cpp:1286
gx_print_error
void gx_print_error(const char *, const std::string &)
Definition: gx_logging.cpp:166
gx_system::PresetFile::size
int size()
Definition: gx_json.cpp:1092
gx_system::JsonParser::begin_array
@ begin_array
Definition: gx_json.h:126
gx_system::PresetFile::ensure_is_current
bool ensure_is_current()
Definition: gx_json.cpp:1101
gx_system::PresetFile::get_filename
const std::string & get_filename() const
Definition: gx_json.h:337
gx_system::PresetFile::readJSON
bool readJSON(const std::string &dirpath, JsonParser &jp, bool *mtime_diff)
Definition: gx_json.cpp:1016
gx_system::PRESET_FLAG_INVALID
@ PRESET_FLAG_INVALID
Definition: gx_json.h:294
gx_system::JsonReader::close
void close()
Definition: gx_json.cpp:714
gx_system::PresetFile::begin
iterator begin()
Definition: gx_json.cpp:1345
gx_system::PresetBanks::make_bank_unique
void make_bank_unique(Glib::ustring &name, std::string *file=0)
Definition: gx_json.cpp:1458
gx_system::JsonParser::read_kv
bool read_kv(const char *key, float &v)
Definition: gx_json.cpp:511
gx_system::JsonWriter::begin_array
void begin_array(bool nl=false)
Definition: gx_json.cpp:184
gx_system::PresetFile::flags
int flags
Definition: gx_json.h:316
gx_system::PresetFile::fail
bool fail()
Definition: gx_json.cpp:970
gx_system::SettingsFileHeader::write_major_minor
void write_major_minor(JsonWriter &jw)
Definition: gx_json.cpp:668
gx_system::PresetFile::get_header
const SettingsFileHeader & get_header()
Definition: gx_json.cpp:1117
gx_system::PresetFile::get_type
int get_type() const
Definition: gx_json.h:361
gx_system::JsonParser::end_array
@ end_array
Definition: gx_json.h:127
gx_system::JsonWriter::set_stream
void set_stream(ostream *o)
Definition: gx_json.h:70
gx_system::PRESET_FLAG_READONLY
@ PRESET_FLAG_READONLY
Definition: gx_json.h:293
gx_system::JsonWriter::~JsonWriter
virtual ~JsonWriter()
Definition: gx_json.cpp:55
gx_system::PresetFile::name
Glib::ustring name
Definition: gx_json.h:314
gx_system::JsonParser::value_true
@ value_true
Definition: gx_json.h:133
gx_system::JsonParser::end_object
@ end_object
Definition: gx_json.h:125
gx_system::GxSettingsBase::current_name
Glib::ustring current_name
Definition: gx_json.h:467
gx_engine::EngineControl
Definition: gx_modulesequencer.h:238
gx_system::JsonReader
Definition: gx_json.cpp:703
gx_system::SettingsFileHeader::is_major_diff
bool is_major_diff() const
Definition: gx_json.h:248
gx_system::PresetFile::readJSON_remote
void readJSON_remote(JsonParser &jp)
Definition: gx_json.cpp:877
gx_system::JsonParser::token
token
Definition: gx_json.h:121
gx_system::SettingsFileHeader::gx_version
static const string gx_version
Definition: gx_json.h:239
gx_system::PresetBanks::PresetBanks
PresetBanks()
Definition: gx_json.cpp:1364
gx_system::PresetFile::writeJSON_remote
void writeJSON_remote(JsonWriter &jw)
Definition: gx_json.cpp:920
gx_system::ModifyStatePreservePreset
Definition: gx_json.cpp:808
gx_system
Definition: gx_json.h:33
gx_system::StateFile::get_header
const SettingsFileHeader & get_header() const
Definition: gx_json.h:267
gx_system::JsonParser::current_value_uint
unsigned int current_value_uint()
Definition: gx_json.h:145
gx_system::JsonStringWriter::send_notify_end
void send_notify_end()
Definition: gx_json.cpp:236
gx_system::PresetBanks::strip_preset_postfix
static bool strip_preset_postfix(std::string &name)
Definition: gx_json.cpp:1450
gx_system::SettingsFileHeader::read_major_minor
void read_major_minor(JsonParser &jp)
Definition: gx_json.cpp:675
gx_system::JsonParser::value_number
@ value_number
Definition: gx_json.h:129
gx_system::PresetTransformer::header
SettingsFileHeader header
Definition: gx_json.h:283
gx_system::PresetBanks::get_name
Glib::ustring get_name(int n)
Definition: gx_json.cpp:1687
gx_system::SettingsFileHeader::minor
@ minor
Definition: gx_json.h:237
gx_system::PresetFile::Position
Definition: gx_json.h:303
gx_system::GxSettingsBase::load_online_presets
void load_online_presets()
Definition: gx_json.cpp:1757
gx_system::AbstractPresetIO::read_preset
virtual void read_preset(JsonParser &, const SettingsFileHeader &)=0
gx_system::GxSettingsBase::load_preset
void load_preset(PresetFile *pf, const Glib::ustring &name)
Definition: gx_json.cpp:1770
gx_system::JsonParser::current_value_int
int current_value_int()
Definition: gx_json.h:144
gx_system::AbstractPresetIO::commit_preset
virtual void commit_preset()=0
gx_system::ModifyStatePreservePreset::ModifyStatePreservePreset
ModifyStatePreservePreset(const string &name, bool *preserve_preset)
Definition: gx_json.cpp:817
gx_system::GxSettingsBase::save_to_state
void save_to_state(bool preserve_preset=false)
Definition: gx_json.cpp:1830
gx_system::PresetFile::erase
bool erase(const Glib::ustring &name)
Definition: gx_json.cpp:1293
gx_system::StateFile::create_reader
JsonParser * create_reader()
Definition: gx_json.cpp:723
gx_system::PresetBanks::end
iterator end()
Definition: gx_json.h:444
gx_engine::EngineControl::update_module_lists
virtual bool update_module_lists()=0
gx_system::JsonParser::current_value_float
float current_value_float()
Definition: gx_json.h:146
gx_system::PresetFile::check_flags
void check_flags()
Definition: gx_json.cpp:1011
gx_system::PresetFile::header
SettingsFileHeader header
Definition: gx_json.h:312
gx_system::JsonParser::reset
void reset()
Definition: gx_json.cpp:250
gx_system::StateFile::create_writer
JsonWriter * create_writer(bool *preserve_preset)
Definition: gx_json.cpp:849
gx_system::JsonParser::peek
token peek()
Definition: gx_json.h:139
gx_system::JsonWriter::write_key
void write_key(const char *p, bool nl=false)
Definition: gx_json.cpp:200
gx_system::JsonParser::set_streampos
void set_streampos(streampos pos)
Definition: gx_json.cpp:571
gx_system::AbstractPresetIO::write_preset
virtual void write_preset(JsonWriter &)=0
gx_system::PresetFile::set_factory
bool set_factory(const Glib::ustring &name_, const std::string &path)
Definition: gx_json.cpp:954
engine.h
gx_system::JsonWriter::reset
void reset()
Definition: gx_json.cpp:59
gx_system::AbstractPresetIO::~AbstractPresetIO
virtual ~AbstractPresetIO()
Definition: gx_json.cpp:1701
gx_system::GxSettingsBase::loadsetting
bool loadsetting(PresetFile *p, const Glib::ustring &name)
Definition: gx_json.cpp:1719
gx_system::GxSettingsBase::get_current_bank_file
PresetFile * get_current_bank_file()
Definition: gx_json.h:483
gx_system::JsonParser::skip_object
void skip_object()
Definition: gx_json.cpp:611
gx_system::PresetTransformer::is
istream * is
Definition: gx_json.h:280
gx_system::JsonWriter::flush
void flush()
Definition: gx_json.cpp:213
gx_system::JsonParser::get_token_name
const char * get_token_name(token tok)
Definition: gx_json.cpp:284
gx_system::JsonStringWriter::send_notify_begin
void send_notify_begin(const char *method)
Definition: gx_json.cpp:226
gx_system::PresetFile::get_index
int get_index(const Glib::ustring &name)
Definition: gx_json.cpp:1134
gx_system::PresetBanks::~PresetBanks
~PresetBanks()
Definition: gx_json.cpp:1368
gx_system::GxSettingsBase::seq
gx_engine::EngineControl & seq
Definition: gx_json.h:468
gx_system::PresetFile::remove_file
bool remove_file()
Definition: gx_json.cpp:1335
gx_system::StateFile::ensure_is_current
void ensure_is_current()
Definition: gx_json.cpp:752
gx_system::PresetFile::PRESET_SCRATCH
@ PRESET_SCRATCH
Definition: gx_json.h:301
gx_system::AbstractStateIO::commit_state
virtual void commit_state()=0
gx_system::unicode2utf8
const char * unicode2utf8(unsigned int input)
Definition: gx_json.cpp:312
gx_system::JsonException::JsonException
JsonException(const Glib::ustring &desc)
Definition: gx_json.cpp:246
gx_system::JsonWriter::end_array
void end_array(bool nl=false)
Definition: gx_json.cpp:192
gx_system::PresetFile::entries
std::vector< Position > entries
Definition: gx_json.h:313
gx_system::PresetBanks::remove
bool remove(const Glib::ustring &bank)
Definition: gx_json.cpp:1655
gx_system::PresetFile::create_file
bool create_file(const Glib::ustring &name, const std::string &path, int tp, int flags)
Definition: gx_json.cpp:994
gx_system::SettingsFileHeader::get_major
int get_major() const
Definition: gx_json.h:245
gx_system::PresetBanks::add_preset_postfix
static std::string add_preset_postfix(const std::string &filename)
Definition: gx_json.cpp:1446
gx_system::PresetFile::is_mutable
bool is_mutable() const
Definition: gx_json.h:367
gx_system::PresetBanks::rename
bool rename(const Glib::ustring &oldname, const Glib::ustring &newname, const std::string &newfile)
Definition: gx_json.cpp:1643
gx_system::PresetTransformer
Definition: gx_json.h:274
gx_system::JsonWriter::write_lit
void write_lit(const string &s, bool nl=false)
Definition: gx_json.cpp:140
gx_system::JsonWriter::is_closed
bool is_closed()
Definition: gx_json.h:74
gx_system::PresetTransformer::abort
void abort()
Definition: gx_json.cpp:1179
gx_system::PresetBanks::save
void save()
Definition: gx_json.cpp:1517
gx_system::PresetFile::close
void close()
Definition: gx_json.h:333
gx_system::PresetFile::writeJSON
void writeJSON(JsonWriter &jw)
Definition: gx_json.cpp:1049
gx_system::StateFile::set_filename
void set_filename(const string &fn)
Definition: gx_json.cpp:746
gx_system::GxSettingsBase::setting_is_preset
bool setting_is_preset()
Definition: gx_json.h:489
gx_system::PresetFile::fill_names
void fill_names(vector< Glib::ustring > &)
Definition: gx_json.cpp:1122
gx_system::PresetFile::rename
bool rename(const Glib::ustring &name, Glib::ustring newname)
Definition: gx_json.cpp:1312
gx_system::PRESET_FLAG_VERSIONDIFF
@ PRESET_FLAG_VERSIONDIFF
Definition: gx_json.h:292