2006-08-15 20:37:04 +00:00
|
|
|
/* -*- indent-tabs-mode: t; tab-width: 8; c-basic-offset: 8; -*- */
|
2006-08-24 19:23:37 +00:00
|
|
|
/* vim: set noet ts=8 sts=8 sw=8 : */
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
/**
|
|
|
|
* Utility functions for the Libisofs library.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <wchar.h>
|
2006-08-15 20:37:04 +00:00
|
|
|
#include <iconv.h>
|
|
|
|
#include <stdlib.h>
|
2006-08-24 19:23:37 +00:00
|
|
|
#include <stdio.h>
|
2006-08-15 20:37:04 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <assert.h>
|
2006-08-24 19:23:37 +00:00
|
|
|
#include <errno.h>
|
2006-08-15 20:37:04 +00:00
|
|
|
|
|
|
|
#include "util.h"
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
int div_up(int n, int div)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
return (n + div - 1) / div;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
int round_up(int n, int mul)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
return div_up(n, mul) * mul;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
wchar_t *towcs(const char *str)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
size_t len = strlen(str);
|
|
|
|
wchar_t *ret = malloc(sizeof(wchar_t) * (len + 1));
|
|
|
|
mbstate_t ps;
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
memset(&ps, 0, sizeof(ps));
|
|
|
|
n = mbsrtowcs(ret, &str, len, &ps);
|
|
|
|
ret[len] = '\0';
|
|
|
|
|
|
|
|
if (n != len) {
|
|
|
|
free(ret);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return ret;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
char *wcstoascii(const wchar_t *wsrc)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
if (!wsrc)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
iconv_t conv = iconv_open("ASCII", "WCHAR_T");
|
|
|
|
size_t outbytes = wcslen(wsrc);
|
|
|
|
size_t inbytes = outbytes * sizeof(wchar_t);
|
|
|
|
char src_[inbytes + sizeof(wchar_t)];
|
|
|
|
char *src = src_;
|
|
|
|
char *ret_, *ret;
|
|
|
|
size_t n;
|
|
|
|
|
|
|
|
if (conv == (iconv_t)-1)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
memcpy(src, wsrc, inbytes + sizeof(wchar_t));
|
|
|
|
ret = malloc(outbytes+1);
|
|
|
|
ret[outbytes] = '\0';
|
|
|
|
ret_ = ret;
|
|
|
|
|
|
|
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
|
|
|
if (n == -1) {
|
|
|
|
free(ret_);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return ret_;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
/* FIXME: C&P */
|
|
|
|
uint16_t *wcstoucs(const wchar_t *wsrc)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
if (!wsrc)
|
|
|
|
return calloc(2, 1); /* empty UCS string */
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
iconv_t conv = iconv_open("UCS-2BE", "WCHAR_T");
|
|
|
|
size_t outbytes = wcslen(wsrc) * 2;
|
|
|
|
size_t inbytes = outbytes * sizeof(wchar_t) / 2;
|
|
|
|
char src_[inbytes + sizeof(wchar_t)];
|
|
|
|
char *src = src_;
|
|
|
|
char *ret_, *ret;
|
|
|
|
size_t n;
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
if (conv == (iconv_t)-1)
|
|
|
|
return calloc(2, 1);
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
memcpy(src, wsrc, inbytes + sizeof(wchar_t));
|
|
|
|
ret = malloc(outbytes + sizeof(wchar_t));
|
|
|
|
ret[outbytes] = 0;
|
|
|
|
ret[outbytes+1] = 0;
|
|
|
|
ret_ = ret;
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
n = iconv(conv, &src, &inbytes, &ret, &outbytes);
|
|
|
|
if (n == -1) {
|
|
|
|
perror ("error in iconv conversion");
|
|
|
|
free(ret_);
|
|
|
|
return calloc(2, 1);
|
|
|
|
}
|
|
|
|
return (uint16_t*)ret_;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
static int valid_d_char(char c)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_');
|
|
|
|
}
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
static int valid_a_char(char c)
|
|
|
|
{
|
|
|
|
return (c >= ' ' && c <= '"') || (c >= '%' && c <= '?')
|
|
|
|
|| (c >= 'A' && c <= 'Z')
|
|
|
|
|| (c == '_');
|
|
|
|
}
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
static int valid_j_char(uint16_t c)
|
|
|
|
{
|
|
|
|
return !(c < (uint16_t)' ' || c == (uint16_t)'*' || c == (uint16_t)'/'
|
|
|
|
|| c == (uint16_t)':' || c == (uint16_t)';'
|
|
|
|
|| c == (uint16_t)'?' || c == (uint16_t)'\\');
|
|
|
|
}
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
/* FIXME: where are these documented? */
|
|
|
|
static int valid_p_char(char c)
|
|
|
|
{
|
|
|
|
return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z')
|
|
|
|
|| (c >= 'a' && c <= 'z')
|
|
|
|
|| (c == '.') || (c == '_') || (c == '-');
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
static char *iso_dirid(const wchar_t *src, int size)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
char *ret = wcstoascii(src);
|
|
|
|
size_t len, i;
|
|
|
|
|
|
|
|
if (!ret)
|
2006-08-15 20:37:04 +00:00
|
|
|
return NULL;
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
len = strlen(ret);
|
|
|
|
if (len > size) {
|
|
|
|
ret[size] = '\0';
|
|
|
|
len = size;
|
|
|
|
}
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
char c = toupper(ret[i]);
|
|
|
|
ret[i] = valid_d_char(c) ? c : '_';
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
return ret;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
char *iso_1_dirid(const wchar_t *src)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
return iso_dirid(src, 8);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *iso_2_dirid(const wchar_t *src)
|
|
|
|
{
|
|
|
|
return iso_dirid(src, 31);
|
|
|
|
}
|
|
|
|
|
|
|
|
char *iso_1_fileid(const wchar_t *wsrc)
|
|
|
|
{
|
|
|
|
char *src = wcstoascii(wsrc);
|
|
|
|
char *dest;
|
|
|
|
char *dot; /* Position of the last dot in the
|
2006-08-15 20:37:04 +00:00
|
|
|
filename, will be used to calculate
|
|
|
|
lname and lext. */
|
|
|
|
int lname, lext, pos, i;
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
if (!src)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
dest = malloc(15); /* 15 = 8 (name) + 1 (.) + 3 (ext) + 2
|
|
|
|
(;1) + 1 (\0) */
|
|
|
|
dot = strrchr(src, '.');
|
|
|
|
|
2006-08-15 20:37:04 +00:00
|
|
|
lext = dot ? strlen(dot + 1) : 0;
|
|
|
|
lname = strlen(src) - lext - (dot ? 1 : 0);
|
|
|
|
|
|
|
|
/* If we can't build a filename, return NULL. */
|
|
|
|
if (lname == 0 && lext == 0) {
|
2006-08-24 19:23:37 +00:00
|
|
|
free(src);
|
2006-08-15 20:37:04 +00:00
|
|
|
free(dest);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos = 0;
|
|
|
|
/* Convert up to 8 characters of the filename. */
|
|
|
|
for (i = 0; i < lname && i < 8; i++) {
|
|
|
|
char c = toupper(src[i]);
|
|
|
|
|
|
|
|
dest[pos++] = valid_d_char(c) ? c : '_';
|
|
|
|
}
|
|
|
|
/* This dot is mandatory, even if there is no extension. */
|
|
|
|
dest[pos++] = '.';
|
|
|
|
/* Convert up to 3 characters of the extension, if any. */
|
|
|
|
for (i = 0; i < lext && i < 3; i++) {
|
|
|
|
char c = toupper(src[lname + 1 + i]);
|
|
|
|
|
|
|
|
dest[pos++] = valid_d_char(c) ? c : '_';
|
|
|
|
}
|
|
|
|
/* File versions are mandatory, even if they aren't used. */
|
|
|
|
dest[pos++] = ';';
|
|
|
|
dest[pos++] = '1';
|
|
|
|
dest[pos] = '\0';
|
|
|
|
dest = (char *)realloc(dest, pos + 1);
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
free(src);
|
2006-08-15 20:37:04 +00:00
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
char *iso_2_fileid(const wchar_t *wsrc)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
char *src = wcstoascii(wsrc);
|
|
|
|
char *dest;
|
|
|
|
char *dot;
|
2006-08-15 20:37:04 +00:00
|
|
|
int lname, lext, lnname, lnext, pos, i;
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
if (!src)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
dest = malloc(34); /* 34 = 30 (name + ext) + 1 (.) + 2
|
|
|
|
(;1) + 1 (\0) */
|
|
|
|
dot = strrchr(src, '.');
|
|
|
|
|
2006-08-15 20:37:04 +00:00
|
|
|
/* Since the maximum length can be divided freely over the name and
|
|
|
|
extension, we need to calculate their new lengths (lnname and
|
|
|
|
lnext). If the original filename is too long, we start by trimming
|
|
|
|
the extension, but keep a minimum extension length of 3. */
|
|
|
|
if (dot == NULL || dot == src || *(dot + 1) == '\0') {
|
|
|
|
lname = strlen(src);
|
|
|
|
lnname = (lname > 30) ? 30 : lname;
|
|
|
|
lext = lnext = 0;
|
|
|
|
} else {
|
|
|
|
lext = strlen(dot + 1);
|
|
|
|
lname = strlen(src) - lext - 1;
|
2006-08-24 19:23:37 +00:00
|
|
|
lnext = (strlen(src) > 31 && lext > 3)
|
|
|
|
? (lname < 27 ? 30 - lname : 3) : lext;
|
2006-08-15 20:37:04 +00:00
|
|
|
lnname = (strlen(src) > 31) ? 30 - lnext : lname;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (lnname == 0 && lnext == 0) {
|
2006-08-24 19:23:37 +00:00
|
|
|
free(src);
|
2006-08-15 20:37:04 +00:00
|
|
|
free(dest);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
pos = 0;
|
|
|
|
/* Convert up to lnname characters of the filename. */
|
|
|
|
for (i = 0; i < lnname; i++) {
|
|
|
|
char c = toupper(src[i]);
|
|
|
|
|
|
|
|
dest[pos++] = valid_d_char(c) ? c : '_';
|
|
|
|
}
|
|
|
|
dest[pos++] = '.';
|
|
|
|
/* Convert up to lnext characters of the extension, if any. */
|
|
|
|
for (i = 0; i < lnext; i++) {
|
|
|
|
char c = toupper(src[lname + 1 + i]);
|
|
|
|
|
|
|
|
dest[pos++] = valid_d_char(c) ? c : '_';
|
|
|
|
}
|
|
|
|
dest[pos++] = ';';
|
|
|
|
dest[pos++] = '1';
|
|
|
|
dest[pos] = '\0';
|
|
|
|
dest = (char *)realloc(dest, pos + 1);
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
free(src);
|
2006-08-15 20:37:04 +00:00
|
|
|
return dest;
|
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
char *
|
|
|
|
iso_p_fileid(const wchar_t *src)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
char *ret = wcstoascii(src);
|
|
|
|
size_t i, len;
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
if (!ret)
|
2006-08-15 20:37:04 +00:00
|
|
|
return NULL;
|
2006-08-24 19:23:37 +00:00
|
|
|
len = strlen(ret);
|
|
|
|
for (i = 0; i < len; i++) {
|
|
|
|
if (!valid_p_char(ret[i])) {
|
|
|
|
ret[i] = (uint16_t)'_';
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
}
|
2006-08-24 19:23:37 +00:00
|
|
|
return ret;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
uint16_t *
|
|
|
|
iso_j_id(const wchar_t *src)
|
2006-08-15 20:37:04 +00:00
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
uint16_t *j_str = wcstoucs(src);
|
|
|
|
size_t len = ucslen(j_str);
|
|
|
|
size_t n;
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
if (len > 128) {
|
|
|
|
j_str[128] = '\0';
|
|
|
|
len = 128;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
for (n = 0; n < len; n++)
|
|
|
|
if (!valid_j_char(j_str[n]))
|
|
|
|
j_str[n] = '_';
|
|
|
|
return j_str;
|
2006-08-15 20:37:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void iso_lsb(uint8_t *buf, uint32_t num, int bytes)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
assert(bytes <= 4);
|
|
|
|
|
|
|
|
for (i = 0; i < bytes; ++i)
|
|
|
|
buf[i] = (num >> (8 * i)) & 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
void iso_msb(uint8_t *buf, uint32_t num, int bytes)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
assert(bytes <= 4);
|
|
|
|
|
|
|
|
for (i = 0; i < bytes; ++i)
|
|
|
|
buf[bytes - 1 - i] = (num >> (8 * i)) & 0xff;
|
|
|
|
}
|
|
|
|
|
|
|
|
void iso_bb(uint8_t *buf, uint32_t num, int bytes)
|
|
|
|
{
|
|
|
|
iso_lsb(buf, num, bytes);
|
|
|
|
iso_msb(buf+bytes, num, bytes);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void iso_datetime_7(unsigned char *buf, time_t t)
|
|
|
|
{
|
|
|
|
static int tzsetup = 0;
|
|
|
|
static int tzoffset;
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
if (!tzsetup) {
|
|
|
|
tzset();
|
|
|
|
|
|
|
|
tzoffset = -timezone / 60 / 15;
|
|
|
|
if (tzoffset < -48)
|
|
|
|
tzoffset += 101;
|
|
|
|
|
|
|
|
tzsetup = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
localtime_r(&t, &tm);
|
|
|
|
|
|
|
|
buf[0] = tm.tm_year;
|
|
|
|
buf[1] = tm.tm_mon + 1;
|
|
|
|
buf[2] = tm.tm_mday;
|
|
|
|
buf[3] = tm.tm_hour;
|
|
|
|
buf[4] = tm.tm_min;
|
|
|
|
buf[5] = tm.tm_sec;
|
|
|
|
buf[6] = tzoffset;
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t iso_datetime_read_7(const uint8_t *buf)
|
|
|
|
{
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
tm.tm_year = buf[0];
|
|
|
|
tm.tm_mon = buf[1] + 1;
|
|
|
|
tm.tm_mday = buf[2];
|
|
|
|
tm.tm_hour = buf[3];
|
|
|
|
tm.tm_min = buf[4];
|
|
|
|
tm.tm_sec = buf[5];
|
|
|
|
|
|
|
|
return mktime(&tm) - buf[6] * 60 * 60;
|
|
|
|
}
|
|
|
|
|
|
|
|
void iso_datetime_17(unsigned char *buf, time_t t)
|
|
|
|
{
|
|
|
|
static int tzsetup = 0;
|
|
|
|
static int tzoffset;
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
if (t == (time_t) - 1) {
|
|
|
|
/* unspecified time */
|
|
|
|
memset(buf, '0', 16);
|
|
|
|
buf[16] = 0;
|
|
|
|
} else {
|
|
|
|
if (!tzsetup) {
|
|
|
|
tzset();
|
|
|
|
|
|
|
|
tzoffset = -timezone / 60 / 15;
|
|
|
|
if (tzoffset < -48)
|
|
|
|
tzoffset += 101;
|
|
|
|
|
|
|
|
tzsetup = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
localtime_r(&t, &tm);
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
sprintf((char*)&buf[0], "%04d", tm.tm_year + 1900);
|
|
|
|
sprintf((char*)&buf[4], "%02d", tm.tm_mon + 1);
|
|
|
|
sprintf((char*)&buf[6], "%02d", tm.tm_mday);
|
|
|
|
sprintf((char*)&buf[8], "%02d", tm.tm_hour);
|
|
|
|
sprintf((char*)&buf[10], "%02d", tm.tm_min);
|
|
|
|
sprintf((char*)&buf[12], "%02d", MIN(59, tm.tm_sec));
|
2006-08-15 20:37:04 +00:00
|
|
|
memcpy(&buf[14], "00", 2);
|
|
|
|
buf[16] = tzoffset;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
time_t iso_datetime_read_17(const uint8_t *buf)
|
|
|
|
{
|
|
|
|
struct tm tm;
|
|
|
|
|
|
|
|
sscanf((char*)&buf[0], "%4d", &tm.tm_year);
|
|
|
|
sscanf((char*)&buf[4], "%2d", &tm.tm_mon);
|
|
|
|
sscanf((char*)&buf[6], "%2d", &tm.tm_mday);
|
|
|
|
sscanf((char*)&buf[8], "%2d", &tm.tm_hour);
|
|
|
|
sscanf((char*)&buf[10], "%2d", &tm.tm_min);
|
|
|
|
sscanf((char*)&buf[12], "%2d", &tm.tm_sec);
|
|
|
|
tm.tm_year -= 1900;
|
|
|
|
tm.tm_mon -= 1;
|
|
|
|
|
|
|
|
return mktime(&tm) - buf[16] * 60 * 60;
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t ucslen(const uint16_t *str)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i=0; str[i]; i++)
|
|
|
|
;
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
/**
|
|
|
|
* Although each character is 2 bytes, we actually compare byte-by-byte
|
|
|
|
* (thats what the spec says).
|
|
|
|
*/
|
2006-08-15 20:37:04 +00:00
|
|
|
int ucscmp(const uint16_t *s1, const uint16_t *s2)
|
|
|
|
{
|
2006-08-24 19:23:37 +00:00
|
|
|
const char *s = (const char*)s1;
|
|
|
|
const char *t = (const char*)s2;
|
|
|
|
size_t len1 = ucslen(s1);
|
|
|
|
size_t len2 = ucslen(s2);
|
|
|
|
size_t i, len = MIN(len1, len2) * 2;
|
2006-08-15 20:37:04 +00:00
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
for (i=0; i < len; i++) {
|
|
|
|
if (s[i] < t[i]) {
|
2006-08-15 20:37:04 +00:00
|
|
|
return -1;
|
2006-08-24 19:23:37 +00:00
|
|
|
} else if (s[i] > t[i]) {
|
2006-08-15 20:37:04 +00:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-24 19:23:37 +00:00
|
|
|
if (len1 < len2)
|
|
|
|
return -1;
|
|
|
|
else if (len1 > len2)
|
|
|
|
return 1;
|
2006-08-15 20:37:04 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t iso_read_lsb(const uint8_t *buf, int bytes)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint32_t ret = 0;
|
|
|
|
|
|
|
|
for (i=0; i<bytes; i++) {
|
|
|
|
ret += ((uint32_t) buf[i]) << (i*8);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t iso_read_msb(const uint8_t *buf, int bytes)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
uint32_t ret = 0;
|
|
|
|
|
|
|
|
for (i=0; i<bytes; i++) {
|
|
|
|
ret += ((uint32_t) buf[bytes-i-1]) << (i*8);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t iso_read_bb(const uint8_t *buf, int bytes)
|
|
|
|
{
|
|
|
|
uint32_t v1 = iso_read_lsb(buf, bytes);
|
|
|
|
uint32_t v2 = iso_read_msb(buf+bytes, bytes);
|
|
|
|
|
|
|
|
assert(v1 == v2);
|
|
|
|
return v1;
|
|
|
|
}
|