00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifdef __cplusplus
00022 #include "SDNV.h"
00023 #include <oasys/debug/DebugUtils.h>
00024 #include <oasys/debug/Log.h>
00025
00026 #define SDNV_FN(_what) SDNV::_what
00027
00028 namespace dtn {
00029
00030 #else // ! __cplusplus
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <oasys/compat/inttypes.h>
00035
00036 #define SDNV_FN(_what) sdnv_##_what
00037
00038
00039 #define ASSERT(x) \
00040 do { \
00041 if (! (x)) { \
00042 fprintf(stderr, "ASSERTION FAILED (" #x ") at %s:%d\n", \
00043 __FILE__, __LINE__); \
00044 exit(1); \
00045 } \
00046 } while (0)
00047
00048
00049 #define log_err_p(p, args...) fprintf(stderr, "error: (" p ") " args);
00050
00051 #define MAX_LENGTH 10
00052
00053 #endif // __cplusplus
00054
00055
00056 int
00057 SDNV_FN(encode)(u_int64_t val, u_char* bp, size_t len)
00058 {
00059 u_char* start = bp;
00060
00061
00062
00063
00064 size_t val_len = 0;
00065 u_int64_t tmp = val;
00066
00067 do {
00068 tmp = tmp >> 7;
00069 val_len++;
00070 } while (tmp != 0);
00071
00072 ASSERT(val_len > 0);
00073 ASSERT(val_len <= MAX_LENGTH);
00074
00075
00076
00077
00078 if (len < val_len) {
00079 return -1;
00080 }
00081
00082
00083
00084
00085
00086 bp += val_len;
00087 u_char high_bit = 0;
00088 do {
00089 --bp;
00090 *bp = (u_char)(high_bit | (val & 0x7f));
00091 high_bit = (1 << 7);
00092 val = val >> 7;
00093 } while (val != 0);
00094
00095 ASSERT(bp == start);
00096
00097 return val_len;
00098 }
00099
00100
00101 size_t
00102 SDNV_FN(encoding_len)(u_int64_t val)
00103 {
00104 u_char buf[16];
00105 int ret = SDNV_FN(encode)(val, buf, sizeof(buf));
00106 ASSERT(ret != -1 && ret != 0);
00107 return ret;
00108 }
00109
00110
00111 int
00112 SDNV_FN(decode)(const u_char* bp, size_t len, u_int64_t* val)
00113 {
00114 const u_char* start = bp;
00115
00116 if (!val) {
00117 return -1;
00118 }
00119
00120
00121
00122
00123
00124
00125 size_t val_len = 0;
00126 *val = 0;
00127 do {
00128 if (len == 0)
00129 return -1;
00130
00131 *val = (*val << 7) | (*bp & 0x7f);
00132 ++val_len;
00133
00134 if ((*bp & (1 << 7)) == 0)
00135 break;
00136
00137 ++bp;
00138 --len;
00139 } while (1);
00140
00141
00142
00143
00144
00145
00146
00147
00148 if ((val_len > MAX_LENGTH) ||
00149 ((val_len == MAX_LENGTH) && (*start != 0x81)))
00150 {
00151 log_err_p("/dtn/bundle/sdnv", "overflow value in sdnv!!!");
00152 return -1;
00153 }
00154
00155
00156
00157
00158
00159
00160 return val_len;
00161 }
00162
00163 #ifdef __cplusplus
00164 }
00165 #endif
00166