fork download
  1. #include <iostream>
  2. #include <string>
  3. #include <stdexcept>
  4. #include <cstring>
  5.  
  6. /*
  7. [19:53:25]{main}z@m:/tmp
  8. $ g++ -std=c++11 src.cpp -o src && ./src pack 2 5 0 2 1 1
  9. 18965
  10. [19:53:34]{main}z@m:/tmp
  11. $ g++ -std=c++11 src.cpp -o src && ./src unpack 18965
  12. SignalPower=2 WorkingGroup=5 IsBlocked=0 ChargeLevel=2 HasVideoCall=1 ConnectionType=1
  13. */
  14.  
  15. struct __attribute__((packed)) TMobileIdentifier {
  16. using TUnderlyingType = uint16_t;
  17. int ConnectionType : 2;
  18. bool HasVideoCall : 1;
  19. int ChargeLevel : 3;
  20. int Reserved6 : 1;
  21. bool IsBlocked : 1;
  22. int Reserved8 : 1;
  23. int WorkingGroup : 4;
  24. int SignalPower : 3;
  25. };
  26. static_assert(
  27. sizeof(TMobileIdentifier) <= sizeof(TMobileIdentifier::TUnderlyingType),
  28. "TMobileIdentifier doesn't fit into uint16_t"
  29. );
  30.  
  31. void shift(int& argc, char**& argv) {
  32. if (argc == 0)
  33. throw std::runtime_error("no arugments left to shift");
  34. argc--;
  35. argv++;
  36. }
  37.  
  38. #define $0 argv[0]
  39. #define $1 argv[1]
  40. #define $2 argv[2]
  41. #define $3 argv[3]
  42. #define $4 argv[4]
  43. #define $5 argv[5]
  44.  
  45. void usage() {
  46. std::cerr << "Usage: packer [pack|unpack] ...args" << std::endl;
  47. }
  48.  
  49. int main(int argc, char** argv) {
  50. if (argc == 1) {
  51. usage();
  52. return 1;
  53. }
  54. shift(argc, argv);
  55.  
  56. std::string mode = $0;
  57. if (mode == "pack") {
  58. shift(argc, argv);
  59. if (argc != 6) {
  60. std::cerr << "Usage: packer pack SIGNAL_POWER WORKING_GROUP IS_BLOCKED CHARGE_LEVEL HAS_VIDEO_CALL CONNECTION_TYPE" << std::endl;
  61. return 1;
  62. }
  63. TMobileIdentifier data = {};
  64. data.SignalPower = std::stoi($0);
  65. data.WorkingGroup = std::stoi($1);
  66. data.IsBlocked = std::stoi($2);
  67. data.ChargeLevel = std::stoi($3);
  68. data.HasVideoCall = std::stoi($4);
  69. data.ConnectionType = std::stoi($5);
  70. TMobileIdentifier::TUnderlyingType encoded = 0;
  71. std::memcpy(&encoded, &data, sizeof(data));
  72. std::cout << encoded << std::endl;
  73. } else if (mode == "unpack") {
  74. shift(argc, argv);
  75. if (argc != 1) {
  76. std::cerr << "Usage: packer unpack NUMBER" << std::endl;
  77. return 1;
  78. }
  79. TMobileIdentifier::TUnderlyingType input = std::stoi($0);
  80. TMobileIdentifier decoded;
  81. std::memcpy(&decoded, &input, sizeof(input));
  82. #define OUTPUT_FIELD(NAME) #NAME "=" << decoded.NAME
  83. std::cout
  84. << OUTPUT_FIELD(SignalPower) << "\t"
  85. << OUTPUT_FIELD(WorkingGroup) << "\t"
  86. << OUTPUT_FIELD(IsBlocked) << "\t"
  87. << OUTPUT_FIELD(ChargeLevel) << "\t"
  88. << OUTPUT_FIELD(HasVideoCall) << "\t"
  89. << OUTPUT_FIELD(ConnectionType)
  90. << std::endl;
  91. #undef OUTPUT_FIELD
  92. } else {
  93. usage();
  94. }
  95. }
Runtime error #stdin #stdout #stderr 0s 3468KB
stdin
Standard input is empty
stdout
Standard output is empty
stderr
Usage: packer [pack|unpack] ...args