[segyio] 47/376: Use htons+friends over homegrown to/from int

Jørgen Kvalsvik jokva-guest at moszumanska.debian.org
Wed Sep 20 08:04:05 UTC 2017


This is an automated email from the git hooks/post-receive script.

jokva-guest pushed a commit to branch debian
in repository segyio.

commit 18bf2a8cdc79af8e1960168511cd4ae51a755813
Author: Jørgen Kvalsvik <jokva at statoil.com>
Date:   Mon Oct 17 15:35:58 2016 +0200

    Use htons+friends over homegrown to/from int
    
    Using htons and friends gives more portability, correctness and speed
    compared to a homegrown solution really only tested on intel. Removes
    the need for some tests in addition.
    
    Introduces the cmake file check_headers which handles portability issues
    and sets up preprocessor directives for what headers to include.
---
 CMakeLists.txt             |  1 +
 cmake/check_includes.cmake | 18 ++++++++++++
 src/segyio/segy.c          | 70 ++++++++++++++--------------------------------
 src/segyio/segy.h          |  8 +++---
 tests/test_segy.c          |  2 --
 tests/test_utils.c         | 28 -------------------
 6 files changed, 44 insertions(+), 83 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0c09501..fd7d072 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -19,6 +19,7 @@ option(BUILD_PYTHON "Build Python wrappers"     ON)
 
 include(cmake/segyio_testing.cmake)
 enable_testing()
+include(cmake/check_includes.cmake)
 
 set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}")
 
diff --git a/cmake/check_includes.cmake b/cmake/check_includes.cmake
new file mode 100644
index 0000000..e6491d4
--- /dev/null
+++ b/cmake/check_includes.cmake
@@ -0,0 +1,18 @@
+include(CheckIncludeFile)
+
+# Portability checks; look for htons function
+check_include_file("netinet/in.h" HAVE_NETINET_IN_H)
+check_include_file("arpa/inet.h" HAVE_ARPA_INET_H)
+check_include_file("winsock2.h" HAVE_WINSOCK2_H)
+
+if (HAVE_NETINET_IN_H)
+    add_definitions("-DHAVE_NETINET_IN_H")
+elseif (HAVE_ARPA_INET_H)
+    add_definitions("-DHAVE_ARPA_INET_H")
+elseif (HAVE_WINSOCK2_H)
+    add_definitions("-DHAVE_WINSOCK2_H")
+else()
+    message(FATAL_ERROR "Could not find htons.")
+endif()
+
+
diff --git a/src/segyio/segy.c b/src/segyio/segy.c
index dc42ab4..9bd1ec6 100644
--- a/src/segyio/segy.c
+++ b/src/segyio/segy.c
@@ -1,4 +1,11 @@
+#ifdef HAVE_NETINET_IN_H
 #include <netinet/in.h>
+#elif HAVE_ARPA_INET_H
+#include <arpa/inet.h>
+#elif HAVE_WINSOCK2_H
+#include <winsock2.h>
+#endif
+
 #include <stdlib.h>
 #include <string.h>
 
@@ -298,59 +305,24 @@ static int bfield_size[] = {
     [- HEADER_SIZE + BIN_Unassigned2]           =  0,
 };
 
-/*
- * to/from_int32 are to be considered internal functions, but have external
- * linkage so that tests can hook into them. They're not declared in the header
- * files, and use of this internal interface is at user's own risk, i.e. it may
- * change without notice.
- */
-int to_int32( const char* buf ) {
-    int32_t value;
-    memcpy( &value, buf, sizeof( value ) );
-    return ((value >> 24) & 0xff)
-         | ((value << 8)  & 0xff0000)
-         | ((value >> 8)  & 0xff00)
-         | ((value << 24) & 0xff000000);
-}
-
-int to_int16( const char* buf ) {
-    int16_t value;
-    memcpy( &value, buf, sizeof( value ) );
-    return ((value >> 8) & 0x00ff)
-         | ((value << 8) & 0xff00);
-}
-
-/* from native int to segy int. fixed-width ints used as byte buffers */
-int32_t from_int32( int32_t buf ) {
-    int32_t value = 0;
-    memcpy( &value, &buf, sizeof( value ) );
-    return ((value >> 24) & 0xff)
-         | ((value << 8)  & 0xff0000)
-         | ((value >> 8)  & 0xff00)
-         | ((value << 24) & 0xff000000);
-}
-
-int16_t from_int16( int16_t buf ) {
-    int16_t value = 0;
-    memcpy( &value, &buf, sizeof( value ) );
-    return ((value >> 8) & 0x00ff)
-         | ((value << 8) & 0xff00);
-}
-
 static int get_field( const char* header,
                       const int* table,
                       int field,
-                      int* f ) {
+                      int32_t* f ) {
 
     const int bsize = table[ field ];
+    uint32_t buf32 = 0;
+    uint16_t buf16 = 0;
 
     switch( bsize ) {
         case 4:
-            *f = to_int32( header + (field - 1) );
+            memcpy( &buf32, header + (field - 1), 4 );
+            *f = (int32_t)ntohl( buf32 );
             return SEGY_OK;
 
         case 2:
-            *f = to_int16( header + (field - 1) );
+            memcpy( &buf16, header + (field - 1), 2 );
+            *f = (int32_t)ntohs( buf16 );
             return SEGY_OK;
 
         case 0:
@@ -366,7 +338,7 @@ int segy_get_field( const char* traceheader, int field, int* f ) {
     return get_field( traceheader, field_size, field, f );
 }
 
-int segy_get_bfield( const char* binheader, int field, int* f ) {
+int segy_get_bfield( const char* binheader, int field, int32_t* f ) {
     field -= SEGY_TEXT_HEADER_SIZE;
 
     if( field < 0 || field >= SEGY_BINARY_HEADER_SIZE )
@@ -375,20 +347,20 @@ int segy_get_bfield( const char* binheader, int field, int* f ) {
     return get_field( binheader, bfield_size, field, f );
 }
 
-static int set_field( char* header, const int* table, int field, int val ) {
+static int set_field( char* header, const int* table, int field, int32_t val ) {
     const int bsize = table[ field ];
 
-    int32_t buf32;
-    int16_t buf16;
+    uint32_t buf32;
+    uint16_t buf16;
 
     switch( bsize ) {
         case 4:
-            buf32 = from_int32( val );
+            buf32 = htonl( val );
             memcpy( header + (field - 1), &buf32, sizeof( buf32 ) );
             return SEGY_OK;
 
         case 2:
-            buf16 = from_int16( val );
+            buf16 = htons( val );
             memcpy( header + (field - 1), &buf16, sizeof( buf16 ) );
             return SEGY_OK;
 
@@ -451,7 +423,7 @@ int segy_format( const char* buf ) {
 }
 
 unsigned int segy_samples( const char* buf ) {
-    int samples;
+    int32_t samples;
     segy_get_bfield( buf, BIN_Samples, &samples );
     return (unsigned int) samples;
 }
diff --git a/src/segyio/segy.h b/src/segyio/segy.h
index 3e92d84..fce6a7a 100644
--- a/src/segyio/segy.h
+++ b/src/segyio/segy.h
@@ -39,10 +39,10 @@ int segy_write_binheader( FILE*, const char* buf );
 unsigned int segy_samples( const char* binheader );
 /* exception: the int returned is an enum, SEGY_SORTING, not an error code */
 int segy_format( const char* binheader );
-int segy_get_field( const char* traceheader, int field, int* f );
-int segy_get_bfield( const char* binheader, int field, int* f );
-int segy_set_field( char* traceheader, int field, int val );
-int segy_set_bfield( char* binheader, int field, int val );
+int segy_get_field( const char* traceheader, int field, int32_t* f );
+int segy_get_bfield( const char* binheader, int field, int32_t* f );
+int segy_set_field( char* traceheader, int field, int32_t val );
+int segy_set_bfield( char* binheader, int field, int32_t val );
 
 unsigned segy_trace_bsize( unsigned int samples );
 /* byte-offset of the first trace header. */
diff --git a/tests/test_segy.c b/tests/test_segy.c
index 39ee295..b7c4560 100644
--- a/tests/test_segy.c
+++ b/tests/test_segy.c
@@ -349,8 +349,6 @@ void testReadCrossLine_22(){
     fclose(fp);
 }
 
-int32_t from_int32( int32_t );
-
 void test_modify_trace_header() {
     const char *file = "test-data/small-traceheader.sgy";
 
diff --git a/tests/test_utils.c b/tests/test_utils.c
index f4e9c63..bf893e9 100644
--- a/tests/test_utils.c
+++ b/tests/test_utils.c
@@ -91,38 +91,10 @@ void testIBMFloat() {
     assertClose(4.17233e-07, epsm, 1e-06);
 }
 
-int to_int16( const char* );
-int to_int32( const char* );
-
-int16_t from_int16( int16_t );
-int32_t from_int32( int32_t );
-
-void test_integer_round_trip() {
-    /* this test probably only works as expected on intel/x86 */
-    /* this is what data looks like when read from segy */
-    char buf16[ 2 ] = { 000, 001 }; /* 1 */
-    /* unsigned to avoid overflow warning on 0257 */
-    unsigned char buf32[ 4 ] = { 0, 0, 011, 0257 };
-
-    int i1 = to_int16( buf16 );
-    int i2479 = to_int32( (char*)buf32 );
-    assertTrue( i1 == 1, "Expected SEGY two's complement 2-byte 1 => 1" );
-    assertTrue( i2479 == 2479, "Expected SEGY two's complement 4-byte 2479 => 2479" );
-
-    int16_t round_int16 = from_int16( 1 );
-    int32_t round_int32 = from_int32( 2479 );
-
-    assertTrue( memcmp( &round_int16, buf16, sizeof( round_int16 ) ) == 0,
-                "int16 did not survive round trip" );
-    assertTrue( memcmp( &round_int32, buf32, sizeof( round_int32 ) ) == 0,
-                "int32 did not survive round trip" );
-}
-
 int main() {
     testEbcdicConversion();
     testEbcdicTable();
     testConversionAllocation();
     testIBMFloat();
-    test_integer_round_trip();
     exit(0);
 }

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-science/packages/segyio.git



More information about the debian-science-commits mailing list