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\n"
            "\n"
            "Convert FILES to either unix or dos line endings.\n");
    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\n", 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,后面有'\0',那只需要+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\n", argv[i]);
                    return 1;
                }
                buf[amt2] = '\0';   // 字符串结尾
                // 先转成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\n", 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] == '\r' && p[1] == '\n') {
            // dos
            *q = '\n';
            p += 2;
            q += 1;
        }
        else if (p[0] == '\r') {
            // old mac
            *q = '\n';
            p += 1;
            q += 1;
        }
        else {
            *q = *p;
            p += 1;
            q += 1;
        }
    }
    *q = '\0';
}

// 这里和to_unix的动作正好相反
void
unix_to_dos(char* buf2, const char* buf)
{
    const char* p = buf;
    char* q = buf2;
    while (*p) {
        if (*p == '\n') {
            q[0] = '\r';
            q[1] = '\n';
            q += 2;
            p += 1;
        } else {
            *q = *p;
            p += 1;
            q += 1;
        }
    }
    *q = '\0';
}

 

时间: 2024-08-01 12:04:45

Android development tools line_endings hacking的相关文章

eclipse-安装&amp;amp;quot;Android DDMS&amp;amp;quot;和&amp;amp;quot;Android Development Tools&amp;amp;quot;出错

问题描述 安装"Android DDMS"和"Android Development Tools"出错 eclipse-ee安装"Android DDMS"和"Android Development Tools"出错了,怎么办 解决方案 出的是什么错误呢?这个需要详细的说明一下. 解决方案二: 建议下载离线包,不然现在上不了google 解决方案三: 看一下这个.搭建android开发环境

使用Eclipse插件Ruby Development Tools

简介:本文介绍如何使用 Eclipse 插件 Ruby Development Tools(RDT),这个插件使 Eclipse 能 够成为一流的 Ruby 开发环境.那些希望利用 Eclipse 社区丰富的基础设施来支持开发的 Ruby 开发人 员会从本文中受益,对有兴趣使用 Ruby 的 Java开发人员也会有所收获. 为什么要使用 Ruby? 为什么 Java 开发人员会关心 Ruby?Ruby 是 10 年前在日本开发出来的通用脚本语言.与流行 的信念相反,它是一种纯面向对象语言.与 J

解决错误ERROR: No suitable Java found. In order to properly use the Android Developer Tools,…

Failed to convert path to a short DOS path: C:\Windows\system32\java.exe 很多人在把ADT更新到ADT17以后使用 SDK里面的工具时遇到了这样的错误: 出错的环境是windows 7 - 64bit Failed to convert path to a short DOS path: C:\Windows\system32\java.exe ERROR: No suitable Java found. In order

和 Eclipse Android Developer Tools 说再见

文|Google Android 产品经理 Jamal Eason 随着 Android Studio 2.2 的发布,现在是时候告别 Eclipse Android Developer Tools 了.我们已正式终止对它们的支持与开发.最佳时机不可错过,赶紧切换到 Android Studio 并体验我们对 Android 开发工作流所做的改进吧. Android Studio 官方 Android IDE Android Studio 具有强大的代码编辑功能以及高级代码自动完成和重构功能.它

head first android development 代码

问题描述 head first android development 代码 新手 head first android development NasaApp应用示例的代码谁有?或者从哪下载?

CentOS6.5 X64中Development tools相关组件表

安装Development Tools要安装的软件包:www.111cn.net Installing:  autoconf               noarch 2.63-5.1.el6                       base    781 k  automake               noarch 1.11.1-4.el6                       base    550 k  bison                  x86_64 2.4.1-

AM335x Android eMMC mkmmc-android.sh hacking

# AM335x Android eMMC mkmmc-android.sh hacking # # 1. 有空解读一下android的分区文件. # 2. 代码来源:https://github.com/hendersa/bbbandroid-external-ti_android_utilities/blob/master/am335x/mk-mmc/mkmmc-android.sh # # 2016-9-8 深圳 南山平山村 曾剑锋 #!/bin/bash # 如果参数只有一个,这里就会使

Android custom View AirConditionerView hacking

package com.example.arc.view; import android.content.Context; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.RectF; import android.graphics.SweepGradient; import android.util.Attr

Android Development Security - Provider Component Security

1. Overview of the Content Provider Component The Content Provider component is one of the key Android app components. It manages data access and is mainly used to implement data sharing between apps. Content Provider data sources can be SQLite datab