mirror of
https://github.com/google/pebble.git
synced 2025-11-24 16:22:25 -05:00
65 lines
1.7 KiB
C
65 lines
1.7 KiB
C
/*
|
|
* Copyright 2024 Google LLC
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#include "sle.h"
|
|
|
|
#include "system/passert.h"
|
|
|
|
// See waftools/sparse_length_encoding.py for more info on SLE encoding/decoding
|
|
|
|
void sle_decode_init(SLEDecodeContext *ctx, const void *sle_buffer) {
|
|
PBL_ASSERTN(ctx && sle_buffer);
|
|
const uint8_t *buffer = (const uint8_t *)sle_buffer;
|
|
ctx->escape = *(buffer++);
|
|
ctx->sle_buffer = buffer;
|
|
ctx->zeros_remaining = 0;
|
|
}
|
|
|
|
bool sle_decode(SLEDecodeContext *ctx, uint8_t *out) {
|
|
if (!ctx->sle_buffer) {
|
|
return false;
|
|
}
|
|
if (ctx->zeros_remaining) {
|
|
*out = 0;
|
|
--ctx->zeros_remaining;
|
|
return true;
|
|
}
|
|
uint8_t byte = *(ctx->sle_buffer++);
|
|
if (byte != ctx->escape) {
|
|
*out = byte;
|
|
} else {
|
|
byte = *(ctx->sle_buffer++);
|
|
if (byte == 0x00) {
|
|
// end of stream
|
|
ctx->sle_buffer = NULL;
|
|
return false;
|
|
} else if (byte == 0x01) {
|
|
// literal escape byte
|
|
*out = ctx->escape;
|
|
} else {
|
|
// a sequence of zeros
|
|
if ((byte & 0x80) == 0) {
|
|
// the count is 1 byte (1-127)
|
|
ctx->zeros_remaining = byte - 1;
|
|
} else {
|
|
ctx->zeros_remaining = (((byte & 0x7f) << 8) | *(ctx->sle_buffer++)) + 0x80 - 1;
|
|
}
|
|
*out = 0;
|
|
}
|
|
}
|
|
return true;
|
|
}
|