Back to index

im-sdk  12.3.91
comp-string.c
Go to the documentation of this file.
00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004 #include <ctype.h>
00005 #include <sys/types.h>
00006 #if defined(lint) && defined(HAVE_NOTE_H)
00007 #include <note.h>
00008 #endif /* lint && HAVE_NOTE_H */
00009 
00010 #include <iiimp-data.h>
00011 
00012 #include "iiimp-dataP.h"
00013 
00014 
00015 IIIMP_string *
00016 iiimp_string_new(
00017     IIIMP_data_s *          data_s,
00018     size_t                  len,
00019     const IIIMP_card16 *    ptr)
00020 {
00021     IIIMP_string *   str;
00022     size_t           nbyte;
00023 
00024     str = (IIIMP_string *)malloc(sizeof (IIIMP_string));
00025     if (NULL == str) {
00026        data_s->status = IIIMP_DATA_MALLOC_ERROR;
00027        return NULL;
00028     }
00029 
00030     nbyte = (2 * len);
00031 
00032     str->nbyte = (2 + nbyte + PAD(2 + nbyte));
00033     str->len = len;
00034     str->next = NULL;
00035 
00036     nbyte = ((sizeof (IIIMP_card16)) * len);
00037 
00038     if (0 == len) {
00039        str->ptr = NULL;
00040     } else {
00041        str->ptr = (IIIMP_card16 *)malloc(str->nbyte);
00042        if (NULL == str->ptr) {
00043            free(str);
00044            data_s->status = IIIMP_DATA_MALLOC_ERROR;
00045            return NULL;
00046        }
00047     }
00048 
00049     if (NULL != ptr) {
00050        (void)memcpy(str->ptr, ptr, nbyte);
00051     }
00052 
00053     return str;
00054 }
00055 
00056 
00057 void
00058 iiimp_string_delete(IIIMP_data_s * data_s, IIIMP_string * str)
00059 {
00060 #if defined(lint) && defined(HAVE_NOTE_H)
00061     NOTE(ARGUNUSED(data_s))
00062 #endif /* lint && HAVE_NOTE_H */
00063     if (NULL == str) return;
00064     free(str->ptr);
00065     free(str);
00066     return;
00067 }
00068 
00069 
00070 void
00071 iiimp_string_list_delete(IIIMP_data_s * data_s, IIIMP_string * str)
00072 {
00073 #if defined(lint) && defined(HAVE_NOTE_H)
00074     NOTE(ARGUNUSED(data_s))
00075 #endif /* lint && HAVE_NOTE_H */
00076     IIIMP_string *   str_next;
00077     for (; NULL != str; str = str_next) {
00078        str_next = str->next;
00079        free(str->ptr);
00080        free(str);
00081     }
00082     return;
00083 }
00084 
00085 
00086 void
00087 iiimp_string_pack(
00088     IIIMP_data_s *   data_s,
00089     IIIMP_string *   m,
00090     size_t *         nbyte,
00091     uchar_t **              ptr)
00092 {
00093     uchar_t * p;
00094     size_t    rest;
00095     int              i;
00096 
00097     rest = *nbyte;
00098     p = *ptr;
00099 
00100     PUTU16((2 * m->len), rest, p, data_s->byte_swap);
00101 
00102     for (i = 0; i < m->len; i++) {
00103        PUTU16(*(m->ptr + i), rest, p, data_s->byte_swap);
00104     }
00105 
00106     if (0 == (1 & m->len)) {
00107        PUTU16(0, rest, p, data_s->byte_swap);
00108     }
00109 
00110     *nbyte = rest;
00111     *ptr = p;
00112 
00113     return;
00114 }
00115 
00116 
00117 void
00118 iiimp_string_list_pack(
00119     IIIMP_data_s *   data_s,
00120     IIIMP_string *   m,
00121     size_t *         nbyte,
00122     uchar_t **              ptr)
00123 {
00124     size_t           rest;
00125     uchar_t *        p;
00126 
00127     rest = *nbyte;
00128     p = *ptr;
00129 
00130     for (; NULL != m; m = m->next) {
00131        iiimp_string_pack(data_s, m, &rest, &p);
00132     }
00133 
00134     *nbyte = rest;
00135     *ptr = p;
00136 
00137     return;
00138 }
00139 
00140 
00141 IIIMP_string *
00142 iiimp_string_unpack(
00143     IIIMP_data_s *   data_s,
00144     size_t *         nbyte,
00145     const uchar_t ** ptr,
00146     size_t           nbyte_max)
00147 {
00148     IIIMP_string *   str;
00149     const uchar_t *  p;
00150     size_t           rest;
00151     size_t           len;
00152     int                     data_size;
00153     int                     i;
00154 
00155     rest = nbyte_max;
00156     p = *ptr;
00157 
00158     if ((*nbyte < rest) ||  (rest < 4)) {
00159        data_s->status = IIIMP_DATA_INVALID;
00160        return NULL;
00161     }
00162 
00163     GET16(len, rest, p, data_s->byte_swap);
00164 
00165     data_size = (len + PAD(2 + len));
00166     if ((0 != (len & 0x01)) || (rest < data_size)) {
00167        data_s->status = IIIMP_DATA_INVALID;
00168        return NULL;
00169     }
00170 
00171     str = (IIIMP_string *)malloc(sizeof (IIIMP_string));
00172     if (NULL == str) {
00173        data_s->status = IIIMP_DATA_MALLOC_ERROR;
00174        return NULL;
00175     }
00176 
00177     str->len = (len / 2);
00178     str->nbyte = (2 + len + PAD(2 + len));
00179     str->next = NULL;
00180     if (0 == len) {
00181        str->ptr = NULL;
00182     } else {
00183        str->ptr = (IIIMP_card16 *)malloc(len);
00184        if (NULL == str->ptr) {
00185            iiimp_string_delete(data_s, str);
00186            data_s->status = IIIMP_DATA_MALLOC_ERROR;
00187            return NULL;
00188        }
00189 
00190        for (i = 0; i < str->len; i++) {
00191            GETU16(*(str->ptr + i), rest, p, data_s->byte_swap);
00192        }
00193     }
00194 
00195     *nbyte -= (2 + data_size);
00196     *ptr += (2 + data_size);
00197 
00198     return str;
00199 }
00200 
00201 
00202 IIIMP_string *
00203 iiimp_string_list_unpack(
00204     IIIMP_data_s *   data_s,
00205     size_t *         nbyte,
00206     const uchar_t ** ptr,
00207     size_t           nbyte_max)
00208 {
00209     IIIMP_string *   str;
00210     size_t           rest;
00211     const uchar_t *  p;
00212     IIIMP_string *   str_first;
00213     IIIMP_string *   str_last;
00214 
00215     rest = nbyte_max;
00216     p = *ptr;
00217     str = NULL;
00218     str_first = NULL;
00219     str_last = NULL;
00220 
00221     if (((*nbyte) < nbyte_max) || (0 != (rest & 0x01)) || (0 == rest)) {
00222        data_s->status = IIIMP_DATA_INVALID;
00223        return NULL;
00224     }
00225 
00226     while (0 < rest) {
00227        str = iiimp_string_unpack(data_s, &rest, &p, rest);
00228        if (NULL == str) {
00229            iiimp_string_list_delete(data_s, str_first);
00230            return NULL;
00231        } else {
00232            if (NULL == str_first) {
00233               str_first = str;
00234            } else {
00235               str_last->next = str;
00236            }
00237            str_last = str;
00238        }
00239     }
00240 
00241     *nbyte -= (nbyte_max - rest);
00242     *ptr = p;
00243 
00244     return str_first;
00245 }
00246 
00247 
00248 void
00249 iiimp_string_print(
00250     IIIMP_data_s *   data_s,
00251     IIIMP_string *   m)
00252 {
00253     int                     i;
00254     const uchar_t *  p;
00255     int                     byte_len;
00256 
00257     if ((NULL == m) || (0 == m->len)) {
00258        return;
00259     }
00260 
00261     /* ASCII or UTF-8 */
00262     for (i = 0; i < m->len; i++) {
00263        if ((*(m->ptr + i) < 0x20) || (0x7f <= *(m->ptr + i))) {
00264            break;
00265        }
00266     }
00267 
00268     if (i == m->len) { /* ASCII */
00269        (void)fputc('"', data_s->print_fp);
00270        for (i = 0; i < m->len; i++) {
00271            (void)fprintf(data_s->print_fp, "%c", *(m->ptr + i));
00272        }
00273        (void)fputc('"', data_s->print_fp);
00274     } else { /* UTF-16 */
00275        p = (uchar_t *)(m->ptr);
00276        byte_len = (m->len * 2);
00277 
00278        for (i = 0; i < byte_len; i += 2) {
00279            (void)fprintf(data_s->print_fp, " U+%04x ", ((*p << 8) | *(p + 1)));
00280            (void)fprintf(data_s->print_fp, "%c", isprint(*p) ? *p : ' ');
00281            p++;
00282            (void)fprintf(data_s->print_fp, "%c", isprint(*p) ? *p : ' ');
00283            p++;
00284        }
00285     }
00286 }
00287 
00288 
00289 void
00290 iiimp_string_list_print(
00291     IIIMP_data_s *   data_s,
00292     IIIMP_string *   m)
00293 {
00294     if (NULL == m) return;
00295     iiimp_string_print(data_s, m);
00296     for (m = m->next; NULL != m; m = m->next) {
00297        (void)fputc(' ', data_s->print_fp);
00298        iiimp_string_print(data_s, m);
00299     }
00300 }
00301 
00302 
00303 /* Local Variables: */
00304 /* c-file-style: "iiim-project" */
00305 /* End: */