123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- /* vim: set expandtab ts=4 sw=4: */
- /*
- * You may redistribute this program and/or modify it under the terms of
- * the GNU General Public License as published by the Free Software Foundation,
- * either version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- #ifndef EncodingScheme_H
- #define EncodingScheme_H
- #include "benc/String.h"
- #include "benc/List.h"
- #include "memory/Allocator.h"
- #include "util/Linker.h"
- Linker_require("switch/EncodingScheme.c");
- #include <stdint.h>
- struct EncodingScheme_Form
- {
- // these only require 5 bits each but use 16 to avoid compiler injected padding
- // which can screw up comparison by memcmp()
- uint16_t bitCount;
- uint16_t prefixLen;
- uint32_t prefix;
- };
- struct EncodingScheme
- {
- struct EncodingScheme_Form* forms;
- int count;
- };
- /**
- * Get the number of the encoding form used to encode the first director in the given label.
- * If there is no matching prefix for any of the forms then EncodingScheme_getFormNum_INVALID is
- * returned.
- */
- #define EncodingScheme_getFormNum_INVALID -1
- int EncodingScheme_getFormNum(const struct EncodingScheme* scheme, uint64_t routeLabel);
- /**
- * Convert the first director in a label from it's current form to the form given by convertTo.
- * convertTo must be between zero and scheme->count unless you are asking for the cannonical form
- * IE: the smallest possible represenation in which case convertTo should be:
- * EncodingScheme_convertLabel_convertTo_CANNONICAL
- *
- * The return value will be the converted label unless conversion is not possible because the
- * format of the label is invalid, the format of the label does not match the scheme, or the
- * label cannot be converted without overrunning the acceptable label size in which case
- * EncodingScheme_convertLabel_INVALID will be returned.
- */
- #define EncodingScheme_convertLabel_convertTo_CANNONICAL (-5000)
- #define EncodingScheme_convertLabel_INVALID (~((uint64_t)0))
- uint64_t EncodingScheme_convertLabel(const struct EncodingScheme* scheme,
- uint64_t routeLabel,
- int convertTo);
- /**
- * Check that the given encoding scheme is conformant to protocol.
- * This will not check some things which are impossible to serialize (will never come from a
- * working deserializer) such as unrepresentable bit-widths but it will check that a representable
- * encoding scheme is indeed valid according to the protocol.
- */
- bool EncodingScheme_isSane(const struct EncodingScheme* scheme);
- String* EncodingScheme_serialize(const struct EncodingScheme* list,
- struct Allocator* alloc);
- struct EncodingScheme* EncodingScheme_deserialize(String* data,
- struct Allocator* alloc);
- struct EncodingScheme* EncodingScheme_defineFixedWidthScheme(int bitCount, struct Allocator* alloc);
- struct EncodingScheme* EncodingScheme_defineDynWidthScheme(const struct EncodingScheme_Form* forms,
- int formCount,
- struct Allocator* alloc);
- #define EncodingScheme_clone(scheme, alloc) \
- EncodingScheme_defineDynWidthScheme((scheme)->forms, (scheme)->count, (alloc))
- static inline int EncodingScheme_formSize(const struct EncodingScheme_Form* form)
- {
- return form->bitCount + form->prefixLen;
- }
- int EncodingScheme_compare(const struct EncodingScheme* a, const struct EncodingScheme* b);
- #define EncodingScheme_equals(a,b) (!EncodingScheme_compare(a,b))
- struct EncodingScheme* EncodingScheme_fromList(List* scheme, struct Allocator* alloc);
- List* EncodingScheme_asList(const struct EncodingScheme* list, struct Allocator* alloc);
- /**
- * Return true if the route is to the switch's router interface.
- */
- int EncodingScheme_isSelfRoute(const struct EncodingScheme* scheme, uint64_t routeLabel);
- /**
- * @return non-zero if the route label is one hop.
- */
- int EncodingScheme_isOneHop(const struct EncodingScheme* scheme, uint64_t routeLabel);
- #define EncodingScheme_parseDirector_INVALID -1
- int EncodingScheme_parseDirector(
- const struct EncodingScheme* scheme, uint64_t label);
- uint64_t EncodingScheme_serializeDirector(
- const struct EncodingScheme* scheme, int number, int formNum);
- // Return true if the encoding scheme is the legacy 358 encoding scheme
- // which gets special treatment.
- bool EncodingScheme_is358(const struct EncodingScheme* scheme);
- const struct EncodingScheme* EncodingScheme_358(void);
- #endif
|