如何以一种优雅的方式转储XML?

lzl124631x

我想将某些信息从已解析的ttf文件转储到XML文件中。ttf中有多个表,例如cmap,head,hhea。我已经定义了这些表的结构,例如:

class Font_Header{
public:
    FIXED   table_version_number;
    FIXED   font_revision;
    ULONG   checksum_adjustment;
// some other field...
    SHORT   index_to_loc_format;
    SHORT   glygh_data_format;
// some member functions...
};

现在,我想编写一个名为dump_info转储此结构的内存布局的函数

void Font_Header::dump_info(FILE *fp, size_t indent){
    INDENT(fp, indent); fprintf(fp, "<head>\n");
    ++indent;
    INDENT(fp, indent); fprintf(fp, "<tableVersion value=\"0x%08x\"/>\n", table_version_number);
// some other lines...
    INDENT(fp, indent); fprintf(fp, "<glyphDataFormat value=\"%d\"/>\n", glygh_data_format);
    --indent;
    INDENT(fp, indent); fprintf(fp, "</head>\n");
}

我的问题是:

  1. 是否有更好的解决方案来实现此目标?我已经写了几N行代码来定义结构,现在我必须再写N一行代码到dump_info这不酷。我想要的东西是这样的:

    foreach field in fields
        dump(indent);
        dumpLn("<$1 value=\"$2\">", field.name, field.value);
        // Fields of different type are dumped in different format!
    end
    
  2. 如何明智地完成缩进?我定义了以下宏

    #define INDENT(fp, indent) for(size_t i = 0; i < (indent); ++i) fprintf((fp), "\t")
    

并将此宏附加到每一行...我想知道是否有一种优雅的方式来完成此任务。

lzl124631x

以下代码是我的尝试。我将类的字段信息存储到一个Notation数组中。我假设ULL(即unsigned long long)是消耗最大内存(8B)的类型,并且始终从每个字段的指针中获得8B。应该特别注意的一件事是,我应始终确保正确分配了formatin Notation例如,如果我想打印一个short值(我只需要2B),但是却分配format一个值("%d"为我获取4B),我将得到一个错误的答案。

仍然有两个问题困扰着我:

  1. 该方法不可移植。不同的平台可能会分配ULL不同的内存大小。
  2. 由于我总是从内存中获得8B的数据,因此不考虑效率问题,这可能会导致读取内存冲突

好吧,更新...我添加maskNotation以获得正确的值,即使format没有正确分配。

请参阅ttf中OS / 2表。它由近40个字段组成。现在,我写了40行来定义该表,写40行来读取该表,并写40行来转储该表的信息!天啊。也许将来我还要添加其他40行,40行和40行...如果我无法自动执行此任务,请杀死我。


#include <stdio.h>

class X{
public:
  char      a;
  short     b;
  int       c;
  double    d;
  X(char a, short b, int c, double d) : a(a), b(b), c(c), d(d) {}
};

typedef unsigned long long ULL;
#define FIELD(c, x)             (((c*)0)->x)
#define OFFSET(c, x)            ((size_t)&FIELD(c, x))
#define SIZE(c, x)              (sizeof(FIELD(c, x)))
#define MASK(c, x)              (((ULL)~0) >> ((sizeof(ULL) - SIZE(c, x)) << 3))
#define NOTATION(c, x, s)       { SIZE(c, x), OFFSET(c, x), #x, s, MASK(c, x) }
#define PTR(c, f)               ((void*)((size_t)&c + f->offset))
#define VALUE(c, f)             (f->mask & *(ULL*)PTR(x, f))
struct Notation{
  size_t        size;
  size_t        offset;
  const char    *name;
  const char    *format;
  ULL           mask;
};

Notation X_field[] = {
  NOTATION(X, a, "%c"),
  NOTATION(X, b, "%d"),  // The right 'format' of short should be %hd. I intentionally set it wrong.
  NOTATION(X, c, "%d"),
  NOTATION(X, d, "%lf")
};

#define PRINT(x, f, s) \
  printf("name: %s, size: %u, ptr: %p, value: " s "\n", #f, sizeof(x.f), &x.f, x.f)

int main(){
  X x('z', 3, 2, 1.5);
  printf("--------------------MANUAL--------------------\n");
  PRINT(x, a, "%c");
  PRINT(x, b, "%hd");
  PRINT(x, c, "%d");
  PRINT(x, d, "%lf");
  printf("--------------------MASK--------------------\n");
  printf("0x%016hhx, %hhu\n", (char)~0, (char)~0);
  printf("0x%016hx, %hu\n", (short)~0, (short)~0);
  printf("0x%016x, %u\n", (int)~0, (int)~0);
  printf("0x%016llx, %llu\n", (ULL)~0, (ULL)~0);
  printf("--------------------FIELD--------------------\n");
  Notation *field = NULL;
  int i = 0;
  for(i = 0, field = X_field; i < 4; ++i, ++field){
    printf("size: %u, offset: %u, name: %s, format: %s, mask: 0x%016llx\n",
      field->size, field->offset, field->name, field->format, field->mask);
  }

  printf("--------------------AUTO--------------------\n");
  for(i = 0, field = X_field; i < 4; ++i, ++field){
    printf("name: %s, size: %u, ptr: %p, value: ", field->name, field->size, PTR(x, field));
    printf(field->format, VALUE(x, field));
    printf("\n");
  }
  return 0;
}

输出:

--------------------MANUAL--------------------
name: a, size: 1, ptr: 0x22ac18, value: z
name: b, size: 2, ptr: 0x22ac1a, value: 3
name: c, size: 4, ptr: 0x22ac1c, value: 2
name: d, size: 8, ptr: 0x22ac20, value: 1.500000
--------------------MASK--------------------
0x00000000000000ff, 255
0x000000000000ffff, 65535
0x00000000ffffffff, 4294967295
0xffffffffffffffff, 18446744073709551615
--------------------FIELD--------------------
size: 1, offset: 0, name: a, format: %c, mask: 0x00000000000000ff
size: 2, offset: 2, name: b, format: %d, mask: 0x000000000000ffff
size: 4, offset: 4, name: c, format: %d, mask: 0x00000000ffffffff
size: 8, offset: 8, name: d, format: %lf, mask: 0xffffffffffffffff
--------------------AUTO--------------------
name: a, size: 1, ptr: 0x22ac18, value: z
name: b, size: 2, ptr: 0x22ac1a, value: 3
name: c, size: 4, ptr: 0x22ac1c, value: 2
name: d, size: 8, ptr: 0x22ac20, value: 1.500000

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

如何以一种优雅的方式按类型筛选锡兰?

来自分类Dev

Haskell-如何以一种优雅的方式以相反的顺序迭代列表元素?

来自分类Dev

如何以一种引导方式绑定动态数据

来自分类Dev

Java:如何以一种优雅的方式将一个从索引0到-2的String数组连接起来?

来自分类Dev

如何使用flexjson以一种优雅的方式反序列化此JSON

来自分类Dev

使用jQuery更改div标签的一种优雅方式

来自分类Dev

appsScript一种优雅的方式来循环范围

来自分类Dev

此python装饰器的一种更优雅的方式

来自分类Dev

Linq to Entities 4.0(“包含”):寻找一种优雅的方式

来自分类Dev

如何以一种可行的方式将OpenSSL包括在iOS项目中

来自分类Dev

如何以一种初学者友好的方式从控制台读取int?

来自分类Dev

如何以绑定到指令angularjs的一种方式传递json对象

来自分类Dev

如何以一种允许我恢复正在执行的操作的方式继续捕获异常?

来自分类Dev

如何以一种面向对象的方式对商店的营业时间进行建模?

来自分类Dev

如何以一种可行的方式将OpenSSL包括在iOS项目中

来自分类Dev

如何以一种不太特定的方式更改Bootstrap表带条纹?

来自分类Dev

如何以编程方式更改一种RecyclerView项目样式?

来自分类Dev

如何以一种友好的方式查看我的Instagram备份数据?

来自分类Dev

如何以只需要一种方法(如果可能)的方式优化我的代码?

来自分类Dev

有没有一种方法可以转储CPU的CPUID信息?

来自分类Dev

有没有一种方法可以转储CPU的CPUID信息?

来自分类Dev

如何以一种用户只能访问一个站点的方式在Ubuntu上配置虚拟主机

来自分类Dev

如何以一种很好的方式在Java的同一列表中查找对象对

来自分类Dev

如何以一种聪明的方式分割一个字符串?

来自分类Dev

在Ruby中是否有一种优雅的方式像Scala中的`require`一样?

来自分类Dev

awk:一种更优雅的方式来过滤另一个文件

来自分类Dev

一种更优雅的方式来处理同一servlet中的不同请求

来自分类Dev

如何以一种无需还原即可读取它们的方式复制/备份所有ubuntu文件?

来自分类Dev

如何以一种可以指示该元素是否已删除的方式指向std :: set的成员?

Related 相关文章

  1. 1

    如何以一种优雅的方式按类型筛选锡兰?

  2. 2

    Haskell-如何以一种优雅的方式以相反的顺序迭代列表元素?

  3. 3

    如何以一种引导方式绑定动态数据

  4. 4

    Java:如何以一种优雅的方式将一个从索引0到-2的String数组连接起来?

  5. 5

    如何使用flexjson以一种优雅的方式反序列化此JSON

  6. 6

    使用jQuery更改div标签的一种优雅方式

  7. 7

    appsScript一种优雅的方式来循环范围

  8. 8

    此python装饰器的一种更优雅的方式

  9. 9

    Linq to Entities 4.0(“包含”):寻找一种优雅的方式

  10. 10

    如何以一种可行的方式将OpenSSL包括在iOS项目中

  11. 11

    如何以一种初学者友好的方式从控制台读取int?

  12. 12

    如何以绑定到指令angularjs的一种方式传递json对象

  13. 13

    如何以一种允许我恢复正在执行的操作的方式继续捕获异常?

  14. 14

    如何以一种面向对象的方式对商店的营业时间进行建模?

  15. 15

    如何以一种可行的方式将OpenSSL包括在iOS项目中

  16. 16

    如何以一种不太特定的方式更改Bootstrap表带条纹?

  17. 17

    如何以编程方式更改一种RecyclerView项目样式?

  18. 18

    如何以一种友好的方式查看我的Instagram备份数据?

  19. 19

    如何以只需要一种方法(如果可能)的方式优化我的代码?

  20. 20

    有没有一种方法可以转储CPU的CPUID信息?

  21. 21

    有没有一种方法可以转储CPU的CPUID信息?

  22. 22

    如何以一种用户只能访问一个站点的方式在Ubuntu上配置虚拟主机

  23. 23

    如何以一种很好的方式在Java的同一列表中查找对象对

  24. 24

    如何以一种聪明的方式分割一个字符串?

  25. 25

    在Ruby中是否有一种优雅的方式像Scala中的`require`一样?

  26. 26

    awk:一种更优雅的方式来过滤另一个文件

  27. 27

    一种更优雅的方式来处理同一servlet中的不同请求

  28. 28

    如何以一种无需还原即可读取它们的方式复制/备份所有ubuntu文件?

  29. 29

    如何以一种可以指示该元素是否已删除的方式指向std :: set的成员?

热门标签

归档