#include #include #include #include #include #if defined(lint) && defined(HAVE_NOTE_H) #include #endif /* lint && HAVE_NOTE_H */ #include #include "iiimp-dataP.h" IIIMP_string * iiimp_string_new( IIIMP_data_s * data_s, size_t len, const IIIMP_card16 * ptr) { IIIMP_string * str; size_t nbyte; str = (IIIMP_string *)malloc(sizeof (IIIMP_string)); if (NULL == str) { data_s->status = IIIMP_DATA_MALLOC_ERROR; return NULL; } nbyte = (2 * len); str->nbyte = (2 + nbyte + PAD(2 + nbyte)); str->len = len; str->next = NULL; nbyte = ((sizeof (IIIMP_card16)) * len); if (0 == len) { str->ptr = NULL; } else { str->ptr = (IIIMP_card16 *)malloc(str->nbyte); if (NULL == str->ptr) { free(str); data_s->status = IIIMP_DATA_MALLOC_ERROR; return NULL; } } if (NULL != ptr) { (void)memcpy(str->ptr, ptr, nbyte); } return str; } void iiimp_string_delete(IIIMP_data_s * data_s, IIIMP_string * str) { #if defined(lint) && defined(HAVE_NOTE_H) NOTE(ARGUNUSED(data_s)) #endif /* lint && HAVE_NOTE_H */ if (NULL == str) return; free(str->ptr); free(str); return; } void iiimp_string_list_delete(IIIMP_data_s * data_s, IIIMP_string * str) { #if defined(lint) && defined(HAVE_NOTE_H) NOTE(ARGUNUSED(data_s)) #endif /* lint && HAVE_NOTE_H */ IIIMP_string * str_next; for (; NULL != str; str = str_next) { str_next = str->next; free(str->ptr); free(str); } return; } void iiimp_string_pack( IIIMP_data_s * data_s, IIIMP_string * m, size_t * nbyte, uchar_t ** ptr) { uchar_t * p; size_t rest; int i; rest = *nbyte; p = *ptr; PUTU16((2 * m->len), rest, p, data_s->byte_swap); for (i = 0; i < m->len; i++) { PUTU16(*(m->ptr + i), rest, p, data_s->byte_swap); } if (0 == (1 & m->len)) { PUTU16(0, rest, p, data_s->byte_swap); } *nbyte = rest; *ptr = p; return; } void iiimp_string_list_pack( IIIMP_data_s * data_s, IIIMP_string * m, size_t * nbyte, uchar_t ** ptr) { size_t rest; uchar_t * p; rest = *nbyte; p = *ptr; for (; NULL != m; m = m->next) { iiimp_string_pack(data_s, m, &rest, &p); } *nbyte = rest; *ptr = p; return; } IIIMP_string * iiimp_string_unpack( IIIMP_data_s * data_s, size_t * nbyte, const uchar_t ** ptr, size_t nbyte_max) { IIIMP_string * str; const uchar_t * p; size_t rest; size_t len; int data_size; int i; rest = nbyte_max; p = *ptr; if ((*nbyte < rest) || (rest < 4)) { data_s->status = IIIMP_DATA_INVALID; return NULL; } GET16(len, rest, p, data_s->byte_swap); data_size = (len + PAD(2 + len)); if ((0 != (len & 0x01)) || (rest < data_size)) { data_s->status = IIIMP_DATA_INVALID; return NULL; } str = (IIIMP_string *)malloc(sizeof (IIIMP_string)); if (NULL == str) { data_s->status = IIIMP_DATA_MALLOC_ERROR; return NULL; } str->len = (len / 2); str->nbyte = (2 + len + PAD(2 + len)); str->next = NULL; if (0 == len) { str->ptr = NULL; } else { str->ptr = (IIIMP_card16 *)malloc(len); if (NULL == str->ptr) { iiimp_string_delete(data_s, str); data_s->status = IIIMP_DATA_MALLOC_ERROR; return NULL; } for (i = 0; i < str->len; i++) { GETU16(*(str->ptr + i), rest, p, data_s->byte_swap); } } *nbyte -= (2 + data_size); *ptr += (2 + data_size); return str; } IIIMP_string * iiimp_string_list_unpack( IIIMP_data_s * data_s, size_t * nbyte, const uchar_t ** ptr, size_t nbyte_max) { IIIMP_string * str; size_t rest; const uchar_t * p; IIIMP_string * str_first; IIIMP_string * str_last; rest = nbyte_max; p = *ptr; str = NULL; str_first = NULL; str_last = NULL; if (((*nbyte) < nbyte_max) || (0 != (rest & 0x01)) || (0 == rest)) { data_s->status = IIIMP_DATA_INVALID; return NULL; } while (0 < rest) { str = iiimp_string_unpack(data_s, &rest, &p, rest); if (NULL == str) { iiimp_string_list_delete(data_s, str_first); return NULL; } else { if (NULL == str_first) { str_first = str; } else { str_last->next = str; } str_last = str; } } *nbyte -= (nbyte_max - rest); *ptr = p; return str_first; } void iiimp_string_print( IIIMP_data_s * data_s, IIIMP_string * m) { int i; const uchar_t * p; int byte_len; if ((NULL == m) || (0 == m->len)) { return; } /* ASCII or UTF-8 */ for (i = 0; i < m->len; i++) { if ((*(m->ptr + i) < 0x20) || (0x7f <= *(m->ptr + i))) { break; } } if (i == m->len) { /* ASCII */ (void)fputc('"', data_s->print_fp); for (i = 0; i < m->len; i++) { (void)fprintf(data_s->print_fp, "%c", *(m->ptr + i)); } (void)fputc('"', data_s->print_fp); } else { /* UTF-16 */ p = (uchar_t *)(m->ptr); byte_len = (m->len * 2); for (i = 0; i < byte_len; i += 2) { (void)fprintf(data_s->print_fp, " U+%04x ", ((*p << 8) | *(p + 1))); (void)fprintf(data_s->print_fp, "%c", isprint(*p) ? *p : ' '); p++; (void)fprintf(data_s->print_fp, "%c", isprint(*p) ? *p : ' '); p++; } } } void iiimp_string_list_print( IIIMP_data_s * data_s, IIIMP_string * m) { if (NULL == m) return; iiimp_string_print(data_s, m); for (m = m->next; NULL != m; m = m->next) { (void)fputc(' ', data_s->print_fp); iiimp_string_print(data_s, m); } } /* Local Variables: */ /* c-file-style: "iiim-project" */ /* End: */