1/*****************************************************************************
2
3Copyright (c) 2007, 2011, Oracle and/or its affiliates. All Rights Reserved.
4
5This program is free software; you can redistribute it and/or modify it under
6the terms of the GNU General Public License as published by the Free Software
7Foundation; version 2 of the License.
8
9This program is distributed in the hope that it will be useful, but WITHOUT
10ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12
13You should have received a copy of the GNU General Public License along with
14this program; if not, write to the Free Software Foundation, Inc.,
1551 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16
17*****************************************************************************/
18
19/******************************************************************//**
20@file include/fts0vlc.ic
21Full text variable length integer encoding/decoding.
22
23Created 2007-03-27 Sunny Bains
24*******************************************************/
25
26#ifndef INNOBASE_FTS0VLC_IC
27#define INNOBASE_FTS0VLC_IC
28
29#include "fts0types.h"
30
31/******************************************************************//**
32Return length of val if it were encoded using our VLC scheme.
33FIXME: We will need to be able encode 8 bytes value
34@return length of value encoded, in bytes */
35UNIV_INLINE
36ulint
37fts_get_encoded_len(
38/*================*/
39 ulint val) /* in: value to encode */
40{
41 if (val <= 127) {
42 return(1);
43 } else if (val <= 16383) {
44 return(2);
45 } else if (val <= 2097151) {
46 return(3);
47 } else if (val <= 268435455) {
48 return(4);
49 } else {
50 /* Possibly we should care that on 64-bit machines ulint can
51 contain values that we can't encode in 5 bytes, but
52 fts_encode_int doesn't handle them either so it doesn't much
53 matter. */
54
55 return(5);
56 }
57}
58
59/******************************************************************//**
60Encode an integer using our VLC scheme and return the length in bytes.
61@return length of value encoded, in bytes */
62UNIV_INLINE
63ulint
64fts_encode_int(
65/*===========*/
66 ulint val, /* in: value to encode */
67 byte* buf) /* in: buffer, must have enough space */
68{
69 ulint len;
70
71 if (val <= 127) {
72 *buf = (byte) val;
73
74 len = 1;
75 } else if (val <= 16383) {
76 *buf++ = (byte)(val >> 7);
77 *buf = (byte)(val & 0x7F);
78
79 len = 2;
80 } else if (val <= 2097151) {
81 *buf++ = (byte)(val >> 14);
82 *buf++ = (byte)((val >> 7) & 0x7F);
83 *buf = (byte)(val & 0x7F);
84
85 len = 3;
86 } else if (val <= 268435455) {
87 *buf++ = (byte)(val >> 21);
88 *buf++ = (byte)((val >> 14) & 0x7F);
89 *buf++ = (byte)((val >> 7) & 0x7F);
90 *buf = (byte)(val & 0x7F);
91
92 len = 4;
93 } else {
94 /* Best to keep the limitations of the 32/64 bit versions
95 identical, at least for the time being. */
96 ut_ad(val <= 4294967295u);
97
98 *buf++ = (byte)(val >> 28);
99 *buf++ = (byte)((val >> 21) & 0x7F);
100 *buf++ = (byte)((val >> 14) & 0x7F);
101 *buf++ = (byte)((val >> 7) & 0x7F);
102 *buf = (byte)(val & 0x7F);
103
104 len = 5;
105 }
106
107 /* High-bit on means "last byte in the encoded integer". */
108 *buf |= 0x80;
109
110 return(len);
111}
112
113/******************************************************************//**
114Decode and return the integer that was encoded using our VLC scheme.
115@return value decoded */
116UNIV_INLINE
117ulint
118fts_decode_vlc(
119/*===========*/
120 byte** ptr) /* in: ptr to decode from, this ptr is
121 incremented by the number of bytes decoded */
122{
123 ulint val = 0;
124
125 for (;;) {
126 byte b = **ptr;
127
128 ++*ptr;
129 val |= (b & 0x7F);
130
131 /* High-bit on means "last byte in the encoded integer". */
132 if (b & 0x80) {
133 break;
134 } else {
135 val <<= 7;
136 }
137 }
138
139 return(val);
140}
141
142#endif
143