浏览代码

[settings] Split fetching and storing out of setting type handlers

Refactor setting type handlers to parse and format values, rather than
storing and fetching formatted values.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 13 年前
父节点
当前提交
831b16adde
共有 4 个文件被更改,包括 353 次插入273 次删除
  1. 338
    243
      src/core/settings.c
  2. 1
    1
      src/core/uuid.c
  3. 13
    28
      src/include/ipxe/settings.h
  4. 1
    1
      src/include/ipxe/uuid.h

+ 338
- 243
src/core/settings.c 查看文件

776
 	return fetch_ipv4_array_setting ( settings, setting, inp, 1 );
776
 	return fetch_ipv4_array_setting ( settings, setting, inp, 1 );
777
 }
777
 }
778
 
778
 
779
+/**
780
+ * Extract numeric value of setting
781
+ *
782
+ * @v raw		Raw setting data
783
+ * @v len		Length of raw setting data
784
+ * @ret signed_value	Value, when interpreted as a signed integer
785
+ * @ret unsigned_value	Value, when interpreted as an unsigned integer
786
+ * @ret len		Length of setting, or negative error
787
+ */
788
+static int numeric_setting_value ( const void *raw, size_t len,
789
+				   signed long *signed_value,
790
+				   unsigned long *unsigned_value ) {
791
+	const uint8_t *unsigned_bytes = raw;
792
+	const int8_t *signed_bytes = raw;
793
+	int is_negative;
794
+	unsigned int i;
795
+	uint8_t byte;
796
+
797
+	/* Range check */
798
+	if ( len > sizeof ( long ) )
799
+		return -ERANGE;
800
+
801
+	/* Convert to host-ordered longs */
802
+	is_negative = ( len && ( signed_bytes[0] < 0 ) );
803
+	*signed_value = ( is_negative ? -1L : 0 );
804
+	*unsigned_value = 0;
805
+	for ( i = 0 ; i < len ; i++ ) {
806
+		byte = unsigned_bytes[i];
807
+		*signed_value = ( ( *signed_value << 8 ) | byte );
808
+		*unsigned_value = ( ( *unsigned_value << 8 ) | byte );
809
+	}
810
+
811
+	return len;
812
+}
813
+
779
 /**
814
 /**
780
  * Fetch value of signed integer setting
815
  * Fetch value of signed integer setting
781
  *
816
  *
786
  */
821
  */
787
 int fetch_int_setting ( struct settings *settings, struct setting *setting,
822
 int fetch_int_setting ( struct settings *settings, struct setting *setting,
788
 			long *value ) {
823
 			long *value ) {
789
-	union {
790
-		uint8_t u8[ sizeof ( long ) ];
791
-		int8_t s8[ sizeof ( long ) ];
792
-	} buf;
824
+	unsigned long dummy;
825
+	long tmp;
793
 	int len;
826
 	int len;
794
-	int i;
795
 
827
 
796
 	/* Avoid returning uninitialised data on error */
828
 	/* Avoid returning uninitialised data on error */
797
 	*value = 0;
829
 	*value = 0;
798
 
830
 
799
 	/* Fetch raw (network-ordered, variable-length) setting */
831
 	/* Fetch raw (network-ordered, variable-length) setting */
800
-	len = fetch_setting ( settings, setting, &buf, sizeof ( buf ) );
832
+	len = fetch_setting ( settings, setting, &tmp, sizeof ( tmp ) );
801
 	if ( len < 0 )
833
 	if ( len < 0 )
802
 		return len;
834
 		return len;
803
-	if ( len > ( int ) sizeof ( buf ) )
804
-		return -ERANGE;
805
-
806
-	/* Convert to host-ordered signed long */
807
-	*value = ( ( buf.s8[0] >= 0 ) ? 0 : -1L );
808
-	for ( i = 0 ; i < len ; i++ ) {
809
-		*value = ( ( *value << 8 ) | buf.u8[i] );
810
-	}
811
 
835
 
812
-	return len;
836
+	/* Extract numeric value */
837
+	return numeric_setting_value ( &tmp, len, value, &dummy );
813
 }
838
 }
814
 
839
 
815
 /**
840
 /**
822
  */
847
  */
823
 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
848
 int fetch_uint_setting ( struct settings *settings, struct setting *setting,
824
 			 unsigned long *value ) {
849
 			 unsigned long *value ) {
825
-	long svalue;
850
+	signed long dummy;
851
+	long tmp;
826
 	int len;
852
 	int len;
827
 
853
 
828
 	/* Avoid returning uninitialised data on error */
854
 	/* Avoid returning uninitialised data on error */
829
 	*value = 0;
855
 	*value = 0;
830
 
856
 
831
-	/* Fetch as a signed long */
832
-	len = fetch_int_setting ( settings, setting, &svalue );
857
+	/* Fetch raw (network-ordered, variable-length) setting */
858
+	len = fetch_setting ( settings, setting, &tmp, sizeof ( tmp ) );
833
 	if ( len < 0 )
859
 	if ( len < 0 )
834
 		return len;
860
 		return len;
835
 
861
 
836
-	/* Mask off sign-extended bits */
837
-	assert ( len <= ( int ) sizeof ( long ) );
838
-	*value = ( svalue & ( -1UL >> ( 8 * ( sizeof ( long ) - len ) ) ) );
839
-
840
-	return len;
862
+	/* Extract numeric value */
863
+	return numeric_setting_value ( &tmp, len, &dummy, value );
841
 }
864
 }
842
 
865
 
843
 /**
866
 /**
929
  */
952
  */
930
 
953
 
931
 /**
954
 /**
932
- * Store value of typed setting
955
+ * Fetch and format value of setting
956
+ *
957
+ * @v settings		Settings block, or NULL to search all blocks
958
+ * @v setting		Setting to fetch
959
+ * @v type		Settings type
960
+ * @v buf		Buffer to contain formatted value
961
+ * @v len		Length of buffer
962
+ * @ret len		Length of formatted value, or negative error
963
+ */
964
+int fetchf_setting ( struct settings *settings, struct setting *setting,
965
+		     char *buf, size_t len ) {
966
+	int raw_len;
967
+	int check_len;
968
+	int rc;
969
+
970
+	/* Fetch raw value */
971
+	raw_len = fetch_setting_len ( settings, setting );
972
+	if ( raw_len < 0 ) {
973
+		rc = raw_len;
974
+		return rc;
975
+	} else {
976
+		uint8_t raw[raw_len];
977
+
978
+		/* Fetch raw value */
979
+		check_len = fetch_setting ( settings, setting, raw,
980
+					    sizeof ( raw ) );
981
+		if ( check_len < 0 )
982
+			return check_len;
983
+		assert ( check_len == raw_len );
984
+
985
+		/* Format value */
986
+		return setting->type->format ( raw, sizeof ( raw ), buf, len );
987
+	}
988
+}
989
+
990
+/**
991
+ * Store formatted value of setting
933
  *
992
  *
934
  * @v settings		Settings block
993
  * @v settings		Settings block
935
  * @v setting		Setting to store
994
  * @v setting		Setting to store
936
- * @v type		Settings type
937
  * @v value		Formatted setting data, or NULL
995
  * @v value		Formatted setting data, or NULL
938
  * @ret rc		Return status code
996
  * @ret rc		Return status code
939
  */
997
  */
940
 int storef_setting ( struct settings *settings, struct setting *setting,
998
 int storef_setting ( struct settings *settings, struct setting *setting,
941
 		     const char *value ) {
999
 		     const char *value ) {
1000
+	int raw_len;
1001
+	int check_len;
1002
+	int rc;
942
 
1003
 
943
-	/* NULL value implies deletion.  Avoid imposing the burden of
944
-	 * checking for NULL values on each typed setting's storef()
945
-	 * method.
946
-	 */
1004
+	/* NULL value implies deletion */
947
 	if ( ! value )
1005
 	if ( ! value )
948
 		return delete_setting ( settings, setting );
1006
 		return delete_setting ( settings, setting );
949
-		
950
-	return setting->type->storef ( settings, setting, value );
1007
+
1008
+	/* Parse formatted value */
1009
+	raw_len = setting->type->parse ( value, NULL, 0 );
1010
+	if ( raw_len < 0 ) {
1011
+		rc = raw_len;
1012
+		return rc;
1013
+	} else {
1014
+		uint8_t raw[raw_len];
1015
+
1016
+		/* Parse formatted value */
1017
+		check_len = setting->type->parse ( value, raw, sizeof ( raw ) );
1018
+		assert ( check_len == raw_len );
1019
+
1020
+		/* Store raw value */
1021
+		return store_setting ( settings, setting, raw, sizeof ( raw ) );
1022
+	}
951
 }
1023
 }
952
 
1024
 
1025
+/******************************************************************************
1026
+ *
1027
+ * Named settings
1028
+ *
1029
+ ******************************************************************************
1030
+ */
1031
+
953
 /**
1032
 /**
954
  * Find named setting
1033
  * Find named setting
955
  *
1034
  *
1176
  */
1255
  */
1177
 
1256
 
1178
 /**
1257
 /**
1179
- * Parse and store value of string setting
1258
+ * Parse string setting value
1180
  *
1259
  *
1181
- * @v settings		Settings block
1182
- * @v setting		Setting to store
1183
- * @v value		Formatted setting data
1184
- * @ret rc		Return status code
1260
+ * @v value		Formatted setting value
1261
+ * @v buf		Buffer to contain raw value
1262
+ * @v len		Length of buffer
1263
+ * @ret len		Length of raw value, or negative error
1185
  */
1264
  */
1186
-static int storef_string ( struct settings *settings, struct setting *setting,
1187
-			   const char *value ) {
1188
-	return store_setting ( settings, setting, value, strlen ( value ) );
1265
+static int parse_string_setting ( const char *value, void *buf, size_t len ) {
1266
+	size_t raw_len = strlen ( value ); /* Exclude terminating NUL */
1267
+
1268
+	/* Copy string to buffer */
1269
+	if ( len > raw_len )
1270
+		len = raw_len;
1271
+	memcpy ( buf, value, len );
1272
+
1273
+	return raw_len;
1189
 }
1274
 }
1190
 
1275
 
1191
 /**
1276
 /**
1192
- * Fetch and format value of string setting
1277
+ * Format string setting value
1193
  *
1278
  *
1194
- * @v settings		Settings block, or NULL to search all blocks
1195
- * @v setting		Setting to fetch
1279
+ * @v raw		Raw setting value
1280
+ * @v raw_len		Length of raw setting value
1196
  * @v buf		Buffer to contain formatted value
1281
  * @v buf		Buffer to contain formatted value
1197
  * @v len		Length of buffer
1282
  * @v len		Length of buffer
1198
  * @ret len		Length of formatted value, or negative error
1283
  * @ret len		Length of formatted value, or negative error
1199
  */
1284
  */
1200
-static int fetchf_string ( struct settings *settings, struct setting *setting,
1201
-			   char *buf, size_t len ) {
1202
-	return fetch_string_setting ( settings, setting, buf, len );
1285
+static int format_string_setting ( const void *raw, size_t raw_len, char *buf,
1286
+				   size_t len ) {
1287
+
1288
+	/* Copy string to buffer, and terminate */
1289
+	memset ( buf, 0, len );
1290
+	if ( len > raw_len )
1291
+		len = raw_len;
1292
+	memcpy ( buf, raw, len );
1293
+
1294
+	return raw_len;
1203
 }
1295
 }
1204
 
1296
 
1205
 /** A string setting type */
1297
 /** A string setting type */
1206
 struct setting_type setting_type_string __setting_type = {
1298
 struct setting_type setting_type_string __setting_type = {
1207
 	.name = "string",
1299
 	.name = "string",
1208
-	.storef = storef_string,
1209
-	.fetchf = fetchf_string,
1300
+	.parse = parse_string_setting,
1301
+	.format = format_string_setting,
1210
 };
1302
 };
1211
 
1303
 
1212
 /**
1304
 /**
1213
- * Parse and store value of URI-encoded string setting
1305
+ * Parse URI-encoded string setting value
1214
  *
1306
  *
1215
- * @v settings		Settings block
1216
- * @v setting		Setting to store
1217
- * @v value		Formatted setting data
1218
- * @ret rc		Return status code
1307
+ * @v value		Formatted setting value
1308
+ * @v buf		Buffer to contain raw value
1309
+ * @v len		Length of buffer
1310
+ * @ret len		Length of raw value, or negative error
1219
  */
1311
  */
1220
-static int storef_uristring ( struct settings *settings,
1221
-			      struct setting *setting,
1222
-			      const char *value ) {
1223
-	char buf[ strlen ( value ) + 1 ]; /* Decoding never expands string */
1224
-	size_t len;
1312
+static int parse_uristring_setting ( const char *value, void *buf,
1313
+				     size_t len ) {
1314
+	char tmp[ len + 1 /* NUL */ ];
1315
+	size_t raw_len;
1316
+
1317
+	/* Decode to temporary buffer (including NUL) */
1318
+	raw_len = uri_decode ( value, tmp, sizeof ( tmp ) );
1225
 
1319
 
1226
-	len = uri_decode ( value, buf, sizeof ( buf ) );
1227
-	return store_setting ( settings, setting, buf, len );
1320
+	/* Copy to output buffer (excluding NUL) */
1321
+	if ( len > raw_len )
1322
+		len = raw_len;
1323
+	memcpy ( buf, tmp, len );
1324
+
1325
+	return raw_len;
1228
 }
1326
 }
1229
 
1327
 
1230
 /**
1328
 /**
1231
- * Fetch and format value of URI-encoded string setting
1329
+ * Format URI-encoded string setting value
1232
  *
1330
  *
1233
- * @v settings		Settings block, or NULL to search all blocks
1234
- * @v setting		Setting to fetch
1331
+ * @v raw		Raw setting value
1332
+ * @v raw_len		Length of raw setting value
1235
  * @v buf		Buffer to contain formatted value
1333
  * @v buf		Buffer to contain formatted value
1236
  * @v len		Length of buffer
1334
  * @v len		Length of buffer
1237
  * @ret len		Length of formatted value, or negative error
1335
  * @ret len		Length of formatted value, or negative error
1238
  */
1336
  */
1239
-static int fetchf_uristring ( struct settings *settings,
1240
-			      struct setting *setting,
1241
-			      char *buf, size_t len ) {
1242
-	ssize_t raw_len;
1337
+static int format_uristring_setting ( const void *raw, size_t raw_len,
1338
+				      char *buf, size_t len ) {
1339
+	char tmp[ raw_len + 1 /* NUL */ ];
1243
 
1340
 
1244
-	/* We need to always retrieve the full raw string to know the
1245
-	 * length of the encoded string.
1246
-	 */
1247
-	raw_len = fetch_setting ( settings, setting, NULL, 0 );
1248
-	if ( raw_len < 0 )
1249
-		return raw_len;
1250
-
1251
-	{
1252
-		char raw_buf[ raw_len + 1 ];
1253
-       
1254
-		fetch_string_setting ( settings, setting, raw_buf,
1255
-				       sizeof ( raw_buf ) );
1256
-		return uri_encode ( raw_buf, buf, len, URI_FRAGMENT );
1257
-	}
1341
+	/* Copy to temporary buffer and terminate */
1342
+	memcpy ( tmp, raw, raw_len );
1343
+	tmp[raw_len] = '\0';
1344
+
1345
+	/* Encode directly into output buffer */
1346
+	return uri_encode ( tmp, buf, len, URI_FRAGMENT );
1258
 }
1347
 }
1259
 
1348
 
1260
 /** A URI-encoded string setting type */
1349
 /** A URI-encoded string setting type */
1261
 struct setting_type setting_type_uristring __setting_type = {
1350
 struct setting_type setting_type_uristring __setting_type = {
1262
 	.name = "uristring",
1351
 	.name = "uristring",
1263
-	.storef = storef_uristring,
1264
-	.fetchf = fetchf_uristring,
1352
+	.parse = parse_uristring_setting,
1353
+	.format = format_uristring_setting,
1265
 };
1354
 };
1266
 
1355
 
1267
 /**
1356
 /**
1268
- * Parse and store value of IPv4 address setting
1357
+ * Parse IPv4 address setting value
1269
  *
1358
  *
1270
- * @v settings		Settings block
1271
- * @v setting		Setting to store
1272
- * @v value		Formatted setting data
1273
- * @ret rc		Return status code
1359
+ * @v value		Formatted setting value
1360
+ * @v buf		Buffer to contain raw value
1361
+ * @v len		Length of buffer
1362
+ * @ret len		Length of raw value, or negative error
1274
  */
1363
  */
1275
-static int storef_ipv4 ( struct settings *settings, struct setting *setting,
1276
-			 const char *value ) {
1364
+static int parse_ipv4_setting ( const char *value, void *buf, size_t len ) {
1277
 	struct in_addr ipv4;
1365
 	struct in_addr ipv4;
1278
 
1366
 
1367
+	/* Parse IPv4 address */
1279
 	if ( inet_aton ( value, &ipv4 ) == 0 )
1368
 	if ( inet_aton ( value, &ipv4 ) == 0 )
1280
 		return -EINVAL;
1369
 		return -EINVAL;
1281
-	return store_setting ( settings, setting, &ipv4, sizeof ( ipv4 ) );
1370
+
1371
+	/* Copy to buffer */
1372
+	if ( len > sizeof ( ipv4 ) )
1373
+		len = sizeof ( ipv4 );
1374
+	memcpy ( buf, &ipv4, len );
1375
+
1376
+	return ( sizeof ( ipv4 ) );
1282
 }
1377
 }
1283
 
1378
 
1284
 /**
1379
 /**
1285
- * Fetch and format value of IPv4 address setting
1380
+ * Format IPv4 address setting value
1286
  *
1381
  *
1287
- * @v settings		Settings block, or NULL to search all blocks
1288
- * @v setting		Setting to fetch
1382
+ * @v raw		Raw setting value
1383
+ * @v raw_len		Length of raw setting value
1289
  * @v buf		Buffer to contain formatted value
1384
  * @v buf		Buffer to contain formatted value
1290
  * @v len		Length of buffer
1385
  * @v len		Length of buffer
1291
  * @ret len		Length of formatted value, or negative error
1386
  * @ret len		Length of formatted value, or negative error
1292
  */
1387
  */
1293
-static int fetchf_ipv4 ( struct settings *settings, struct setting *setting,
1294
-			 char *buf, size_t len ) {
1295
-	struct in_addr ipv4;
1296
-	int raw_len;
1388
+static int format_ipv4_setting ( const void *raw, size_t raw_len, char *buf,
1389
+				 size_t len ) {
1390
+	const struct in_addr *ipv4 = raw;
1297
 
1391
 
1298
-	if ( ( raw_len = fetch_ipv4_setting ( settings, setting, &ipv4 ) ) < 0)
1299
-		return raw_len;
1300
-	return snprintf ( buf, len, "%s", inet_ntoa ( ipv4 ) );
1392
+	if ( raw_len < sizeof ( *ipv4 ) )
1393
+		return -EINVAL;
1394
+	return snprintf ( buf, len, "%s", inet_ntoa ( *ipv4 ) );
1301
 }
1395
 }
1302
 
1396
 
1303
 /** An IPv4 address setting type */
1397
 /** An IPv4 address setting type */
1304
 struct setting_type setting_type_ipv4 __setting_type = {
1398
 struct setting_type setting_type_ipv4 __setting_type = {
1305
 	.name = "ipv4",
1399
 	.name = "ipv4",
1306
-	.storef = storef_ipv4,
1307
-	.fetchf = fetchf_ipv4,
1400
+	.parse = parse_ipv4_setting,
1401
+	.format = format_ipv4_setting,
1308
 };
1402
 };
1309
 
1403
 
1310
 /**
1404
 /**
1311
- * Parse and store value of integer setting
1405
+ * Parse integer setting value
1312
  *
1406
  *
1313
- * @v settings		Settings block
1314
- * @v setting		Setting to store
1315
- * @v value		Formatted setting data
1407
+ * @v value		Formatted setting value
1408
+ * @v buf		Buffer to contain raw value
1409
+ * @v len		Length of buffer
1316
  * @v size		Integer size, in bytes
1410
  * @v size		Integer size, in bytes
1317
- * @ret rc		Return status code
1411
+ * @ret len		Length of raw value, or negative error
1318
  */
1412
  */
1319
-static int storef_int ( struct settings *settings, struct setting *setting,
1320
-			const char *value, unsigned int size ) {
1413
+static int parse_int_setting ( const char *value, void *buf, size_t len,
1414
+			       unsigned int size ) {
1321
 	union {
1415
 	union {
1322
 		uint32_t num;
1416
 		uint32_t num;
1323
 		uint8_t bytes[4];
1417
 		uint8_t bytes[4];
1324
 	} u;
1418
 	} u;
1325
 	char *endp;
1419
 	char *endp;
1326
 
1420
 
1421
+	/* Parse value */
1327
 	u.num = htonl ( strtoul ( value, &endp, 0 ) );
1422
 	u.num = htonl ( strtoul ( value, &endp, 0 ) );
1328
 	if ( *endp )
1423
 	if ( *endp )
1329
 		return -EINVAL;
1424
 		return -EINVAL;
1330
-	return store_setting ( settings, setting, 
1331
-			       &u.bytes[ sizeof ( u ) - size ], size );
1425
+
1426
+	/* Copy to buffer */
1427
+	if ( len > size )
1428
+		len = size;
1429
+	memcpy ( buf, &u.bytes[ sizeof ( u ) - size ], len );
1430
+
1431
+	return size;
1332
 }
1432
 }
1333
 
1433
 
1334
 /**
1434
 /**
1335
- * Parse and store value of 8-bit integer setting
1435
+ * Parse 8-bit integer setting value
1336
  *
1436
  *
1337
- * @v settings		Settings block
1338
- * @v setting		Setting to store
1339
- * @v value		Formatted setting data
1437
+ * @v value		Formatted setting value
1438
+ * @v buf		Buffer to contain raw value
1439
+ * @v len		Length of buffer
1340
  * @v size		Integer size, in bytes
1440
  * @v size		Integer size, in bytes
1341
- * @ret rc		Return status code
1441
+ * @ret len		Length of raw value, or negative error
1342
  */
1442
  */
1343
-static int storef_int8 ( struct settings *settings, struct setting *setting,
1344
-			 const char *value ) {
1345
-	return storef_int ( settings, setting, value, 1 );
1443
+static int parse_int8_setting ( const char *value, void *buf, size_t len ) {
1444
+	return parse_int_setting ( value, buf, len, sizeof ( uint8_t ) );
1346
 }
1445
 }
1347
 
1446
 
1348
 /**
1447
 /**
1349
- * Parse and store value of 16-bit integer setting
1448
+ * Parse 16-bit integer setting value
1350
  *
1449
  *
1351
- * @v settings		Settings block
1352
- * @v setting		Setting to store
1353
- * @v value		Formatted setting data
1450
+ * @v value		Formatted setting value
1451
+ * @v buf		Buffer to contain raw value
1452
+ * @v len		Length of buffer
1354
  * @v size		Integer size, in bytes
1453
  * @v size		Integer size, in bytes
1355
- * @ret rc		Return status code
1454
+ * @ret len		Length of raw value, or negative error
1356
  */
1455
  */
1357
-static int storef_int16 ( struct settings *settings, struct setting *setting,
1358
-			  const char *value ) {
1359
-	return storef_int ( settings, setting, value, 2 );
1456
+static int parse_int16_setting ( const char *value, void *buf, size_t len ) {
1457
+	return parse_int_setting ( value, buf, len, sizeof ( uint16_t ) );
1360
 }
1458
 }
1361
 
1459
 
1362
 /**
1460
 /**
1363
- * Parse and store value of 32-bit integer setting
1461
+ * Parse 32-bit integer setting value
1364
  *
1462
  *
1365
- * @v settings		Settings block
1366
- * @v setting		Setting to store
1367
- * @v value		Formatted setting data
1463
+ * @v value		Formatted setting value
1464
+ * @v buf		Buffer to contain raw value
1465
+ * @v len		Length of buffer
1368
  * @v size		Integer size, in bytes
1466
  * @v size		Integer size, in bytes
1369
- * @ret rc		Return status code
1467
+ * @ret len		Length of raw value, or negative error
1370
  */
1468
  */
1371
-static int storef_int32 ( struct settings *settings, struct setting *setting,
1372
-			  const char *value ) {
1373
-	return storef_int ( settings, setting, value, 4 );
1469
+static int parse_int32_setting ( const char *value, void *buf, size_t len ) {
1470
+	return parse_int_setting ( value, buf, len, sizeof ( uint32_t ) );
1374
 }
1471
 }
1375
 
1472
 
1376
 /**
1473
 /**
1377
- * Fetch and format value of signed integer setting
1474
+ * Format signed integer setting value
1378
  *
1475
  *
1379
- * @v settings		Settings block, or NULL to search all blocks
1380
- * @v setting		Setting to fetch
1476
+ * @v raw		Raw setting value
1477
+ * @v raw_len		Length of raw setting value
1381
  * @v buf		Buffer to contain formatted value
1478
  * @v buf		Buffer to contain formatted value
1382
  * @v len		Length of buffer
1479
  * @v len		Length of buffer
1383
  * @ret len		Length of formatted value, or negative error
1480
  * @ret len		Length of formatted value, or negative error
1384
  */
1481
  */
1385
-static int fetchf_int ( struct settings *settings, struct setting *setting,
1386
-			char *buf, size_t len ) {
1387
-	long value;
1388
-	int rc;
1482
+static int format_int_setting ( const void *raw, size_t raw_len, char *buf,
1483
+				size_t len ) {
1484
+	signed long value;
1485
+	unsigned long dummy;
1486
+	int check_len;
1389
 
1487
 
1390
-	if ( ( rc = fetch_int_setting ( settings, setting, &value ) ) < 0 )
1391
-		return rc;
1488
+	/* Extract numeric value */
1489
+	check_len = numeric_setting_value ( raw, raw_len, &value, &dummy );
1490
+	if ( check_len < 0 )
1491
+		return check_len;
1492
+	assert ( check_len == ( int ) raw_len );
1493
+
1494
+	/* Format value */
1392
 	return snprintf ( buf, len, "%ld", value );
1495
 	return snprintf ( buf, len, "%ld", value );
1393
 }
1496
 }
1394
 
1497
 
1395
 /**
1498
 /**
1396
- * Fetch and format value of unsigned integer setting
1499
+ * Format unsigned integer setting value
1397
  *
1500
  *
1398
- * @v settings		Settings block, or NULL to search all blocks
1399
- * @v setting		Setting to fetch
1501
+ * @v raw		Raw setting value
1502
+ * @v raw_len		Length of raw setting value
1400
  * @v buf		Buffer to contain formatted value
1503
  * @v buf		Buffer to contain formatted value
1401
  * @v len		Length of buffer
1504
  * @v len		Length of buffer
1402
  * @ret len		Length of formatted value, or negative error
1505
  * @ret len		Length of formatted value, or negative error
1403
  */
1506
  */
1404
-static int fetchf_uint ( struct settings *settings, struct setting *setting,
1405
-			 char *buf, size_t len ) {
1507
+static int format_uint_setting ( const void *raw, size_t raw_len, char *buf,
1508
+				 size_t len ) {
1509
+	signed long dummy;
1406
 	unsigned long value;
1510
 	unsigned long value;
1407
-	int rc;
1511
+	int check_len;
1408
 
1512
 
1409
-	if ( ( rc = fetch_uint_setting ( settings, setting, &value ) ) < 0 )
1410
-		return rc;
1513
+	/* Extract numeric value */
1514
+	check_len = numeric_setting_value ( raw, raw_len, &dummy, &value );
1515
+	if ( check_len < 0 )
1516
+		return check_len;
1517
+	assert ( check_len == ( int ) raw_len );
1518
+
1519
+	/* Format value */
1411
 	return snprintf ( buf, len, "%#lx", value );
1520
 	return snprintf ( buf, len, "%#lx", value );
1412
 }
1521
 }
1413
 
1522
 
1414
 /** A signed 8-bit integer setting type */
1523
 /** A signed 8-bit integer setting type */
1415
 struct setting_type setting_type_int8 __setting_type = {
1524
 struct setting_type setting_type_int8 __setting_type = {
1416
 	.name = "int8",
1525
 	.name = "int8",
1417
-	.storef = storef_int8,
1418
-	.fetchf = fetchf_int,
1526
+	.parse = parse_int8_setting,
1527
+	.format = format_int_setting,
1419
 };
1528
 };
1420
 
1529
 
1421
 /** A signed 16-bit integer setting type */
1530
 /** A signed 16-bit integer setting type */
1422
 struct setting_type setting_type_int16 __setting_type = {
1531
 struct setting_type setting_type_int16 __setting_type = {
1423
 	.name = "int16",
1532
 	.name = "int16",
1424
-	.storef = storef_int16,
1425
-	.fetchf = fetchf_int,
1533
+	.parse = parse_int16_setting,
1534
+	.format = format_int_setting,
1426
 };
1535
 };
1427
 
1536
 
1428
 /** A signed 32-bit integer setting type */
1537
 /** A signed 32-bit integer setting type */
1429
 struct setting_type setting_type_int32 __setting_type = {
1538
 struct setting_type setting_type_int32 __setting_type = {
1430
 	.name = "int32",
1539
 	.name = "int32",
1431
-	.storef = storef_int32,
1432
-	.fetchf = fetchf_int,
1540
+	.parse = parse_int32_setting,
1541
+	.format = format_int_setting,
1433
 };
1542
 };
1434
 
1543
 
1435
 /** An unsigned 8-bit integer setting type */
1544
 /** An unsigned 8-bit integer setting type */
1436
 struct setting_type setting_type_uint8 __setting_type = {
1545
 struct setting_type setting_type_uint8 __setting_type = {
1437
 	.name = "uint8",
1546
 	.name = "uint8",
1438
-	.storef = storef_int8,
1439
-	.fetchf = fetchf_uint,
1547
+	.parse = parse_int8_setting,
1548
+	.format = format_uint_setting,
1440
 };
1549
 };
1441
 
1550
 
1442
 /** An unsigned 16-bit integer setting type */
1551
 /** An unsigned 16-bit integer setting type */
1443
 struct setting_type setting_type_uint16 __setting_type = {
1552
 struct setting_type setting_type_uint16 __setting_type = {
1444
 	.name = "uint16",
1553
 	.name = "uint16",
1445
-	.storef = storef_int16,
1446
-	.fetchf = fetchf_uint,
1554
+	.parse = parse_int16_setting,
1555
+	.format = format_uint_setting,
1447
 };
1556
 };
1448
 
1557
 
1449
 /** An unsigned 32-bit integer setting type */
1558
 /** An unsigned 32-bit integer setting type */
1450
 struct setting_type setting_type_uint32 __setting_type = {
1559
 struct setting_type setting_type_uint32 __setting_type = {
1451
 	.name = "uint32",
1560
 	.name = "uint32",
1452
-	.storef = storef_int32,
1453
-	.fetchf = fetchf_uint,
1561
+	.parse = parse_int32_setting,
1562
+	.format = format_uint_setting,
1454
 };
1563
 };
1455
 
1564
 
1456
 /**
1565
 /**
1457
- * Parse and store value of hex string setting
1566
+ * Parse hex string setting value
1458
  *
1567
  *
1459
- * @v settings		Settings block
1460
- * @v setting		Setting to store
1461
- * @v value		Formatted setting data
1462
- * @ret rc		Return status code
1568
+ * @v value		Formatted setting value
1569
+ * @v buf		Buffer to contain raw value
1570
+ * @v len		Length of buffer
1571
+ * @ret len		Length of raw value, or negative error
1463
  */
1572
  */
1464
-static int storef_hex ( struct settings *settings, struct setting *setting,
1465
-			const char *value ) {
1573
+static int parse_hex_setting ( const char *value, void *buf, size_t len ) {
1466
 	char *ptr = ( char * ) value;
1574
 	char *ptr = ( char * ) value;
1467
-	uint8_t bytes[ strlen ( value ) ]; /* cannot exceed strlen(value) */
1468
-	unsigned int len = 0;
1575
+	uint8_t *bytes = buf;
1576
+	unsigned int count = 0;
1577
+	uint8_t byte;
1469
 
1578
 
1470
 	while ( 1 ) {
1579
 	while ( 1 ) {
1471
-		bytes[len++] = strtoul ( ptr, &ptr, 16 );
1580
+		byte = strtoul ( ptr, &ptr, 16 );
1581
+		if ( count++ < len )
1582
+			*bytes++ = byte;
1472
 		switch ( *ptr ) {
1583
 		switch ( *ptr ) {
1473
 		case '\0' :
1584
 		case '\0' :
1474
-			return store_setting ( settings, setting, bytes, len );
1585
+			return count;
1475
 		case ':' :
1586
 		case ':' :
1476
 		case '-' :
1587
 		case '-' :
1477
 			ptr++;
1588
 			ptr++;
1483
 }
1594
 }
1484
 
1595
 
1485
 /**
1596
 /**
1486
- * Fetch and format value of hex string setting
1597
+ * Format hex string setting value
1487
  *
1598
  *
1488
- * @v settings		Settings block, or NULL to search all blocks
1489
- * @v setting		Setting to fetch
1599
+ * @v raw		Raw setting value
1600
+ * @v raw_len		Length of raw setting value
1490
  * @v buf		Buffer to contain formatted value
1601
  * @v buf		Buffer to contain formatted value
1491
  * @v len		Length of buffer
1602
  * @v len		Length of buffer
1492
  * @v delimiter		Byte delimiter
1603
  * @v delimiter		Byte delimiter
1493
  * @ret len		Length of formatted value, or negative error
1604
  * @ret len		Length of formatted value, or negative error
1494
  */
1605
  */
1495
-static int fetchf_hex ( struct settings *settings, struct setting *setting,
1496
-			char *buf, size_t len, const char *delimiter ) {
1497
-	int raw_len;
1498
-	int check_len;
1606
+static int format_hex_setting ( const void *raw, size_t raw_len, char *buf,
1607
+				size_t len, const char *delimiter ) {
1608
+	const uint8_t *bytes = raw;
1499
 	int used = 0;
1609
 	int used = 0;
1500
-	int i;
1501
-
1502
-	raw_len = fetch_setting_len ( settings, setting );
1503
-	if ( raw_len < 0 )
1504
-		return raw_len;
1505
-
1506
-	{
1507
-		uint8_t raw[raw_len];
1508
-
1509
-		check_len = fetch_setting ( settings, setting, raw,
1510
-					    sizeof ( raw ) );
1511
-		if ( check_len < 0 )
1512
-			return check_len;
1513
-		assert ( check_len == raw_len );
1514
-		
1515
-		if ( len )
1516
-			buf[0] = 0; /* Ensure that a terminating NUL exists */
1517
-		for ( i = 0 ; i < raw_len ; i++ ) {
1518
-			used += ssnprintf ( ( buf + used ), ( len - used ),
1519
-					    "%s%02x", ( used ? delimiter : "" ),
1520
-					    raw[i] );
1521
-		}
1522
-		return used;
1610
+	unsigned int i;
1611
+
1612
+	if ( len )
1613
+		buf[0] = 0; /* Ensure that a terminating NUL exists */
1614
+	for ( i = 0 ; i < raw_len ; i++ ) {
1615
+		used += ssnprintf ( ( buf + used ), ( len - used ),
1616
+				    "%s%02x", ( used ? delimiter : "" ),
1617
+				    bytes[i] );
1523
 	}
1618
 	}
1619
+	return used;
1524
 }
1620
 }
1525
 
1621
 
1526
 /**
1622
 /**
1527
- * Fetch and format value of hex string setting (using colon delimiter)
1623
+ * Format hex string setting value (using colon delimiter)
1528
  *
1624
  *
1529
- * @v settings		Settings block, or NULL to search all blocks
1530
- * @v setting		Setting to fetch
1625
+ * @v raw		Raw setting value
1626
+ * @v raw_len		Length of raw setting value
1531
  * @v buf		Buffer to contain formatted value
1627
  * @v buf		Buffer to contain formatted value
1532
  * @v len		Length of buffer
1628
  * @v len		Length of buffer
1533
  * @ret len		Length of formatted value, or negative error
1629
  * @ret len		Length of formatted value, or negative error
1534
  */
1630
  */
1535
-static int fetchf_hex_colon ( struct settings *settings,
1536
-			      struct setting *setting,
1537
-			      char *buf, size_t len ) {
1538
-	return fetchf_hex ( settings, setting, buf, len, ":" );
1631
+static int format_hex_colon_setting ( const void *raw, size_t raw_len,
1632
+				      char *buf, size_t len ) {
1633
+	return format_hex_setting ( raw, raw_len, buf, len, ":" );
1539
 }
1634
 }
1540
 
1635
 
1541
 /**
1636
 /**
1542
- * Fetch and format value of hex string setting (using hyphen delimiter)
1637
+ * Format hex string setting value (using hyphen delimiter)
1543
  *
1638
  *
1544
- * @v settings		Settings block, or NULL to search all blocks
1545
- * @v setting		Setting to fetch
1639
+ * @v raw		Raw setting value
1640
+ * @v raw_len		Length of raw setting value
1546
  * @v buf		Buffer to contain formatted value
1641
  * @v buf		Buffer to contain formatted value
1547
  * @v len		Length of buffer
1642
  * @v len		Length of buffer
1548
  * @ret len		Length of formatted value, or negative error
1643
  * @ret len		Length of formatted value, or negative error
1549
  */
1644
  */
1550
-static int fetchf_hex_hyphen ( struct settings *settings,
1551
-			       struct setting *setting,
1552
-			       char *buf, size_t len ) {
1553
-	return fetchf_hex ( settings, setting, buf, len, "-" );
1645
+static int format_hex_hyphen_setting ( const void *raw, size_t raw_len,
1646
+				       char *buf, size_t len ) {
1647
+	return format_hex_setting ( raw, raw_len, buf, len, "-" );
1554
 }
1648
 }
1555
 
1649
 
1556
 /** A hex-string setting (colon-delimited) */
1650
 /** A hex-string setting (colon-delimited) */
1557
 struct setting_type setting_type_hex __setting_type = {
1651
 struct setting_type setting_type_hex __setting_type = {
1558
 	.name = "hex",
1652
 	.name = "hex",
1559
-	.storef = storef_hex,
1560
-	.fetchf = fetchf_hex_colon,
1653
+	.parse = parse_hex_setting,
1654
+	.format = format_hex_colon_setting,
1561
 };
1655
 };
1562
 
1656
 
1563
 /** A hex-string setting (hyphen-delimited) */
1657
 /** A hex-string setting (hyphen-delimited) */
1564
 struct setting_type setting_type_hexhyp __setting_type = {
1658
 struct setting_type setting_type_hexhyp __setting_type = {
1565
 	.name = "hexhyp",
1659
 	.name = "hexhyp",
1566
-	.storef = storef_hex,
1567
-	.fetchf = fetchf_hex_hyphen,
1660
+	.parse = parse_hex_setting,
1661
+	.format = format_hex_hyphen_setting,
1568
 };
1662
 };
1569
 
1663
 
1570
 /**
1664
 /**
1571
- * Parse and store value of UUID setting
1665
+ * Parse UUID setting value
1572
  *
1666
  *
1573
- * @v settings		Settings block
1574
- * @v setting		Setting to store
1575
- * @v value		Formatted setting data
1576
- * @ret rc		Return status code
1667
+ * @v value		Formatted setting value
1668
+ * @v buf		Buffer to contain raw value
1669
+ * @v len		Length of buffer
1670
+ * @ret len		Length of raw value, or negative error
1577
  */
1671
  */
1578
-static int storef_uuid ( struct settings *settings __unused,
1579
-			 struct setting *setting __unused,
1580
-			 const char *value __unused ) {
1672
+static int parse_uuid_setting ( const char *value __unused,
1673
+				void *buf __unused, size_t len __unused ) {
1581
 	return -ENOTSUP;
1674
 	return -ENOTSUP;
1582
 }
1675
 }
1583
 
1676
 
1584
 /**
1677
 /**
1585
- * Fetch and format value of UUID setting
1678
+ * Format UUID setting value
1586
  *
1679
  *
1587
- * @v settings		Settings block, or NULL to search all blocks
1588
- * @v setting		Setting to fetch
1680
+ * @v raw		Raw setting value
1681
+ * @v raw_len		Length of raw setting value
1589
  * @v buf		Buffer to contain formatted value
1682
  * @v buf		Buffer to contain formatted value
1590
  * @v len		Length of buffer
1683
  * @v len		Length of buffer
1591
  * @ret len		Length of formatted value, or negative error
1684
  * @ret len		Length of formatted value, or negative error
1592
  */
1685
  */
1593
-static int fetchf_uuid ( struct settings *settings, struct setting *setting,
1594
-			 char *buf, size_t len ) {
1595
-	union uuid uuid;
1596
-	int raw_len;
1686
+static int format_uuid_setting ( const void *raw, size_t raw_len, char *buf,
1687
+				 size_t len ) {
1688
+	const union uuid *uuid = raw;
1689
+
1690
+	/* Range check */
1691
+	if ( raw_len != sizeof ( *uuid ) )
1692
+		return -ERANGE;
1597
 
1693
 
1598
-	if ( ( raw_len = fetch_uuid_setting ( settings, setting, &uuid ) ) < 0)
1599
-		return raw_len;
1600
-	return snprintf ( buf, len, "%s", uuid_ntoa ( &uuid ) );
1694
+	/* Format value */
1695
+	return snprintf ( buf, len, "%s", uuid_ntoa ( uuid ) );
1601
 }
1696
 }
1602
 
1697
 
1603
 /** UUID setting type */
1698
 /** UUID setting type */
1604
 struct setting_type setting_type_uuid __setting_type = {
1699
 struct setting_type setting_type_uuid __setting_type = {
1605
 	.name = "uuid",
1700
 	.name = "uuid",
1606
-	.storef = storef_uuid,
1607
-	.fetchf = fetchf_uuid,
1701
+	.parse = parse_uuid_setting,
1702
+	.format = format_uuid_setting,
1608
 };
1703
 };
1609
 
1704
 
1610
 /******************************************************************************
1705
 /******************************************************************************

+ 1
- 1
src/core/uuid.c 查看文件

35
  * @v uuid		UUID
35
  * @v uuid		UUID
36
  * @ret string		UUID in canonical form
36
  * @ret string		UUID in canonical form
37
  */
37
  */
38
-char * uuid_ntoa ( union uuid *uuid ) {
38
+char * uuid_ntoa ( const union uuid *uuid ) {
39
 	static char buf[37]; /* "00000000-0000-0000-0000-000000000000" */
39
 	static char buf[37]; /* "00000000-0000-0000-0000-000000000000" */
40
 
40
 
41
 	sprintf ( buf, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",
41
 	sprintf ( buf, "%08x-%04x-%04x-%04x-%02x%02x%02x%02x%02x%02x",

+ 13
- 28
src/include/ipxe/settings.h 查看文件

161
 	 * This is the name exposed to the user (e.g. "string").
161
 	 * This is the name exposed to the user (e.g. "string").
162
 	 */
162
 	 */
163
 	const char *name;
163
 	const char *name;
164
-	/** Parse and set value of setting
164
+	/** Parse formatted setting value
165
 	 *
165
 	 *
166
-	 * @v settings		Settings block
167
-	 * @v setting		Setting to store
168
-	 * @v value		Formatted setting data
169
-	 * @ret rc		Return status code
166
+	 * @v value		Formatted setting value
167
+	 * @v buf		Buffer to contain raw value
168
+	 * @v len		Length of buffer
169
+	 * @ret len		Length of raw value, or negative error
170
 	 */
170
 	 */
171
-	int ( * storef ) ( struct settings *settings, struct setting *setting,
172
-			   const char *value );
173
-	/** Fetch and format value of setting
171
+	int ( * parse ) ( const char *value, void *buf, size_t len );
172
+	/** Format setting value
174
 	 *
173
 	 *
175
-	 * @v settings		Settings block
176
-	 * @v setting		Setting to fetch
174
+	 * @v raw		Raw setting value
175
+	 * @v raw_len		Length of raw setting value
177
 	 * @v buf		Buffer to contain formatted value
176
 	 * @v buf		Buffer to contain formatted value
178
 	 * @v len		Length of buffer
177
 	 * @v len		Length of buffer
179
 	 * @ret len		Length of formatted value, or negative error
178
 	 * @ret len		Length of formatted value, or negative error
180
 	 */
179
 	 */
181
-	int ( * fetchf ) ( struct settings *settings, struct setting *setting,
182
-			   char *buf, size_t len );
180
+	int ( * format ) ( const void *raw, size_t raw_len, char *buf,
181
+			   size_t len );
183
 };
182
 };
184
 
183
 
185
 /** Configuration setting type table */
184
 /** Configuration setting type table */
273
 
272
 
274
 extern int setting_name ( struct settings *settings, struct setting *setting,
273
 extern int setting_name ( struct settings *settings, struct setting *setting,
275
 			  char *buf, size_t len );
274
 			  char *buf, size_t len );
275
+extern int fetchf_setting ( struct settings *settings, struct setting *setting,
276
+			    char *buf, size_t len );
276
 extern int storef_setting ( struct settings *settings,
277
 extern int storef_setting ( struct settings *settings,
277
 			    struct setting *setting,
278
 			    struct setting *setting,
278
 			    const char *value );
279
 			    const char *value );
354
 	return store_setting ( settings, setting, NULL, 0 );
355
 	return store_setting ( settings, setting, NULL, 0 );
355
 }
356
 }
356
 
357
 
357
-/**
358
- * Fetch and format value of setting
359
- *
360
- * @v settings		Settings block, or NULL to search all blocks
361
- * @v setting		Setting to fetch
362
- * @v type		Settings type
363
- * @v buf		Buffer to contain formatted value
364
- * @v len		Length of buffer
365
- * @ret len		Length of formatted value, or negative error
366
- */
367
-static inline int fetchf_setting ( struct settings *settings,
368
-				   struct setting *setting,
369
-				   char *buf, size_t len ) {
370
-	return setting->type->fetchf ( settings, setting, buf, len );
371
-}
372
-
373
 /**
358
 /**
374
  * Delete named setting
359
  * Delete named setting
375
  *
360
  *

+ 1
- 1
src/include/ipxe/uuid.h 查看文件

28
 	uint8_t raw[16];
28
 	uint8_t raw[16];
29
 };
29
 };
30
 
30
 
31
-extern char * uuid_ntoa ( union uuid *uuid );
31
+extern char * uuid_ntoa ( const union uuid *uuid );
32
 
32
 
33
 #endif /* _IPXE_UUID_H */
33
 #endif /* _IPXE_UUID_H */

正在加载...
取消
保存