summaryrefslogtreecommitdiff
path: root/mysys/my_vle.c
diff options
context:
space:
mode:
Diffstat (limited to 'mysys/my_vle.c')
-rw-r--r--mysys/my_vle.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/mysys/my_vle.c b/mysys/my_vle.c
new file mode 100644
index 00000000000..5b93ba69bd9
--- /dev/null
+++ b/mysys/my_vle.c
@@ -0,0 +1,112 @@
+/*
+ Copyright (C) 2005 MySQL AB
+
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License as
+ published by the Free Software Foundation; version 2 of the License.
+
+ 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, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+ USA
+*/
+
+/*
+ Variable length encoding.
+
+ A method to store an arbitrary-size non-negative integer. We let the
+ most significant bit of the number indicate that the next byte
+ should be contatenated to form the real number.
+*/
+
+#include "my_vle.h"
+
+/*
+ Function to encode an unsigned long as VLE. The bytes for the VLE
+ will be written to the location pointed to by 'out'. The maximum
+ number of bytes written will be 'max'.
+
+ PARAMETERS
+
+ out Pointer to beginning of where to store VLE bytes.
+ max Maximum number of bytes to write.
+ n Number to encode.
+
+ RETURN VALUE
+ On success, one past the end of the array containing the VLE
+ bytes. On failure, the 'out' pointer is returned.
+*/
+
+byte*
+my_vle_encode(byte* out, my_size_t max, ulong n)
+{
+ byte buf[my_vle_sizeof(n)];
+ byte *ptr= buf;
+ my_size_t len;
+
+ do
+ {
+ *ptr++= (byte) (n & 0x7F);
+ n>>= 7;
+ }
+ while (n > 0);
+
+ len= ptr - buf;
+
+ if (len <= max)
+ {
+ /*
+ The bytes are stored in reverse order in 'buf'. Let's write them
+ in correct order to the output buffer and set the MSB at the
+ same time.
+ */
+ while (ptr-- > buf)
+ {
+ byte v= *ptr;
+ if (ptr > buf)
+ v|= 0x80;
+ *out++= v;
+ }
+ }
+
+ return out;
+}
+
+/*
+ Function to decode a VLE representation of an integral value.
+
+
+ PARAMETERS
+
+ result_ptr Pointer to an unsigned long where the value will be written.
+ vle Pointer to the VLE bytes.
+
+ RETURN VALUE
+
+ One-past the end of the VLE bytes. The routine will never read
+ more than sizeof(*result_ptr) + 1 bytes.
+*/
+
+byte const*
+my_vle_decode(ulong *result_ptr, byte const *vle)
+{
+ ulong result= 0;
+ my_size_t cnt= 1;
+
+ do
+ {
+ result<<= 7;
+ result|= (*vle & 0x7F);
+ }
+ while ((*vle++ & 0x80) && ++cnt <= sizeof(*result_ptr) + 1);
+
+ if (cnt <= sizeof(*result_ptr) + 1)
+ *result_ptr= result;
+
+ return vle;
+}