RapidJSON简介及使用

RapidJSON是腾讯开源的一个高效的C++ JSON解析器及生成器,它是只有头文件的C++库。RapidJSON是跨平台的,支持Windows, Linux, Mac OS X及iOS, Android。它的源码在GitHub - Tencent/rapidjson: A fast JSON parser/generator for C++ with both SAX/DOM style API,稳定版本为2016年发布的1.1.0版本。

RapidJSON特点:

(1). RapidJSON小而全:它同时支持SAX和DOM风格的API,SAX解析器只有约500行代码。

(2). RapidJSON快:它的性能可与strlen()相比,可支持SSE2/SSE4.2加速,使用模版及内联函数去降低函数调用开销。

(3). RapidJSON独立:它不依赖于BOOST等外部库,它甚至不依赖于STL。

(4). RapidJSON对内存友好:在大部分32/64位机器上,每个JSON值只占16字节(除字符串外),它预设使用一个快速的内存分配器,令分析器可以紧凑地分配内存。

(5). RapidJSON对Unicode友好:它支持UTF-8、UTF-16、UTF-32(大端序/小端序),并内部支持这些编码的检测、校验及转码。例如,RapidJSON可以在分析一个UTF-8文件至DOM (Document Object Model, 文件对象模型)时,把当中的JSON字符串转码至UTF-16。它也支持代理对(surrogate pair)及"\u0000"(空字符)。

每个JSON值都储存为Value类,而Document类则表示整个DOM,它存储了一个DOM 树的根Value。RapidJSON的所有公开类型及函数都在rapidjson命名空间中。

以上内容摘自:http://rapidjson.org/zh-cn/,关于RapidJSON的更详细介绍可以参考此网页。

           以下是测试代码(test_rapidjson.cpp):

#include "funset.hpp"
#include "rapidjson/document.h"
//#include "rapidjson/writer.h"
#include "rapidjson/prettywriter.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>
#include <fstream>
#include <string>
#include "common.hpp"

int test_rapidjson_parse()
{
#ifdef _MSC_VER
	const char* file_name = "E:/GitCode/Messy_Test/testdata/json.data";
#else
	const char* file_name = "testdata/json.data";
#endif
	std::ifstream in(file_name);
	if (!in.is_open()) {
		fprintf(stderr, "fail to read json file: %s\n", file_name);
		return -1;
	}

	std::string json_content((std::istreambuf_iterator<char>(in)), std::istreambuf_iterator<char>());
	in.close();

	rapidjson::Document dom;
	if (!dom.Parse(json_content.c_str()).HasParseError()) {
		if (dom.HasMember("name") && dom["name"].IsString()) {
			fprintf(stdout, "name: %s\n", dom["name"].GetString());
		}

		if (dom.HasMember("address") && dom["address"].IsString()) {
			fprintf(stdout, "address: %s\n", utf8_to_gbk(dom["address"].GetString()));
		}

		if (dom.HasMember("age") && dom["age"].IsInt()) {
			fprintf(stdout, "age: %d\n", dom["age"].GetInt());
		}

		const char* tmp = "xxx";
		if (!dom.HasMember(tmp)) {
			fprintf(stdout, "Warning: it has no member: %s\n", tmp);
		}

		if (dom.HasMember("value1") && dom["value1"].IsArray()) {
			const rapidjson::Value& arr = dom["value1"];
			for (int i = 0; i < arr.Size(); ++i) {
				const rapidjson::Value& tmp = arr[i];
				
				fprintf(stdout, "value1:\ni = %d:", i);
				for (int j = 0; j < tmp.Size(); ++j) {
					if (tmp[j].IsInt())
						fprintf(stdout, "%d, ", tmp[j].GetInt());
					if (tmp[j].IsFloat())
						fprintf(stdout, "%.1f, ", tmp[j].GetFloat());
				}
				fprintf(stdout, "\n");
			}
		}

		if (dom.HasMember("value2") && dom["value2"].IsArray()) {
			const rapidjson::Value& arr = dom["value2"];

			fprintf(stdout, "value2: ");
			for (int i = 0; i < arr.Size(); ++i) {
				fprintf(stdout, "%.2f, ", arr[i].GetFloat());
			}
			fprintf(stdout, "\n");
		}

		if (dom.HasMember("bei_jing") && dom["bei_jing"].IsObject()) {
			const rapidjson::Value& obj = dom["bei_jing"];

			if (obj.HasMember("address") && obj["address"].IsString()) {
				fprintf(stdout, "address: %s\n", utf8_to_gbk(obj["address"].GetString()));
			}

			if (obj.HasMember("car") && obj["car"].IsBool()) {
				fprintf(stdout, "car: %d\n", obj["car"].GetBool());
			}

			if (obj.HasMember("cat") && obj["cat"].IsBool()) {
				fprintf(stdout, "cat: %d\n", obj["cat"].GetBool());
			}
		}

		if (dom.HasMember("shan_dong") && dom["shan_dong"].IsObject()) {
			const rapidjson::Value& obj = dom["shan_dong"];

			if (obj.HasMember("address") && obj["address"].IsString()) {
				fprintf(stdout, "address: %s\n", utf8_to_gbk(obj["address"].GetString()));
			}

			if (obj.HasMember("value1") && obj["value1"].IsArray()) {
				const rapidjson::Value& arr = obj["value1"];

				if (arr[0].HasMember("ji_nan") && arr[0]["ji_nan"].IsString()) {
					fprintf(stdout, "ji_nan: %s\n", utf8_to_gbk(arr[0]["ji_nan"].GetString()));
				}

				if (arr[0].HasMember("tai_an") && arr[0]["tai_an"].IsString()) {
					fprintf(stdout, "tai_an: %s\n", utf8_to_gbk(arr[0]["tai_an"].GetString()));
				}
			}
		}
	} else {
		fprintf(stderr, "fail to parse json file: %s\n", file_name);
		return -1;
	}

	// iter json
	for (rapidjson::Value::ConstMemberIterator iter = dom.MemberBegin(); iter != dom.MemberEnd(); ++iter) {
		fprintf(stdout, "iter json name: %s, type: %d\n", iter->name.GetString(), iter->value.GetType());
	}

	return 0;
}

int test_rapidjson_write()
{
	rapidjson::StringBuffer buf;
	//rapidjson::Writer<rapidjson::StringBuffer> writer(buf);
	rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf); // it can word wrap

	writer.StartObject();

	writer.Key("name"); writer.String("spring");
	writer.Key("address"); writer.String("北京");
	writer.Key("age"); writer.Int(30);

	writer.Key("value1");
	writer.StartArray();
	writer.StartArray();
	writer.Double(23); writer.Double(43); writer.Double(-2.3); writer.Double(6.7);     
    writer.Double(90);
	writer.EndArray();

	writer.StartArray();
	writer.Int(-9); writer.Int(-19); writer.Int(10); writer.Int(2);
	writer.EndArray();

	writer.StartArray();
	writer.Int(-5); writer.Int(-55);
	writer.EndArray();
	writer.EndArray();

	writer.Key("value2");
	writer.StartArray();
	writer.Double(13.3); writer.Double(1.9); writer.Double(2.10);
	writer.EndArray();

	writer.Key("bei_jing");
	writer.StartObject();
	writer.Key("address"); writer.String("海淀");
	writer.Key("car"); writer.Bool(false);
	writer.Key("cat"); writer.Bool(true);
	writer.EndObject();

	writer.Key("shan_dong");
	writer.StartObject();
	writer.Key("address"); writer.String("济南");
	writer.Key("value1");
	writer.StartArray();
	writer.Key("ji_nan"); writer.String("趵突泉");
	writer.Key("tai_an"); writer.String("泰山");
	writer.EndArray();
	writer.EndObject();

	writer.EndObject();

	const char* json_content = buf.GetString();
	fprintf(stdout, "json content: %s\n", json_content);

#ifdef _MSC_VER
	const char* file_name = "E:/GitCode/Messy_Test/testdata/out.json";
#else
	const char* file_name = "testdata/out.json";
#endif
	std::ofstream outfile;
	outfile.open(file_name);
	if (!outfile.is_open()) {
		fprintf(stderr, "fail to open file to write: %s\n", file_name);
		return -1;
	}

	outfile << json_content << std::endl;
	outfile.close();

	return 0;
}

json.data内容如下:

{
  "name": "spring",
  "address": "北京",
  "age": 30,
  "value1": [[23, 43, -2.3, 6.7, 90],
             [-9, -19, 10, 2],
             [-5, -55]],
  "value2": [13.3, 1.9, 2.10],
  
  "bei_jing": {
    "address": "海淀",
    "car": false,
    "cat": true
  },
  "shan_dong": {
    "address": "济南",
    "value1": [{"ji_nan": "趵突泉"}, {"tai_an": "泰山"}]
  }
}

test_rapidjson_parse的执行结果如下:与实际结果一致

test_rapidjson_write的执行结果如下:与预期一致,将rapidjson::Writer<rapidjson::StringBuffer> writer(buf)调整为rapidjson::PrettyWriter<rapidjson::StringBuffer> writer(buf);可使结果自动换行

GitHubGitHub - fengbingchun/Messy_Test: C++/C++11/C++14's usage

### 回答1: 半导体激光器LD (Laser Diode) 是一种将电能转化为激光能的器件。其工作原理基于电子在半导体材料中的激发和辐射。 在半导体材料中,当外加电场的作用下,正负电荷被分离形成带电粒子。在PN结形成的区域内,电子从N区向P区迁移,空穴从P区向N区迁移,形成了扩散电流。 当电流通过半导体材料时,少数载流子(电子和空穴)通过复合过程散失能量。在此过程中,激发态被生成,激光的核心部分。这些激发态持续存在一段时间,直到它们通过受激辐射的过程放出光子并降至基态。 为了增加受激辐射的可能性,半导体材料是由多个PN结组成的,形成了一个与电流垂直的因子。这种结构叫做活性层。在活性层内,电子和空穴进行受激辐射,产生的光谱位于可见光范围内。 为了实现激光的单一频道输出,半导体材料通常采用量子阱结构。量子阱是一种能够限制电子和空穴的空间范围的结构,使它们在特定的波长发出激光。这种结构使得半导体激光器能够产生具有更窄频宽的光。 在半导体激光器的结构中,开孔或凸起的区域被形成,形成反射镜。反射镜与活性层之间的区域称为腔结构。当电流通过结构时,反射镜形成的腔中的光子被来回反射,增加了受激辐射的概率。最终,激光通过半导体材料的一个边界逃逸出来,形成了可见光。 总而言之,半导体激光器通过电流激发半导体材料中的电子和空穴,产生激发态。这些激发态在活性层中通过受激辐射过程放出光子,形成激光。通过反射镜产生的腔结构增加了受激辐射的概率,最终实现激光的输出。半导体激光器因其小巧、高效、可调谐等特点在通信、医学、测量等领域有着广泛的应用。 ### 回答2: 半导体激光器(LD)是一种利用半导体材料产生和放大激光的器件。其工作原理可以分为以下几个步骤: 首先,通过半导体材料的特殊结构,在材料中形成一个GaN(Gallium Nitride)的PN结构。PN结构是指在半导体材料中形成一个正负电荷的结构,其中P端富含正电荷,N端富含负电荷。 然后,当在P端施加正向电流,而在N端施加负向电流时,电流开始流经PN结构,形成电流载流子的流动。这些载流子可以是电子或正空穴。 接下来,当电流载流子流经PN结构时,它们会与材料内的特定能级相互作用,导致电子从高能级跃迁到低能级,释放出光子能量。这个能级之间的电子跃迁过程是光的产生。 最后,通过在PN结构中的两端放置反射镜,形成一个光学谐振腔,使激光光子在谐振腔内反复来回反射,并不断被放大。其中一个反射镜是透明的,允许激光通过。 通过以上步骤,电流载流子在PN结构中反复跃迁,不断产生并放大激光。这种激光可以是持续激光,也可以是脉冲激光,具有窄的谱宽和高的光强度,广泛应用于光通信、激光医疗、光存储等领域。 ### 回答3: 半导体激光器LD(Laser Diode)是一种利用半导体材料产生激光的器件。它的工作原理基于半导体的PN结和电子激发态之间的相互作用。 在半导体材料中,N区富电子,P区富空穴。当P、N两区相连接时,形成一个PN结。在静止状态下,PN结处形成一个电势垒,电子从N区到P区,空穴从P区到N区,产生等量的正负离子,形成动态平衡。 当向PN结施加外加电压时,使电子从N区向P区流动,空穴从P区向N区流动,电子与空穴在PN结区域发生复合,这称为正向偏置。在正向偏置下,电子从N区向P区跃迁,形成激活的电子。当激活的电子回降到基态时,将释放能量,这个能量的释放过程称为辐射,其中包括光子的辐射。而光子的辐射又称为自发辐射。 然而,自发辐射的光子往往散射或被吸收,难以形成有效的激射。为了增加自发辐射光子被吸收概率,同时提高被放大的光子数目,需要在PN结两侧之间制备一个光学反射镜结构。这样可以使光子在多次来回反射后产生的叠加效应,在适当的条件下实现光子的增长。当光子数目足够多时,则会出现放大效应,形成激光输出,这称为受激辐射。 激光的波长取决于半导体材料带隙宽度的能量差。通过控制材料的成分和结构,可以实现不同波长的激光输出。 总之,半导体激光器LD的工作原理主要是通过正向偏置下的电子和空穴的复合过程释放能量,形成自发辐射,并通过光学反射镜结构实现光子的增长,最终实现激光的放大和输出。
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值