Hex.cpp 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. /***************************************************************************
  2. *
  3. * Project _____ __ ____ _ _
  4. * ( _ ) /__\ (_ _)_| |_ _| |_
  5. * )(_)( /(__)\ )( (_ _)(_ _)
  6. * (_____)(__)(__)(__) |_| |_|
  7. *
  8. *
  9. * Copyright 2018-present, Leonid Stryzhevskyi <lganzzzo@gmail.com>
  10. *
  11. * Licensed under the Apache License, Version 2.0 (the "License");
  12. * you may not use this file except in compliance with the License.
  13. * You may obtain a copy of the License at
  14. *
  15. * http://www.apache.org/licenses/LICENSE-2.0
  16. *
  17. * Unless required by applicable law or agreed to in writing, software
  18. * distributed under the License is distributed on an "AS IS" BASIS,
  19. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  20. * See the License for the specific language governing permissions and
  21. * limitations under the License.
  22. *
  23. ***************************************************************************/
  24. #include "Hex.hpp"
  25. #if defined(WIN32) || defined(_WIN32)
  26. #include <winsock2.h>
  27. #else
  28. #include <arpa/inet.h>
  29. #endif
  30. namespace oatpp { namespace encoding {
  31. const char* Hex::ALPHABET_UPPER = "0123456789ABCDEF";
  32. const char* Hex::ALPHABET_LOWER = "0123456789abcdef";
  33. void Hex::writeUInt16(v_uint16 value, p_char8 buffer){
  34. *((p_uint32) buffer) = htonl((ALPHABET_UPPER[ value & 0x000F ] ) |
  35. (ALPHABET_UPPER[(value & 0x00F0) >> 4] << 8) |
  36. (ALPHABET_UPPER[(value & 0x0F00) >> 8] << 16) |
  37. (ALPHABET_UPPER[(value & 0xF000) >> 12] << 24));
  38. }
  39. void Hex::writeUInt32(v_uint32 value, p_char8 buffer){
  40. writeUInt16(value >> 16, buffer);
  41. writeUInt16(v_uint16(value), buffer + 4);
  42. }
  43. v_int32 Hex::readUInt16(const char* buffer, v_uint16& value) {
  44. value = 0;
  45. for(v_int32 i = 0; i < 4; i++){
  46. v_char8 a = buffer[i];
  47. if(a >= '0' && a <= '9') {
  48. value |= (a - '0') << ((3 - i) << 2);
  49. } else if (a >= 'A' && a <= 'F') {
  50. value |= (a - 'A' + 10) << ((3 - i) << 2);
  51. } else if (a >= 'a' && a <= 'f') {
  52. value |= (a - 'a' + 10) << ((3 - i) << 2);
  53. } else {
  54. return ERROR_UNKNOWN_SYMBOL;
  55. }
  56. }
  57. return 0;
  58. }
  59. v_int32 Hex::readUInt32(const char* buffer, v_uint32& value) {
  60. value = 0;
  61. for(v_int32 i = 0; i < 8; i++){
  62. v_char8 a = buffer[i];
  63. if(a >= '0' && a <= '9') {
  64. value |= (a - '0') << ((7 - i) << 2);
  65. } else if (a >= 'A' && a <= 'F') {
  66. value |= (a - 'A' + 10) << ((7 - i) << 2);
  67. } else if (a >= 'a' && a <= 'f') {
  68. value |= (a - 'a' + 10) << ((7 - i) << 2);
  69. } else {
  70. return ERROR_UNKNOWN_SYMBOL;
  71. }
  72. }
  73. return 0;
  74. }
  75. void Hex::encode(data::stream::ConsistentOutputStream* stream,
  76. const void* data, v_buff_size size,
  77. const char* alphabet)
  78. {
  79. p_char8 buffer = (p_char8) data;
  80. v_char8 oneByteBuffer[2];
  81. for(v_buff_size i = 0; i < size; i ++) {
  82. auto c = buffer[i];
  83. v_char8 b1 = 0x0F & (c >> 4);
  84. v_char8 b2 = 0x0F & (c);
  85. oneByteBuffer[0] = alphabet[b1];
  86. oneByteBuffer[1] = alphabet[b2];
  87. stream->writeSimple(oneByteBuffer, 2);
  88. }
  89. }
  90. void Hex::decode(data::stream::ConsistentOutputStream* stream,
  91. const void* data, v_buff_size size, bool allowSeparators)
  92. {
  93. p_char8 buffer = (p_char8) data;
  94. v_char8 byte = 0;
  95. v_int32 shift = 4;
  96. for(v_buff_size i = 0; i < size; i ++) {
  97. auto a = buffer[i];
  98. if(a >= '0' && a <= '9') {
  99. byte |= (a - '0') << shift;
  100. shift -= 4;
  101. } else if (a >= 'A' && a <= 'F') {
  102. byte |= (a - 'A' + 10) << shift;
  103. shift -= 4;
  104. } else if (a >= 'a' && a <= 'f') {
  105. byte |= (a - 'a' + 10) << shift;
  106. shift -= 4;
  107. } else if(!allowSeparators) {
  108. throw DecodingError("Invalid Character");
  109. }
  110. if(shift < 0) {
  111. stream->writeCharSimple(byte);
  112. byte = 0;
  113. shift = 4;
  114. }
  115. }
  116. if(shift != 4) {
  117. throw DecodingError("Invalid input data size");
  118. }
  119. }
  120. }}