~ubuntu-branches/ubuntu/trusty/sunpinyin/trusty-proposed

« back to all changes in this revision

Viewing changes to src/slm/tslmendian/writer.h

  • Committer: Bazaar Package Importer
  • Author(s): Zhengpeng Hou
  • Date: 2010-09-06 12:23:46 UTC
  • Revision ID: james.westby@ubuntu.com-20100906122346-yamofztk2j5p85fs
Tags: upstream-2.0.2
ImportĀ upstreamĀ versionĀ 2.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#ifndef WRITER_H
 
2
#define WRITER_H
 
3
 
 
4
#include <stdio.h>
 
5
#include <stdint.h>
 
6
#include <algorithm>
 
7
 
 
8
#ifndef LITTLE_ENDIAN
 
9
enum {
 
10
    BIG_ENDIAN = 4321,
 
11
    LITTLE_ENDIAN = 1234,
 
12
    UNKNOWN_ENDIAN = 0x0000
 
13
};
 
14
#else
 
15
#define UNKNOWN_ENDIAN (0x0000)
 
16
#endif
 
17
int get_host_endian();
 
18
int parse_endian(const char* arg);
 
19
const char* endian2str(int endian);
 
20
 
 
21
// change the byte order of given variable
 
22
template <typename Type>
 
23
Type change_byte_order(const Type& v)
 
24
{
 
25
    Type t = v;
 
26
    const size_t size = sizeof(v);
 
27
    uint8_t* first = (uint8_t*)(&t);
 
28
    uint8_t* last  = first+size-1;
 
29
    while (first < last) {
 
30
        std::swap(*first++, *last--);
 
31
    }
 
32
    return t;
 
33
}
 
34
    
 
35
template <typename T>
 
36
class OtherEndian
 
37
{
 
38
public:
 
39
    typedef T TargetType;
 
40
    static TargetType create(const T& from)
 
41
    {
 
42
        return from;
 
43
    }
 
44
};
 
45
 
 
46
#if WORDS_BIGENDIAN
 
47
#define DEFINE_OTHER_TYPE(__T__) typedef __T__##_BE TargetType
 
48
#else
 
49
#define DEFINE_OTHER_TYPE(__T__) typedef __T__##_LE TargetType
 
50
#endif
 
51
 
 
52
//
 
53
// we always defined a reversed layout of big-endian and little-endian 
 
54
// bit-field struct, so such kind of struct need to be reverted if host
 
55
// arch is different from build arch.
 
56
//
 
57
template <typename T>
 
58
bool revert_write(const T& t, FILE *fp)
 
59
{
 
60
    T reverted = change_byte_order(t);
 
61
    typename OtherEndian<T>::TargetType o =
 
62
        OtherEndian<T>::create(reverted);
 
63
    return fwrite(&o, sizeof(o), 1, fp) == 1;
 
64
}
 
65
 
 
66
//
 
67
// if the struct has non-bit-field member(s), TTransUnit, among others,
 
68
// the order of members is the same as how they are defined.
 
69
//
 
70
 
 
71
class Writer
 
72
{
 
73
public:
 
74
    Writer(FILE *fp, bool doRevert)
 
75
        : m_fp (fp), m_doRevert(doRevert)
 
76
    {}
 
77
    
 
78
    template <typename T>
 
79
    bool write(const T& t)
 
80
    {
 
81
        if (m_doRevert)
 
82
            return revert_write(t, m_fp);
 
83
        else
 
84
            return fwrite(&t, sizeof(t), 1, m_fp) == 1;
 
85
    }
 
86
    
 
87
    
 
88
    template <typename T>
 
89
    bool write(const T* t, size_t len)
 
90
    {
 
91
        for (unsigned i = 0; i < len; i++) {
 
92
            if (!write(t[i]))
 
93
                return false;
 
94
        }
 
95
        return true;
 
96
    }
 
97
private:
 
98
    FILE *m_fp;
 
99
    const bool m_doRevert;
 
100
};
 
101
 
 
102
 
 
103
 
 
104
#endif // WRITER_H