diff --git a/src/util.c b/src/util.c index 4be894e..1f9022b 100644 --- a/src/util.c +++ b/src/util.c @@ -16,6 +16,7 @@ #include #include #include +#include int div_up(int n, int div) { @@ -191,6 +192,12 @@ static int valid_d_char(char c) return (c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c == '_'); } +static int valid_a_char(char c) +{ + return (c >= ' ' && c <= '"') || (c >= '%' && c <= '?') + || (c >= 'A' && c <= 'Z') || (c == '_'); +} + void iso_dirid(char *src, int maxlen) { size_t len, i; @@ -286,3 +293,158 @@ void iso_2_fileid(char *src) } src[pos] = '\0'; } + +int str2d_char(const char *icharset, const char *input, char **output) +{ + int ret; + char *ascii; + size_t len, i; + + if (output == NULL) { + return ISO_MEM_ERROR; + } + + /** allow NULL input */ + if (input == NULL) { + *output = NULL; + return 0; + } + + /* this checks for NULL parameters */ + ret = str2ascii(icharset, input, &ascii); + if (ret < 0) { + *output = NULL; + return ret; + } + + len = strlen(ascii); + + for (i = 0; i < len; ++i) { + char c = toupper(ascii[i]); + ascii[i] = valid_d_char(c) ? c : '_'; + } + + *output = ascii; + return ISO_SUCCESS; +} + +int str2a_char(const char *icharset, const char *input, char **output) +{ + int ret; + char *ascii; + size_t len, i; + + if (output == NULL) { + return ISO_MEM_ERROR; + } + + /** allow NULL input */ + if (input == NULL) { + *output = NULL; + return 0; + } + + /* this checks for NULL parameters */ + ret = str2ascii(icharset, input, &ascii); + if (ret < 0) { + *output = NULL; + return ret; + } + + len = strlen(ascii); + + for (i = 0; i < len; ++i) { + char c = toupper(ascii[i]); + ascii[i] = valid_a_char(c) ? c : '_'; + } + + *output = ascii; + return ISO_SUCCESS; +} + +void iso_lsb(uint8_t *buf, uint32_t num, int bytes) +{ + int i; + + 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; + + 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; + int tzoffset; + struct tm tm; + + if (!tzsetup) { + tzset(); + 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; +#ifdef HAVE_TM_GMTOFF + tzoffset = tm.tm_gmtoff / 60 / 15; +#else + tzoffset = timezone / 60 / 15; +#endif + if (tzoffset > 52) + tzoffset -= 101; + buf[6] = tzoffset; +} + +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(); + tzsetup = 1; + } + + localtime_r(&t, &tm); + + 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)); + memcpy(&buf[14], "00", 2); +#ifdef HAVE_TM_GMTOFF + tzoffset = tm.tm_gmtoff / 60 / 15; +#else + tzoffset = timezone / 60 / 15; +#endif + if (tzoffset > 52) + tzoffset -= 101; + buf[16] = tzoffset; + } +} diff --git a/src/util.h b/src/util.h index 8e19ac0..453bb46 100644 --- a/src/util.h +++ b/src/util.h @@ -9,6 +9,17 @@ #ifndef LIBISO_UTIL_H_ #define LIBISO_UTIL_H_ +#include +#include + +#ifndef MAX +# define MAX(a, b) (((a) > (b)) ? (a) : (b)) +#endif + +#ifndef MIN +# define MIN(a, b) (((a) < (b)) ? (a) : (b)) +#endif + extern inline int div_up(int n, int div); extern inline int round_up(int n, int mul); @@ -60,4 +71,22 @@ void iso_1_fileid(char *src); */ void iso_2_fileid(char *src); +/** + * Convert a given input string to d-chars. + * @return + * 1 on succes, < 0 error, 0 if input was null (output is set to null) + */ +int str2d_char(const char *icharset, const char *input, char **output); +int str2a_char(const char *icharset, const char *input, char **output); + +void iso_lsb(uint8_t *buf, uint32_t num, int bytes); +void iso_msb(uint8_t *buf, uint32_t num, int bytes); +void iso_bb(uint8_t *buf, uint32_t num, int bytes); + +/** Records the date/time into a 7 byte buffer (ECMA-119, 9.1.5) */ +void iso_datetime_7(uint8_t *buf, time_t t); + +/** Records the date/time into a 17 byte buffer (ECMA-119, 8.4.26.1) */ +void iso_datetime_17(uint8_t *buf, time_t t); + #endif /*LIBISO_UTIL_H_*/