cocos2d-x mruby学习笔记--扩展

今天练了一下手。使用cocos2d-x unzip库实现了解压zip到目录的方法。。嗯嗯。后来才发现cocos2d-x原来有zipUtil实现。实现起来应该更简单。嗯嗯,反正是练手的

顺便加了两个开源的相关库。mruby-pack和mruby-zlib


#include <stdlib.h>
#include <stdio.h>
#include <zlib.h>
#include <sys/stat.h>
#include <ctype.h>

#include "mruby.h"
#include "mruby/value.h"
#include "mruby/string.h"
#include "base/ccConfig.h"

#include "cocos2d.h"
#include "unzip.h"
#include "platform/CCFileUtils.h"


#define UNZIP_BUFFER_SIZE    8192
#define UNZIP_MAX_FILENAME   512

extern bool rubyval_to_std_string(mrb_state* mrb, mrb_value arg, std::string* outValue, const char* funcName = "");

using namespace cocos2d;

bool unzip_createDirectory(const char *path)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WINRT) || (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
    return FileUtils::getInstance()->createDirectory(path);
#elif (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32)
    BOOL ret = CreateDirectoryA(path, nullptr);
    if (!ret && ERROR_ALREADY_EXISTS != GetLastError())
    {
        return false;
    }
    return true;
#else
    mode_t processMask = umask(0);
    int ret = mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO);
    umask(processMask);
    if (ret != 0 && (errno != EEXIST))
    {
        return false;
    }

    return true;
#endif


}


static voidpf
zlib_alloc(voidpf opaque, uInt n, uInt size)
{
  return calloc((size_t) n, (size_t) size);
}

static void
zlib_free(voidpf opaque, voidpf p)
{
  free((void *) p);
}

static mrb_value
mrb_zlib_raise(mrb_state *mrb, z_streamp strm, int err)
{
  char msg[256];
  snprintf(msg, 256, "zlib error (%d): %s", err, strm->msg);
  mrb_raise(mrb, E_RUNTIME_ERROR, msg);
  return mrb_nil_value();
}

static mrb_value
ruby_cocos2dx_zlib_deflate_static(mrb_state *mrb, mrb_value self)
{
  struct RString *result;
  mrb_value value_data, value_result = mrb_nil_value();
  z_stream strm;
  int res;

  mrb_get_args(mrb, "S", &value_data);

  strm.zalloc = zlib_alloc;
  strm.zfree = zlib_free;
  strm.opaque = NULL;

  res = deflateInit(&strm, Z_DEFAULT_COMPRESSION);
  if (res != Z_OK) {
    mrb_zlib_raise(mrb, &strm, res);
  }

  value_result = mrb_str_buf_new(mrb,
      deflateBound(&strm, RSTRING_LEN(value_data)));
  result = mrb_str_ptr(value_result);

  strm.next_in = (Bytef *) RSTRING_PTR(value_data);
  strm.avail_in = RSTRING_LEN(value_data);
  strm.next_out = (Bytef *) RSTRING_PTR(value_result);
  strm.avail_out = RSTRING_CAPA(value_result);

  while (1) {
    res = deflate(&strm, Z_FINISH);
    if (res == Z_OK) {
      value_result = mrb_str_resize(mrb, value_result,
          RSTRING_CAPA(value_result) * 2);
      strm.next_out = (Bytef *) RSTRING_PTR(value_result) + strm.total_out;
      strm.avail_out = RSTRING_CAPA(value_result) - strm.total_out;
    }
    else if (res == Z_STREAM_END) {
      result->as.heap.len = strm.total_out;
      *(result->as.heap.ptr + result->as.heap.len) = '\0';

      res = deflateEnd(&strm);
      if (res != Z_OK) {
        mrb_zlib_raise(mrb, &strm, res);
      }
      break;
    }
    else {
      mrb_zlib_raise(mrb, &strm, res);
    }
  }

  return value_result;
}

static mrb_value
ruby_cocos2dx_zlib_inflate_static(mrb_state *mrb, mrb_value self)
{
  struct RString *result;
  mrb_value value_data, value_result = mrb_nil_value();
  z_stream strm;
  int res;

  mrb_get_args(mrb, "S", &value_data);

  strm.zalloc = zlib_alloc;
  strm.zfree = zlib_free;
  strm.opaque = NULL;
  strm.next_in = (Bytef *) RSTRING_PTR(value_data);
  strm.avail_in = RSTRING_LEN(value_data);

  res = inflateInit(&strm);
  if (res != Z_OK) {
    mrb_zlib_raise(mrb, &strm, res);
  }

  value_result = mrb_str_buf_new(mrb, RSTRING_LEN(value_data));
  result = mrb_str_ptr(value_result);

  strm.next_out = (Bytef *) RSTRING_PTR(value_result);
  strm.avail_out = RSTRING_CAPA(value_result);

  while (1) {
    res = inflate(&strm, Z_NO_FLUSH);
    if (res == Z_OK) {
      value_result = mrb_str_resize(mrb, value_result,
          RSTRING_CAPA(value_result) * 2);
      strm.next_out = (Bytef *) RSTRING_PTR(value_result) + strm.total_out;
      strm.avail_out = RSTRING_CAPA(value_result) - strm.total_out;
    }
    else if (res == Z_STREAM_END) {
      result->as.heap.len = strm.total_out;
      *(result->as.heap.ptr + result->as.heap.len) = '\0';

      res = inflateEnd(&strm);
      if (res != Z_OK) {
        mrb_zlib_raise(mrb, &strm, res);
      }
      break;
    }
    else {
      mrb_zlib_raise(mrb, &strm, res);
    }
  }

  return value_result;
}

mrb_value ruby_cocos2dx_zlib_unzip_static(mrb_state* mrb, mrb_value self){
    mrb_value* argv;
    int argc;
    mrb_get_args(mrb, "*", &argv, &argc);

    bool ok = true;
    mrb_value mrbfalse=mrb_bool_value((mrb_bool)false);
    do {
        if (argc == 2) {
          const char* arg0;
          std::string arg0_tmp; 
          ok = rubyval_to_std_string(mrb, argv[0], &arg0_tmp, "CC::Zlib:unzip"); 
          if (!ok) { break; }
          arg0 = arg0_tmp.c_str();
          
          const char* arg1;
          std::string arg1_tmp; 
          ok = rubyval_to_std_string(mrb, argv[1], &arg1_tmp, "CC::Zlib.unzip"); 
          if (!ok) { break; }
          if (arg1_tmp[arg1_tmp.length()-1] != '/'){
              arg1_tmp=arg1_tmp+'/';
          }
          arg1 = arg1_tmp.c_str();
          unzFile zipfile = unzOpen(arg0);
          if (! zipfile)
          {
             mrb_raise(mrb, E_RUNTIME_ERROR, "can not open zip file : CC::Zlib.unzip");
             return mrbfalse;
          }

          unz_global_info global_info;
          if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
          {
              mrb_raise(mrb, E_RUNTIME_ERROR, "can not read file global info : CC::Zlib.unzip");
              unzClose(zipfile);
              return mrbfalse;
          }

          char readBuffer[UNZIP_BUFFER_SIZE];

          uLong i;
          for (i = 0; i < global_info.number_entry; ++i)
          {
              // Get info about current file.
              unz_file_info fileInfo;
              char fileName[UNZIP_MAX_FILENAME];
              if (unzGetCurrentFileInfo(zipfile,
                                  &fileInfo,
                                  fileName,
                                  UNZIP_MAX_FILENAME,
                                  nullptr,
                                  0,
                                  nullptr,
                                  0) != UNZ_OK)
              {
                  mrb_raise(mrb, E_RUNTIME_ERROR, "can not read file info : CC::Zlib.unzip");
                  unzClose(zipfile);
                  return mrbfalse;
              }
              const std::string fullPath = arg1_tmp + fileName;
              const size_t filenameLength = strlen(fileName);
              if (fileName[filenameLength-1] == '/')
              {
                  // 创建目录
                  if (!unzip_createDirectory(fullPath.c_str()))
                  {
                      mrb_raise(mrb, E_RUNTIME_ERROR, "can not create directory  : CC::Zlib.unzip");
                      unzClose(zipfile);
                      return mrbfalse;
                  }
              }
               else
            {
                //如果不存在目录则创建
                const std::string fileNameStr(fileName);
                
                size_t startIndex=0;
                
                size_t index=fileNameStr.find("/",startIndex);
                
                while(index != std::string::npos)
                {
                    const std::string dir=arg1_tmp+fileNameStr.substr(0,index);
                    
                    FILE *out = fopen(dir.c_str(), "r");
                    
                    if(!out)
                    {
                        if (!unzip_createDirectory(dir.c_str()))
                        {
                            mrb_raise(mrb, E_RUNTIME_ERROR, "can not create directory  : CC::Zlib.unzip");
                           
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值