00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #pragma ident "@(#) libf/fio/frwd.c 92.3 09/29/99 19:50:24"
00039
00040 #include <errno.h>
00041 #include <fortran.h>
00042 #include <liberrno.h>
00043 #ifdef _ABSOFT
00044 #include <stdlib.h>
00045 #endif
00046 #include <cray/nassert.h>
00047 #include "fio.h"
00048
00049 #include <stdlib.h>
00050
00051 #define TBFSZ (4096 * sizeof(long))
00052
00053 static const _f_int bitoff = 0;
00054 static const _f_int stride = 1;
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 long
00091 _frwd(
00092 unit *cup,
00093 void *uda,
00094 type_packet *tip,
00095 int mode,
00096 int *ubcret,
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 long *wr,
00107
00108
00109
00110
00111
00112
00113
00114 int *status)
00115 {
00116 register int fdsize;
00117 register int padbyts;
00118 register long elsize;
00119 register long items;
00120 register ftype_t type;
00121 register size_t breq;
00122 register ssize_t ret;
00123 register int64 totbits;
00124 int padubc;
00125 int ubc;
00126 _f_int icount;
00127
00128
00129
00130 #ifdef _UNICOS
00131 assert ( _numargs() == 7 );
00132 #endif
00133 assert ( mode == FULL || mode == PARTIAL );
00134 assert ( tip != NULL );
00135 assert ( status != NULL );
00136
00137 type = tip->type90;
00138 elsize = tip->elsize;
00139 items = tip->count;
00140 breq = elsize * items;
00141 padbyts = 0;
00142 padubc = 0;
00143 ubc = 0;
00144
00145
00146
00147
00148
00149 if (ubcret != NULL) {
00150 if ((*ubcret & 7) != 0 && cup->ufs != FS_FDC) {
00151 errno = FEUBCINV;
00152 return(IOERR);
00153 }
00154 if (type != DVTYPE_TYPELESS) {
00155 errno = FEINTUNK;
00156 return(IOERR);
00157 }
00158
00159
00160
00161 breq -= *ubcret >> 3;
00162 ubc = *ubcret & 7;
00163 }
00164 #if NUMERIC_DATA_CONVERSION_ENABLED
00165 else {
00166
00167
00168
00169
00170
00171
00172 if ((cup->urecpos & cup->ualignmask) != 0 &&
00173 type != DVTYPE_ASCII &&
00174 items > 0 &&
00175 #if defined(__mips) || defined(_LITTLE_ENDIAN)
00176 elsize > 2 ) {
00177 #else
00178 elsize > 4 ) {
00179 #endif
00180
00181 long blanks;
00182 COMPADD(cup, padbyts, padubc, blanks);
00183 }
00184 }
00185 #endif
00186
00187 cup->ulastyp = type;
00188
00189 *status = CNT;
00190
00191
00192
00193
00194 switch ( cup->ufs ) {
00195
00196 case STD:
00197
00198
00199
00200
00201
00202 if (items == 0)
00203 return(0);
00204
00205 ret = 1;
00206
00207 if (padbyts > 0) {
00208 int dummy;
00209
00210 ret = fread(&dummy, 1, padbyts, cup->ufp.std);
00211
00212 if (ret > 0)
00213 cup->urecpos += (uint64)ret << 3;
00214
00215 }
00216 if (ret > 0)
00217 ret = fread(uda, 1, breq, cup->ufp.std );
00218
00219 if (ret == 0) {
00220 if ( ferror(cup->ufp.std) ) {
00221 if (errno == 0)
00222 errno = FESTIOER;
00223 return(IOERR);
00224 }
00225 *status = EOD;
00226 return(0);
00227 }
00228
00229
00230
00231
00232 icount = ret / elsize;
00233 cup->urecpos = cup->urecpos + (uint64) (ret << 3);
00234
00235 if ((ret % elsize) != 0)
00236 if (type == DVTYPE_TYPELESS) {
00237
00238 icount = icount + 1;
00239
00240 if (ubcret != NULL)
00241 *ubcret = (elsize - (ret % elsize)) << 3;
00242 }
00243 else
00244 if (icount == 0) {
00245 errno = FERDPEOR;
00246 return(IOERR);
00247 }
00248
00249 break;
00250
00251 case FS_FDC:
00252
00253
00254
00255
00256 if (padbyts > 0) {
00257 long paddval;
00258
00259 ret = XRCALL(cup->ufp.fdc, readrtn) cup->ufp.fdc,
00260 CPTR2BP(&paddval), padbyts, &cup->uffsw,
00261 PARTIAL, &padubc);
00262
00263 if (ret != padbyts || FFSTAT(cup->uffsw) != FFCNT) {
00264
00265 if (ret < 0) {
00266 errno = cup->uffsw.sw_error;
00267 return(IOERR);
00268 }
00269
00270 *status = FF2FTNST(FFSTAT(cup->uffsw));
00271
00272 return(0);
00273 }
00274
00275 cup->urecpos += ((uint64)ret << 3) - padubc;
00276 }
00277
00278
00279
00280 if (tip->cnvindx == 0) {
00281 register short erret;
00282
00283
00284
00285 ret = XRCALL(cup->ufp.fdc, readrtn) cup->ufp.fdc,
00286 CPTR2BP(uda), breq,
00287 &cup->uffsw, mode, &ubc);
00288
00289 *status = FF2FTNST(FFSTAT(cup->uffsw));
00290 erret = 0;
00291
00292 if (*status == EOR)
00293 cup->ulastyp = DVTYPE_TYPELESS;
00294
00295 if (ret < 0) {
00296
00297 errno = cup->uffsw.sw_error;
00298
00299 if (errno == FETAPUTE) {
00300 ret = cup->uffsw.sw_count;
00301 erret = 1;
00302 }
00303 else
00304 return(IOERR);
00305 }
00306 else
00307 if (ret == 0)
00308 return(0);
00309
00310
00311
00312
00313
00314
00315
00316 totbits = ((uint64)ret << 3) - ubc;
00317 cup->urecpos = cup->urecpos + totbits;
00318 icount = totbits / (elsize << 3);
00319
00320 if (type == DVTYPE_TYPELESS) {
00321
00322 if ((((uint64)icount*elsize) << 3) != totbits) {
00323
00324 icount = icount + 1;
00325
00326 if (ubcret != NULL)
00327 *ubcret = (elsize << 3) -
00328 (totbits % (elsize << 3));
00329 }
00330
00331 if (wr != NULL)
00332 *wr = icount;
00333 }
00334 else
00335 if (icount == 0) {
00336 errno = FERDPEOR;
00337 erret = 1;
00338 }
00339
00340 if (erret == 1)
00341 return(IOERR);
00342
00343 goto done;
00344 }
00345
00346 #if NUMERIC_DATA_CONVERSION_ENABLED
00347
00348
00349
00350 {
00351 int (* cvt_fun)();
00352 _f_int dctype;
00353 char tbuf[TBFSZ];
00354 char *bptr;
00355
00356 cvt_fun = __fndc_ncfunc[tip->cnvindx].to_native;
00357
00358 #if !defined(__mips) && !defined(_LITTLE_ENDIAN)
00359 if (!_loaded(cvt_fun)) {
00360 errno = FELDDCNV;
00361 return(IOERR);
00362 }
00363 #endif
00364
00365 fdsize = tip->extlen;
00366 dctype = tip->cnvtype;
00367
00368
00369
00370
00371
00372
00373
00374
00375 if (fdsize == 0) {
00376 errno = FDC_ERR_NCVRT;
00377 return(IOERR);
00378 }
00379
00380 totbits = items * fdsize;
00381
00382
00383 if (type == DVTYPE_ASCII)
00384 totbits = totbits * tip->elsize;
00385
00386 if (ubcret != NULL)
00387 totbits = totbits - *ubcret;
00388
00389
00390
00391
00392
00393
00394 bptr = tbuf;
00395 breq = (totbits + 7) >> 3;
00396 ubc = ((uint64)breq << 3) - totbits;
00397
00398 if (breq > TBFSZ) {
00399 bptr = (char *) malloc(breq);
00400
00401 if (bptr == NULL) {
00402 errno = FENOMEMY;
00403 return(IOERR);
00404 }
00405 }
00406
00407
00408
00409 ret = XRCALL(cup->ufp.fdc, readrtn) cup->ufp.fdc,
00410 CPTR2BP(bptr), breq,
00411 &cup->uffsw, mode, &ubc);
00412
00413 *status = FF2FTNST(FFSTAT(cup->uffsw));
00414
00415 if (*status == EOR)
00416 cup->ulastyp = DVTYPE_TYPELESS;
00417
00418 if (ret <= 0) {
00419 register long stat = EOR;
00420
00421 if (bptr != tbuf)
00422 free(bptr);
00423
00424 if (ret < 0) {
00425 errno = cup->uffsw.sw_error;
00426 stat = IOERR;
00427 }
00428
00429 return(stat);
00430 }
00431
00432
00433
00434
00435
00436 totbits = ((uint64)ret << 3) - ubc;
00437 icount = totbits / fdsize;
00438
00439 if (((int64)icount * fdsize) != totbits) {
00440 if (bptr != tbuf)
00441 free(bptr);
00442
00443 errno = FDC_ERR_PITM;
00444 return(IOERR);
00445 }
00446
00447
00448
00449 {
00450 register _f_int numerr;
00451 #ifdef _CRAY
00452 _fcd craychr;
00453
00454 craychr = _cptofcd((char *)uda, items);
00455 #endif
00456
00457 if (tip->newfunc) {
00458 _f_int flen;
00459 _f_int nlen;
00460
00461 flen = fdsize;
00462 nlen = tip->intlen;
00463
00464 numerr = cvt_fun(&dctype, &icount, (void *) bptr,
00465 &bitoff, (void *)uda, &stride, &nlen,
00466 &flen,
00467 #ifdef _CRAY
00468 craychr);
00469 #else
00470 (char *)uda, items);
00471 #endif
00472 }
00473 else {
00474
00475 numerr = cvt_fun(&dctype, &icount, (void *)bptr,
00476 &bitoff, (void *)uda, &stride,
00477 #ifdef _CRAY
00478 craychr);
00479 #else
00480 (char *)uda, items);
00481 #endif
00482 }
00483
00484 if (bptr != tbuf)
00485 free(bptr);
00486
00487 if (numerr != 0) {
00488 errno = (numerr < 0) ? FEINTUNK : FDC_ERR_NCVRT;
00489 return(IOERR);
00490 }
00491 }
00492 }
00493
00494 cup->urecpos += totbits;
00495 #endif
00496
00497 break;
00498
00499 case FS_AUX:
00500 errno = FEMIXAUX;
00501 icount = IOERR;
00502 break;
00503
00504 default:
00505 errno = FEINTFST;
00506 icount = IOERR;
00507 break;
00508 }
00509
00510 done:
00511 return(icount);
00512 }