本文整理汇总了C++中sc_format_path函数的典型用法代码示例。如果您正苦于以下问题:C++ sc_format_path函数的具体用法?C++ sc_format_path怎么用?C++ sc_format_path使用的例子?那么恭喜您, 这里精选的函数代码示例或许可以为您提供帮助。
在下文中一共展示了sc_format_path函数的20个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于我们的系统推荐出更棒的C++代码示例。
示例1: do_genkey
int do_genkey(sc_card_t *card, u8 key_id, unsigned int key_len)
{
int r;
sc_cardctl_openpgp_keygen_info_t key_info;
u8 fingerprints[60];
sc_path_t path;
sc_file_t *file;
if (key_id < 1 || key_id > 3) {
printf("Unknown key ID %d.\n", key_id);
return 1;
}
memset(&key_info, 0, sizeof(sc_cardctl_openpgp_keygen_info_t));
key_info.keytype = key_id;
key_info.modulus_len = key_len;
key_info.modulus = malloc(key_len/8);
r = sc_card_ctl(card, SC_CARDCTL_OPENPGP_GENERATE_KEY, &key_info);
free(key_info.modulus);
if (r < 0) {
printf("Failed to generate key. Error %s.\n", sc_strerror(r));
return 1;
}
sc_format_path("006E007300C5", &path);
r = sc_select_file(card, &path, &file);
r = sc_read_binary(card, 0, fingerprints, 60, 0);
if (r < 0) {
printf("Failed to retrieve fingerprints. Error %s.\n", sc_strerror(r));
return 1;
}
printf("Fingerprint:\n%s\n", (char *)sc_dump_hex(fingerprints + 20*(key_id - 1), 20));
return 0;
}
开发者ID:andyvand,项目名称:OpenSC,代码行数:32,代码来源:openpgp-tool.c
示例2: gpk_lock_pinfile
/*
* Lock the pin file
*/
static int
gpk_lock_pinfile(struct sc_profile *profile, sc_card_t *card,
sc_file_t *pinfile)
{
struct sc_path path;
struct sc_file *parent = NULL;
int r;
/* Select the parent DF */
path = pinfile->path;
if (path.len >= 2)
path.len -= 2;
if (path.len == 0)
sc_format_path("3F00", &path);
if ((r = sc_select_file(card, &path, &parent)) < 0)
return r;
/* Present PINs etc as necessary */
r = sc_pkcs15init_authenticate(profile, card, parent, SC_AC_OP_LOCK);
if (r >= 0)
r = gpk_lock(card, pinfile, SC_AC_OP_WRITE);
sc_file_free(parent);
return r;
}
开发者ID:guadalinex-archive,项目名称:guadalinex-v5,代码行数:28,代码来源:pkcs15-gpk.c
示例3: incrypto34_create_dir
/*
* Create the Application DF
*/
static int
incrypto34_create_dir(sc_profile_t *profile, sc_pkcs15_card_t *p15card, sc_file_t *df)
{
int r;
struct sc_file *file;
struct sc_path path;
memset(&file, 0, sizeof(file));
sc_format_path("3F00", &path);
if ((r = sc_select_file(p15card->card, &path, &file)) < 0)
return r;
if ((r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_CREATE)) < 0)
return r;
/* Create the application DF */
if ((r = sc_pkcs15init_create_file(profile, p15card, df)) < 0)
return r;
if ((r = sc_select_file(p15card->card, &df->path, NULL)) < 0)
return r;
/* Create a security environment for this DF.
*/
if ((r = incrypto34_create_sec_env(profile, p15card->card, 0x01, 0x00)) < 0)
return r;
return 0;
}
开发者ID:securez,项目名称:opendnie,代码行数:29,代码来源:pkcs15-incrypto34.c
示例4: do_fileid
static int
do_fileid(struct state *cur, int argc, char **argv)
{
struct file_info *fi;
struct sc_file *df, *file = cur->file->file;
struct sc_path temp, *path = &file->path;
/* sc_format_path doesn't return an error indication
* when it's unable to parse the path */
sc_format_path(argv[0], &temp);
if (temp.len != 2) {
parse_error(cur, "Invalid file ID length\n");
return 1;
}
/* Get the DF, if any */
if ((fi = cur->file->parent) && (df = fi->file)) {
if (df->path.len == 0) {
parse_error(cur, "No path/fileid set for parent DF\n");
return 1;
}
if (df->path.len + 2 > sizeof(df->path)) {
parse_error(cur, "File path too long\n");
return 1;
}
*path = df->path;
}
memcpy(path->value + path->len, temp.value, 2);
path->len += 2;
file->id = (temp.value[0] << 8) | temp.value[1];
return 0;
}
开发者ID:Emergya,项目名称:opendnie-debian-packaging,代码行数:33,代码来源:profile.c
示例5: dump_ef
static
int dump_ef(sc_card_t * card, const char *path, u8 * buf, size_t * buf_len)
{
int rv;
sc_file_t *file = NULL;
sc_path_t scpath;
sc_format_path(path, &scpath);
rv = sc_select_file(card, &scpath, &file);
if (rv < 0) {
if (file)
sc_file_free(file);
return rv;
}
if (file->size > *buf_len) {
sc_file_free(file);
return SC_ERROR_BUFFER_TOO_SMALL;
}
rv = sc_read_binary(card, 0, buf, file->size, 0);
sc_file_free(file);
if (rv < 0)
return rv;
*buf_len = rv;
return SC_SUCCESS;
}
开发者ID:martinpaljak,项目名称:OpenSC,代码行数:25,代码来源:pkcs15-pteid.c
示例6: sc_pkcs15emu_get_df
static sc_pkcs15_df_t * sc_pkcs15emu_get_df(sc_pkcs15_card_t *p15card,
unsigned int type)
{
sc_pkcs15_df_t *df;
sc_file_t *file;
int created = 0;
while (1) {
for (df = p15card->df_list; df; df = df->next) {
if (df->type == type) {
if (created)
df->enumerated = 1;
return df;
}
}
assert(created == 0);
file = sc_file_new();
if (!file)
return NULL;
sc_format_path("11001101", &file->path);
sc_pkcs15_add_df(p15card, type, &file->path);
sc_file_free(file);
created++;
}
}
开发者ID:RaedChaabouni,项目名称:OpenSC,代码行数:27,代码来源:pkcs15-syn.c
示例7: handle_change
static void handle_change( sc_card_t *card, int pin1, int pin2,
int do_change, u8 *newpin, int newlen)
{
sc_path_t p;
sc_file_t *f;
struct sc_apdu a;
u8 ref;
int i;
printf("\n%s %s with %s: ", do_change ? "Changing" : "Unblocking", pinlist[pin1].label, pinlist[pin2].label);
sc_format_path(pinlist[pin1].path,&p);
if((i=sc_select_file(card,&p,&f))<0){
printf("\nCannot select %s, %s\n", pinlist[pin1].label, sc_strerror(i));
return;
}
ref=f->prop_attr[2] | (strlen(pinlist[pin1].path)>8 ? 0x80 : 0x00);
if(do_change){
sc_format_apdu(card, &a, SC_APDU_CASE_3_SHORT, 0x24, 0x01, ref);
a.data=newpin, a.lc=a.datalen=newlen;
} else {
sc_format_apdu(card, &a, SC_APDU_CASE_1, 0x2C, 0x03, ref);
}
if((i=sc_transmit_apdu(card, &a))<0){
printf("\nsc_transmit_apdu() failed, %s\n", sc_strerror(i));
return;
}
if(a.sw1!=0x90 && a.sw2!=0x00){
printf("%02X%02X\n", a.sw1, a.sw2);
return;
}
printf("OK\n");
}
开发者ID:Emergya,项目名称:opendnie-debian-packaging,代码行数:34,代码来源:netkey-tool.c
示例8: show_card
static void show_card(sc_card_t *card)
{
sc_path_t path;
sc_file_t *file;
u8 buf[100];
int i, len;
sc_format_path("3F002F02",&path);
if((i=sc_select_file(card,&path,&file))<0){
printf("\nCannot select Serial-Number 2F02, is this a NetKey-Card ??\n");
return;
}
if(file->type!=SC_FILE_TYPE_WORKING_EF || file->ef_structure!=SC_FILE_EF_TRANSPARENT ||
file->size!=12 || (len=sc_read_binary(card,0,buf,12,0))!=12 || buf[0]!=0x5A || buf[1]!=0x0A
){
printf("\nInvald Serial-Number: Type=%d, EF-Structure=%d, Size=%lu\n",
file->type, file->ef_structure, (unsigned long) file->size
);
return;
}
printf("\nSerial-Number: ");
for(i=2;i<11;++i) printf("%02X", buf[i]);
printf("%X\n\n", buf[11]>>4);
for(i=0;i<4;++i) show_pin(card, i);
// printf("%s: %u tries left, %u tries max, %s\n", pinlist[i].label, pinlist[i].tries, max, status);
if(pinlist[0].len) show_initial_puk(card);
}
开发者ID:Emergya,项目名称:opendnie-debian-packaging,代码行数:29,代码来源:netkey-tool.c
示例9: list_files
static int list_files(void)
{
sc_path_t path;
int r;
sc_format_path("3F00", &path);
r = enum_dir(path, 0);
return r;
}
开发者ID:guadalinex-archive,项目名称:guadalinex-v5,代码行数:9,代码来源:opensc-tool.c
示例10: insert_cert
static int insert_cert(
sc_pkcs15_card_t *p15card,
const char *path,
unsigned char id,
int writable,
const char *label
){
sc_card_t *card=p15card->card;
sc_context_t *ctx=p15card->card->ctx;
struct sc_pkcs15_cert_info cert_info;
struct sc_pkcs15_object cert_obj;
unsigned char cert[20];
int r;
memset(&cert_info, 0, sizeof(cert_info));
cert_info.id.len = 1;
cert_info.id.value[0] = id;
cert_info.authority = 0;
sc_format_path(path, &cert_info.path);
memset(&cert_obj, 0, sizeof(cert_obj));
strlcpy(cert_obj.label, label, sizeof(cert_obj.label));
cert_obj.flags = writable ? SC_PKCS15_CO_FLAG_MODIFIABLE : 0;
if(sc_select_file(card, &cert_info.path, NULL)!=SC_SUCCESS){
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
"Select(%s) failed\n", path);
return 1;
}
if(sc_read_binary(card, 0, cert, sizeof(cert), 0)<0){
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
"ReadBinary(%s) failed\n", path);
return 2;
}
if(cert[0]!=0x30 || cert[1]!=0x82){
sc_debug(ctx, SC_LOG_DEBUG_NORMAL,
"Invalid Cert: %02X:%02X:...\n", cert[0], cert[1]);
return 3;
}
/* some certificates are prefixed by an OID */
if(cert[4]==0x06 && cert[5]<10 && cert[6+cert[5]]==0x30 && cert[7+cert[5]]==0x82){
cert_info.path.index=6+cert[5];
cert_info.path.count=(cert[8+cert[5]]<<8) + cert[9+cert[5]] + 4;
} else {
cert_info.path.index=0;
cert_info.path.count=(cert[2]<<8) + cert[3] + 4;
}
r=sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
if(r!=SC_SUCCESS){
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "sc_pkcs15emu_add_x509_cert(%s) failed\n", path);
return 4;
}
sc_debug(ctx, SC_LOG_DEBUG_NORMAL, "%s: OK, Index=%d, Count=%d\n", path, cert_info.path.index, cert_info.path.count);
return 0;
}
开发者ID:CendioOssman,项目名称:OpenSC,代码行数:57,代码来源:pkcs15-tcos.c
示例11: do_cd
static int do_cd(int argc, char **argv)
{
sc_path_t path;
sc_file_t *file;
int r;
if (argc != 1)
goto usage;
if (strcmp(argv[0], "..") == 0) {
path = current_path;
if (path.len < 4) {
printf("unable to go up, already in MF.\n");
return -1;
}
if (path.type == SC_PATH_TYPE_DF_NAME) {
sc_format_path("3F00", &path);
}
else {
path.len -= 2;
}
r = sc_select_file(card, &path, &file);
if (r) {
printf("unable to go up: %s\n", sc_strerror(r));
return -1;
}
if (current_file)
sc_file_free(current_file);
current_file = file;
current_path = path;
return 0;
}
if (arg_to_path(argv[0], &path, 0) != 0)
goto usage;
r = sc_select_file(card, &path, &file);
if (r) {
check_ret(r, SC_AC_OP_SELECT, "unable to select DF", current_file);
return -1;
}
if ((file->type != SC_FILE_TYPE_DF) && (card->type != SC_CARD_TYPE_BELPIC_EID)) {
printf("Error: file is not a DF.\n");
sc_file_free(file);
select_current_path_or_die();
return -1;
}
current_path = path;
if (current_file)
sc_file_free(current_file);
current_file = file;
return 0;
usage:
puts("Usage: cd <file_id>|aid:<DF name>");
return -1;
}
开发者ID:emilianobonassi,项目名称:OpenSC,代码行数:57,代码来源:opensc-explorer.c
示例12: select_esteid_df
int
select_esteid_df (sc_card_t * card)
{
int r;
sc_path_t tmppath;
sc_format_path ("3F00EEEE", &tmppath);
r = sc_select_file (card, &tmppath, NULL);
LOG_TEST_RET(card->ctx, r, "esteid select DF failed");
return r;
}
开发者ID:marschap,项目名称:OpenSC,代码行数:10,代码来源:pkcs15-esteid.c
示例13: loadCertificate
/* Loads certificates.
* Certificates are stored in a ZLib compressed form with
* a 4 byte header, so we extract, decompress and cache
* them.
*/
static int loadCertificate(sc_pkcs15_card_t * p15card, int i,
const char *certPath, const char *certLabel)
{
unsigned char *compCert = NULL, *cert = NULL, size[2];
unsigned long int compLen, len;
sc_pkcs15_cert_info_t cert_info;
sc_pkcs15_object_t cert_obj;
sc_path_t cpath;
sc_card_t *card = p15card->card;
sc_pkcs15_id_t id;
int r;
memset(&cert_info, 0, sizeof(cert_info));
memset(&cert_obj, 0, sizeof(cert_obj));
sc_format_path(certPath, &cpath);
if (sc_select_file(card, &cpath, NULL) != SC_SUCCESS)
return SC_ERROR_WRONG_CARD;
sc_read_binary(card, 2, size, 2, 0);
compLen = (size[0] << 8) + size[1];
compCert =
(unsigned char *) malloc(compLen * sizeof(unsigned char));
len = 4 * compLen; /*Approximation of the uncompressed size */
cert = (unsigned char *) malloc(len * sizeof(unsigned char));
sc_read_binary(card, 4, compCert, compLen, 0);
if ((r = uncompress(cert, &len, compCert, compLen)) != Z_OK) {
sc_error(p15card->card->ctx, "Zlib error: %d", r);
return SC_ERROR_INTERNAL;
}
cpath.index = 0;
cpath.count = len;
sc_pkcs15_cache_file(p15card, &cpath, cert, len);
id.len=1;
id.value[0] = i + 1;
cert_info.id = id;
cert_info.path = cpath;
cert_info.authority = (i == 2);
strlcpy(cert_obj.label, certLabel, sizeof(cert_obj.label));
cert_obj.flags = SC_PKCS15_CO_FLAG_MODIFIABLE;
sc_pkcs15emu_add_x509_cert(p15card, &cert_obj, &cert_info);
return SC_SUCCESS;
}
开发者ID:guadalinex-archive,项目名称:guadalinex-v5,代码行数:59,代码来源:pkcs15-infocamere.c
示例14: sc_pkcs15_detect
int sc_pkcs15_detect(sc_card_t *card)
{
int r;
sc_path_t path;
sc_format_path("NA0000063504B43532D3135", &path);
r = sc_select_file(card, &path, NULL);
if (r != 0)
return 0;
return 1;
}
开发者ID:guadalinex-archive,项目名称:guadalinex-v5,代码行数:11,代码来源:pkcs15.c
示例15: openpgp_store_data
static int openpgp_store_data(struct sc_pkcs15_card *p15card, struct sc_profile *profile,
struct sc_pkcs15_object *obj, struct sc_pkcs15_der *content,
struct sc_path *path)
{
sc_card_t *card = p15card->card;
sc_file_t *file;
sc_pkcs15_cert_info_t *cinfo;
sc_pkcs15_id_t *cid;
int r;
LOG_FUNC_CALLED(card->ctx);
switch (obj->type & SC_PKCS15_TYPE_CLASS_MASK) {
case SC_PKCS15_TYPE_PRKEY:
case SC_PKCS15_TYPE_PUBKEY:
/* For these two type, store_data just don't need to do anything.
* All have been done already before this function is called */
r = SC_SUCCESS;
break;
case SC_PKCS15_TYPE_CERT:
cinfo = (sc_pkcs15_cert_info_t *) obj->data;
cid = &(cinfo->id);
if (cid->len != 1) {
sc_log(card->ctx, "ID=%s is not valid.", sc_dump_hex(cid->value, cid->len));
LOG_FUNC_RETURN(card->ctx, SC_ERROR_INVALID_ARGUMENTS);
}
/* OpenPGP card v.2 contains only 1 certificate */
if (cid->value[0] != 3) {
sc_log(card->ctx,
"This version does not support certificate ID = %d (only ID=3 is supported).",
cid->value[0]);
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}
/* Just update the certificate DO */
sc_format_path("7F21", path);
r = sc_select_file(card, path, &file);
LOG_TEST_RET(card->ctx, r, "Cannot select cert file");
r = sc_pkcs15init_authenticate(profile, p15card, file, SC_AC_OP_UPDATE);
if (r >= 0 && content->len)
r = sc_update_binary(p15card->card, 0,
(const unsigned char *) content->value,
content->len, 0);
break;
default:
r = SC_ERROR_NOT_IMPLEMENTED;
}
LOG_FUNC_RETURN(card->ctx, r);
}
开发者ID:miguel-cv,项目名称:OpenSC,代码行数:53,代码来源:pkcs15-openpgp.c
示例16: westcos_pkcs15init_init_card
static int westcos_pkcs15init_init_card(sc_profile_t *profile,
sc_pkcs15_card_t *p15card)
{
int r;
struct sc_path path;
sc_format_path("3F00", &path);
r = sc_select_file(p15card->card, &path, NULL);
if(r) return (r);
return r;
}
开发者ID:exciler,项目名称:OpenSC,代码行数:12,代码来源:pkcs15-westcos.c
示例17: sc_pkcs15_parse_unusedspace
int sc_pkcs15_parse_unusedspace(const u8 * buf, size_t buflen, struct sc_pkcs15_card *card)
{
const u8 *p = buf;
size_t left = buflen;
int r;
sc_path_t path, dummy_path;
sc_pkcs15_id_t auth_id;
struct sc_asn1_entry asn1_unusedspace[] = {
{ "UnusedSpace", SC_ASN1_STRUCT, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
struct sc_asn1_entry asn1_unusedspace_values[] = {
{ "path", SC_ASN1_PATH, SC_ASN1_TAG_SEQUENCE | SC_ASN1_CONS, 0, NULL, NULL },
{ "authId", SC_ASN1_PKCS15_ID, SC_ASN1_TAG_OCTET_STRING, SC_ASN1_OPTIONAL, NULL, NULL },
{ NULL, 0, 0, 0, NULL, NULL }
};
/* Clean the list if already present */
while (card->unusedspace_list)
sc_pkcs15_remove_unusedspace(card, card->unusedspace_list);
sc_format_path("3F00", &dummy_path);
dummy_path.index = dummy_path.count = 0;
sc_format_asn1_entry(asn1_unusedspace, asn1_unusedspace_values, NULL, 1);
sc_format_asn1_entry(asn1_unusedspace_values, &path, NULL, 1);
sc_format_asn1_entry(asn1_unusedspace_values+1, &auth_id, NULL, 0);
while (left > 0) {
memset(&auth_id, 0, sizeof(auth_id));
r = sc_asn1_decode(card->card->ctx, asn1_unusedspace, p, left, &p, &left);
if (r == SC_ERROR_ASN1_END_OF_CONTENTS)
break;
if (r < 0)
return r;
/* If the path length is 0, it's a dummy path then don't add it.
* If the path length isn't included (-1) then it's against the standard
* but we'll just ignore it instead of returning an error. */
if (path.count > 0) {
r = sc_pkcs15_make_absolute_path(&card->file_app->path, &path);
if (r < 0)
return r;
r = sc_pkcs15_add_unusedspace(card, &path, &auth_id);
if (r)
return r;
}
}
card->unusedspace_read = 1;
return 0;
}
开发者ID:guadalinex-archive,项目名称:guadalinex-v5,代码行数:52,代码来源:pkcs15.c
示例18: do_info
static int do_info(sc_card_t *card, const struct ef_name_map *map)
{
int i;
u8 buf[2048];
for (i = 0; map[i].ef != NULL; i++) {
sc_path_t path;
sc_file_t *file;
size_t count;
int r;
sc_format_path(map[i].ef, &path);
r = sc_select_file(card, &path, &file);
if (r) {
util_error("failed to select EF %s: %s", map[i].ef, sc_strerror(r));
return EXIT_FAILURE;
}
count = file->size;
if (!count)
continue;
if (count > sizeof(buf) - 1) {
util_error("too small buffer to read the OpenPGP map");
return EXIT_FAILURE;
}
r = sc_read_binary(card, 0, buf, count, 0);
if (r < 0) {
util_error("failed to read %s: %s", map[i].ef, sc_strerror(r));
return EXIT_FAILURE;
}
if (r != (signed) count || (size_t) r < map[i].offset + map[i].length) {
util_error("%s: expecting %"SC_FORMAT_LEN_SIZE_T"d bytes, got only %d",
map[i].ef, count, r);
return EXIT_FAILURE;
}
if (map[i].offset > 0) {
memmove(buf, buf + map[i].offset, map[i].length);
count -= map[i].offset;
}
if (map[i].length > 0 && count > map[i].length)
count = map[i].length;
if (map[i].type == TYPE_STRING)
buf[count] = '\0';
display_data(&map[i], buf, count);
}
return EXIT_SUCCESS;
}
开发者ID:marschap,项目名称:OpenSC,代码行数:51,代码来源:openpgp-tool.c
示例19: myeid_init_card
static int myeid_init_card(sc_profile_t *profile,
sc_card_t *card)
{
struct sc_path path;
sc_file_t *file;
int r;
SC_FUNC_CALLED(card->ctx, 1);
sc_format_path("3F00", &path);
r = sc_select_file(card, &path, NULL);
SC_FUNC_RETURN(card->ctx, 1, r);
}
开发者ID:Emergya,项目名称:opendnie-debian-packaging,代码行数:14,代码来源:pkcs15-myeid.c
示例20: jpki_set_security_env
static int
jpki_set_security_env(sc_card_t * card,
const sc_security_env_t * env, int se_num)
{
int rc;
sc_path_t path;
LOG_FUNC_CALLED(card->ctx);
sc_log(card->ctx,
"flags=%08lx op=%d alg=%d algf=%08x algr=%08x kr0=%02x, krfl=%"SC_FORMAT_LEN_SIZE_T"u",
env->flags, env->operation, env->algorithm,
env->algorithm_flags, env->algorithm_ref, env->key_ref[0],
env->key_ref_len);
switch (env->operation) {
case SC_SEC_OPERATION_SIGN:
break;
default:
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}
switch (env->key_ref[0]) {
case 1:
sc_format_path(JPKI_AUTH_KEY, &path);
break;
case 2:
sc_format_path(JPKI_SIGN_KEY, &path);
break;
default:
LOG_FUNC_RETURN(card->ctx, SC_ERROR_NOT_SUPPORTED);
}
path.type = SC_PATH_TYPE_FILE_ID;
rc = sc_select_file(card, &path, NULL);
LOG_TEST_RET(card->ctx, rc, "select key failed");
LOG_FUNC_RETURN(card->ctx, SC_SUCCESS);
}
开发者ID:jpki,项目名称:OpenSC,代码行数:37,代码来源:card-jpki.c
注:本文中的sc_format_path函数示例由纯净天空整理自Github/MSDocs等源码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。 |
请发表评论