Audacity  3.0.3
ProjectSerializer.cpp
Go to the documentation of this file.
1 /**********************************************************************
2 
3  Audacity: A Digital Audio Editor
4  Audacity(R) is copyright (c) 1999-2010 Audacity Team.
5  License: GPL v2. See License.txt.
6 
7  ProjectSerializer.cpp
8 
9 *******************************************************************//********************************************************************/
15 
16 
17 #include "ProjectSerializer.h"
18 
19 #include <algorithm>
20 #include <cstdint>
21 #include <mutex>
22 #include <wx/ustring.h>
23 
27 
28 // Simple "binary xml" format used exclusively for project documents.
29 //
30 // It is not intended that the user view or modify the file.
31 //
32 // It IS intended that very little work be done during auto save, so numbers
33 // and strings are written in their native format. They will be converted
34 // during recovery.
35 //
36 // The file has 3 main sections:
37 //
38 // character size 1 (UTF-8), 2 (UTF-16) or 4 (UTF-32)
39 // name dictionary dictionary of all names used in the document
40 // data fields the "encoded" XML document
41 //
42 // If a subtree is added, it will be preceded with FT_Push to tell the decoder
43 // to preserve the active dictionary. The decoder will then restore the
44 // dictionary when an FT_Pop is encountered. Nesting is unlimited.
45 //
46 // To save space, each name (attribute or element) encountered is stored in
47 // the name dictionary and replaced with the assigned 2-byte identifier.
48 //
49 // All strings are in native unicode format, 2-byte or 4-byte.
50 //
51 // All name "lengths" are 2-byte signed, so are limited to 32767 bytes long.
52 // All string/data "lengths" are 4-byte signed.
53 
55 {
56  FT_CharSize, // type, ID, value
57  FT_StartTag, // type, ID
58  FT_EndTag, // type, ID
59  FT_String, // type, ID, string length, string
60  FT_Int, // type, ID, value
61  FT_Bool, // type, ID, value
62  FT_Long, // type, ID, value
63  FT_LongLong, // type, ID, value
64  FT_SizeT, // type, ID, value
65  FT_Float, // type, ID, value, digits
66  FT_Double, // type, ID, value, digits
67  FT_Data, // type, string length, string
68  FT_Raw, // type, string length, string
69  FT_Push, // type only
70  FT_Pop, // type only
71  FT_Name // type, ID, name length, name
72 };
73 
74 // Static so that the dict can be reused each time.
75 //
76 // If entries get added later, like when an envelope node (for example)
77 // is written and then the envelope is later removed, the dict will still
78 // contain the envelope name, but that's not a problem.
79 
81 wxMemoryBuffer ProjectSerializer::mDict;
82 
84 {
85  return
86 XO("This recovery file was saved by Audacity 2.3.0 or before.\n"
87  "You need to run that version of Audacity to recover the project." );
88 }
89 
90 namespace {
91  // Aliases for the FIXED-WIDTH integer types that are used in the file
92  // format.
93 
94  // Chosen so that among the four build types (32 bit Windows, 64
95  // bit Windows, 64 bit Mac clang, Linux g++) presently done (3.0.0
96  // development), we use the narrowest width of the type on any of them, so
97  // that anything saved on one build will be read back identically on all
98  // builds. (Although this means that very large values on some systems might
99  // be saved and then read back with loss.)
100 
101  // In fact the only types for which this matters are long (only 32 bits on
102  // 32 and 64 bit Windows) and size_t (only 32 bits on 32 bit Windows).
103 
104  using UShort = std::uint16_t;
105  using Int = std::int32_t;
106 
107  using Long = std::int32_t; // To save long values
108  using ULong = std::uint32_t; // To save size_t values
109 
110  using LongLong = std::int64_t;
111 
112  // Detect this computer's endianness
114  {
115  const std::uint32_t x = 1u;
116  return
117  static_cast<const unsigned char*>(static_cast<const void*>(&x))[0];
118  // We will assume the same for other widths!
119  }
120  // In C++20 this could be
121  // constexpr bool IsLittleEndian = (std::endian::native == std::endian::little);
122  // static_assert( IsLittleEndian || (std::endian::native == std::endian::big),
123  // "Oh no! I'm mixed-endian!" );
124 
125  // Functions that can read and write native integer types to a canonicalized
126  // little-endian file format. (We don't bother to do the same for floating
127  // point numbers.)
128 
129  // Write native little-endian to little-endian file format
130  template< typename Number >
131  void WriteLittleEndian( wxMemoryBuffer &out, Number value )
132  {
133  out.AppendData( &value, sizeof(value) );
134  }
135 
136  // Write native big-endian to little-endian file format
137  template< typename Number >
138  void WriteBigEndian( wxMemoryBuffer &out, Number value )
139  {
140  auto begin = static_cast<unsigned char*>( static_cast<void*>( &value ) );
141  std::reverse( begin, begin + sizeof( value ) );
142  out.AppendData( &value, sizeof(value) );
143  }
144 
145  // Read little-endian file format to native little-endian
146  template< typename Number >
147  Number ReadLittleEndian( wxMemoryInputStream &in )
148  {
149  Number result;
150  in.Read( &result, sizeof(result) );
151  return result;
152  }
153 
154  // Read little-endian file format to native big-endian
155  template< typename Number >
156  Number ReadBigEndian( wxMemoryInputStream &in )
157  {
158  Number result;
159  in.Read( &result, sizeof(result) );
160  auto begin = static_cast<unsigned char*>( static_cast<void*>( &result ) );
161  std::reverse( begin, begin + sizeof( result ) );
162  return result;
163  }
164 
165  // Choose between implementations!
166  static const auto WriteUShort = IsLittleEndian()
167  ? &WriteLittleEndian<UShort> : &WriteBigEndian<UShort>;
168  static const auto WriteInt = IsLittleEndian()
169  ? &WriteLittleEndian<Int> : &WriteBigEndian<Int>;
170  static const auto WriteLong = IsLittleEndian()
171  ? &WriteLittleEndian<Long> : &WriteBigEndian<Long>;
172  static const auto WriteULong = IsLittleEndian()
173  ? &WriteLittleEndian<ULong> : &WriteBigEndian<ULong>;
174  static const auto WriteLongLong = IsLittleEndian()
175  ? &WriteLittleEndian<LongLong> : &WriteBigEndian<LongLong>;
176 
177  static const auto ReadUShort = IsLittleEndian()
178  ? &ReadLittleEndian<UShort> : &ReadBigEndian<UShort>;
179  static const auto ReadInt = IsLittleEndian()
180  ? &ReadLittleEndian<Int> : &ReadBigEndian<Int>;
181  static const auto ReadLong = IsLittleEndian()
182  ? &ReadLittleEndian<Long> : &ReadBigEndian<Long>;
183  static const auto ReadULong = IsLittleEndian()
184  ? &ReadLittleEndian<ULong> : &ReadBigEndian<ULong>;
185  static const auto ReadLongLong = IsLittleEndian()
186  ? &ReadLittleEndian<LongLong> : &ReadBigEndian<LongLong>;
187 
188  // Functions to read and write certain lengths -- maybe we will change
189  // our choices for widths or signedness?
190 
191  using Length = Int; // Instead, as wide as size_t?
192  static const auto WriteLength = WriteInt;
193  static const auto ReadLength = ReadInt;
194 
195  using Digits = Int; // Instead, just an unsigned char?
196  static const auto WriteDigits = WriteInt;
197  static const auto ReadDigits = ReadInt;
198 }
199 
201 {
202  mDict.SetBufSize(allocSize);
203  mBuffer.SetBufSize(allocSize);
204 
205  static std::once_flag flag;
206  std::call_once(flag, []{
207  // Just once per run, store header information in the unique static
208  // dictionary that will be written into each project that is saved.
209  // Store the size of "wxStringCharType" so we can convert during recovery
210  // in case the file is used on a system with a different character size.
211  char size = sizeof(wxStringCharType);
212  mDict.AppendByte(FT_CharSize);
213  mDict.AppendData(&size, 1);
214  });
215 
216  mDictChanged = false;
217 }
218 
220 {
221 }
222 
223 void ProjectSerializer::StartTag(const wxString & name)
224 {
225  mBuffer.AppendByte(FT_StartTag);
226  WriteName(name);
227 }
228 
229 void ProjectSerializer::EndTag(const wxString & name)
230 {
231  mBuffer.AppendByte(FT_EndTag);
232  WriteName(name);
233 }
234 
235 void ProjectSerializer::WriteAttr(const wxString & name, const wxChar *value)
236 {
237  WriteAttr(name, wxString(value));
238 }
239 
240 void ProjectSerializer::WriteAttr(const wxString & name, const wxString & value)
241 {
242  mBuffer.AppendByte(FT_String);
243  WriteName(name);
244 
245  const Length len = value.length() * sizeof(wxStringCharType);
246  WriteLength( mBuffer, len );
247  mBuffer.AppendData(value.wx_str(), len);
248 }
249 
250 void ProjectSerializer::WriteAttr(const wxString & name, int value)
251 {
252  mBuffer.AppendByte(FT_Int);
253  WriteName(name);
254 
255  WriteInt( mBuffer, value );
256 }
257 
258 void ProjectSerializer::WriteAttr(const wxString & name, bool value)
259 {
260  mBuffer.AppendByte(FT_Bool);
261  WriteName(name);
262 
263  mBuffer.AppendByte(value);
264 }
265 
266 void ProjectSerializer::WriteAttr(const wxString & name, long value)
267 {
268  mBuffer.AppendByte(FT_Long);
269  WriteName(name);
270 
271  WriteLong( mBuffer, value );
272 }
273 
274 void ProjectSerializer::WriteAttr(const wxString & name, long long value)
275 {
276  mBuffer.AppendByte(FT_LongLong);
277  WriteName(name);
278 
279  WriteLongLong( mBuffer, value );
280 }
281 
282 void ProjectSerializer::WriteAttr(const wxString & name, size_t value)
283 {
284  mBuffer.AppendByte(FT_SizeT);
285  WriteName(name);
286 
287  WriteULong( mBuffer, value );
288 }
289 
290 void ProjectSerializer::WriteAttr(const wxString & name, float value, int digits)
291 {
292  mBuffer.AppendByte(FT_Float);
293  WriteName(name);
294 
295  mBuffer.AppendData(&value, sizeof(value));
296  WriteDigits( mBuffer, digits );
297 }
298 
299 void ProjectSerializer::WriteAttr(const wxString & name, double value, int digits)
300 {
301  mBuffer.AppendByte(FT_Double);
302  WriteName(name);
303 
304  mBuffer.AppendData(&value, sizeof(value));
305  WriteDigits( mBuffer, digits );
306 }
307 
308 void ProjectSerializer::WriteData(const wxString & value)
309 {
310  mBuffer.AppendByte(FT_Data);
311 
312  Length len = value.length() * sizeof(wxStringCharType);
313  WriteLength( mBuffer, len );
314  mBuffer.AppendData(value.wx_str(), len);
315 }
316 
317 void ProjectSerializer::Write(const wxString & value)
318 {
319  mBuffer.AppendByte(FT_Raw);
320  Length len = value.length() * sizeof(wxStringCharType);
321  WriteLength( mBuffer, len );
322  mBuffer.AppendData(value.wx_str(), len);
323 }
324 
326 {
327  mBuffer.AppendByte(FT_Push);
328 
329  mBuffer.AppendData(value.mDict.GetData(), value.mDict.GetDataLen());
330  mBuffer.AppendData(value.mBuffer.GetData(), value.mBuffer.GetDataLen());
331 
332  mBuffer.AppendByte(FT_Pop);
333 }
334 
335 void ProjectSerializer::WriteName(const wxString & name)
336 {
337  wxASSERT(name.length() * sizeof(wxStringCharType) <= SHRT_MAX);
338  UShort id;
339 
340  auto nameiter = mNames.find(name);
341  if (nameiter != mNames.end())
342  {
343  id = nameiter->second;
344  }
345  else
346  {
347  // mNames is static. This appends each name to static mDict only once
348  // in each run.
349  UShort len = name.length() * sizeof(wxStringCharType);
350 
351  id = mNames.size();
352  mNames[name] = id;
353 
354  mDict.AppendByte(FT_Name);
355  WriteUShort( mDict, id );
356  WriteUShort( mDict, len );
357  mDict.AppendData(name.wx_str(), len);
358 
359  mDictChanged = true;
360  }
361 
362  WriteUShort( mBuffer, id );
363 }
364 
365 const wxMemoryBuffer &ProjectSerializer::GetDict() const
366 {
367  return mDict;
368 }
369 
370 const wxMemoryBuffer &ProjectSerializer::GetData() const
371 {
372  return mBuffer;
373 }
374 
376 {
377  return mBuffer.GetDataLen() == 0;
378 }
379 
381 {
382  return mDictChanged;
383 }
384 
385 // See ProjectFileIO::LoadProject() for explanation of the blockids arg
386 wxString ProjectSerializer::Decode(const wxMemoryBuffer &buffer)
387 {
388  wxMemoryInputStream in(buffer.GetData(), buffer.GetDataLen());
389 
390  XMLStringWriter out;
391 
392  std::vector<char> bytes;
393  IdMap mIds;
394  std::vector<IdMap> mIdStack;
395  char mCharSize = 0;
396 
397  mIds.clear();
398 
399  struct Error{}; // exception type for short-range try/catch
400  auto Lookup = [&mIds]( UShort id ) -> const wxString &
401  {
402  auto iter = mIds.find( id );
403  if (iter == mIds.end())
404  {
405  throw Error{};
406  }
407  return iter->second;
408  };
409 
410  auto ReadString = [&mCharSize, &in, &bytes](int len) -> wxString
411  {
412  bytes.reserve( len + 4 );
413  auto data = bytes.data();
414  in.Read( data, len );
415  // Make a null terminator of the widest type
416  memset( data + len, '\0', 4 );
417  wxUString str;
418 
419  switch (mCharSize)
420  {
421  case 1:
422  str.assignFromUTF8(data, len);
423  break;
424 
425  case 2:
426  str.assignFromUTF16((wxChar16 *) data, len / 2);
427  break;
428 
429  case 4:
430  str = wxU32CharBuffer::CreateNonOwned((wxChar32 *) data, len / 4);
431  break;
432 
433  default:
434  wxASSERT_MSG(false, wxT("Characters size not 1, 2, or 4"));
435  break;
436  }
437 
438  return str;
439  };
440 
441  try
442  {
443  while (!in.Eof())
444  {
445  UShort id;
446 
447  switch (in.GetC())
448  {
449  case FT_Push:
450  {
451  mIdStack.push_back(mIds);
452  mIds.clear();
453  }
454  break;
455 
456  case FT_Pop:
457  {
458  mIds = mIdStack.back();
459  mIdStack.pop_back();
460  }
461  break;
462 
463  case FT_Name:
464  {
465  id = ReadUShort( in );
466  auto len = ReadUShort( in );
467  mIds[id] = ReadString(len);
468  }
469  break;
470 
471  case FT_StartTag:
472  {
473  id = ReadUShort( in );
474 
475  out.StartTag(Lookup(id));
476  }
477  break;
478 
479  case FT_EndTag:
480  {
481  id = ReadUShort( in );
482 
483  out.EndTag(Lookup(id));
484  }
485  break;
486 
487  case FT_String:
488  {
489  id = ReadUShort( in );
490  int len = ReadLength( in );
491  out.WriteAttr(Lookup(id), ReadString(len));
492  }
493  break;
494 
495  case FT_Float:
496  {
497  float val;
498 
499  id = ReadUShort( in );
500  in.Read(&val, sizeof(val));
501  int dig = ReadDigits( in );
502 
503  out.WriteAttr(Lookup(id), val, dig);
504  }
505  break;
506 
507  case FT_Double:
508  {
509  double val;
510 
511  id = ReadUShort( in );
512  in.Read(&val, sizeof(val));
513  int dig = ReadDigits( in );
514 
515  out.WriteAttr(Lookup(id), val, dig);
516  }
517  break;
518 
519  case FT_Int:
520  {
521  id = ReadUShort( in );
522  int val = ReadInt( in );
523 
524  out.WriteAttr(Lookup(id), val);
525  }
526  break;
527 
528  case FT_Bool:
529  {
530  unsigned char val;
531 
532  id = ReadUShort( in );
533  in.Read(&val, 1);
534 
535  out.WriteAttr(Lookup(id), val);
536  }
537  break;
538 
539  case FT_Long:
540  {
541  id = ReadUShort( in );
542  long val = ReadLong( in );
543 
544  out.WriteAttr(Lookup(id), val);
545  }
546  break;
547 
548  case FT_LongLong:
549  {
550  id = ReadUShort( in );
551  long long val = ReadLongLong( in );
552  out.WriteAttr(Lookup(id), val);
553  }
554  break;
555 
556  case FT_SizeT:
557  {
558  id = ReadUShort( in );
559  size_t val = ReadULong( in );
560 
561  out.WriteAttr(Lookup(id), val);
562  }
563  break;
564 
565  case FT_Data:
566  {
567  int len = ReadLength( in );
568  out.WriteData(ReadString(len));
569  }
570  break;
571 
572  case FT_Raw:
573  {
574  int len = ReadLength( in );
575  out.Write(ReadString(len));
576  }
577  break;
578 
579  case FT_CharSize:
580  {
581  in.Read(&mCharSize, 1);
582  }
583  break;
584 
585  default:
586  wxASSERT(true);
587  break;
588  }
589  }
590  }
591  catch( const Error& )
592  {
593  // Document was corrupt, or platform differences in size or endianness
594  // were not well canonicalized
595  return {};
596  }
597 
598  return out;
599 }
size
size_t size
Definition: ffmpeg-2.3.6-single-header.h:412
XMLWriter::EndTag
virtual void EndTag(const wxString &name)
Definition: XMLWriter.cpp:99
TranslatableString
Holds a msgid for the translation catalog; may also bind format arguments.
Definition: TranslatableString.h:32
ProjectSerializer::mNames
static NameMap mNames
Definition: ProjectSerializer.h:78
FieldTypes
FieldTypes
Definition: ProjectSerializer.cpp:55
anonymous_namespace{ProjectSerializer.cpp}::IsLittleEndian
bool IsLittleEndian()
Definition: ProjectSerializer.cpp:113
ProjectSerializer.h
anonymous_namespace{ProjectSerializer.cpp}::WriteLength
static const auto WriteLength
Definition: ProjectSerializer.cpp:192
ProjectSerializer::Decode
static wxString Decode(const wxMemoryBuffer &buffer)
Definition: ProjectSerializer.cpp:386
anonymous_namespace{ProjectSerializer.cpp}::WriteULong
static const auto WriteULong
Definition: ProjectSerializer.cpp:172
ProjectSerializer::mDict
static wxMemoryBuffer mDict
Definition: ProjectSerializer.h:79
ProjectSerializer::IsEmpty
bool IsEmpty() const
Definition: ProjectSerializer.cpp:375
FT_Data
@ FT_Data
Definition: ProjectSerializer.cpp:67
ProjectSerializer::DictChanged
bool DictChanged() const
Definition: ProjectSerializer.cpp:380
anonymous_namespace{ProjectSerializer.cpp}::WriteUShort
static const auto WriteUShort
Definition: ProjectSerializer.cpp:166
flag
static std::once_flag flag
Definition: WaveformView.cpp:1124
anonymous_namespace{ProjectSerializer.cpp}::WriteDigits
static const auto WriteDigits
Definition: ProjectSerializer.cpp:196
ProjectSerializer::FailureMessage
static TranslatableString FailureMessage(const FilePath &filePath)
Definition: ProjectSerializer.cpp:83
anonymous_namespace{ProjectSerializer.cpp}::ReadBigEndian
Number ReadBigEndian(wxMemoryInputStream &in)
Definition: ProjectSerializer.cpp:156
anonymous_namespace{ProjectSerializer.cpp}::UShort
std::uint16_t UShort
Definition: ProjectSerializer.cpp:104
ProjectSerializer::WriteSubTree
void WriteSubTree(const ProjectSerializer &value)
Definition: ProjectSerializer.cpp:325
anonymous_namespace{ProjectSerializer.cpp}::WriteBigEndian
void WriteBigEndian(wxMemoryBuffer &out, Number value)
Definition: ProjectSerializer.cpp:138
FT_SizeT
@ FT_SizeT
Definition: ProjectSerializer.cpp:64
XO
#define XO(s)
Definition: Internat.h:31
XMLStringWriter
Wrapper to output XML data to strings.
Definition: XMLWriter.h:136
FT_Bool
@ FT_Bool
Definition: ProjectSerializer.cpp:61
anonymous_namespace{ProjectSerializer.cpp}::ReadULong
static const auto ReadULong
Definition: ProjectSerializer.cpp:183
anonymous_namespace{ProjectSerializer.cpp}::WriteLittleEndian
void WriteLittleEndian(wxMemoryBuffer &out, Number value)
Definition: ProjectSerializer.cpp:131
ProjectSerializer::StartTag
void StartTag(const wxString &name) override
Definition: ProjectSerializer.cpp:223
FT_StartTag
@ FT_StartTag
Definition: ProjectSerializer.cpp:57
anonymous_namespace{ProjectSerializer.cpp}::ReadLength
static const auto ReadLength
Definition: ProjectSerializer.cpp:193
ProjectSerializer::~ProjectSerializer
virtual ~ProjectSerializer()
Definition: ProjectSerializer.cpp:219
anonymous_namespace{ProjectSerializer.cpp}::WriteLong
static const auto WriteLong
Definition: ProjectSerializer.cpp:170
FT_Float
@ FT_Float
Definition: ProjectSerializer.cpp:65
anonymous_namespace{ProjectSerializer.cpp}::ReadDigits
static const auto ReadDigits
Definition: ProjectSerializer.cpp:197
FilePath
wxString FilePath
Definition: Project.h:20
ProjectSerializer::GetDict
const wxMemoryBuffer & GetDict() const
Definition: ProjectSerializer.cpp:365
FT_Int
@ FT_Int
Definition: ProjectSerializer.cpp:60
ProjectSerializer::ProjectSerializer
ProjectSerializer(size_t allocSize=1024 *1024)
Definition: ProjectSerializer.cpp:200
ProjectSerializer::WriteData
void WriteData(const wxString &value) override
Definition: ProjectSerializer.cpp:308
XMLStringWriter::Write
void Write(const wxString &data) override
Definition: XMLWriter.cpp:427
IdMap
std::unordered_map< unsigned short, wxString > IdMap
Definition: ProjectSerializer.h:30
name
const TranslatableString name
Definition: Distortion.cpp:98
ProjectSerializer::Write
void Write(const wxString &data) override
Definition: ProjectSerializer.cpp:317
anonymous_namespace{ProjectSerializer.cpp}::Long
std::int32_t Long
Definition: ProjectSerializer.cpp:107
FT_EndTag
@ FT_EndTag
Definition: ProjectSerializer.cpp:58
anonymous_namespace{ProjectSerializer.cpp}::ReadLittleEndian
Number ReadLittleEndian(wxMemoryInputStream &in)
Definition: ProjectSerializer.cpp:147
ProjectSerializer::mDictChanged
bool mDictChanged
Definition: ProjectSerializer.h:76
NameMap
std::unordered_map< wxString, unsigned short > NameMap
Definition: ProjectSerializer.h:29
anonymous_namespace{ProjectSerializer.cpp}::ReadUShort
static const auto ReadUShort
Definition: ProjectSerializer.cpp:177
FT_Pop
@ FT_Pop
Definition: ProjectSerializer.cpp:70
anonymous_namespace{ProjectSerializer.cpp}::Int
std::int32_t Int
Definition: ProjectSerializer.cpp:105
anonymous_namespace{ProjectSerializer.cpp}::WriteLongLong
static const auto WriteLongLong
Definition: ProjectSerializer.cpp:174
anonymous_namespace{ProjectSerializer.cpp}::ReadInt
static const auto ReadInt
Definition: ProjectSerializer.cpp:179
id
int id
Definition: WaveTrackControls.cpp:591
ProjectSerializer::GetData
const wxMemoryBuffer & GetData() const
Definition: ProjectSerializer.cpp:370
anonymous_namespace{ProjectSerializer.cpp}::ULong
std::uint32_t ULong
Definition: ProjectSerializer.cpp:108
ProjectSerializer::WriteName
void WriteName(const wxString &name)
Definition: ProjectSerializer.cpp:335
ProjectSerializer::EndTag
void EndTag(const wxString &name) override
Definition: ProjectSerializer.cpp:229
anonymous_namespace{ProjectSerializer.cpp}::Length
Int Length
Definition: ProjectSerializer.cpp:191
anonymous_namespace{ProjectSerializer.cpp}::WriteInt
static const auto WriteInt
Definition: ProjectSerializer.cpp:168
FT_Double
@ FT_Double
Definition: ProjectSerializer.cpp:66
XMLWriter::WriteAttr
void WriteAttr(const wxString &name, const Identifier &value)
Definition: XMLWriter.h:34
FT_Long
@ FT_Long
Definition: ProjectSerializer.cpp:62
anonymous_namespace{ProjectSerializer.cpp}::ReadLongLong
static const auto ReadLongLong
Definition: ProjectSerializer.cpp:185
anonymous_namespace{ProjectSerializer.cpp}::LongLong
std::int64_t LongLong
Definition: ProjectSerializer.cpp:110
FT_String
@ FT_String
Definition: ProjectSerializer.cpp:59
ProjectSerializer::mBuffer
wxMemoryBuffer mBuffer
Definition: ProjectSerializer.h:75
anonymous_namespace{ProjectSerializer.cpp}::Digits
Int Digits
Definition: ProjectSerializer.cpp:195
FT_Name
@ FT_Name
Definition: ProjectSerializer.cpp:71
XMLWriter::WriteData
virtual void WriteData(const wxString &value)
Definition: XMLWriter.cpp:199
ProjectSerializer
a class used to (de)serialize the project catalog
Definition: ProjectSerializer.h:34
FT_Raw
@ FT_Raw
Definition: ProjectSerializer.cpp:68
FT_LongLong
@ FT_LongLong
Definition: ProjectSerializer.cpp:63
XMLWriter::StartTag
virtual void StartTag(const wxString &name)
Definition: XMLWriter.cpp:76
anonymous_namespace{ProjectSerializer.cpp}::ReadLong
static const auto ReadLong
Definition: ProjectSerializer.cpp:181
FT_CharSize
@ FT_CharSize
Definition: ProjectSerializer.cpp:56
FT_Push
@ FT_Push
Definition: ProjectSerializer.cpp:69
ProjectSerializer::WriteAttr
void WriteAttr(const wxString &name, const wxString &value) override
Definition: ProjectSerializer.cpp:240