#include "calculate_parking_tickets_parse_tariff.h" #include "calculate_parking_tickets_tariff.h" #include #include #include #include #include #include #include #include #include "rapidjson/stringbuffer.h" #include #include using namespace rapidjson; #define MAX_READ_BUFFER_SIZE 10000000 static const char *weekStr[] { "week1", "week2", "week3" }; static const char *weekDayStr[] { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" }; static const int constexpr STEP_PRICE = 1; static const int constexpr STEP_NEXT = 2; parking_tariff_t *parking_tariff_t::parseTariff(const char *confFile) { parking_tariff_t *tariff = 0; FILE* fp = fopen(confFile, "r"); if (fp) { fseek(fp, 0 , SEEK_END); long const bufSize = ftell(fp) + 1024; fseek(fp, 0 , SEEK_SET); char *readBuffer = (char *)malloc(bufSize); if (readBuffer) { memset(readBuffer, 0x00, bufSize); FileReadStream is(fp, readBuffer, bufSize); Document d; if (d.ParseStream(is).HasParseError()) { fprintf(stderr, "\nError(offset %u): %s\n", (unsigned)d.GetErrorOffset(), GetParseError_En(d.GetParseError())); free(readBuffer); fclose(fp); return 0; } tariff = new parking_tariff_t(); if (d.HasMember(FREE_OF_CHARGE)) { Value::MemberIterator o = d.FindMember(FREE_OF_CHARGE); assert(o != d.MemberEnd()); assert(o->value.IsString()); std::string foc = o->value.GetString(); tariff->free_of_charge = std::stoi(foc); } if (d.HasMember(UNIT_SCALE_FACTOR)) { Value::MemberIterator o = d.FindMember(UNIT_SCALE_FACTOR); assert(o != d.MemberEnd()); assert(o->value.IsString()); std::string usf = o->value.GetString(); tariff->unit_scale_factor = std::stof(usf); } if (d.HasMember(UNIT_DEFINITION)) { Value::MemberIterator o = d.FindMember(UNIT_DEFINITION); assert(o != d.MemberEnd()); assert(o->value.IsString()); std::string udef = o->value.GetString(); tariff->unit_definition = std::stoi(udef); } if (d.HasMember(VAT)) { Value::MemberIterator o = d.FindMember(VAT); assert(o != d.MemberEnd()); assert(o->value.IsString()); std::string vat = o->value.GetString(); tariff->vat = std::stof(vat); } if (d.HasMember(MAX_PARKING_PRICE)) { Value::MemberIterator o = d.FindMember(MAX_PARKING_PRICE); assert(o != d.MemberEnd()); assert(o->value.IsString()); std::string mp = o->value.GetString(); if (mp == "unlimited") { tariff->max_parking_price_units = ~0; } else { tariff->max_parking_price_units = (uint32_t)std::stoul(mp); } } if (d.HasMember(MAX_PRICE_FOR_24_HOURS)) { Value::MemberIterator o = d.FindMember(MAX_PRICE_FOR_24_HOURS); assert(o != d.MemberEnd()); assert(o->value.IsString()); std::string mp = o->value.GetString(); if (mp == "unlimited") { tariff->max_price_for_24_hours = ~0; } else { tariff->max_price_for_24_hours = (uint32_t)std::stoul(mp); } } QDate today = QDate::currentDate(); int todayWeekDay = today.dayOfWeek(); if (todayWeekDay > Qt::Monday) { int day = today.day() - todayWeekDay; if (!today.setDate(today.year(), today.month(), day)) { qFatal("Setting today failed"); } } QDate monday = today; // "week1" : { for (int w = 0; w < 3; ++w) { assert(d.HasMember(weekStr[w])); // "Monday": { for (int j = Qt::Monday - 1; j < Qt::Sunday; ++j) { QDateTime startMinute(monday.addDays(w*7+j), QTime( 0, 0)); Value::MemberIterator wObj = d.FindMember(weekStr[w]); assert(wObj != d.MemberEnd()); assert(wObj->value.IsObject()); Value::MemberIterator stepsForDay = wObj->value.FindMember(weekDayStr[j]); assert(stepsForDay != wObj->value.MemberEnd()); assert(stepsForDay->value.IsObject()); // name : time, price, next-tariff-step // "000000" : [ "00:00", "800000", "000001" ], // "000001" : [ "07:00", "350000", "000002" ], // ... // "000014" : [ "20:00", "800000", "000011" ] // }, int k = 0; for (Value::ConstMemberIterator step = stepsForDay->value.MemberBegin(); step != stepsForDay->value.MemberEnd(); ++step) { assert(step->name.IsString()); assert(step->value.IsArray()); QString name(step->name.GetString()); int const week = name.midRef(0, 1).toInt(); int const weekDay = name.midRef(1, 1).toInt(); int const stepIndex = name.midRef(2).toInt(); assert(w == week); assert(j == weekDay); assert(k == stepIndex); uint32_t price_units = QString(step->value[STEP_PRICE].GetString()).toUInt(); QString next = QString(step->value[STEP_NEXT].GetString()); int const nextWeek = next.midRef(0, 1).toInt(); int const nextWeekDay = next.midRef(1, 1).toInt(); int const nextStepIndex = next.midRef(2).toInt(); //qDebug() << startMinute.addSecs(stepIndex*60) // << "(" << week << weekDay << stepIndex << ")" // << "(" << nextWeek << nextWeekDay << nextStepIndex << ")"; tariff->m_tariffSteps[week][weekDay][stepIndex] = TariffStep(startMinute.addSecs(stepIndex*60), price_units, &tariff->m_tariffSteps[nextWeek][nextWeekDay][nextStepIndex]); ++k; } } } free(readBuffer); } fclose(fp); } return tariff; }