66#include " defs.h"
77
88using namespace std ;
9+ // functions used
10+ bool numcheck_int (string s) {
11+ for (auto & p : s) {
12+ if ((p < ' 0' || p > ' 9' ) && p != ' \n ' && p != ' ' && p != ' \t ' &&p!=' -' &&p!=' +' ) {
13+ return false ;
14+ }
15+ }
16+ return true ;
17+ }
918
19+ bool numcheck_decimal (string s) {
20+ bool decimal_point_exists = false ;
21+ for (auto & p : s) {
22+ if ((p < ' 0' || p > ' 9' ) && p != ' \n ' && p != ' ' && p != ' \t ' && p != ' -' && p != ' +' ) {
23+ if (p == ' .' && (!decimal_point_exists)) {
24+ decimal_point_exists = true ;
25+ }
26+ else {
27+ return false ;
28+ }
29+ }
30+ }
31+ return true ;
32+ }
33+
34+ // functions in class
1035void chart_store::skip_space () {
1136 /* *
1237 * The function skips the white space and new line in xml file
@@ -269,8 +294,9 @@ void chart_store::parse_elem() {
269294 // normal xml tag:<...>
270295 buf_index++;// '>'
271296 if (tag == " m_notes" ) {// start reading notes
272- if (modes == 0 )modes = 1 ;
297+ if (modes == 0 )modes = 1 ;// middle mode
273298 else if (modes == 1 || modes == 2 || modes == 3 ) {
299+ // start reading notes
274300 note_trigger = true ;
275301 }
276302 else {
@@ -283,16 +309,27 @@ void chart_store::parse_elem() {
283309 }
284310 }
285311 else if (tag == " CMapNoteAsset" ) {// head of a note
286- if (!note_reading) {
287- note_reading = true ;
288- tempnote = new note;
312+ if (note_trigger) {
313+ if (!note_reading) {
314+ note_reading = true ;
315+ tempnote = new note;
316+ }
317+ else {
318+ // get error position
319+ char lln[64 ];
320+ snprintf (lln, sizeof (lln), " %d." , lines);
321+
322+ throw std::logic_error (" Read notes error: <CMapNoteAsset> note asset error, triggered at line "
323+ + string (lln));
324+ return ;
325+ }
289326 }
290327 else {
291328 // get error position
292329 char lln[64 ];
293330 snprintf (lln, sizeof (lln), " %d." , lines);
294331
295- throw std::logic_error (" Read notes error: <CMapNoteAsset> note asset error , triggered at line "
332+ throw std::logic_error (" Read notes error: Unexpected note detected outside the note lists , triggered at line "
296333 + string (lln));
297334 return ;
298335 }
@@ -320,7 +357,17 @@ void chart_store::parse_elem() {
320357 }
321358 }
322359 // read text
323- string text = parse_elem_text ();
360+ string text = " " ;
361+ try {
362+ text = parse_elem_text ();
363+ }
364+ catch (exception& ex) {
365+ char lln[64 ];
366+ snprintf (lln, sizeof (lln), " %d." , tag_line);
367+ string errmsg = ex.what ();
368+ throw std::logic_error (errmsg+" Tag begins at line " + string (lln));
369+ return ;
370+ }
324371 if (text != " " ) {
325372 if (tag == " m_path" ) { // read name
326373 name = text;
@@ -377,88 +424,202 @@ void chart_store::parse_elem() {
377424 name_id = text;
378425 }
379426 else if (tag == " m_id" ) {// note id
380- extr.str (text);
381- if (tempnote != NULL ) {
382- extr >> tempnote->id ;// read current note id
427+ if (note_reading) {
428+ // only numbers should exist in id
429+ bool valid = numcheck_int (text);
430+ if (!valid) {
431+ // get error position
432+ char lln[64 ];
433+ snprintf (lln, sizeof (lln), " %d." , lines);
434+
435+ throw std::logic_error (" Read note error: ID is not an integer. Occured at line " + string (lln));
436+ return ;
437+ }
438+ extr.str (text);
439+ if (tempnote != NULL ) {
440+ extr >> tempnote->id ;// read current note id
441+ if (extr.fail ()) {
442+ printf (" boo\n " );
443+ }
444+ }
445+ else {
446+ throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
447+ return ;
448+ }
449+ extr.clear ();
383450 }
384- else {
385- throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
451+ else { // not in <CMapNoteAsset>
452+ // get error position
453+ char lln[64 ];
454+ snprintf (lln, sizeof (lln), " %d." , lines);
455+
456+ throw std::logic_error (" Read note error: Note info detected outside <CMapNoteAsset>. Occured at line " + string (lln));
386457 return ;
387458 }
388- extr.clear ();
389459 }
390460 else if (tag == " m_type" ) {// note type
391- if (tempnote != NULL ) {
392- if (text == " NORMAL" )
393- {
394- tempnote->notetype = NORMAL;
395- }
396- else if (text == " CHAIN" ) {
397- tempnote->notetype = CHAIN;
398- }
399- else if (text == " HOLD" ) {
400- tempnote->notetype = HOLD;
401- }
402- else if (text == " SUB" ) {
403- tempnote->notetype = SUB;
461+ if (note_reading) {
462+ if (tempnote != NULL ) {
463+ if (text == " NORMAL" )
464+ {
465+ tempnote->notetype = NORMAL;
466+ }
467+ else if (text == " CHAIN" ) {
468+ tempnote->notetype = CHAIN;
469+ }
470+ else if (text == " HOLD" ) {
471+ tempnote->notetype = HOLD;
472+ }
473+ else if (text == " SUB" ) {
474+ tempnote->notetype = SUB;
475+ }
476+ else {
477+ char errnote[64 ], lln[64 ];
478+ snprintf (errnote, sizeof (errnote), " %d" , tempnote->id );
479+ snprintf (lln, sizeof (lln), " %d." , lines);
480+ throw std::logic_error (" Read notes error: Invalid note type at note #" + string (errnote) + " .\n Please check line " + string (lln));
481+
482+ }
404483 }
405484 else {
406- char errnote[64 ], lln[64 ];
407- snprintf (errnote, sizeof (errnote), " %d" , tempnote->id );
408- snprintf (lln, sizeof (lln), " %d." , lines);
409- throw std::logic_error (" Read notes error: Invalid note type at note #" + string (errnote) + " .\n Please check line " + string (lln));
410485
486+ throw std::logic_error (" Read notes error: Invalid note type at undefined note" );
411487 }
412488 }
413- else {
489+ else {// not in <CMapNoteAsset>
490+ // get error position
491+ char lln[64 ];
492+ snprintf (lln, sizeof (lln), " %d." , lines);
414493
415- throw std::logic_error (" Read notes error: Invalid note type at undefined note" );
494+ throw std::logic_error (" Read note error: Note info detected outside <CMapNoteAsset>. Occured at line " + string (lln));
495+ return ;
416496 }
417497 }
418498 else if (tag == " m_time" && note_trigger == true ) {// note time
419- extr.str (text);
420- if (tempnote != NULL ) {
421- extr >> tempnote->time ;// read current note time
422- extr.clear ();
499+ if (note_reading) {
500+ bool valid = numcheck_decimal (text);
501+ if (!valid) {
502+ // get error position
503+ char lln[64 ];
504+ snprintf (lln, sizeof (lln), " %d." , lines);
505+
506+ throw std::logic_error (" Read note error: time is not a valid decimal expression. Occured at line " + string (lln));
507+ return ;
508+ }
509+ extr.str (text);
510+ if (tempnote != NULL ) {
511+ extr >> tempnote->time ;// read current note time
512+ extr.clear ();
513+ }
514+ else {
515+ throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
516+ return ;
517+ }
423518 }
424- else {
425- throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
519+ else {// not in <CMapNoteAsset>
520+ // get error position
521+ char lln[64 ];
522+ snprintf (lln, sizeof (lln), " %d." , lines);
523+
524+ throw std::logic_error (" Read note error: Note info detected outside <CMapNoteAsset>. Occured at line " + string (lln));
426525 return ;
427526 }
428527 }
429528 else if (tag == " m_position" ) {// note position
430- extr.str (text);
431- if (tempnote != NULL ) {
432- extr >> tempnote->position ;// read current note position
433- extr.clear ();
529+ if (note_reading) {
530+ bool valid = numcheck_decimal (text);
531+ if (!valid) {
532+ // get error position
533+ char lln[64 ];
534+ snprintf (lln, sizeof (lln), " %d." , lines);
535+
536+ throw std::logic_error (" Read note error: note position is not a valid decimal expression. Occured at line " + string (lln));
537+ return ;
538+ }
539+ extr.str (text);
540+ if (tempnote != NULL ) {
541+ extr >> tempnote->position ;// read current note position
542+ extr.clear ();
543+ }
544+ else {
545+ throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
546+ return ;
547+ }
434548 }
435- else {
436- throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
549+ else {// not in <CMapNoteAsset>
550+ // get error position
551+ char lln[64 ];
552+ snprintf (lln, sizeof (lln), " %d." , lines);
553+
554+ throw std::logic_error (" Read note error: Note info detected outside <CMapNoteAsset>. Occured at line " + string (lln));
437555 return ;
556+
438557 }
439558 }
440559 else if (tag == " m_width" ) {// note width
441- extr.str (text);
442- if (tempnote != NULL ) {
443- extr >> tempnote->width ;// read current note width
444- extr.clear ();
560+ if (note_reading) {
561+ bool valid = numcheck_decimal (text);
562+ if (!valid) {
563+ // get error position
564+ char lln[64 ];
565+ snprintf (lln, sizeof (lln), " %d." , lines);
566+
567+ throw std::logic_error (" Read note error: note width is not a valid decimal expression. Occured at line " + string (lln));
568+ return ;
569+ }
570+ extr.str (text);
571+ if (tempnote != NULL ) {
572+ extr >> tempnote->width ;// read current note width
573+ extr.clear ();
574+ }
575+ else {
576+ throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
577+ return ;
578+ }
445579 }
446- else {
447- throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
580+ else {// not in <CMapNoteAsset>
581+ // get error position
582+ char lln[64 ];
583+ snprintf (lln, sizeof (lln), " %d." , lines);
584+
585+ throw std::logic_error (" Read note error: Note info detected outside <CMapNoteAsset>. Occured at line " + string (lln));
448586 return ;
587+
449588 }
450589 }
451590 else if (tag == " m_subId" ) {// sub id of a hold,-1 for non-hold notes
452- extr.str (text);
453- if (tempnote != NULL ) {
454- extr >> tempnote->subid ;// read subId
455- extr.clear ();
591+ if (note_reading) {
592+ // only numbers should exist in id
593+ bool valid = numcheck_int (text);
594+ if (!valid) {
595+ // get error position
596+ char lln[64 ];
597+ snprintf (lln, sizeof (lln), " %d." , lines);
598+
599+ throw std::logic_error (" Read note error: note sub ID is not an integer. Occured at line " + string (lln));
600+ return ;
601+ }
602+ extr.str (text);
603+ if (tempnote != NULL ) {
604+ extr >> tempnote->subid ;// read subId
605+ extr.clear ();
606+ }
607+ else {
608+ throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
609+ return ;
610+ }
456611 }
457- else {
458- throw std::logic_error (" Read notes error: Unable to create object \" note\" " );
612+ else {// not in <CMapNoteAsset>
613+ // get error position
614+ char lln[64 ];
615+ snprintf (lln, sizeof (lln), " %d." , lines);
616+
617+ throw std::logic_error (" Read note error: Note info detected outside <CMapNoteAsset>. Occured at line " + string (lln));
459618 return ;
619+
460620 }
461621 }
622+ // ignore all other tags
462623 }
463624 }
464625 else if (t_buf[buf_index] == ' <' ) {
@@ -653,13 +814,17 @@ void chart_store::parse_elem() {
653814 break ;
654815 default :
655816 delete tempnote;
817+ // need to set to NULL after deletion
818+ tempnote = NULL ;
656819 // get error position
657820 char lln[64 ];
658821 snprintf (lln, sizeof (lln), " %d." , lines);
659822
660823 throw std::logic_error (" Read notes error at line " + string (lln));
661824 }
662825 delete tempnote;
826+ // need to set to NULL after deletion
827+ tempnote = NULL ;
663828 note_reading = false ;
664829 }
665830 else {
@@ -731,7 +896,11 @@ void chart_store::parse_elem() {
731896 string val = parse_elem_attr_val ();
732897 }
733898 catch (exception& ex) {
734- throw std::logic_error (ex.what ());
899+ char lln[64 ];
900+ snprintf (lln, sizeof (lln), " %d." ,tag_line);
901+ string errmsg = ex.what ();
902+
903+ throw std::logic_error (errmsg+" The xml tag begins at line " +string (lln));
735904 return ;
736905 }
737906 }
@@ -884,7 +1053,7 @@ string chart_store::parse_elem_attr_val() {
8841053 buf_index++;
8851054 // missing the right quotation mark
8861055 if (buf_index >= t_buf.length ()) {
887- throw std::logic_error (" attribute value syntax error " );
1056+ throw std::logic_error (" attribute value not closed (missing quotation mark). " );
8881057 return " " ;
8891058 }
8901059 }
0 commit comments