This commit is contained in:
louiscklaw
2025-01-31 21:28:24 +08:00
parent ca0eb416dd
commit 86fddf271b
10 changed files with 336 additions and 0 deletions

8
mercury25/gitUpdate.bat Normal file
View File

@@ -0,0 +1,8 @@
git status .
echo "press enter to continue"
@pause
git add .
git commit -m"update mercury25,"
start git push

3
mercury25/task1/notes.md Normal file
View File

@@ -0,0 +1,3 @@
https://github.com/errorterror6/COMP1521-24T2
TEL: 9 7 6 6 2 6 2 2

View File

@@ -0,0 +1,22 @@
# COMP1521 22T2 ... a general makefile for multiple exercises
ifneq (, $(shell which dcc))
CC = dcc
else ifneq (, $(shell which clang) )
CC = clang
else
CC = gcc
endif
EXERCISES ?=
CLEAN_FILES ?=
.DEFAULT_GOAL = all
.PHONY: all clean
-include *.mk
all: ${EXERCISES}
clean:
-rm -f ${CLEAN_FILES}

View File

@@ -0,0 +1,73 @@
////////////////////////////////////////////////////////////////////////
// COMP1521 24T2 --- Assignment 2: `rbuoy', a simple file synchroniser
// <https://cgi.cse.unsw.edu.au/~cs1521/24T2/assignments/ass2/index.html>
//
// Written by YOUR-NAME-HERE (z5555555) on INSERT-DATE-HERE.
// INSERT-DESCRIPTION-OF-PROGAM-HERE
//
// 2023-07-12 v1.0 Team COMP1521 <cs1521 at cse.unsw.edu.au>
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "rbuoy.h"
/// @brief Create a TABI file from an array of pathnames.
/// @param out_pathname A path to where the new TABI file should be created.
/// @param in_pathnames An array of strings containing, in order, the files
// that should be placed in the new TABI file.
/// @param num_in_pathnames The length of the `in_pathnames` array. In
/// subset 5, when this is zero, you should include
/// everything in the current directory.
void stage_1(char *out_pathname, char *in_pathnames[], size_t num_in_pathnames) {
// TODO: implement this.
// Hint: you will need to:
// * Open `out_pathname` using fopen, which will be the output TABI file.
// * For each pathname in `in_pathnames`:
// * Write the length of the pathname as a 2 byte little endian integer
// * Write the pathname
// * Check the size of the input file, e.g. using stat
// * Compute the number of blocks using number_of_blocks_in_file
// * Write the number of blocks as a 3 byte little endian integer
// * Open the input file, and read in blocks of size BLOCK_SIZE, and
// * For each block call hash_black to compute the hash
// * Write out that hash as an 8 byte little endian integer
// Each time you need to write out a little endian integer you should
// compute each byte using bitwise operations like <<, &, or |
}
/// @brief Create a TBBI file from a TABI file.
/// @param out_pathname A path to where the new TBBI file should be created.
/// @param in_pathname A path to where the existing TABI file is located.
void stage_2(char *out_pathname, char *in_pathname) {
// TODO: implement this.
}
/// @brief Create a TCBI file from a TBBI file.
/// @param out_pathname A path to where the new TCBI file should be created.
/// @param in_pathname A path to where the existing TBBI file is located.
void stage_3(char *out_pathname, char *in_pathname) {
// TODO: implement this.
}
/// @brief Apply a TCBI file to the filesystem.
/// @param in_pathname A path to where the existing TCBI file is located.
void stage_4(char *in_pathname) {
// TODO: implement this.
}

View File

@@ -0,0 +1,42 @@
#ifndef RSYNC_H
#define RSYNC_H
#include <stdlib.h>
#include <stdint.h>
// Sizes (in bytes) of various fields.
#define MAGIC_SIZE 4
#define NUM_RECORDS_SIZE 1
#define PATHNAME_LEN_SIZE 2
#define NUM_BLOCKS_SIZE 3
#define HASH_SIZE 8
#define MODE_SIZE 10
#define FILE_SIZE_SIZE 4
#define BLOCK_INDEX_SIZE 3
#define UPDATE_LEN_SIZE 2
#define MATCH_BYTE_BITS 8
// Note that the rbuoy index magic numbers are exactly 4 bytes, and so
// don't include the nul-terminator implicit at the end of these strings.
#define TYPE_A_MAGIC "TABI"
#define TYPE_B_MAGIC "TBBI"
#define TYPE_C_MAGIC "TCBI"
// The maximum size of a block (the trailing block of a file might be smaller).
#define BLOCK_SIZE 256
// rbuoy.c
void stage_1(char *out_pathname, char *in_pathnames[], size_t num_in_pathnames);
void stage_2(char *out_pathname, char *in_pathname);
void stage_3(char *out_pathname, char *in_pathname);
void stage_4(char *in_pathname);
// rbuoy_provided.c
uint64_t hash_block(char block[], size_t block_size);
size_t number_of_blocks_in_file(size_t num_bytes);
size_t num_tbbi_match_bytes(size_t num_blocks);
#endif /* RSYNC_H */

View File

@@ -0,0 +1,23 @@
CFLAGS =
ifneq (, $(shell which dcc))
CC ?= dcc
else
CC ?= clang
CFLAGS += -Wall
endif
EXERCISES += rbuoy
SRC = rbuoy.c rbuoy_main.c rbuoy_provided.c
INCLUDES = rbuoy.h
# if you add extra .c files, add them here
SRC +=
# if you add extra .h files, add them here
INCLUDES +=
rbuoy: $(SRC) $(INCLUDES)
$(CC) $(CFLAGS) $(SRC) -o $@

View File

@@ -0,0 +1,23 @@
// Given up to BLOCK_SIZE (256) bytes, produce the
// hash of that block. You should not modify this file,
// and should not attempt to compile it as part of your
// solution.
// You can run this program yourself using
// 1521 rbuoy-hash-block - for example,
// 1521 rbuoy-hash-block < examples/aaa/emojis.txt
#include "rbuoy.h"
#include <stdio.h>
int main(void) {
char buf[BLOCK_SIZE];
// Read in up to BLOCK_SIZE bytes from stdin
size_t bytes_read = fread(buf, 1, BLOCK_SIZE, stdin);
// It's important that we pass in the number of bytes read
// to hash_block - not BLOCK_SIZE - since it's possible that
// we reach the end of file/user input before filling up
// the buffer.
printf("%016lx\n", hash_block(buf, bytes_read));
return 0;
}

View File

@@ -0,0 +1,95 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <getopt.h>
#include "rbuoy.h"
int main(int argc, char **argv) {
int stage = 0;
for (;;) {
int option_index;
int opt = getopt_long(
argc, argv,
":1234",
(struct option[]) {
{"stage-1", no_argument, NULL, 1},
{"stage-2", no_argument, NULL, 2},
{"stage-3", no_argument, NULL, 3},
{"stage-4", no_argument, NULL, 4},
{0, 0, 0, '?'},
},
&option_index
);
if (opt == -1) {
break;
}
switch (opt) {
case 1:
case 2:
case 3:
case 4: {
stage = opt;
break;
}
case ':':
case '?':
default: {
fprintf(stderr, "Usage: %s [--stage-1|--stage-2|--stage-3|--stage-4]\n", argv[0]);
return EXIT_FAILURE;
}
}
}
switch (stage) {
case 1: {
if (argc - optind < 1) {
fprintf(stderr, "Usage: %s --stage-1 <outfile> [<file> ...]\n", argv[0]);
return EXIT_FAILURE;
}
char *outfile = argv[optind];
char **files = argv + optind + 1;
size_t num_files = argc - optind - 1;
stage_1(outfile, files, num_files);
break;
}
case 2: {
if (argc - optind != 2) {
fprintf(stderr, "Usage: %s --stage-2 <outfile> <infile>\n", argv[0]);
return EXIT_FAILURE;
}
char *outfile = argv[optind];
char *infile = argv[optind + 1];
stage_2(outfile, infile);
break;
}
case 3: {
if (argc - optind != 2) {
fprintf(stderr, "Usage: %s --stage-3 <outfile> <infile>\n", argv[0]);
return EXIT_FAILURE;
}
char *outfile = argv[optind];
char *infile = argv[optind + 1];
stage_3(outfile, infile);
break;
}
case 4: {
if (argc - optind != 1) {
fprintf(stderr, "Usage: %s --stage-4 <infile>\n", argv[0]);
return EXIT_FAILURE;
}
char *infile = argv[optind];
stage_4(infile);
break;
}
case 0: {
fprintf(stderr, "Usage: %s [--stage-1|--stage-2|--stage-3|--stage-4]\n", argv[0]);
return EXIT_FAILURE;
}
}
return EXIT_SUCCESS;
}

View File

@@ -0,0 +1,47 @@
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include "rbuoy.h"
/// @brief Compute the hash of a block of bytes, using the 64 bit NFV-1a hash.
///
/// If you wish to represent your bytes differently (say as an array of uint8_t)
/// you may want to make a wrapper around this function.
///
/// @param block The array of bytes to be hashed.
/// @param block_size The length of that array. Must be at most 256.
///
/// @return The hash of the block.
uint64_t hash_block(char block[], size_t block_size) {
assert(block_size <= BLOCK_SIZE);
uint64_t hash = 0xcbf29ce484222325ull;
for (size_t i = 0; i < block_size; ++i) {
hash ^= (unsigned char) block[i];
hash *= 0x100000001b3;
}
return hash;
}
/// @brief Compute the number of blocks in a file, given its size.
/// @param num_bytes The number of bytes in a file.
/// @return The nunber of blocks that are needed for that file.
size_t number_of_blocks_in_file(size_t num_bytes) {
// This is equal to
// ceil(num_bytes / BLOCK_SIZE)
return (num_bytes + BLOCK_SIZE - 1) / BLOCK_SIZE;
}
/// @brief Compute the nunber of 'match' bytes that are needed for a TBBI record.
/// @param num_blocks The number of blocks.
/// @return The number of 'match' bytes needed.
size_t num_tbbi_match_bytes(size_t num_blocks) {
// This is equal to
// ceil(num_blocks / 8)
return (num_blocks + MATCH_BYTE_BITS - 1) / MATCH_BYTE_BITS;
}