EncodingScheme.h 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. /* vim: set expandtab ts=4 sw=4: */
  2. /*
  3. * You may redistribute this program and/or modify it under the terms of
  4. * the GNU General Public License as published by the Free Software Foundation,
  5. * either version 3 of the License, or (at your option) any later version.
  6. *
  7. * This program is distributed in the hope that it will be useful,
  8. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. * GNU General Public License for more details.
  11. *
  12. * You should have received a copy of the GNU General Public License
  13. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  14. */
  15. #ifndef EncodingScheme_H
  16. #define EncodingScheme_H
  17. #include "benc/String.h"
  18. #include "benc/List.h"
  19. #include "memory/Allocator.h"
  20. #include "util/Linker.h"
  21. Linker_require("switch/EncodingScheme.c")
  22. #include <stdint.h>
  23. struct EncodingScheme_Form
  24. {
  25. // these only require 5 bits each but use 16 to avoid compiler injected padding
  26. // which can screw up comparison by memcmp()
  27. uint16_t bitCount;
  28. uint16_t prefixLen;
  29. uint32_t prefix;
  30. };
  31. struct EncodingScheme
  32. {
  33. struct EncodingScheme_Form* forms;
  34. int count;
  35. };
  36. /**
  37. * Get the number of the encoding form used to encode the first director in the given label.
  38. * If there is no matching prefix for any of the forms then EncodingScheme_getFormNum_INVALID is
  39. * returned.
  40. */
  41. #define EncodingScheme_getFormNum_INVALID -1
  42. int EncodingScheme_getFormNum(struct EncodingScheme* scheme, uint64_t routeLabel);
  43. /**
  44. * Convert the first director in a label from it's current form to the form given by convertTo.
  45. * convertTo must be between zero and scheme->count unless you are asking for the cannonical form
  46. * IE: the smallest possible represenation in which case convertTo should be:
  47. * EncodingScheme_convertLabel_convertTo_CANNONICAL
  48. *
  49. * The return value will be the converted label unless conversion is not possible because the
  50. * format of the label is invalid, the format of the label does not match the scheme, or the
  51. * label cannot be converted without overrunning the acceptable label size in which case
  52. * EncodingScheme_convertLabel_INVALID will be returned.
  53. */
  54. #define EncodingScheme_convertLabel_convertTo_CANNONICAL (-5000)
  55. #define EncodingScheme_convertLabel_INVALID (~((uint64_t)0))
  56. uint64_t EncodingScheme_convertLabel(struct EncodingScheme* scheme,
  57. uint64_t routeLabel,
  58. int convertTo);
  59. /**
  60. * Check that the given encoding scheme is conformant to protocol.
  61. * This will not check some things which are impossible to serialize (will never come from a
  62. * working deserializer) such as unrepresentable bit-widths but it will check that a representable
  63. * encoding scheme is indeed valid according to the protocol.
  64. */
  65. bool EncodingScheme_isSane(struct EncodingScheme* scheme);
  66. String* EncodingScheme_serialize(struct EncodingScheme* list,
  67. struct Allocator* alloc);
  68. struct EncodingScheme* EncodingScheme_deserialize(String* data,
  69. struct Allocator* alloc);
  70. struct EncodingScheme* EncodingScheme_defineFixedWidthScheme(int bitCount, struct Allocator* alloc);
  71. struct EncodingScheme* EncodingScheme_defineDynWidthScheme(struct EncodingScheme_Form* forms,
  72. int formCount,
  73. struct Allocator* alloc);
  74. #define EncodingScheme_clone(scheme, alloc) \
  75. EncodingScheme_defineDynWidthScheme((scheme)->forms, (scheme)->count, (alloc))
  76. static inline int EncodingScheme_formSize(const struct EncodingScheme_Form* form)
  77. {
  78. return form->bitCount + form->prefixLen;
  79. }
  80. int EncodingScheme_compare(struct EncodingScheme* a, struct EncodingScheme* b);
  81. #define EncodingScheme_equals(a,b) (!EncodingScheme_compare(a,b))
  82. struct EncodingScheme* EncodingScheme_fromList(List* scheme, struct Allocator* alloc);
  83. List* EncodingScheme_asList(struct EncodingScheme* list, struct Allocator* alloc);
  84. #endif