Json库源码解析

自己项目中的Json库源码

先从使用方式开始:
image.png

Json::Value _json;
调用Value类的构造函数

image.png

跳转到里面 可以看到 Value类的主要成员是这些

再看构造函数:


image.png

从传递参数可以得知:最开始的初始化代码应该是调用的 Value( ValueType type = nullValue );这个构造函数,接下来转进去看看具体逻辑:

Value::Value( ValueType type )
   : type_( type )
   , allocated_( 0 )
   , comments_( 0 )
# ifdef JSON_VALUE_USE_INTERNAL_MAP
   , itemIsUsed_( 0 )
#endif
{
   switch ( type )
   {
   case nullValue:
      break;
   case intValue:
   case uintValue:
      value_.int_ = 0;
      break;
   case realValue:
      value_.real_ = 0.0;
      break;
   case stringValue:
      value_.string_ = 0;
      break;
#ifndef JSON_VALUE_USE_INTERNAL_MAP
   case arrayValue:
   case objectValue:
      value_.map_ = new ObjectValues();
      break;
#else
   case arrayValue:
      value_.array_ = arrayAllocator()->newArray();
      break;
   case objectValue:
      value_.map_ = mapAllocator()->newMap();
      break;
#endif
   case booleanValue:
      value_.bool_ = false;
      break;
   default:
      JSON_ASSERT_UNREACHABLE;
   }
}

上面代码主要是通过传递的valueType来确定如何进行初始化,如果是空的话 那么默认就break掉

这里展开说一下

 case objectValue:
      value_.map_ = new ObjectValues();
      break;

当时objectValue 的时当前的value_.map_对象进行了初始化,看看ObjectValues()干了什么


image.png

可以看到实际上就是new了一个map,key是CZString,Value是Value类型
再看看CZString又是啥:


image.png

可以看到这个类的成员主要是一个 char *cstr_ 以及一个index_;

接下来是使用Json::Value类

常见用法:


image.png

访问这个json对象的某个Key对应的Json

image.png

可以看到Value类重载了[]这个运算符,参数传的是char*类型 和 string类型都有

首先看第一个函数

Value &
Value::operator[]( const char *key )
{
   return resolveReference( key, false );
}
Value &
Value::resolveReference( const char *key, 
                         bool isStatic )
{
   JSON_ASSERT( type_ == nullValue  ||  type_ == objectValue );  //只允许nullValue和objectValue类型
   if ( type_ == nullValue )
      *this = Value( objectValue ); //调用构造函数 Value(objectValue); 实际上就是new 了个map 
#ifndef JSON_VALUE_USE_INTERNAL_MAP
   CZString actualKey( key, isStatic ? CZString::noDuplication 
                                     : CZString::duplicateOnCopy ); //调用了CZString的构造函数,生成一个名为actualKey的对象
   ObjectValues::iterator it = value_.map_->lower_bound( actualKey );
   if ( it != value_.map_->end()  &&  (*it).first == actualKey )
      return (*it).second;

   ObjectValues::value_type defaultValue( actualKey, null );
   it = value_.map_->insert( it, defaultValue );
   Value &value = (*it).second;
   return value;
#else
   return value_.map_->resolveReference( key, isStatic );
#endif
}
image.png

CZString的构造函数代码如下

这个函数做的就是把传来的cstr赋值到cstr_上,并且把allocate分配方式记录在index_上。
上面static = false ,对应的allocate =duplicateOnCopy ==2;

接下来就是通关lower_bound函数找到这个key对应的value
如果没找到就生成一个defaultValue 并且返回。

一些常用的函数解析

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容