GRASS Programmer's Manual
6.4.2(2012)
|
00001 #include <stdio.h> 00002 #include <stdlib.h> 00003 #include <string.h> 00004 #include <sys/types.h> 00005 #include <unistd.h> 00006 #include <rpc/types.h> 00007 #include <rpc/xdr.h> 00008 #include "G3d_intern.h" 00009 00010 /*---------------------------------------------------------------------------*/ 00011 00012 int G3d_isXdrNullNum(const void *num, int isFloat) 00013 { 00014 static const char null_bytes[8] = { 00015 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 00016 }; 00017 00018 return memcmp(num, null_bytes, isFloat ? 4 : 8) == 0; 00019 } 00020 00021 /*---------------------------------------------------------------------------*/ 00022 00023 int G3d_isXdrNullFloat(const float *f) 00024 { 00025 return G3d_isXdrNullNum(f, 1); 00026 } 00027 00028 /*---------------------------------------------------------------------------*/ 00029 00030 int G3d_isXdrNullDouble(const double *d) 00031 { 00032 return G3d_isXdrNullNum(d, 0); 00033 } 00034 00035 /*---------------------------------------------------------------------------*/ 00036 00037 void G3d_setXdrNullNum(void *num, int isFloat) 00038 { 00039 static const char null_bytes[8] = { 00040 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF 00041 }; 00042 00043 memcpy(num, null_bytes, isFloat ? 4 : 8); 00044 } 00045 00046 /*---------------------------------------------------------------------------*/ 00047 00048 void G3d_setXdrNullDouble(double *d) 00049 { 00050 G3d_setXdrNullNum(d, 0); 00051 } 00052 00053 /*---------------------------------------------------------------------------*/ 00054 00055 void G3d_setXdrNullFloat(float *f) 00056 { 00057 G3d_setXdrNullNum(f, 1); 00058 } 00059 00060 /*---------------------------------------------------------------------------*/ 00061 00062 XDR xdrEncodeStream, xdrDecodeStream; /* xdr support structures */ 00063 00064 int G3d_initFpXdr(G3D_Map * map, int misuseBytes) 00065 00066 00067 00068 /* nof addtl bytes allocated for the xdr array so that */ 00069 /* the array can also be (mis)used for other purposes */ 00070 { 00071 int doAlloc; 00072 00073 doAlloc = 0; 00074 00075 if (xdr == NULL) { 00076 xdrLength = map->tileSize * G3D_MAX(map->numLengthExtern, 00077 map->numLengthIntern) + 00078 misuseBytes; 00079 xdr = G3d_malloc(xdrLength); 00080 if (xdr == NULL) { 00081 G3d_error("G3d_initFpXdr: error in G3d_malloc"); 00082 return 0; 00083 } 00084 00085 doAlloc = 1; 00086 } 00087 else if (map->tileSize * G3D_MAX(map->numLengthExtern, 00088 map->numLengthIntern) + misuseBytes 00089 > xdrLength) { 00090 xdrLength = map->tileSize * G3D_MAX(map->numLengthExtern, 00091 map->numLengthIntern) + 00092 misuseBytes; 00093 xdr = G3d_realloc(xdr, xdrLength); 00094 if (xdr == NULL) { 00095 G3d_error("G3d_initFpXdr: error in G3d_realloc"); 00096 return 0; 00097 } 00098 00099 doAlloc = 1; 00100 } 00101 00102 if (doAlloc) { 00103 xdrmem_create(&(xdrEncodeStream), xdr, (u_int) xdrLength, XDR_ENCODE); 00104 xdrmem_create(&(xdrDecodeStream), xdr, (u_int) xdrLength, XDR_DECODE); 00105 } 00106 00107 return 1; 00108 } 00109 00110 /*---------------------------------------------------------------------------*/ 00111 00112 static void *xdrTmp; 00113 static int dstType, srcType, type, externLength, eltLength, isFloat, useXdr; 00114 static int (*xdrFun) (); 00115 static XDR *xdrs; 00116 static double tmpValue, *tmp; 00117 00118 int G3d_initCopyToXdr(G3D_Map * map, int sType) 00119 { 00120 xdrTmp = xdr; 00121 useXdr = map->useXdr; 00122 srcType = sType; 00123 00124 if (map->useXdr == G3D_USE_XDR) { 00125 if (!xdr_setpos(&(xdrEncodeStream), 0)) { 00126 G3d_error("G3d_InitCopyToXdr: positioning xdr failed"); 00127 return 0; 00128 } 00129 xdrs = &(xdrEncodeStream); 00130 } 00131 00132 type = map->type; 00133 isFloat = (type == FCELL_TYPE); 00134 externLength = G3d_externLength(type); 00135 eltLength = G3d_length(srcType); 00136 if (isFloat) 00137 xdrFun = xdr_float; 00138 else 00139 xdrFun = xdr_double; 00140 tmp = &tmpValue; 00141 00142 return 1; 00143 } 00144 00145 /*---------------------------------------------------------------------------*/ 00146 00147 int G3d_copyToXdr(const void *src, int nofNum) 00148 { 00149 int i; 00150 00151 if (useXdr == G3D_NO_XDR) { 00152 G3d_copyValues(src, 0, srcType, xdrTmp, 0, type, nofNum); 00153 xdrTmp = G_incr_void_ptr(xdrTmp, nofNum * G3d_externLength(type)); 00154 return 1; 00155 } 00156 00157 for (i = 0; i < nofNum; i++, src = G_incr_void_ptr(src, eltLength)) { 00158 00159 if (G3d_isNullValueNum(src, srcType)) { 00160 G3d_setXdrNullNum(xdrTmp, isFloat); 00161 if (!xdr_setpos(xdrs, xdr_getpos(xdrs) + externLength)) { 00162 G3d_error("G3d_copyToXdr: positioning xdr failed"); 00163 return 0; 00164 } 00165 } 00166 else { 00167 if (type == srcType) { 00168 if (xdrFun(xdrs, src) < 0) { 00169 G3d_error("G3d_copyToXdr: writing xdr failed"); 00170 return 0; 00171 } 00172 } 00173 else { 00174 if (type == FCELL_TYPE) 00175 *((float *)tmp) = (float)*((double *)src); 00176 else 00177 *((double *)tmp) = (double)*((float *)src); 00178 if (xdrFun(xdrs, tmp) < 0) { 00179 G3d_error("G3d_copyToXdr: writing xdr failed"); 00180 return 0; 00181 } 00182 } 00183 } 00184 00185 xdrTmp = G_incr_void_ptr(xdrTmp, externLength); 00186 } 00187 00188 return 1; 00189 } 00190 00191 /*---------------------------------------------------------------------------*/ 00192 00193 int G3d_initCopyFromXdr(G3D_Map * map, int dType) 00194 { 00195 xdrTmp = xdr; 00196 useXdr = map->useXdr; 00197 dstType = dType; 00198 00199 if (useXdr == G3D_USE_XDR) { 00200 if (!xdr_setpos(&(xdrDecodeStream), 0)) { 00201 G3d_error("G3d_initCopyFromXdr: positioning xdr failed"); 00202 return 0; 00203 } 00204 xdrs = &(xdrDecodeStream); 00205 } 00206 00207 type = map->type; 00208 isFloat = (type == FCELL_TYPE); 00209 externLength = G3d_externLength(type); 00210 eltLength = G3d_length(dstType); 00211 if (isFloat) 00212 xdrFun = xdr_float; 00213 else 00214 xdrFun = xdr_double; 00215 tmp = &tmpValue; 00216 00217 return 1; 00218 } 00219 00220 /*---------------------------------------------------------------------------*/ 00221 00222 int G3d_copyFromXdr(int nofNum, void *dst) 00223 { 00224 int i; 00225 00226 if (useXdr == G3D_NO_XDR) { 00227 G3d_copyValues(xdrTmp, 0, type, dst, 0, dstType, nofNum); 00228 xdrTmp = G_incr_void_ptr(xdrTmp, nofNum * G3d_externLength(type)); 00229 return 1; 00230 } 00231 00232 for (i = 0; i < nofNum; i++, dst = G_incr_void_ptr(dst, eltLength)) { 00233 00234 if (G3d_isXdrNullNum(xdrTmp, isFloat)) { 00235 G3d_setNullValue(dst, 1, dstType); 00236 if (!xdr_setpos(xdrs, xdr_getpos(xdrs) + externLength)) { 00237 G3d_error("G3d_copyFromXdr: positioning xdr failed"); 00238 return 0; 00239 } 00240 } 00241 else { 00242 if (type == dstType) { 00243 if (xdrFun(xdrs, dst) < 0) { 00244 G3d_error("G3d_copyFromXdr: reading xdr failed"); 00245 return 0; 00246 } 00247 } 00248 else { 00249 if (xdrFun(xdrs, tmp) < 0) { 00250 G3d_error("G3d_copyFromXdr: reading xdr failed"); 00251 return 0; 00252 } 00253 if (type == FCELL_TYPE) 00254 *((double *)dst) = (double)*((float *)tmp); 00255 else 00256 *((float *)dst) = (float)*((double *)tmp); 00257 } 00258 } 00259 00260 xdrTmp = G_incr_void_ptr(xdrTmp, externLength); 00261 } 00262 00263 return 1; 00264 }