/* Copyright(C) 2009 Yoshinori Oota All rights reserved. */
#include <stdio.h>
#include <stdlib.h>
struct Memento;
/* Originator Interface */
struct Originator {
int saved_;
char* words_;
void (*Print)(struct Originator* pthis);
void (*Write)(struct Originator* pthis ,const char* words);
struct Memento* (*CreateMemento)(struct Originator* pthis);
void (*SetMemento)(struct Originator* pthis ,struct Memento* m);
};
struct Originator* New_Originator();
void Delete_Originator(struct Originator* org);
void Originator_Print(struct Originator* pthis);
void Originator_Write(struct Originator* pthis ,const char* words);
struct Memento* Originator_CreateMemento(struct Originator* pthis);
void Originator_SetMemento(struct Originator* pthis ,struct Memento* memento);
/* Memento Interface */
struct Memento {
char* snapshot_;
char* (*GetSnapshot)(struct Memento* pthis);
};
struct Memento* New_Memento(char* words);
void Delete_Memento(struct Memento* memento);
char* Memento_GetSnapshot(struct Memento* pthis);
/* Originator Class Implementation */
struct Originator* New_Originator() {
struct Originator* orginator = (struct Originator*)malloc(sizeof(struct Originator));
orginator->saved_ = 0;
orginator->words_ = NULL;
orginator->Print = &Originator_Print;
orginator->Write = &Originator_Write;
orginator->SetMemento = &Originator_SetMemento;
orginator->CreateMemento = &Originator_CreateMemento;
return originator;
}
void Delete_Originator(struct Originator* orginator) {
if (originator == NULL) {
return;
}
free(orginator->words_);
orginator->words_ = NULL;
free(orginator);
orginator = NULL;
return;
}
void Originator_Write(struct Originator* pthis ,const char *words) {
char* buf = NULL;
if (pthis->words_ != NULL && pthis->saved_ == 1) { //すでに保存された文字なら上書き
buf = (char*)malloc(strlen(words)+1);
strcpy(buf ,words);
pthis->saved_ = 0; //保存状態をリセット
free(pthis->words_);
pthis->words_ = buf;
} else if (pthis->words_ != NULL && pthis->saved_ == 0) { //まだ保存されていない文字なら追記
buf = (char*)malloc(strlen(pthis->words_)+strlen(words)+1);
strcpy(buf, pthis->words_);
strcat(buf, words);
free(pthis->words_);
pthis->words_ = buf;
} else {
buf = (char*)malloc(strlen(words)+1);
strcpy(buf ,words);
pthis->words_ = buf;
}
return;
}
struct Memento* Originator_CreateMemento(struct Originator* pthis) {
struct Memento* memento = NULL;
memento = New_Memento(pthis->words_);
pthis->saved_ = 1;
return memento;
}
void Originator_SetMemento(struct Originator* pthis ,struct Memento* memento) {
char* snapshot = NULL;
snapshot = memento->GetSnapshot(memento);
if (pthis->words_ != NULL) {
free(pthis->words_);
}
pthis->words_ = snapshot;
return;
}
void Originator_Print(struct Originator* pthis) {
printf("******************\n");
printf("%s\n" ,pthis->words_);
return;
}
/* Memento Class Interface */
struct Memento* New_Memento(char* words) {
char* buf = NULL;
struct Memento* memento = NULL;
buf = (char*)malloc(strlen(words)+1);
strcpy(buf ,words);
memento = (struct Memento*)malloc(sizeof(struct Memento));
memento->snapshot_ = buf;
memento->GetSnapshot = &Memento_GetSnapshot;
return memento;
}
void Delete_Memento(struct Memento* memento) {
if (memento == NULL) {
return;
}
free(memento->snapshot_);
memento->snapshot_ = NULL;
free(memento);
memento = NULL;
return;
}
char* Memento_GetSnapshot(struct Memento* pthis) {
char* buf = NULL;
buf = (char*)malloc(strlen(pthis->snapshot_)+1);
strcpy(buf ,pthis->snapshot_);
return buf;
}
/* CareTaker Implementation */
struct MementoList {
struct Memento* memento_;
struct MementoList* next_;
};
struct MementoList* gMementoTop = NULL;
struct MementoList* gMementoLast = NULL;
int gMementoMaxNum = 0;
void CareTaker_Save(struct Originator* originator) {
struct MementoList* list = NULL;
list = (struct MementoList*)malloc(sizeof(struct MementoList));
list->memento_ = originator->CreateMemento(originator);
list->next_ = NULL;
if (gMementoTop == NULL) {
gMementoTop = list;
gMementoLast = list;
} else {
gMementoLast->next_ = list;
gMementoLast = list;
}
++gMementoMaxNum;
return;
}
void CareTaker_PutBack(struct Originator* originator ,int index) {
int i = 0;
struct MementoList* cur = gMementoTop;
if (index >= gMementoMaxNum) return;
while (i < index) {
cur = cur->next_;
++i;
}
originator->SetMemento(originator ,cur->memento_);
return;
}
void CareTaker_Clean() {
struct MementoList* cur = NULL;
struct MementoList* tmp = NULL;
cur = gMementoTop;
while (cur != NULL) {
tmp = cur->next_;
Delete_Memento(cur->memento_);
free(cur);
cur = tmp;
}
return;
}
int main() {
struct Originator* originator = NULL;
originator = New_Originator();
originator->Write(originator ,"古池や蛙飛び込む池の音。\n");
CareTaker_Save(originator); // 最初の状態を記録(1世代目)
originator->Write(originator ,"雀の子そこのけそこのけ御馬が通る。つづいて、");
originator->Write(originator ,"夏草や兵どもが夢のあと。\n");
CareTaker_Save(originator); // 2世代目の状態を記録
originator->Write(originator ,"馬ぼくぼく我を絵にみん夏野哉。さらに、");
originator->Write(originator ,"馬かたはしらじしぐれの大井川。\n");
CareTaker_Save(originator); // 3世代目の状態を記録
originator->Print(originator);
// 2世代の状態にセットしよう!
CareTaker_PutBack(originator ,1);
originator->Print(originator);
// 最初の状態にセットしよう!
CareTaker_PutBack(originator ,0);
originator->Print(originator);
// 3世代目の状態に戻してみよう!
CareTaker_PutBack(originator ,2);
originator->Print(originator);
Delete_Originator(originator);
CareTaker_Clean();
return 0;
}
|