Data serialization in C?

前端 未结 5 1713
清歌不尽
清歌不尽 2021-01-14 20:50

I have this structure which I want to write to a file:

typedef struct
{
    char* egg;
    unsigned long sausage;
    long bacon;
    double spam;
} order;
<         


        
5条回答
  •  说谎
    说谎 (楼主)
    2021-01-14 21:26

    This answer uses Nils Pipenbrinck's method but I have changed a few details that I think help to ensure real C99 portability. This solution lives in an imaginary context where encode_int64 and encode_int32 etc already exist.

    #include      
    #include                                                          
    
    #define PORTABLE_INTLEAST64_MAX ((int_least64_t)9223372036854775807) /* 2^63-1*/             
    
    /* NOTE: +-inf and nan not handled. quickest solution                            
     * is to encode 0 for !isfinite(val) */                                          
    void encode_double(struct encoder *rec, double val) {                            
        int exp = 0;                                                                 
        double norm = frexp(val, &exp);                                              
        int_least64_t scale = norm*PORTABLE_INTLEAST64_MAX;                          
        encode_int64(rec, scale);                                                    
        encode_int32(rec, exp);                                                      
    }                                                                                
    
    void decode_double(struct encoder *rec, double *val) {                           
        int_least64_t scale = 0;                                                     
        int_least32_t exp = 0;                                                       
        decode_int64(rec, &scale);                                                   
        decode_int32(rec, &exp);                                                     
        *val = ldexp((double)scale/PORTABLE_INTLEAST64_MAX, exp);                    
    }
    

    This is still not a real solution, inf and nan can not be encoded. Also notice that both parts of the double carry sign bits.

    int_least64_t is guaranteed by the standard (int64_t is not), and we use the least perimissible maximum for this type to scale the double. The encoding routines accept int_least64_t but will have to reject input that is larger than 64 bits for portability, the same for the 32 bit case.

提交回复
热议问题