[Getdata-commits] SF.net SVN: getdata:[874] trunk/getdata
Scientific Database Format
Brought to you by:
ketiltrout
|
From: <ket...@us...> - 2013-12-17 02:04:56
|
Revision: 874
http://sourceforge.net/p/getdata/code/874
Author: ketiltrout
Date: 2013-12-17 02:04:49 +0000 (Tue, 17 Dec 2013)
Log Message:
-----------
Perform all the endianness-correction detection logic in one place (_GD_CheckByteSex) instead of duplicating it all over the place; unrelated doc updates.
Modified Paths:
--------------
trunk/getdata/ChangeLog
trunk/getdata/man/gd_add_bit.3
trunk/getdata/man/gd_alter_bit.3
trunk/getdata/src/add.c
trunk/getdata/src/encoding.c
trunk/getdata/src/endian.c
trunk/getdata/src/flimits.c
trunk/getdata/src/fpos.c
trunk/getdata/src/getdata.c
trunk/getdata/src/internal.h
trunk/getdata/src/mod.c
trunk/getdata/src/move.c
trunk/getdata/src/nframes.c
trunk/getdata/src/parse.c
trunk/getdata/src/putdata.c
Modified: trunk/getdata/ChangeLog
===================================================================
--- trunk/getdata/ChangeLog 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/ChangeLog 2013-12-17 02:04:49 UTC (rev 874)
@@ -1,3 +1,13 @@
+2013-12-12 D. V. Wiebe <ge...@ke...> svn:874
+ * src/endian.c (_GD_CheckByteSex): Added.
+ * src/endian.c (_GD_FileSwapBytes): Added (replacing macro in internal.h).
+ * src/endian.c (_GD_FixEndianness): Call _GD_CheckByteSex() to check wether
+ correction is needed.
+
+ * src/getdata.c (_GD_DoRaw) src/move.c (_GD_MogrifyFile) src/putdata.c
+ (_GD_DoRawOut): Let _GD_FixEndianness and _GD_CheckByteSex do the endianness
+ logic.
+
2013-12-12 D. V. Wiebe <ge...@ke...> svn:872
* configure.ac: Disable PHP bindings if we don't have a C99 compiler.
Modified: trunk/getdata/man/gd_add_bit.3
===================================================================
--- trunk/getdata/man/gd_add_bit.3 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/man/gd_add_bit.3 2013-12-17 02:04:49 UTC (rev 874)
@@ -311,7 +311,7 @@
is 2**24. It is larger on a 64-bit system.
The C89 GetData API provides different prototypes for
-.BR gd_add_clincom ()", " gd_add_cpolynom (),
+.BR gd_add_clincom "(), " gd_add_cpolynom (),
and
.BR gd_add_crecip ():
.PP
@@ -331,7 +331,7 @@
.BI int " fragment_index );
.HP
.BI "int gd_add_crecip(DIRFILE *" dirfile ", const char *" field_name ,
-.BI "const char *" in_field ", double " cdividend [2],
+.BI "const char *" in_field ", const double " cdividend [2],
.BI "int " fragment_index );
.hy
.ad n
Modified: trunk/getdata/man/gd_alter_bit.3
===================================================================
--- trunk/getdata/man/gd_alter_bit.3 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/man/gd_alter_bit.3 2013-12-17 02:04:49 UTC (rev 874)
@@ -302,7 +302,7 @@
.BI "int " poly_ord ", const char *" in_fields ", const double *" ca );
.HP
.BI "int gd_alter_crecip(DIRFILE *" dirfile ", const char *" field_code ,
-.BI "const char *" in_field ", double " cdividend [2]);
+.BI "const char *" in_field ", const double " cdividend [2]);
.hy
.ad n
.PP
@@ -337,7 +337,10 @@
.BR gd_alter_crecip ()
is always available, and may be accessed as
.BR gd_alter_crecip89 (),
-with the C89 prototype, in both the C99 and C89 APIs.
+with the C89 prototype, in both the C99 and C89 APIs. Passing NULL as
+.I cdividend
+is equivalent to specifying a dividend of zero: it indicates no change to the
+dividend parameter.
.SH SEE ALSO
.BR gd_alter_entry (3),
Modified: trunk/getdata/src/add.c
===================================================================
--- trunk/getdata/src/add.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/add.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -298,8 +298,7 @@
GD_SIZE(E->EN(raw,data_type))) == 0)
_GD_SetError(D, GD_E_BAD_TYPE, entry->EN(raw,data_type), NULL, 0, NULL);
else if (_GD_InitRawIO(D, E, NULL, 0, NULL, 0,
- GD_FILE_WRITE | GD_FILE_TOUCH,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ GD_FILE_WRITE | GD_FILE_TOUCH, _GD_FileSwapBytes(D, E)))
{
;
} else if (D->fragment[E->fragment_index].ref_name == NULL) {
Modified: trunk/getdata/src/encoding.c
===================================================================
--- trunk/getdata/src/encoding.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/encoding.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -36,6 +36,7 @@
NULL
#define GD_EF_GENERIC_SET &_GD_GenericName, NULL, NULL, NULL, NULL, NULL, \
NULL, NULL, &_GD_GenericMove, &_GD_GenericUnlink
+
#ifdef USE_MODULES
#define GD_EXT_ENCODING_NULL(sc,ex,ec,af,ff) \
{ sc,ex,ec,af,ff,GD_EF_PROVIDES,GD_EF_NULL_SET }
Modified: trunk/getdata/src/endian.c
===================================================================
--- trunk/getdata/src/endian.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/endian.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -63,7 +63,7 @@
break;
/* if the field's data type is one byte long, and no in-framework
- * byte-swapping is required, do nothing */
+ * byte-swapping is performed, do nothing */
if (D->entry[i]->e->u.raw.size == 1 &&
!(gd_ef_[D->entry[i]->e->u.raw.file[0].subenc].flags & GD_EF_SWAP))
continue;
@@ -174,40 +174,164 @@
return D->fragment[fragment].byte_sex;
}
-void _GD_ArmEndianise(uint64_t* databuffer, int is_complex, size_t ns)
+static void _GD_ArmEndianise(uint64_t* databuffer, size_t ns)
{
uint64_t *p;
- dtrace("%p, %i, %zi", databuffer, is_complex, ns);
+ dtrace("%p, %zi", databuffer, ns);
- if (is_complex)
- ns *= 2;
-
for (p = databuffer; p < databuffer + ns; ++p)
*p = ((*p & 0xffffffff) << 32) | ((*p & 0xffffffff00000000ULL) >> 32);
dreturnvoid();
}
-void _GD_FixEndianness(void* databuffer, size_t size, size_t ns)
+/* determine byte sex flags for the machine endianness */
+#ifdef FLOATS_BIGENDIAN
+#define GD_FLOAT_SEX GD_BIG_ENDIAN
+#else
+#define GD_FLOAT_SEX GD_LITTLE_ENDIAN
+#endif
+
+#ifdef WORDS_BIGENDIAN
+#define GD_INT_SEX GD_BIG_ENDIAN
+#else
+#define GD_INT_SEX GD_LITTLE_ENDIAN
+#endif
+
+/* returns non-zero if sex1 and sex2 imply byte sex correction is required, and
+ * sets *arm_fix if middle-ended double correction is needed; returns
+ */
+int _GD_CheckByteSex(gd_type_t type, unsigned sex1, unsigned sex2,
+ int skip_bytes, int *restrict arm_fix)
{
+ int endian_fix = 0;
+
+ dtrace("0x%X, 0x%X, 0x%X, %p", type, sex1, sex2, arm_fix);
+
+ /* the trivial case */
+ if (GD_SIZE(type) < 1 || (skip_bytes && GD_SIZE(type) == 1)) {
+ if (arm_fix)
+ *arm_fix = 0;
+ dreturn("%i/%i", 0, 0);
+ return 0;
+ }
+
+ /* ensure we have exactly one of GD_BIG_ENDIAN or GD_LITTLE_ENDIAN set in
+ * both bitfields */
+ if (type & (GD_IEEE754 | GD_COMPLEX)) {
+ /* arm check */
+ if (arm_fix) {
+ if (type == GD_FLOAT64 || type == GD_COMPLEX128)
+ *arm_fix = ((sex1 & GD_ARM_FLAG) != (sex2 & GD_ARM_FLAG));
+ else
+ *arm_fix = 0;
+ }
+
+ switch (sex1 & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) {
+ case 0:
+ sex1 |= GD_FLOAT_SEX;
+ break;
+ case GD_LITTLE_ENDIAN | GD_BIG_ENDIAN:
+ sex1 &= ~GD_FLOAT_SEX;
+ break;
+ default:
+ break; /* bits are okay */
+ }
+ switch (sex2 & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) {
+ case 0:
+ sex2 |= GD_FLOAT_SEX;
+ break;
+ case GD_LITTLE_ENDIAN | GD_BIG_ENDIAN:
+ sex2 &= ~GD_FLOAT_SEX;
+ break;
+ default:
+ break; /* bits are okay */
+ }
+ } else {
+ if (arm_fix)
+ *arm_fix = 0;
+
+ switch (sex1 & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) {
+ case 0:
+ sex1 |= GD_INT_SEX;
+ break;
+ case GD_LITTLE_ENDIAN | GD_BIG_ENDIAN:
+ sex1 &= ~GD_INT_SEX;
+ break;
+ default:
+ break; /* bits are okay */
+ }
+ switch (sex2 & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) {
+ case 0:
+ sex2 |= GD_INT_SEX;
+ break;
+ case GD_LITTLE_ENDIAN | GD_BIG_ENDIAN:
+ sex2 &= ~GD_INT_SEX;
+ break;
+ default:
+ break; /* bits are okay */
+ }
+ }
+
+ /* endianness check */
+ endian_fix = ((sex1 & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) !=
+ (sex2 & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)));
+
+ dreturn("%i/%i", endian_fix, arm_fix ? *arm_fix : -1);
+ return endian_fix;
+}
+
+/* returns non-zero if the byte sex of RAW entry E is different than the native
+ * machine endianness */
+int _GD_FileSwapBytes(const DIRFILE *restrict D, const gd_entry_t *restrict E)
+{
+ int swap;
+
+ dtrace("%p, %p", D, E);
+
+ swap = _GD_CheckByteSex(E->EN(raw,data_type),
+ D->fragment[E->fragment_index].byte_sex, 0, 0, NULL);
+
+ dreturn("%i", swap);
+ return swap;
+}
+
+void _GD_FixEndianness(void* databuffer, size_t ns, gd_type_t type, unsigned
+ old_sex, unsigned new_sex)
+{
size_t i;
+ int endian_fix, arm_fix;
- dtrace("%p, %zu, %" PRNsize_t, databuffer, size, ns);
+ dtrace("%p, %" PRNsize_t ", 0x%X, 0x%X, 0x%X", databuffer, ns, type, old_sex,
+ new_sex);
- switch (size) {
- case 2:
- for (i = 0; i < ns; ++i)
- ((uint16_t*)databuffer)[i] = gd_swap16(((uint16_t*)databuffer)[i]);
- break;
- case 4:
- for (i = 0; i < ns; ++i)
- ((uint32_t*)databuffer)[i] = gd_swap32(((uint32_t*)databuffer)[i]);
- break;
- case 8:
- for (i = 0; i < ns; ++i)
- ((uint64_t*)databuffer)[i] = gd_swap64(((uint64_t*)databuffer)[i]);
- break;
+ /* compare byte sexes */
+ endian_fix = _GD_CheckByteSex(type, old_sex, new_sex, 1, &arm_fix);
+
+ /* complex data - treat as twice as many floating point */
+ if (type & GD_COMPLEX) {
+ ns *= 2;
+ type = (GD_SIZE(type) >> 1) | GD_IEEE754;
}
+ if (arm_fix)
+ _GD_ArmEndianise(databuffer, ns);
+
+ if (endian_fix)
+ switch (GD_SIZE(type)) {
+ case 2:
+ for (i = 0; i < ns; ++i)
+ ((uint16_t*)databuffer)[i] = gd_swap16(((uint16_t*)databuffer)[i]);
+ break;
+ case 4:
+ for (i = 0; i < ns; ++i)
+ ((uint32_t*)databuffer)[i] = gd_swap32(((uint32_t*)databuffer)[i]);
+ break;
+ case 8:
+ for (i = 0; i < ns; ++i)
+ ((uint64_t*)databuffer)[i] = gd_swap64(((uint64_t*)databuffer)[i]);
+ break;
+ }
+
dreturnvoid();
}
Modified: trunk/getdata/src/flimits.c
===================================================================
--- trunk/getdata/src/flimits.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/flimits.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -201,7 +201,7 @@
ns = (*gd_ef_[E->e->u.raw.file[0].subenc].size)(
D->fragment[E->fragment_index].dirfd, E->e->u.raw.file,
- E->EN(raw,data_type), _GD_FileSwapBytes(D, E->fragment_index));
+ E->EN(raw,data_type), _GD_FileSwapBytes(D, E));
if (ns < 0) {
_GD_SetError(D, GD_E_RAW_IO, 0, E->e->u.raw.file[0].name, errno, NULL);
Modified: trunk/getdata/src/fpos.c
===================================================================
--- trunk/getdata/src/fpos.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/fpos.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -39,7 +39,7 @@
/* We must open the file to know its starting offset */
if (E->e->u.raw.file[0].idata < 0)
if (_GD_InitRawIO(D, E, NULL, 0, NULL, 0, GD_FILE_READ,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
{
break;
}
@@ -175,7 +175,7 @@
dreturn("%i", -1);
return -1;
} else if (_GD_InitRawIO(D, E, NULL, 0, NULL, GD_EF_SEEK, GD_FILE_WRITE,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
{
dreturn("%i", -1);
return -1;
@@ -255,7 +255,7 @@
case GD_RAW_ENTRY:
/* open/create the file, if necessary */
if (_GD_InitRawIO(D, E, NULL, 0, NULL, GD_EF_SEEK, mode,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
{
break;
}
Modified: trunk/getdata/src/getdata.c
===================================================================
--- trunk/getdata/src/getdata.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/getdata.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -253,8 +253,8 @@
static size_t _GD_DoRaw(DIRFILE *restrict D, gd_entry_t *restrict E, off64_t s0,
size_t ns, gd_type_t return_type, void *restrict data_out)
{
- size_t n_read = 0;
- ssize_t samples_read;
+ size_t n_read, zeroed_samples = 0;
+ ssize_t samples_read = 0;
char *databuffer;
size_t zero_pad = 0;
@@ -274,11 +274,10 @@
}
if (zero_pad > 0) {
- n_read = _GD_FillZero(databuffer, E->EN(raw,data_type), (zero_pad > ns) ?
- ns :
- zero_pad);
- ns -= n_read;
- E->e->u.raw.file[0].pos = s0 + n_read - E->EN(raw,spf) *
+ zeroed_samples = _GD_FillZero(databuffer, E->EN(raw,data_type),
+ (zero_pad > ns) ? ns : zero_pad);
+ ns -= zeroed_samples;
+ E->e->u.raw.file[0].pos = s0 + zeroed_samples - E->EN(raw,spf) *
D->fragment[E->fragment_index].frame_offset;
s0 = 0;
}
@@ -286,7 +285,7 @@
if (ns > 0) {
/** open the file (and cache the fp) if it hasn't been opened yet. */
if (_GD_InitRawIO(D, E, NULL, 0, NULL, GD_EF_SEEK | GD_EF_READ,
- GD_FILE_READ, _GD_FileSwapBytes(D, E->fragment_index)))
+ GD_FILE_READ, _GD_FileSwapBytes(D, E)))
{
free(databuffer);
dreturn("%i", 0);
@@ -302,9 +301,9 @@
return 0;
}
- samples_read =
- (*gd_ef_[E->e->u.raw.file[0].subenc].read)(E->e->u.raw.file,
- databuffer + n_read * E->e->u.raw.size, E->EN(raw,data_type), ns);
+ samples_read = (*gd_ef_[E->e->u.raw.file[0].subenc].read)(E->e->u.raw.file,
+ databuffer + zeroed_samples * E->e->u.raw.size, E->EN(raw,data_type),
+ ns);
if (samples_read == -1) {
_GD_SetError(D, GD_E_RAW_IO, 0, E->e->u.raw.file[0].name, errno, NULL);
@@ -313,35 +312,15 @@
return 0;
}
- if (gd_ef_[E->e->u.raw.file[0].subenc].flags & GD_EF_ECOR) {
- /* convert to/from middle-ended doubles */
- if ((E->EN(raw,data_type) == GD_FLOAT64 ||
- E->EN(raw,data_type) == GD_COMPLEX128) &&
- D->fragment[E->fragment_index].byte_sex & GD_ARM_FLAG)
- {
- _GD_ArmEndianise((uint64_t *)(databuffer + n_read * E->e->u.raw.size),
- E->EN(raw,data_type) & GD_COMPLEX, samples_read);
- }
+ if (gd_ef_[E->e->u.raw.file[0].subenc].flags & GD_EF_ECOR)
+ _GD_FixEndianness(databuffer + zeroed_samples * E->e->u.raw.size,
+ samples_read, E->EN(raw,data_type),
+ D->fragment[E->fragment_index].byte_sex, 0);
- if (D->fragment[E->fragment_index].byte_sex &
-#ifdef WORDS_BIGENDIAN
- GD_LITTLE_ENDIAN
-#else
- GD_BIG_ENDIAN
-#endif
- )
- {
- if (E->EN(raw,data_type) & GD_COMPLEX)
- _GD_FixEndianness(databuffer + n_read * E->e->u.raw.size,
- E->e->u.raw.size / 2, samples_read * 2);
- else
- _GD_FixEndianness(databuffer + n_read * E->e->u.raw.size,
- E->e->u.raw.size, samples_read);
- }
- }
+ }
- n_read += samples_read;
- }
+ n_read = samples_read + zeroed_samples;
+
_GD_ConvertType(D, databuffer, E->EN(raw,data_type), data_out, return_type,
n_read);
Modified: trunk/getdata/src/internal.h
===================================================================
--- trunk/getdata/src/internal.h 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/internal.h 2013-12-17 02:04:49 UTC (rev 874)
@@ -807,7 +807,12 @@
#define GD_E_ARG_NO_VERS 5
#define GD_E_ARG_BAD_VERS 6
+/* the size of the memory buffer used for various bulk I/O operations */
+#define BUFFER_SIZE 9000000
+/* number of lines chunked-in from a LINTERP table at a time */
+#define GD_LUT_CHUNK 100
+
/* I/O flags */
#define GD_FILE_READ 0x1
#define GD_FILE_WRITE 0x2
@@ -899,20 +904,19 @@
} u;
};
-#define GD_ENC_NONE 0
-#define GD_ENC_SLIM 1
-#define GD_ENC_GZ_RAW 2
-#define GD_ENC_BZ2_RAW 3
-#define GD_ENC_ASCII 4
-#define GD_ENC_LZMA_RAW 5
-#define GD_ENC_XZ_RAW 6
-#define GD_ENC_SIE 7
-#define GD_ENC_ZZIP 8
-#define GD_ENC_ZZSLIM 9
-#define GD_ENC_UNKNOWN 10
+/* _GD_FiniRawIO flags */
+#define GD_FINIRAW_KEEP 0x0
+#define GD_FINIRAW_DISCARD 0x1
+#define GD_FINIRAW_DEFER 0x2
+#define GD_FINIRAW_CLOTEMP 0x4
-#define GD_N_SUBENCODINGS (GD_ENC_UNKNOWN + 1)
+/* number of subencodings (ie. the length of the gd_ef_ array */
+#define GD_N_SUBENCODINGS 11
+/* the last record of the gd_ef_ array is always the unknown encoding */
+#define GD_ENC_UNKNOWN (GD_N_SUBENCODINGS - 1)
+
+/* external module function provides flags */
#define GD_EF_NAME 0x0001
#define GD_EF_OPEN 0x0002
#define GD_EF_CLOSE 0x0004
@@ -924,21 +928,7 @@
#define GD_EF_MOVE 0x0100
#define GD_EF_UNLINK 0x0200
-#define GD_FINIRAW_KEEP 0x0
-#define GD_FINIRAW_DISCARD 0x1
-#define GD_FINIRAW_DEFER 0x2
-#define GD_FINIRAW_CLOTEMP 0x4
-
-#define BUFFER_SIZE 9000000
-
-#define GD_LUT_CHUNK 100
-
-/* helper macro */
-#if defined ARM_ENDIAN_FLOATS || \
- ((defined WORDS_BIGENDIAN) ^ (defined FLOATS_BIGENDIAN))
-# define SCREWY_FLOATS
-#endif
-
+/* encoding scheme method prototypes */
typedef int (*gd_ef_name_t)(DIRFILE *D, const char *, struct gd_raw_file_*,
const char*, int, int);
typedef int (*gd_ef_open_t)(int, struct gd_raw_file_*, int, unsigned int);
@@ -955,17 +945,38 @@
/* Encoding scheme flags */
#define GD_EF_ECOR 0x1 /* post-framework byte-sex correction required */
-#define GD_EF_SWAP 0x2 /* in-framework byte-sex metadata correction required */
+#define GD_EF_SWAP 0x2 /* in-framework byte-sex metadata correction occurs */
#define GD_EF_OOP 0x4 /* writes occur out-of-place */
#define GD_EF_EDAT 0x8 /* The /ENCODING datum is used */
+
+/* Just so we're clear on the difference between GD_EF_ECOR and GD_EF_SWAP:
+ *
+ * - ECOR means the data returned by the encoding framework has the byte sex of
+ * the fragment; GetData needs to swap bytes around after the framework
+ * finishes if this is different than the machine endianness. Most binary
+ * formats set ECOR, but TEXT doesn't, since sscanf() puts stuff into the
+ * machine endianness.
+ *
+ * - SWAP means that internal workings of the encoding needs to know whether
+ * the byte sex of the fragment is different than the machine endianness.
+ * This is set by SIE since its sample indices are stored in the fragment
+ * endianness, which need to be converted by within the encoding scheme itself
+ * to be able to read opposite endian data files.
+ *
+ * Note: any encoding scheme could set SWAP instead of ECOR and then perform its
+ * own byte sex correction to hide it from GetData proper, but this should be
+ * avoided because it can lead to more byte swapping than necessary.
+ */
+
/* Encoding schemes */
extern struct encoding_t {
- unsigned long int scheme;
- const char* ext;
- unsigned int flags; /* flags */
- const char* affix;
- const char* ffname;
- unsigned int provides;
+ unsigned long int scheme; /* scheme number (the gd_open() flag value) */
+ const char* ext; /* filename extension */
+ unsigned int flags; /* encoding flags */
+ const char* affix; /* function name prefix (NULL for internal scheme)*/
+ const char* ffname; /* /ENCODING directive name */
+ unsigned int provides; /* bitfield of functions provided by external
+ module (0 for internal scheme) */
gd_ef_name_t name;
gd_ef_open_t open;
gd_ef_close_t close;
@@ -980,14 +991,10 @@
/* Format file fragment metadata */
struct gd_fragment_t {
- /* Canonical name (full path) */
- char* cname;
- /* Subdirectory name */
- char* sname;
- /* basename */
- char *bname;
- /* External name (the one that appears in the format file) */
- char* ename;
+ char* cname; /* Canonical name (full path) */
+ char* sname; /* Subdirectory name (path relative to dirfile or absolute) */
+ char *bname; /* basename (filename) */
+ char* ename; /* External name (the one that appears in the format file) */
void *enc_data;
int modified;
int parent;
@@ -1011,7 +1018,7 @@
int rc;
};
-/* internal flags */
+/* internal dirfile flags */
#define GD_MULTISTANDARD 0x20000000 /* have multiple standards in format */
#define GD_HAVE_VERSION 0x40000000 /* have computed the version */
#define GD_INVALID 0x80000000 /* the dirfile is invalid */
@@ -1023,6 +1030,7 @@
#define GD_REPR_MOD 'm'
#define GD_REPR_ARG 'a'
+/* the implicit representation */
#define GD_REPR_AUTO GD_REPR_REAL
/* The DIRFILE struct. */
@@ -1089,7 +1097,6 @@
/* forward declarations */
void *_GD_Alloc(DIRFILE*, gd_type_t, size_t) __attribute_malloc__;
-void _GD_ArmEndianise(uint64_t*, int, size_t);
int _GD_BadInput(DIRFILE *, const gd_entry_t *, int, int);
#define _GD_BadWindop(op) \
@@ -1101,6 +1108,7 @@
int _GD_CalculateEntry(DIRFILE *restrict, gd_entry_t *restrict, int);
char *_GD_CanonicalPath(const char *restrict, const char *restrict);
+int _GD_CheckByteSex(gd_type_t, unsigned, unsigned, int, int *restrict);
gd_entry_t *_GD_CheckParent(DIRFILE *restrict D, char **restrict name, int me,
int linenum);
int _GD_CheckCodeAffixes(DIRFILE *D, const gd_entry_t *P,
@@ -1131,12 +1139,8 @@
gd_entry_t *_GD_FindFieldAndRepr(DIRFILE *restrict, const char *restrict,
char **restrict, int *restrict, unsigned int *restrict, int, int);
uint64_t _GD_FindVersion(DIRFILE *D);
-void _GD_FixEndianness(void* databuffer, size_t size, size_t ns);
-#ifdef WORDS_BIGENDIAN
-#define _GD_FileSwapBytes(D,i) ((D)->fragment[i].byte_sex & GD_LITTLE_ENDIAN)
-#else
-#define _GD_FileSwapBytes(D,i) ((D)->fragment[i].byte_sex & GD_BIG_ENDIAN)
-#endif
+void _GD_FixEndianness(void*, size_t, gd_type_t, unsigned, unsigned);
+int _GD_FileSwapBytes(const DIRFILE *restrict, const gd_entry_t *restrict);
int _GD_FiniRawIO(DIRFILE*, const gd_entry_t*, int, int);
void _GD_Flush(DIRFILE *restrict, gd_entry_t *restrict, int, int);
void _GD_FlushMeta(DIRFILE* D, int fragment, int force);
@@ -1347,6 +1351,7 @@
# define gd_nothrow
#endif
+/* deal with GD_ANON */
#ifdef GD_C89_API
# define EN(t,v) u.t.v
#else
Modified: trunk/getdata/src/mod.c
===================================================================
--- trunk/getdata/src/mod.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/mod.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -335,7 +335,7 @@
/* open the old file */
if (_GD_InitRawIO(D, E, NULL, 0, NULL, 0, GD_FILE_READ,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
{
break;
} else if ((*enc->seek)(E->e->u.raw.file, 0, E->EN(raw,data_type),
@@ -350,7 +350,7 @@
/* Create a temporary file and open it */
if (_GD_InitRawIO(D, E, NULL, -1, enc, 0, GD_FILE_WRITE | GD_FILE_TEMP,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
break;
else if (_GD_WriteSeek(D, E, enc, 0, GD_FILE_WRITE | GD_FILE_TEMP)
== -1)
Modified: trunk/getdata/src/move.c
===================================================================
--- trunk/getdata/src/move.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/move.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -30,7 +30,7 @@
ssize_t nread, nwrote;
int subencoding = GD_ENC_UNKNOWN;
int i, ef_swap;
- int arm_endianise;
+ int arm_fix = 0, endian_fix = 0;
void *buffer;
dtrace("%p, %p, %lu, %lu, %lli, %i, %i, %p", D, E, encoding, byte_sex,
@@ -92,33 +92,41 @@
enc_in = gd_ef_ + E->e->u.raw.file[0].subenc;
- /* Need to do the ARM thing? */
- arm_endianise = (((byte_sex & GD_ARM_FLAG) && (enc_out->flags & GD_EF_ECOR)) ^
- ((D->fragment[E->fragment_index].byte_sex & GD_ARM_FLAG) &&
- (enc_in->flags & GD_EF_ECOR))) && (E->EN(raw,data_type) == GD_FLOAT64 ||
- E->EN(raw,data_type) == GD_COMPLEX128);
+ /* if neither encoding scheme does internal byte swapping, and the data
+ * type can't be endianness swapped, sex differences can't matter */
+ if (GD_SIZE(E->e->u.raw.size) != 1 || (enc_in->flags & GD_EF_SWAP) ||
+ (enc_out->flags & GD_EF_SWAP))
+ {
+ /* figure out whether endianness correction is required */
+ if ((enc_in->flags & GD_EF_ECOR) || (enc_in->flags & GD_EF_ECOR)) {
+ unsigned in_sex = D->fragment[E->fragment_index].byte_sex;
+ unsigned out_sex = byte_sex;
- /* Normalise endiannesses */
-#ifdef WORDS_BIGENDIAN
- ef_swap = (byte_sex & GD_LITTLE_ENDIAN) ? 1 : 0;
- byte_sex = ((byte_sex & GD_LITTLE_ENDIAN) &&
- (enc_out->flags & (GD_EF_ECOR | GD_EF_SWAP))) ^
- ((D->fragment[E->fragment_index].byte_sex & GD_LITTLE_ENDIAN) &&
- (enc_in->flags & (GD_EF_ECOR | GD_EF_SWAP)));
-#else
- ef_swap = (byte_sex & GD_BIG_ENDIAN) ? 1 : 0;
- byte_sex = ((byte_sex & GD_BIG_ENDIAN) &&
- (enc_out->flags & (GD_EF_ECOR | GD_EF_SWAP))) ^
- ((D->fragment[E->fragment_index].byte_sex & GD_BIG_ENDIAN) &&
- (enc_in->flags & (GD_EF_ECOR | GD_EF_SWAP)));
-#endif
- /* Now byte_sex is true if endianness conversion is required. */
+ /* fix endian flags for encoding behaviour */
+ if (!(enc_in->flags & (GD_EF_SWAP | GD_EF_ECOR))) {
+ in_sex = (in_sex & ~(GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) |
+ (out_sex & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN));
+ if (!(enc_in->flags & GD_EF_ECOR))
+ in_sex = (in_sex & ~GD_ARM_FLAG) | (out_sex & GD_ARM_FLAG);
+ }
+ if (!(enc_out->flags & (GD_EF_SWAP | GD_EF_ECOR))) {
+ out_sex = (out_sex & ~(GD_LITTLE_ENDIAN | GD_BIG_ENDIAN)) |
+ (in_sex & (GD_LITTLE_ENDIAN | GD_BIG_ENDIAN));
+ if (!(enc_out->flags & GD_EF_ECOR))
+ out_sex = (out_sex & ~GD_ARM_FLAG) | (in_sex | GD_ARM_FLAG);
+ }
+
+ endian_fix = _GD_CheckByteSex(E->EN(raw,data_type), in_sex, out_sex, 0,
+ &arm_fix);
+ }
+ }
+
/* If all that's changing is the byte sex, but we don't need to do
* endianness conversion, don't do anything */
if (offset == 0 && encoding == D->fragment[E->fragment_index].encoding &&
- !byte_sex && !arm_endianise && strcmp(new_filebase,
- E->e->u.raw.filebase) == 0 && D->fragment[new_fragment].dirfd ==
+ !endian_fix && !arm_fix && strcmp(new_filebase, E->e->u.raw.filebase) == 0
+ && D->fragment[new_fragment].dirfd ==
D->fragment[E->fragment_index].dirfd)
{
free(new_filebase);
@@ -139,13 +147,16 @@
/* Open the input file, if necessary */
if (_GD_InitRawIO(D, E, NULL, 0, NULL, 0, GD_FILE_READ,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
{
free(new_filebase);
dreturn("%i", -1);
return -1;
}
+ /* set ef_swap, the output encoding in-framework endian correction flag */
+ ef_swap = _GD_CheckByteSex(E->EN(raw,data_type), byte_sex, 0, 0, NULL);
+
/* Create the output file and open it. If we're changing encodings, we
* could write to the new file directly. However, we use a temporary file
* anyway just to keep things clean. */
@@ -202,18 +213,9 @@
if (nread == 0)
break;
- /* fix army-ness, if required */
- if (arm_endianise)
- _GD_ArmEndianise((uint64_t *)buffer, E->EN(raw,data_type) & GD_COMPLEX,
- nread);
-
/* swap endianness, if required */
- if (byte_sex) {
- if (E->EN(raw,data_type) & GD_COMPLEX)
- _GD_FixEndianness((char *)buffer, E->e->u.raw.size / 2, nread * 2);
- else
- _GD_FixEndianness((char *)buffer, E->e->u.raw.size, nread);
- }
+ _GD_FixEndianness(buffer, nread, E->EN(raw,data_type),
+ D->fragment[E->fragment_index].byte_sex, byte_sex);
nwrote = _GD_WriteOut(E, enc_out, buffer, E->EN(raw,data_type), nread, 1);
Modified: trunk/getdata/src/nframes.c
===================================================================
--- trunk/getdata/src/nframes.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/nframes.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -57,9 +57,8 @@
nf = (*gd_ef_[D->reference_field->e->u.raw.file[0].subenc].size)(
D->fragment[D->reference_field->fragment_index].dirfd,
- D->reference_field->e->u.raw.file,
- D->reference_field->EN(raw,data_type), _GD_FileSwapBytes(D,
- D->reference_field->fragment_index));
+ D->reference_field->e->u.raw.file, D->reference_field->EN(raw,data_type),
+ _GD_FileSwapBytes(D, D->reference_field));
if (nf < 0) {
_GD_SetError(D, GD_E_RAW_IO, 0, D->reference_field->e->u.raw.file[0].name,
Modified: trunk/getdata/src/parse.c
===================================================================
--- trunk/getdata/src/parse.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/parse.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -1573,7 +1573,7 @@
_GD_SetError(D, GD_E_UNSUPPORTED, 0, NULL, 0, NULL);
else
_GD_InitRawIO(D, E, NULL, 0, NULL, 0, GD_FILE_WRITE | GD_FILE_TOUCH,
- _GD_FileSwapBytes(D, E->fragment_index));
+ _GD_FileSwapBytes(D, E));
}
/* Is this the first raw field ever defined? */
Modified: trunk/getdata/src/putdata.c
===================================================================
--- trunk/getdata/src/putdata.c 2013-12-13 00:43:41 UTC (rev 873)
+++ trunk/getdata/src/putdata.c 2013-12-17 02:04:49 UTC (rev 874)
@@ -67,34 +67,14 @@
return 0;
}
- if (gd_ef_[E->e->u.raw.file[0].subenc].flags & GD_EF_ECOR) {
- /* convert to/from middle-ended doubles */
- if ((E->EN(raw,data_type) == GD_FLOAT64 || E->EN(raw,data_type) ==
- GD_COMPLEX128) &&
- D->fragment[E->fragment_index].byte_sex & GD_ARM_FLAG)
- {
- _GD_ArmEndianise((uint64_t*)databuffer, E->EN(raw,data_type) & GD_COMPLEX,
- ns);
- }
+ /* fix endianness, if necessary */
+ if (gd_ef_[E->e->u.raw.file[0].subenc].flags & GD_EF_ECOR)
+ _GD_FixEndianness(databuffer, ns, E->EN(raw,data_type), 0,
+ D->fragment[E->fragment_index].byte_sex);
- if (D->fragment[E->fragment_index].byte_sex &
-#ifdef WORDS_BIGENDIAN
- GD_LITTLE_ENDIAN
-#else
- GD_BIG_ENDIAN
-#endif
- )
- {
- if (E->EN(raw,data_type) & GD_COMPLEX)
- _GD_FixEndianness((char *)databuffer, E->e->u.raw.size / 2, ns * 2);
- else
- _GD_FixEndianness((char *)databuffer, E->e->u.raw.size, ns);
- }
- }
/* write data to file. */
-
if (_GD_InitRawIO(D, E, NULL, 0, NULL, 0, GD_FILE_WRITE,
- _GD_FileSwapBytes(D, E->fragment_index)))
+ _GD_FileSwapBytes(D, E)))
{
free(databuffer);
dreturn("%i", 0);
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|