zoukankan      html  css  js  c++  java
  • Android development tools line_endings hacking

    /********************************************************************
     *       Android development tools line_endings hacking
     * 说明:
     *     本文主要是对android源代码中的line_endings开发工具进行了解读,
     * 目的是为了知道传说中的dos,unix文件之间转换的工作机制。
     *
     *                                  2016-5-3 深圳 南山平山村 曾剑锋
     *******************************************************************/
    
    
    #include <unistd.h>
    #include <fcntl.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <sys/stat.h>
    
    #define BUFSIZE (1024*8)
    static void to_unix(char* buf);
    static void unix_to_dos(char* buf2, const char* buf);
    
    // 使用方法
    int usage()
    {
        fprintf(stderr, "usage: line_endings unix|dos FILES
    "
                "
    "
                "Convert FILES to either unix or dos line endings.
    ");
        return 1;
    }
    
    // 定义Node数据结构
    typedef struct Node {
        struct Node *next;
        char buf[BUFSIZE*2+3];
    } Node;
    
    int
    main(int argc, char** argv)
    {
        // 枚举UNIX,DOS两种数据
        enum { UNIX, DOS } ending;
        int i;
    
        // 参数个数判断
        if (argc < 2) {
            return usage();
        }
    
        // 参数比较
        if (0 == strcmp("unix", argv[1])) {
            ending = UNIX;
        }
        else if (0 == strcmp("dos", argv[1])) {
            ending = DOS;
        }
        else {
            return usage();
        }
    
        // 命令行传入的参数可能有多个,利用for循环进行轮流转换。
        for (i=2; i<argc; i++) {
            int fd;
            int len;
    
            // force implied
            chmod(argv[i], S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP);
    
            // 打开文件
            fd = open(argv[i], O_RDWR);
            if (fd < 0) {
                fprintf(stderr, "unable to open file for read/write: %s
    ", argv[i]);
                return 1;
            }
    
            // 获取文件大小
            len = lseek(fd, 0, SEEK_END);
            lseek(fd, 0, SEEK_SET);
    
            // 文件长度正常才有必要进行转换
            if (len > 0) {
                // 创建根节点
                Node* root = malloc(sizeof(Node));
                Node* node = root;
                node->buf[0] = 0; // root节点的buf数据位0
    
                while (len > 0) {
                    // 创建节点,并出示节点
                    node->next = malloc(sizeof(Node));
                    node = node->next;
                    node->next = NULL;
    
                    // 这里还是没搞太懂为什么要+2,后面有'',那只需要+1就行了,为什么
                    // 还要+2,没搞懂。
                    char buf[BUFSIZE+2];
                    ssize_t amt;
                    ssize_t amt2 = len < BUFSIZE ? len : BUFSIZE;
                    amt = read(fd, buf, amt2);
                    if (amt != amt2) {
                        fprintf(stderr, "unable to read file: %s
    ", argv[i]);
                        return 1;
                    }
                    buf[amt2] = '';   // 字符串结尾
                    // 先转成unix文档
                    to_unix(buf);
                    if (ending == UNIX) {
                        strcpy(node->buf, buf);
                    } else {
                        // 这里BUFSIZE*2的主要原因应该是怕所有的都是换行符,这样转换出来
                        // 就是*2了,但是没搞懂为什么要+3,个人感觉最多有个+1就行了。
                        char buf2[(BUFSIZE*2)+3];
                        unix_to_dos(buf2, buf);
                        strcpy(node->buf, buf2);
                    }
                    len -= amt2;
                }
    
                // 将文件长度修改为0,并重新从文件头开始
                ftruncate(fd, 0);
                lseek(fd, 0, SEEK_SET);
                // 循环将链表中的内容写入文件,并释放链表中的内容
                while (root) {
                    ssize_t amt2 = strlen(root->buf);
                    if (amt2 > 0) {
                        ssize_t amt = write(fd, root->buf, amt2);
                        if (amt != amt2) {
                            fprintf(stderr, "unable to write file: %s
    ", argv[i]);
                            return 1;
                        }
                    }
                    node = root;
                    root = root->next;
                    free(node);
                }
            }
            close(fd);
        }
        return 0;
    }
    
    // 这里相当于是字符的的不断的拷贝
    void
    to_unix(char* buf)
    {
        char* p = buf;
        char* q = buf;
        while (*p) {
            if (p[0] == '
    ' && p[1] == '
    ') {
                // dos
                *q = '
    ';
                p += 2;
                q += 1;
            }
            else if (p[0] == '
    ') {
                // old mac
                *q = '
    ';
                p += 1;
                q += 1;
            }
            else {
                *q = *p;
                p += 1;
                q += 1;
            }
        }
        *q = '';
    }
    
    // 这里和to_unix的动作正好相反
    void
    unix_to_dos(char* buf2, const char* buf)
    {
        const char* p = buf;
        char* q = buf2;
        while (*p) {
            if (*p == '
    ') {
                q[0] = '
    ';
                q[1] = '
    ';
                q += 2;
                p += 1;
            } else {
                *q = *p;
                p += 1;
                q += 1;
            }
        }
        *q = '';
    }
  • 相关阅读:
    TreeSelect组件:vmodel语法糖进行父子组件传值案例
    带 icon 的输入框:slot方式。slot="prefix"和slot="suffix"
    双向绑定vmodel与单向绑定vbind:value
    使用Set集合对List集合去重
    前端报错: error in ./src/assets/fonts/iconfont.svg?t=1523541245904,Module parse failed: Unexpected token (1:0),vue.config.js中引入chainWebpack后报错
    当主键不是id时,而是其他字段,那么该字段要加上@Id注解(除了表中指定主键,实体类中也要用@Id指定主键)
    java将文件转为base64字符串和将base64字符串转为文件
    父组件向子组件传递getList方法:provide/inject
    带卡片的input输入框
    C#中使用#if DEBUG
  • 原文地址:https://www.cnblogs.com/zengjfgit/p/5453959.html
Copyright © 2011-2022 走看看